You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
308 lines
8.4 KiB
JavaScript
308 lines
8.4 KiB
JavaScript
7 years ago
|
require("./core");
|
||
|
var types = require("../lib/types");
|
||
|
var def = types.Type.def;
|
||
|
var or = types.Type.or;
|
||
|
var builtin = types.builtInTypes;
|
||
|
var isString = builtin.string;
|
||
|
var isNumber = builtin.number;
|
||
|
var isBoolean = builtin.boolean;
|
||
|
var defaults = require("../lib/shared").defaults;
|
||
|
|
||
|
def("JSXAttribute")
|
||
|
.bases("Node")
|
||
|
.build("name", "value")
|
||
|
.field("name", or(def("JSXIdentifier"), def("JSXNamespacedName")))
|
||
|
.field("value", or(
|
||
|
def("Literal"), // attr="value"
|
||
|
def("JSXExpressionContainer"), // attr={value}
|
||
|
null // attr= or just attr
|
||
|
), defaults["null"]);
|
||
|
|
||
|
def("JSXIdentifier")
|
||
|
.bases("Identifier")
|
||
|
.build("name")
|
||
|
.field("name", isString);
|
||
|
|
||
|
def("JSXNamespacedName")
|
||
|
.bases("Node")
|
||
|
.build("namespace", "name")
|
||
|
.field("namespace", def("JSXIdentifier"))
|
||
|
.field("name", def("JSXIdentifier"));
|
||
|
|
||
|
def("JSXMemberExpression")
|
||
|
.bases("MemberExpression")
|
||
|
.build("object", "property")
|
||
|
.field("object", or(def("JSXIdentifier"), def("JSXMemberExpression")))
|
||
|
.field("property", def("JSXIdentifier"))
|
||
|
.field("computed", isBoolean, defaults.false);
|
||
|
|
||
|
var JSXElementName = or(
|
||
|
def("JSXIdentifier"),
|
||
|
def("JSXNamespacedName"),
|
||
|
def("JSXMemberExpression")
|
||
|
);
|
||
|
|
||
|
def("JSXSpreadAttribute")
|
||
|
.bases("Node")
|
||
|
.build("argument")
|
||
|
.field("argument", def("Expression"));
|
||
|
|
||
|
var JSXAttributes = [or(
|
||
|
def("JSXAttribute"),
|
||
|
def("JSXSpreadAttribute")
|
||
|
)];
|
||
|
|
||
|
def("JSXExpressionContainer")
|
||
|
.bases("Expression")
|
||
|
.build("expression")
|
||
|
.field("expression", def("Expression"));
|
||
|
|
||
|
def("JSXElement")
|
||
|
.bases("Expression")
|
||
|
.build("openingElement", "closingElement", "children")
|
||
|
.field("openingElement", def("JSXOpeningElement"))
|
||
|
.field("closingElement", or(def("JSXClosingElement"), null), defaults["null"])
|
||
|
.field("children", [or(
|
||
|
def("JSXElement"),
|
||
|
def("JSXExpressionContainer"),
|
||
|
def("JSXText"),
|
||
|
def("Literal") // TODO Esprima should return JSXText instead.
|
||
|
)], defaults.emptyArray)
|
||
|
.field("name", JSXElementName, function() {
|
||
|
// Little-known fact: the `this` object inside a default function
|
||
|
// is none other than the partially-built object itself, and any
|
||
|
// fields initialized directly from builder function arguments
|
||
|
// (like openingElement, closingElement, and children) are
|
||
|
// guaranteed to be available.
|
||
|
return this.openingElement.name;
|
||
|
})
|
||
|
.field("selfClosing", isBoolean, function() {
|
||
|
return this.openingElement.selfClosing;
|
||
|
})
|
||
|
.field("attributes", JSXAttributes, function() {
|
||
|
return this.openingElement.attributes;
|
||
|
});
|
||
|
|
||
|
def("JSXOpeningElement")
|
||
|
.bases("Node") // TODO Does this make sense? Can't really be an JSXElement.
|
||
|
.build("name", "attributes", "selfClosing")
|
||
|
.field("name", JSXElementName)
|
||
|
.field("attributes", JSXAttributes, defaults.emptyArray)
|
||
|
.field("selfClosing", isBoolean, defaults["false"]);
|
||
|
|
||
|
def("JSXClosingElement")
|
||
|
.bases("Node") // TODO Same concern.
|
||
|
.build("name")
|
||
|
.field("name", JSXElementName);
|
||
|
|
||
|
def("JSXText")
|
||
|
.bases("Literal")
|
||
|
.build("value")
|
||
|
.field("value", isString);
|
||
|
|
||
|
def("JSXEmptyExpression").bases("Expression").build();
|
||
|
|
||
|
// Type Annotations
|
||
|
def("Type")
|
||
|
.bases("Node");
|
||
|
|
||
|
def("AnyTypeAnnotation")
|
||
|
.bases("Type");
|
||
|
|
||
|
def("VoidTypeAnnotation")
|
||
|
.bases("Type");
|
||
|
|
||
|
def("NumberTypeAnnotation")
|
||
|
.bases("Type");
|
||
|
|
||
|
def("NumberLiteralTypeAnnotation")
|
||
|
.bases("Type")
|
||
|
.build("value", "raw")
|
||
|
.field("value", isNumber)
|
||
|
.field("raw", isString);
|
||
|
|
||
|
def("StringTypeAnnotation")
|
||
|
.bases("Type");
|
||
|
|
||
|
def("StringLiteralTypeAnnotation")
|
||
|
.bases("Type")
|
||
|
.build("value", "raw")
|
||
|
.field("value", isString)
|
||
|
.field("raw", isString);
|
||
|
|
||
|
def("BooleanTypeAnnotation")
|
||
|
.bases("Type");
|
||
|
|
||
|
def("BooleanLiteralTypeAnnotation")
|
||
|
.bases("Type")
|
||
|
.build("value", "raw")
|
||
|
.field("value", isBoolean)
|
||
|
.field("raw", isString);
|
||
|
|
||
|
def("TypeAnnotation")
|
||
|
.bases("Node")
|
||
|
.build("typeAnnotation")
|
||
|
.field("typeAnnotation", def("Type"));
|
||
|
|
||
|
def("NullableTypeAnnotation")
|
||
|
.bases("Type")
|
||
|
.build("typeAnnotation")
|
||
|
.field("typeAnnotation", def("Type"));
|
||
|
|
||
|
def("FunctionTypeAnnotation")
|
||
|
.bases("Type")
|
||
|
.build("params", "returnType", "rest", "typeParameters")
|
||
|
.field("params", [def("FunctionTypeParam")])
|
||
|
.field("returnType", def("Type"))
|
||
|
.field("rest", or(def("FunctionTypeParam"), null))
|
||
|
.field("typeParameters", or(def("TypeParameterDeclaration"), null));
|
||
|
|
||
|
def("FunctionTypeParam")
|
||
|
.bases("Node")
|
||
|
.build("name", "typeAnnotation", "optional")
|
||
|
.field("name", def("Identifier"))
|
||
|
.field("typeAnnotation", def("Type"))
|
||
|
.field("optional", isBoolean);
|
||
|
|
||
|
def("ArrayTypeAnnotation")
|
||
|
.bases("Type")
|
||
|
.build("elementType")
|
||
|
.field("elementType", def("Type"));
|
||
|
|
||
|
def("ObjectTypeAnnotation")
|
||
|
.bases("Type")
|
||
|
.build("properties")
|
||
|
.field("properties", [def("ObjectTypeProperty")])
|
||
|
.field("indexers", [def("ObjectTypeIndexer")], defaults.emptyArray)
|
||
|
.field("callProperties", [def("ObjectTypeCallProperty")], defaults.emptyArray);
|
||
|
|
||
|
def("ObjectTypeProperty")
|
||
|
.bases("Node")
|
||
|
.build("key", "value", "optional")
|
||
|
.field("key", or(def("Literal"), def("Identifier")))
|
||
|
.field("value", def("Type"))
|
||
|
.field("optional", isBoolean);
|
||
|
|
||
|
def("ObjectTypeIndexer")
|
||
|
.bases("Node")
|
||
|
.build("id", "key", "value")
|
||
|
.field("id", def("Identifier"))
|
||
|
.field("key", def("Type"))
|
||
|
.field("value", def("Type"));
|
||
|
|
||
|
def("ObjectTypeCallProperty")
|
||
|
.bases("Node")
|
||
|
.build("value")
|
||
|
.field("value", def("FunctionTypeAnnotation"))
|
||
|
.field("static", isBoolean, false);
|
||
|
|
||
|
def("QualifiedTypeIdentifier")
|
||
|
.bases("Node")
|
||
|
.build("qualification", "id")
|
||
|
.field("qualification", or(def("Identifier"), def("QualifiedTypeIdentifier")))
|
||
|
.field("id", def("Identifier"));
|
||
|
|
||
|
def("GenericTypeAnnotation")
|
||
|
.bases("Type")
|
||
|
.build("id", "typeParameters")
|
||
|
.field("id", or(def("Identifier"), def("QualifiedTypeIdentifier")))
|
||
|
.field("typeParameters", or(def("TypeParameterInstantiation"), null));
|
||
|
|
||
|
def("MemberTypeAnnotation")
|
||
|
.bases("Type")
|
||
|
.build("object", "property")
|
||
|
.field("object", def("Identifier"))
|
||
|
.field("property", or(def("MemberTypeAnnotation"), def("GenericTypeAnnotation")));
|
||
|
|
||
|
def("UnionTypeAnnotation")
|
||
|
.bases("Type")
|
||
|
.build("types")
|
||
|
.field("types", [def("Type")]);
|
||
|
|
||
|
def("IntersectionTypeAnnotation")
|
||
|
.bases("Type")
|
||
|
.build("types")
|
||
|
.field("types", [def("Type")]);
|
||
|
|
||
|
def("TypeofTypeAnnotation")
|
||
|
.bases("Type")
|
||
|
.build("argument")
|
||
|
.field("argument", def("Type"));
|
||
|
|
||
|
def("Identifier")
|
||
|
.field("typeAnnotation", or(def("TypeAnnotation"), null), defaults["null"]);
|
||
|
|
||
|
def("TypeParameterDeclaration")
|
||
|
.bases("Node")
|
||
|
.build("params")
|
||
|
.field("params", [def("Identifier")]);
|
||
|
|
||
|
def("TypeParameterInstantiation")
|
||
|
.bases("Node")
|
||
|
.build("params")
|
||
|
.field("params", [def("Type")]);
|
||
|
|
||
|
def("Function")
|
||
|
.field("returnType", or(def("TypeAnnotation"), null), defaults["null"])
|
||
|
.field("typeParameters", or(def("TypeParameterDeclaration"), null), defaults["null"]);
|
||
|
|
||
|
def("ClassProperty")
|
||
|
.build("key", "typeAnnotation")
|
||
|
.field("typeAnnotation", def("TypeAnnotation"))
|
||
|
.field("static", isBoolean, false);
|
||
|
|
||
|
def("ClassImplements")
|
||
|
.field("typeParameters", or(def("TypeParameterInstantiation"), null), defaults["null"]);
|
||
|
|
||
|
def("InterfaceDeclaration")
|
||
|
.bases("Statement")
|
||
|
.build("id", "body", "extends")
|
||
|
.field("id", def("Identifier"))
|
||
|
.field("typeParameters", or(def("TypeParameterDeclaration"), null), defaults["null"])
|
||
|
.field("body", def("ObjectTypeAnnotation"))
|
||
|
.field("extends", [def("InterfaceExtends")]);
|
||
|
|
||
|
def("InterfaceExtends")
|
||
|
.bases("Node")
|
||
|
.build("id")
|
||
|
.field("id", def("Identifier"))
|
||
|
.field("typeParameters", or(def("TypeParameterInstantiation"), null));
|
||
|
|
||
|
def("TypeAlias")
|
||
|
.bases("Statement")
|
||
|
.build("id", "typeParameters", "right")
|
||
|
.field("id", def("Identifier"))
|
||
|
.field("typeParameters", or(def("TypeParameterDeclaration"), null))
|
||
|
.field("right", def("Type"));
|
||
|
|
||
|
def("TypeCastExpression")
|
||
|
.bases("Expression")
|
||
|
.build("expression", "typeAnnotation")
|
||
|
.field("expression", def("Expression"))
|
||
|
.field("typeAnnotation", def("TypeAnnotation"));
|
||
|
|
||
|
def("TupleTypeAnnotation")
|
||
|
.bases("Type")
|
||
|
.build("types")
|
||
|
.field("types", [def("Type")]);
|
||
|
|
||
|
def("DeclareVariable")
|
||
|
.bases("Statement")
|
||
|
.build("id")
|
||
|
.field("id", def("Identifier"));
|
||
|
|
||
|
def("DeclareFunction")
|
||
|
.bases("Statement")
|
||
|
.build("id")
|
||
|
.field("id", def("Identifier"));
|
||
|
|
||
|
def("DeclareClass")
|
||
|
.bases("InterfaceDeclaration")
|
||
|
.build("id");
|
||
|
|
||
|
def("DeclareModule")
|
||
|
.bases("Statement")
|
||
|
.build("id", "body")
|
||
|
.field("id", or(def("Identifier"), def("Literal")))
|
||
|
.field("body", def("BlockStatement"));
|