ast-types
Advanced tools
Comparing version 0.3.35 to 0.3.36
234
lib/types.js
@@ -47,3 +47,3 @@ var assert = require("assert"); | ||
// redefinition of exported properties. | ||
Object.defineProperty(exports, "Type", { value: Type }); | ||
exports.Type = Type; | ||
@@ -85,6 +85,3 @@ // Like .check, except that failure triggers an AssertionError. | ||
var builtInTypes = {}; | ||
Object.defineProperty(exports, "builtInTypes", { | ||
enumerable: true, | ||
value: builtInTypes | ||
}); | ||
exports.builtInTypes = builtInTypes; | ||
@@ -273,2 +270,3 @@ function defBuiltInType(example, name) { | ||
allSupertypes: { value: {} }, // Includes own typeName. | ||
supertypeList: { value: [] }, // Linear inheritance hierarchy. | ||
allFields: { value: {} }, // Includes inherited fields. | ||
@@ -307,2 +305,25 @@ | ||
// Returns an object mapping from every known type in the defCache to the | ||
// most specific supertype whose name is an own property of the candidates | ||
// object. | ||
exports.computeSupertypeLookupTable = function(candidates) { | ||
var table = {}; | ||
for (var typeName in defCache) { | ||
if (hasOwn.call(defCache, typeName)) { | ||
var d = defCache[typeName]; | ||
assert.strictEqual(d.finalized, true); | ||
for (var i = 0; i < d.supertypeList.length; ++i) { | ||
var superTypeName = d.supertypeList[i]; | ||
if (hasOwn.call(candidates, superTypeName)) { | ||
table[typeName] = superTypeName; | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
return table; | ||
}; | ||
Dp.checkAllFields = function(value, deep) { | ||
@@ -394,5 +415,3 @@ var allFields = this.allFields; | ||
var builders = {}; | ||
Object.defineProperty(exports, "builders", { | ||
value: builders | ||
}); | ||
exports.builders = builders; | ||
@@ -404,24 +423,22 @@ // This object is used as prototype for any node created by a builder. | ||
// nodes. The replaced method (if any) is returned for easy wrapping. | ||
Object.defineProperty(exports, "defineMethod", { | ||
value: function(name, func) { | ||
var old = nodePrototype[name]; | ||
exports.defineMethod = function(name, func) { | ||
var old = nodePrototype[name]; | ||
// Pass undefined as func to delete nodePrototype[name]. | ||
if (isUndefined.check(func)) { | ||
delete nodePrototype[name]; | ||
// Pass undefined as func to delete nodePrototype[name]. | ||
if (isUndefined.check(func)) { | ||
delete nodePrototype[name]; | ||
} else { | ||
isFunction.assert(func); | ||
} else { | ||
isFunction.assert(func); | ||
Object.defineProperty(nodePrototype, name, { | ||
enumerable: true, // For discoverability. | ||
configurable: true, // For delete proto[name]. | ||
value: func | ||
}); | ||
} | ||
return old; | ||
Object.defineProperty(nodePrototype, name, { | ||
enumerable: true, // For discoverability. | ||
configurable: true, // For delete proto[name]. | ||
value: func | ||
}); | ||
} | ||
}); | ||
return old; | ||
}; | ||
// Calling the .build method of a Def simultaneously marks the type as | ||
@@ -556,22 +573,18 @@ // buildable (by defining builders[getBuilderName(typeName)]) and | ||
var namedTypes = {}; | ||
Object.defineProperty(exports, "namedTypes", { | ||
value: namedTypes | ||
}); | ||
exports.namedTypes = namedTypes; | ||
// Get the value of an object property, taking object.type and default | ||
// functions into account. | ||
Object.defineProperty(exports, "getFieldValue", { | ||
value: function(object, fieldName) { | ||
var d = Def.fromValue(object); | ||
if (d) { | ||
var field = d.allFields[fieldName]; | ||
if (field) { | ||
return field.getValue(object); | ||
} | ||
exports.getFieldValue = function(object, fieldName) { | ||
var d = Def.fromValue(object); | ||
if (d) { | ||
var field = d.allFields[fieldName]; | ||
if (field) { | ||
return field.getValue(object); | ||
} | ||
return object[fieldName]; | ||
} | ||
}); | ||
return object[fieldName]; | ||
}; | ||
// Iterate over all defined fields of an object, including those missing | ||
@@ -581,27 +594,25 @@ // or undefined, passing each field name and effective value (as returned | ||
// Def, the callback will never be called. | ||
Object.defineProperty(exports, "eachField", { | ||
value: function(object, callback, context) { | ||
var d = Def.fromValue(object); | ||
if (d) { | ||
var all = d.allFields; | ||
Object.keys(all).forEach(function(name) { | ||
var field = all[name]; | ||
if (!field.hidden) { | ||
callback.call(this, name, field.getValue(object)); | ||
} | ||
}, context); | ||
} else { | ||
assert.strictEqual( | ||
"type" in object, false, | ||
"did not recognize object of type " + JSON.stringify(object.type) | ||
); | ||
exports.eachField = function(object, callback, context) { | ||
var d = Def.fromValue(object); | ||
if (d) { | ||
var all = d.allFields; | ||
Object.keys(all).forEach(function(name) { | ||
var field = all[name]; | ||
if (!field.hidden) { | ||
callback.call(this, name, field.getValue(object)); | ||
} | ||
}, context); | ||
} else { | ||
assert.strictEqual( | ||
"type" in object, false, | ||
"did not recognize object of type " + JSON.stringify(object.type) | ||
); | ||
// If we could not infer a Def type for this object, just | ||
// iterate over its keys in the normal way. | ||
Object.keys(object).forEach(function(name) { | ||
callback.call(this, name, object[name]); | ||
}, context); | ||
} | ||
// If we could not infer a Def type for this object, just | ||
// iterate over its keys in the normal way. | ||
Object.keys(object).forEach(function(name) { | ||
callback.call(this, name, object[name]); | ||
}, context); | ||
} | ||
}); | ||
}; | ||
@@ -612,29 +623,27 @@ // Similar to eachField, except that iteration stops as soon as the | ||
// returned true for any element or not. | ||
Object.defineProperty(exports, "someField", { | ||
value: function(object, callback, context) { | ||
var d = Def.fromValue(object); | ||
if (d) { | ||
var all = d.allFields; | ||
return Object.keys(all).some(function(name) { | ||
var field = all[name]; | ||
if (!field.hidden) { | ||
var value = field.getValue(object); | ||
return callback.call(this, name, value); | ||
} | ||
}, context); | ||
} | ||
assert.strictEqual( | ||
"type" in object, false, | ||
"did not recognize object of type " + JSON.stringify(object.type) | ||
); | ||
// If we could not infer a Def type for this object, just iterate | ||
// over its keys in the normal way. | ||
return Object.keys(object).some(function(name) { | ||
return callback.call(this, name, object[name]); | ||
exports.someField = function(object, callback, context) { | ||
var d = Def.fromValue(object); | ||
if (d) { | ||
var all = d.allFields; | ||
return Object.keys(all).some(function(name) { | ||
var field = all[name]; | ||
if (!field.hidden) { | ||
var value = field.getValue(object); | ||
return callback.call(this, name, value); | ||
} | ||
}, context); | ||
} | ||
}); | ||
assert.strictEqual( | ||
"type" in object, false, | ||
"did not recognize object of type " + JSON.stringify(object.type) | ||
); | ||
// If we could not infer a Def type for this object, just iterate | ||
// over its keys in the normal way. | ||
return Object.keys(object).some(function(name) { | ||
return callback.call(this, name, object[name]); | ||
}, context); | ||
}; | ||
// This property will be overridden as true by individual Def instances | ||
@@ -669,5 +678,42 @@ // when they are finalized. | ||
Object.defineProperty(this, "finalized", { value: true }); | ||
// A linearization of the inheritance hierarchy. | ||
populateSupertypeList(this.typeName, this.supertypeList); | ||
} | ||
}; | ||
function populateSupertypeList(typeName, list) { | ||
list.length = 0; | ||
list.push(typeName); | ||
var lastSeen = {}; | ||
for (var pos = 0; pos < list.length; ++pos) { | ||
typeName = list[pos]; | ||
var d = defCache[typeName]; | ||
assert.strictEqual(d.finalized, true); | ||
// If we saw typeName earlier in the breadth-first traversal, | ||
// delete the last-seen occurrence. | ||
if (hasOwn.call(lastSeen, typeName)) { | ||
delete list[lastSeen[typeName]]; | ||
} | ||
// Record the new index of the last-seen occurrence of typeName. | ||
lastSeen[typeName] = pos; | ||
// Enqueue the base names of this type. | ||
list.push.apply(list, d.baseNames); | ||
} | ||
// Compaction loop to remove array holes. | ||
for (var to = 0, from = to, len = list.length; from < len; ++from) { | ||
if (hasOwn.call(list, from)) { | ||
list[to++] = list[from]; | ||
} | ||
} | ||
list.length = to; | ||
} | ||
function extend(into, from) { | ||
@@ -681,12 +727,6 @@ Object.keys(from).forEach(function(name) { | ||
Object.defineProperty(exports, "finalize", { | ||
// This function should be called at the end of any complete file of | ||
// type definitions. It declares that everything defined so far is | ||
// complete and needs no further modification, and defines all | ||
// finalized types as properties of exports.namedTypes. | ||
value: function() { | ||
Object.keys(defCache).forEach(function(name) { | ||
defCache[name].finalize(); | ||
}); | ||
} | ||
}); | ||
exports.finalize = function() { | ||
Object.keys(defCache).forEach(function(name) { | ||
defCache[name].finalize(); | ||
}); | ||
}; |
@@ -28,1 +28,2 @@ var types = require("./lib/types"); | ||
exports.NodePath = require("./lib/node-path"); | ||
exports.computeSupertypeLookupTable = types.computeSupertypeLookupTable; |
@@ -21,3 +21,3 @@ { | ||
], | ||
"version": "0.3.35", | ||
"version": "0.3.36", | ||
"homepage": "http://github.com/benjamn/ast-types", | ||
@@ -24,0 +24,0 @@ "repository": { |
@@ -50,2 +50,28 @@ var assert = require("assert"); | ||
describe("computeSupertypeLookupTable", function() { | ||
it("should resolve the most precise supertypes", function() { | ||
var table = types.computeSupertypeLookupTable({ | ||
Function: true, | ||
Declaration: true, | ||
ArrowFunctionExpression: true, | ||
Expression: true, | ||
Identifier: true | ||
}); | ||
function check(subtype, expectedSupertype) { | ||
assert.strictEqual(table[subtype], expectedSupertype); | ||
} | ||
check("FunctionExpression", "Function"); | ||
check("FunctionDeclaration", "Function"); | ||
check("VariableDeclaration", "Declaration"); | ||
check("Identifier", "Identifier"); | ||
check("ArrowFunctionExpression", "ArrowFunctionExpression"); | ||
check("ForInStatement"); | ||
check("Node"); | ||
check("ThisExpression", "Expression"); | ||
check("Property"); | ||
}); | ||
}); | ||
describe("shallow and deep checks", function() { | ||
@@ -52,0 +78,0 @@ var index = b.identifier("foo"); |
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
438482
12202