ast-types
Advanced tools
Comparing version 0.7.8 to 0.8.2
@@ -5,7 +5,2 @@ var types = require("../lib/types"); | ||
var or = Type.or; | ||
var builtin = types.builtInTypes; | ||
var isString = builtin.string; | ||
var isNumber = builtin.number; | ||
var isBoolean = builtin.boolean; | ||
var isRegExp = builtin.RegExp; | ||
var shared = require("../lib/shared"); | ||
@@ -25,3 +20,3 @@ var defaults = shared.defaults; | ||
.bases("Printable") | ||
.field("type", isString) | ||
.field("type", String) | ||
.field("comments", or( | ||
@@ -36,3 +31,3 @@ [def("Comment")], | ||
.field("end", def("Position")) | ||
.field("source", or(isString, null), defaults["null"]); | ||
.field("source", or(String, null), defaults["null"]); | ||
@@ -44,2 +39,7 @@ def("Position") | ||
def("File") | ||
.bases("Node") | ||
.build("program") | ||
.field("program", def("Program")); | ||
def("Program") | ||
@@ -108,3 +108,3 @@ .bases("Node") | ||
.field("cases", [def("SwitchCase")]) | ||
.field("lexical", isBoolean, defaults["false"]); | ||
.field("lexical", Boolean, defaults["false"]); | ||
@@ -166,3 +166,3 @@ def("ReturnStatement") | ||
.bases("Statement") | ||
.build("left", "right", "body", "each") | ||
.build("left", "right", "body") | ||
.field("left", or( | ||
@@ -172,4 +172,3 @@ def("VariableDeclaration"), | ||
.field("right", def("Expression")) | ||
.field("body", def("Statement")) | ||
.field("each", isBoolean); | ||
.field("body", def("Statement")); | ||
@@ -193,6 +192,3 @@ def("DebuggerStatement").bases("Statement").build(); | ||
.field("kind", or("var", "let", "const")) | ||
.field("declarations", [or( | ||
def("VariableDeclarator"), | ||
def("Identifier") // TODO Esprima deviation. | ||
)]); | ||
.field("declarations", [def("VariableDeclarator")]); | ||
@@ -226,4 +222,3 @@ def("VariableDeclarator") | ||
.field("key", or(def("Literal"), def("Identifier"))) | ||
// esprima allows Pattern | ||
.field("value", or(def("Expression"), def("Pattern"))); | ||
.field("value", def("Expression")); | ||
@@ -244,5 +239,5 @@ def("SequenceExpression") | ||
.field("argument", def("Expression")) | ||
// TODO Esprima doesn't bother with this field, presumably because | ||
// it's always true for unary operators. | ||
.field("prefix", isBoolean, defaults["true"]); | ||
// Esprima doesn't bother with this field, presumably because it's | ||
// always true for unary operators. | ||
.field("prefix", Boolean, defaults["true"]); | ||
@@ -284,3 +279,3 @@ var BinaryOperator = or( | ||
.field("argument", def("Expression")) | ||
.field("prefix", isBoolean); | ||
.field("prefix", Boolean); | ||
@@ -324,24 +319,6 @@ var LogicalOperator = or("||", "&&"); | ||
.field("property", or(def("Identifier"), def("Expression"))) | ||
.field("computed", isBoolean, defaults["false"]); | ||
.field("computed", Boolean, defaults["false"]); | ||
def("Pattern").bases("Node"); | ||
def("ObjectPattern") | ||
.bases("Pattern") | ||
.build("properties") | ||
// TODO File a bug to get PropertyPattern added to the interfaces API. | ||
// esprima uses Property | ||
.field("properties", [or(def("PropertyPattern"), def("Property"))]); | ||
def("PropertyPattern") | ||
.bases("Pattern") | ||
.build("key", "pattern") | ||
.field("key", or(def("Literal"), def("Identifier"))) | ||
.field("pattern", def("Pattern")); | ||
def("ArrayPattern") | ||
.bases("Pattern") | ||
.build("elements") | ||
.field("elements", [or(def("Pattern"), null)]); | ||
def("SwitchCase") | ||
@@ -357,3 +334,3 @@ .bases("Node") | ||
.build("name") | ||
.field("name", isString); | ||
.field("name", String); | ||
@@ -364,25 +341,21 @@ def("Literal") | ||
.build("value") | ||
.field("value", or( | ||
isString, | ||
isBoolean, | ||
null, // isNull would also work here. | ||
isNumber, | ||
isRegExp | ||
)) | ||
.field("value", or(String, Boolean, null, Number, RegExp)) | ||
.field("regex", or({ | ||
pattern: isString, | ||
flags: isString | ||
pattern: String, | ||
flags: String | ||
}, null), function() { | ||
if (!isRegExp.check(this.value)) | ||
return null; | ||
if (this.value instanceof RegExp) { | ||
var flags = ""; | ||
var flags = ""; | ||
if (this.value.ignoreCase) flags += "i"; | ||
if (this.value.multiline) flags += "m"; | ||
if (this.value.global) flags += "g"; | ||
if (this.value.ignoreCase) flags += "i"; | ||
if (this.value.multiline) flags += "m"; | ||
if (this.value.global) flags += "g"; | ||
return { | ||
pattern: this.value.source, | ||
flags: flags | ||
}; | ||
return { | ||
pattern: this.value.source, | ||
flags: flags | ||
}; | ||
} | ||
return null; | ||
}); | ||
@@ -393,3 +366,3 @@ | ||
.bases("Printable") | ||
.field("value", isString) | ||
.field("value", String) | ||
// A .leading comment comes before the node, whereas a .trailing | ||
@@ -400,4 +373,4 @@ // comment comes after it. These two fields should not both be true, | ||
// e.g. { /*dangling*/ }. | ||
.field("leading", isBoolean, defaults["true"]) | ||
.field("trailing", isBoolean, defaults["false"]); | ||
.field("leading", Boolean, defaults["true"]) | ||
.field("trailing", Boolean, defaults["false"]); | ||
@@ -404,0 +377,0 @@ // Block comment. The .type really should be BlockComment rather than |
@@ -5,5 +5,2 @@ require("./core"); | ||
var or = types.Type.or; | ||
var builtin = types.builtInTypes; | ||
var isString = builtin.string; | ||
var isBoolean = builtin.boolean; | ||
@@ -23,3 +20,3 @@ // Note that none of these types are buildable because the Mozilla Parser | ||
.field("right", or(def("Identifier"), def("Expression"))) | ||
.field("computed", isBoolean); | ||
.field("computed", Boolean); | ||
@@ -29,3 +26,3 @@ def("XMLFunctionQualifiedIdentifier") | ||
.field("right", or(def("Identifier"), def("Expression"))) | ||
.field("computed", isBoolean); | ||
.field("computed", Boolean); | ||
@@ -57,3 +54,3 @@ def("XMLAttributeSelector") | ||
.bases("XML") | ||
.field("text", isString); | ||
.field("text", String); | ||
@@ -74,19 +71,19 @@ def("XMLStartTag") | ||
.bases("XML") | ||
.field("contents", or(isString, [def("XML")])); | ||
.field("contents", or(String, [def("XML")])); | ||
def("XMLAttribute") | ||
.bases("XML") | ||
.field("value", isString); | ||
.field("value", String); | ||
def("XMLCdata") | ||
.bases("XML") | ||
.field("contents", isString); | ||
.field("contents", String); | ||
def("XMLComment") | ||
.bases("XML") | ||
.field("contents", isString); | ||
.field("contents", String); | ||
def("XMLProcessingInstruction") | ||
.bases("XML") | ||
.field("target", isString) | ||
.field("contents", or(isString, null)); | ||
.field("target", String) | ||
.field("contents", or(String, null)); |
157
def/es6.js
@@ -5,15 +5,22 @@ require("./core"); | ||
var or = types.Type.or; | ||
var builtin = types.builtInTypes; | ||
var isBoolean = builtin.boolean; | ||
var isObject = builtin.object; | ||
var isString = builtin.string; | ||
var defaults = require("../lib/shared").defaults; | ||
def("Function") | ||
.field("generator", isBoolean, defaults["false"]) | ||
.field("expression", isBoolean, defaults["false"]) | ||
.field("generator", Boolean, defaults["false"]) | ||
.field("expression", Boolean, defaults["false"]) | ||
.field("defaults", [or(def("Expression"), null)], defaults.emptyArray) | ||
// TODO This could be represented as a SpreadElementPattern in .params. | ||
// TODO This could be represented as a RestElement in .params. | ||
.field("rest", or(def("Identifier"), null), defaults["null"]); | ||
// The ESTree way of representing a ...rest parameter. | ||
def("RestElement") | ||
.bases("Pattern") | ||
.build("argument") | ||
.field("argument", def("Pattern")); | ||
def("SpreadElementPattern") | ||
.bases("Pattern") | ||
.build("argument") | ||
.field("argument", def("Pattern")); | ||
def("FunctionDeclaration") | ||
@@ -25,4 +32,4 @@ .build("id", "params", "body", "generator", "expression"); | ||
// TODO The Parser API calls this ArrowExpression, but Esprima uses | ||
// ArrowFunctionExpression. | ||
// The Parser API calls this ArrowExpression, but Esprima and all other | ||
// actual parsers use ArrowFunctionExpression. | ||
def("ArrowFunctionExpression") | ||
@@ -44,3 +51,3 @@ .bases("Function", "Expression") | ||
.field("argument", or(def("Expression"), null)) | ||
.field("delegate", isBoolean, defaults["false"]); | ||
.field("delegate", Boolean, defaults["false"]); | ||
@@ -66,28 +73,36 @@ def("GeneratorExpression") | ||
.field("right", def("Expression")) | ||
.field("each", isBoolean); | ||
.field("each", Boolean); | ||
def("ModuleSpecifier") | ||
.bases("Literal") | ||
.build("value") | ||
.field("value", isString); | ||
def("Property") | ||
// Esprima extensions not mentioned in the Mozilla Parser API: | ||
.field("key", or(def("Literal"), def("Identifier"), def("Expression"))) | ||
.field("method", isBoolean, defaults["false"]) | ||
.field("shorthand", isBoolean, defaults["false"]) | ||
.field("computed", isBoolean, defaults["false"]); | ||
.field("value", or(def("Expression"), def("Pattern"))) | ||
.field("method", Boolean, defaults["false"]) | ||
.field("shorthand", Boolean, defaults["false"]) | ||
.field("computed", Boolean, defaults["false"]); | ||
def("PropertyPattern") | ||
.bases("Pattern") | ||
.build("key", "pattern") | ||
.field("key", or(def("Literal"), def("Identifier"), def("Expression"))) | ||
.field("computed", isBoolean, defaults["false"]); | ||
.field("pattern", def("Pattern")) | ||
.field("computed", Boolean, defaults["false"]); | ||
def("ObjectPattern") | ||
.bases("Pattern") | ||
.build("properties") | ||
.field("properties", [or(def("PropertyPattern"), def("Property"))]); | ||
def("ArrayPattern") | ||
.bases("Pattern") | ||
.build("elements") | ||
.field("elements", [or(def("Pattern"), null)]); | ||
def("MethodDefinition") | ||
.bases("Declaration") | ||
.build("kind", "key", "value", "static") | ||
.field("kind", or("init", "get", "set", "")) | ||
.field("kind", or("constructor", "method", "get", "set")) | ||
.field("key", or(def("Literal"), def("Identifier"), def("Expression"))) | ||
.field("value", def("Function")) | ||
.field("computed", isBoolean, defaults["false"]) | ||
.field("static", isBoolean, defaults["false"]); | ||
.field("computed", Boolean, defaults["false"]) | ||
.field("static", Boolean, defaults["false"]); | ||
@@ -108,15 +123,14 @@ def("SpreadElement") | ||
def("SpreadElementPattern") | ||
// Note: this node type is *not* an AssignmentExpression with a Pattern on | ||
// the left-hand side! The existing AssignmentExpression type already | ||
// supports destructuring assignments. AssignmentPattern nodes may appear | ||
// wherever a Pattern is allowed, and the right-hand side represents a | ||
// default value to be destructured against the left-hand side, if no | ||
// value is otherwise provided. For example: default parameter values. | ||
def("AssignmentPattern") | ||
.bases("Pattern") | ||
.build("argument") | ||
.field("argument", def("Pattern")); | ||
.build("left", "right") | ||
.field("left", def("Pattern")) | ||
.field("right", def("Expression")); | ||
def("ArrayPattern") | ||
.field("elements", [or( | ||
def("Pattern"), | ||
null, | ||
// used by esprima | ||
def("SpreadElement") | ||
)]); | ||
var ClassBodyElement = or( | ||
@@ -133,3 +147,3 @@ def("MethodDefinition"), | ||
.field("key", or(def("Literal"), def("Identifier"), def("Expression"))) | ||
.field("computed", isBoolean, defaults["false"]); | ||
.field("computed", Boolean, defaults["false"]); | ||
@@ -171,71 +185,6 @@ def("ClassPropertyDefinition") // static property | ||
def("Specifier").bases("Node"); | ||
def("NamedSpecifier") | ||
.bases("Specifier") | ||
// Note: this abstract type is intentionally not buildable. | ||
.field("id", def("Identifier")) | ||
.field("name", or(def("Identifier"), null), defaults["null"]); | ||
// Like NamedSpecifier, except type:"ExportSpecifier" and buildable. | ||
// export {<id [as name]>} [from ...]; | ||
def("ExportSpecifier") | ||
.bases("NamedSpecifier") | ||
.build("id", "name"); | ||
// export <*> from ...; | ||
def("ExportBatchSpecifier") | ||
.bases("Specifier") | ||
.build(); | ||
// Like NamedSpecifier, except type:"ImportSpecifier" and buildable. | ||
// import {<id [as name]>} from ...; | ||
def("ImportSpecifier") | ||
.bases("NamedSpecifier") | ||
.build("id", "name"); | ||
// import <* as id> from ...; | ||
def("ImportNamespaceSpecifier") | ||
.bases("Specifier") | ||
.build("id") | ||
.field("id", def("Identifier")); | ||
// import <id> from ...; | ||
def("ImportDefaultSpecifier") | ||
.bases("Specifier") | ||
.build("id") | ||
.field("id", def("Identifier")); | ||
def("ExportDeclaration") | ||
.bases("Declaration") | ||
.build("default", "declaration", "specifiers", "source") | ||
.field("default", isBoolean) | ||
.field("declaration", or( | ||
def("Declaration"), | ||
def("Expression"), // Implies default. | ||
null | ||
)) | ||
.field("specifiers", [or( | ||
def("ExportSpecifier"), | ||
def("ExportBatchSpecifier") | ||
)], defaults.emptyArray) | ||
.field("source", or( | ||
def("Literal"), | ||
def("ModuleSpecifier"), | ||
null | ||
), defaults["null"]); | ||
def("ImportDeclaration") | ||
.bases("Declaration") | ||
.build("specifiers", "source") | ||
.field("specifiers", [or( | ||
def("ImportSpecifier"), | ||
def("ImportNamespaceSpecifier"), | ||
def("ImportDefaultSpecifier") | ||
)], defaults.emptyArray) | ||
.field("source", or( | ||
def("Literal"), | ||
def("ModuleSpecifier") | ||
)); | ||
def("TaggedTemplateExpression") | ||
.bases("Expression") | ||
.build("tag", "quasi") | ||
.field("tag", def("Expression")) | ||
@@ -253,3 +202,3 @@ .field("quasi", def("TemplateLiteral")); | ||
.build("value", "tail") | ||
.field("value", {"cooked": isString, "raw": isString}) | ||
.field("tail", isBoolean); | ||
.field("value", {"cooked": String, "raw": String}) | ||
.field("tail", Boolean); |
@@ -1,2 +0,3 @@ | ||
require("./core"); | ||
require("./es6"); | ||
var types = require("../lib/types"); | ||
@@ -6,7 +7,6 @@ var def = types.Type.def; | ||
var builtin = types.builtInTypes; | ||
var isBoolean = builtin.boolean; | ||
var defaults = require("../lib/shared").defaults; | ||
def("Function") | ||
.field("async", isBoolean, defaults["false"]); | ||
.field("async", Boolean, defaults["false"]); | ||
@@ -28,7 +28,5 @@ def("SpreadProperty") | ||
.field("properties", [or( | ||
def("Property"), | ||
def("PropertyPattern"), | ||
def("SpreadPropertyPattern"), | ||
// used by esprima | ||
def("Property"), | ||
def("SpreadProperty") | ||
def("SpreadPropertyPattern") | ||
)]); | ||
@@ -40,2 +38,2 @@ | ||
.field("argument", or(def("Expression"), null)) | ||
.field("all", isBoolean, defaults["false"]); | ||
.field("all", Boolean, defaults["false"]); |
@@ -1,9 +0,6 @@ | ||
require("./core"); | ||
require("./es7"); | ||
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; | ||
@@ -24,3 +21,3 @@ | ||
.build("name") | ||
.field("name", isString); | ||
.field("name", String); | ||
@@ -38,3 +35,3 @@ def("JSXNamespacedName") | ||
.field("property", def("JSXIdentifier")) | ||
.field("computed", isBoolean, defaults.false); | ||
.field("computed", Boolean, defaults.false); | ||
@@ -81,3 +78,3 @@ var JSXElementName = or( | ||
}) | ||
.field("selfClosing", isBoolean, function() { | ||
.field("selfClosing", Boolean, function() { | ||
return this.openingElement.selfClosing; | ||
@@ -94,3 +91,3 @@ }) | ||
.field("attributes", JSXAttributes, defaults.emptyArray) | ||
.field("selfClosing", isBoolean, defaults["false"]); | ||
.field("selfClosing", Boolean, defaults["false"]); | ||
@@ -105,3 +102,3 @@ def("JSXClosingElement") | ||
.build("value") | ||
.field("value", isString); | ||
.field("value", String); | ||
@@ -111,13 +108,19 @@ def("JSXEmptyExpression").bases("Expression").build(); | ||
// Type Annotations | ||
def("Type") | ||
.bases("Node"); | ||
def("Type").bases("Node"); | ||
def("AnyTypeAnnotation") | ||
.bases("Type"); | ||
.bases("Type") | ||
.build(); | ||
def("MixedTypeAnnotation") | ||
.bases("Type") | ||
.build(); | ||
def("VoidTypeAnnotation") | ||
.bases("Type"); | ||
.bases("Type") | ||
.build(); | ||
def("NumberTypeAnnotation") | ||
.bases("Type"); | ||
.bases("Type") | ||
.build(); | ||
@@ -127,7 +130,8 @@ def("NumberLiteralTypeAnnotation") | ||
.build("value", "raw") | ||
.field("value", isNumber) | ||
.field("raw", isString); | ||
.field("value", Number) | ||
.field("raw", String); | ||
def("StringTypeAnnotation") | ||
.bases("Type"); | ||
.bases("Type") | ||
.build(); | ||
@@ -137,7 +141,8 @@ def("StringLiteralTypeAnnotation") | ||
.build("value", "raw") | ||
.field("value", isString) | ||
.field("raw", isString); | ||
.field("value", String) | ||
.field("raw", String); | ||
def("BooleanTypeAnnotation") | ||
.bases("Type"); | ||
.bases("Type") | ||
.build(); | ||
@@ -147,4 +152,4 @@ def("BooleanLiteralTypeAnnotation") | ||
.build("value", "raw") | ||
.field("value", isBoolean) | ||
.field("raw", isString); | ||
.field("value", Boolean) | ||
.field("raw", String); | ||
@@ -174,3 +179,3 @@ def("TypeAnnotation") | ||
.field("typeAnnotation", def("Type")) | ||
.field("optional", isBoolean); | ||
.field("optional", Boolean); | ||
@@ -187,3 +192,5 @@ def("ArrayTypeAnnotation") | ||
.field("indexers", [def("ObjectTypeIndexer")], defaults.emptyArray) | ||
.field("callProperties", [def("ObjectTypeCallProperty")], defaults.emptyArray); | ||
.field("callProperties", | ||
[def("ObjectTypeCallProperty")], | ||
defaults.emptyArray); | ||
@@ -195,3 +202,3 @@ def("ObjectTypeProperty") | ||
.field("value", def("Type")) | ||
.field("optional", isBoolean); | ||
.field("optional", Boolean); | ||
@@ -209,3 +216,3 @@ def("ObjectTypeIndexer") | ||
.field("value", def("FunctionTypeAnnotation")) | ||
.field("static", isBoolean, false); | ||
.field("static", Boolean, false); | ||
@@ -215,3 +222,5 @@ def("QualifiedTypeIdentifier") | ||
.build("qualification", "id") | ||
.field("qualification", or(def("Identifier"), def("QualifiedTypeIdentifier"))) | ||
.field("qualification", | ||
or(def("Identifier"), | ||
def("QualifiedTypeIdentifier"))) | ||
.field("id", def("Identifier")); | ||
@@ -229,3 +238,5 @@ | ||
.field("object", def("Identifier")) | ||
.field("property", or(def("MemberTypeAnnotation"), def("GenericTypeAnnotation"))); | ||
.field("property", | ||
or(def("MemberTypeAnnotation"), | ||
def("GenericTypeAnnotation"))); | ||
@@ -261,4 +272,8 @@ def("UnionTypeAnnotation") | ||
def("Function") | ||
.field("returnType", or(def("TypeAnnotation"), null), defaults["null"]) | ||
.field("typeParameters", or(def("TypeParameterDeclaration"), null), defaults["null"]); | ||
.field("returnType", | ||
or(def("TypeAnnotation"), null), | ||
defaults["null"]) | ||
.field("typeParameters", | ||
or(def("TypeParameterDeclaration"), null), | ||
defaults["null"]); | ||
@@ -268,6 +283,8 @@ def("ClassProperty") | ||
.field("typeAnnotation", def("TypeAnnotation")) | ||
.field("static", isBoolean, false); | ||
.field("static", Boolean, false); | ||
def("ClassImplements") | ||
.field("typeParameters", or(def("TypeParameterInstantiation"), null), defaults["null"]); | ||
.field("typeParameters", | ||
or(def("TypeParameterInstantiation"), null), | ||
defaults["null"]); | ||
@@ -278,3 +295,5 @@ def("InterfaceDeclaration") | ||
.field("id", def("Identifier")) | ||
.field("typeParameters", or(def("TypeParameterDeclaration"), null), defaults["null"]) | ||
.field("typeParameters", | ||
or(def("TypeParameterDeclaration"), null), | ||
defaults["null"]) | ||
.field("body", def("ObjectTypeAnnotation")) | ||
@@ -281,0 +300,0 @@ .field("extends", [def("InterfaceExtends")]); |
@@ -5,3 +5,5 @@ require("./core"); | ||
var or = types.Type.or; | ||
var geq = require("../lib/shared").geq; | ||
var shared = require("../lib/shared"); | ||
var geq = shared.geq; | ||
var defaults = shared.defaults; | ||
@@ -12,2 +14,6 @@ def("Function") | ||
def("ForInStatement") | ||
.build("left", "right", "body", "each") | ||
.field("each", Boolean, defaults["false"]); | ||
def("ForOfStatement") | ||
@@ -14,0 +20,0 @@ .bases("Statement") |
110
lib/types.js
@@ -83,2 +83,4 @@ var assert = require("assert"); | ||
var builtInCtorFns = []; | ||
var builtInCtorTypes = []; | ||
var builtInTypes = {}; | ||
@@ -90,10 +92,14 @@ exports.builtInTypes = builtInTypes; | ||
Object.defineProperty(builtInTypes, name, { | ||
enumerable: true, | ||
value: new Type(function(value) { | ||
return objToStr.call(value) === objStr; | ||
}, name) | ||
}); | ||
var type = new Type(function(value) { | ||
return objToStr.call(value) === objStr; | ||
}, name); | ||
return builtInTypes[name]; | ||
builtInTypes[name] = type; | ||
if (example && typeof example.constructor === "function") { | ||
builtInCtorFns.push(example.constructor); | ||
builtInCtorTypes.push(type); | ||
} | ||
return type; | ||
} | ||
@@ -105,3 +111,3 @@ | ||
// returns false for [], /./, new Date, and null. | ||
var isString = defBuiltInType("", "string"); | ||
var isString = defBuiltInType("truthy", "string"); | ||
var isFunction = defBuiltInType(function(){}, "function"); | ||
@@ -138,6 +144,13 @@ var isArray = defBuiltInType([], "array"); | ||
// If isFunction.check(from), assume that from is a binary predicate | ||
// function we can use to define the type. | ||
if (isFunction.check(from)) | ||
if (isFunction.check(from)) { | ||
var bicfIndex = builtInCtorFns.indexOf(from); | ||
if (bicfIndex >= 0) { | ||
return builtInCtorTypes[bicfIndex]; | ||
} | ||
// If isFunction.check(from), and from is not a built-in | ||
// constructor, assume from is a binary predicate function we can | ||
// use to define the type. | ||
return new Type(from, name); | ||
} | ||
@@ -331,3 +344,3 @@ // As a last resort, toType returns a type that matches any value that | ||
var d = defCache[typeName]; | ||
assert.strictEqual(d.finalized, true); | ||
assert.strictEqual(d.finalized, true, typeName); | ||
for (var j = 0; j < d.supertypeList.length; ++j) { | ||
@@ -347,3 +360,3 @@ var superTypeName = d.supertypeList[j]; | ||
var allFields = this.allFields; | ||
assert.strictEqual(this.finalized, true); | ||
assert.strictEqual(this.finalized, true, this.typeName); | ||
@@ -412,7 +425,11 @@ function checkFieldByName(name) { | ||
Dp.bases = function() { | ||
var args = slice.call(arguments); | ||
var bases = this.baseNames; | ||
assert.strictEqual(this.finalized, false); | ||
if (this.finalized) { | ||
assert.deepEqual(args, bases); | ||
return this; | ||
} | ||
each.call(arguments, function(baseName) { | ||
args.forEach(function(baseName) { | ||
isString.assert(baseName); | ||
@@ -460,2 +477,4 @@ | ||
var isArrayOfString = isString.arrayOf(); | ||
// Calling the .build method of a Def simultaneously marks the type as | ||
@@ -468,6 +487,9 @@ // buildable (by defining builders[getBuilderName(typeName)]) and | ||
var newBuildParams = slice.call(arguments); | ||
isArrayOfString.assert(newBuildParams); | ||
// Calling Def.prototype.build multiple times has the effect of merely | ||
// redefining this property. | ||
Object.defineProperty(self, "buildParams", { | ||
value: slice.call(arguments), | ||
value: newBuildParams, | ||
writable: false, | ||
@@ -478,5 +500,2 @@ enumerable: false, | ||
assert.strictEqual(self.finalized, false); | ||
isString.arrayOf().assert(self.buildParams); | ||
if (self.buildable) { | ||
@@ -491,3 +510,3 @@ // If this Def is already buildable, update self.buildParams and | ||
// like SourceLocation, but that seems harmless (TODO?). | ||
self.field("type", isString, function() { return self.typeName }); | ||
self.field("type", String, function() { return self.typeName }); | ||
@@ -597,3 +616,8 @@ // Override Dp.buildable for this Def instance. | ||
Dp.field = function(name, type, defaultFn, hidden) { | ||
assert.strictEqual(this.finalized, false); | ||
if (this.finalized) { | ||
console.error("Ignoring attempt to redefine field " + | ||
JSON.stringify(name) + " of finalized type " + | ||
JSON.stringify(this.typeName)); | ||
return this; | ||
} | ||
this.ownFields[name] = new Field(name, type, defaultFn, hidden); | ||
@@ -665,24 +689,34 @@ return this; // For chaining. | ||
Dp.finalize = function() { | ||
var self = this; | ||
// It's not an error to finalize a type more than once, but only the | ||
// first call to .finalize does anything. | ||
if (!this.finalized) { | ||
var allFields = this.allFields; | ||
var allSupertypes = this.allSupertypes; | ||
if (!self.finalized) { | ||
var allFields = self.allFields; | ||
var allSupertypes = self.allSupertypes; | ||
this.baseNames.forEach(function(name) { | ||
self.baseNames.forEach(function(name) { | ||
var def = defCache[name]; | ||
def.finalize(); | ||
extend(allFields, def.allFields); | ||
extend(allSupertypes, def.allSupertypes); | ||
if (def instanceof Def) { | ||
def.finalize(); | ||
extend(allFields, def.allFields); | ||
extend(allSupertypes, def.allSupertypes); | ||
} else { | ||
var message = "unknown supertype name " + | ||
JSON.stringify(name) + | ||
" for subtype " + | ||
JSON.stringify(self.typeName); | ||
assert.ok(false, message); | ||
} | ||
}); | ||
// TODO Warn if fields are overridden with incompatible types. | ||
extend(allFields, this.ownFields); | ||
allSupertypes[this.typeName] = this; | ||
extend(allFields, self.ownFields); | ||
allSupertypes[self.typeName] = self; | ||
this.fieldNames.length = 0; | ||
self.fieldNames.length = 0; | ||
for (var fieldName in allFields) { | ||
if (hasOwn.call(allFields, fieldName) && | ||
!allFields[fieldName].hidden) { | ||
this.fieldNames.push(fieldName); | ||
self.fieldNames.push(fieldName); | ||
} | ||
@@ -692,14 +726,14 @@ } | ||
// Types are exported only once they have been finalized. | ||
Object.defineProperty(namedTypes, this.typeName, { | ||
Object.defineProperty(namedTypes, self.typeName, { | ||
enumerable: true, | ||
value: this.type | ||
value: self.type | ||
}); | ||
Object.defineProperty(this, "finalized", { value: true }); | ||
Object.defineProperty(self, "finalized", { value: true }); | ||
// A linearization of the inheritance hierarchy. | ||
populateSupertypeList(this.typeName, this.supertypeList); | ||
populateSupertypeList(self.typeName, self.supertypeList); | ||
if (this.buildable && this.supertypeList.lastIndexOf("Expression") >= 0) { | ||
wrapExpressionBuilderWithStatement(this.typeName); | ||
if (self.buildable && self.supertypeList.lastIndexOf("Expression") >= 0) { | ||
wrapExpressionBuilderWithStatement(self.typeName); | ||
} | ||
@@ -706,0 +740,0 @@ } |
@@ -14,2 +14,4 @@ var types = require("./lib/types"); | ||
require("./def/fb-harmony"); | ||
require("./def/esprima"); | ||
require("./def/babel"); | ||
@@ -16,0 +18,0 @@ types.finalize(); |
@@ -21,3 +21,3 @@ { | ||
], | ||
"version": "0.7.8", | ||
"version": "0.8.2", | ||
"homepage": "http://github.com/benjamn/ast-types", | ||
@@ -31,14 +31,14 @@ "repository": { | ||
"scripts": { | ||
"test": "mocha --reporter spec test/run.js" | ||
"test": "mocha --reporter spec --full-trace test/run.js" | ||
}, | ||
"dependencies": { | ||
}, | ||
"dependencies": {}, | ||
"devDependencies": { | ||
"babel-core": "^5.6.15", | ||
"esprima": "~1.2.2", | ||
"esprima-fb": "~14001.1.0-dev-harmony-fb", | ||
"mocha": "~1.20.1" | ||
"mocha": "~2.2.5" | ||
}, | ||
"engines": { | ||
"node": ">= 0.6" | ||
"node": ">= 0.8" | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
128387
21
3083
4