jscodeshift
Advanced tools
Comparing version 0.1.2 to 0.1.3
@@ -17,40 +17,7 @@ /* | ||
var types = recast.types; | ||
var NodePath = types.NodePath; | ||
var Node = types.namedTypes.Node; | ||
var astTypes = recast.types; | ||
var types = astTypes.namedTypes; | ||
var NodePath = astTypes.NodePath; | ||
var Node = types.Node; | ||
var _typedCollectionCache = Object.create(null); | ||
function _createCollectionForType(type) { | ||
/*jshint evil:true*/ | ||
// Yeah this is ugly, but I want to give the function a proper name to make | ||
// debugging easier. Maybe can omit the name at some point. | ||
var Constr = eval( | ||
'(function ' + type + 'Collection() { Collection.apply(this, arguments);})' | ||
); | ||
// TODO: Try to find a solution for types having multiple supertypes. | ||
// E.g. a FunctionExpression has the supertypes Function and Expression. | ||
// Not sure if this is an issue so far. | ||
var supertypes = types.getSupertypeNames(type.toString()); | ||
var superTypePrototype = supertypes[0] ? | ||
_getCollectionForType(supertypes[0]).prototype : | ||
Collection.prototype; | ||
Constr.prototype = Object.create( | ||
superTypePrototype, | ||
{constructor: {value: Constr, writeable: true, configurable: true}} | ||
); | ||
return Constr; | ||
} | ||
function _getCollectionForType(type) { | ||
if (!(type in _typedCollectionCache)) { | ||
_typedCollectionCache[type] = _createCollectionForType(type); | ||
} | ||
return _typedCollectionCache[type]; | ||
} | ||
/** | ||
@@ -66,5 +33,7 @@ * This represents a generic collection of node paths. It only has a generic | ||
* @param {Collection} parent A parent collection | ||
* @param {Array} types An array of types all the paths in the collection | ||
* have in common. If not passed, it will be inferred from the paths. | ||
* @return {Collection} | ||
*/ | ||
function Collection(paths, parent) { | ||
function Collection(paths, parent, types) { | ||
assert.ok(Array.isArray(paths), 'Collection is passed an array'); | ||
@@ -77,2 +46,8 @@ assert.ok( | ||
this.__paths = paths; | ||
if (types && !Array.isArray(types)) { | ||
types = _toTypeArray(types); | ||
} else if (!types || Array.isArray(types) && types.length === 0) { | ||
types = _inferTypes(paths); | ||
} | ||
this.$Collection_types = types.length === 0 ? _defaultType : types; | ||
} | ||
@@ -188,10 +163,68 @@ | ||
*/ | ||
Object.defineProperty(Collection.prototype,"get",{writable:true,configurable:true,value:function() { | ||
var path = this.__paths[0]; | ||
return path.get.apply(path, arguments); | ||
}}); | ||
Object.defineProperty(Collection.prototype,"get",{writable:true,configurable:true,value:function() { | ||
var path = this.__paths[0]; | ||
return path.get.apply(path, arguments); | ||
}}); | ||
/** | ||
* Returns the type(s) of the collection. This is only used for unit tests, | ||
* I don't think other consumers would need it. | ||
* | ||
* @return {Array<string>} | ||
*/ | ||
Object.defineProperty(Collection.prototype,"getTypes",{writable:true,configurable:true,value:function() { | ||
return this.$Collection_types; | ||
}}); | ||
/** | ||
* Returns true if this collection has the type 'type'. | ||
* | ||
* @param {Type} type | ||
* @return {boolean} | ||
*/ | ||
Object.defineProperty(Collection.prototype,"isOfType",{writable:true,configurable:true,value:function(type) { | ||
return !!type && this.$Collection_types.indexOf(type.toString()) > -1; | ||
}}); | ||
/** | ||
* Given a set of paths, this infers the common types of all paths. | ||
* | ||
* @param {Array} paths An array of paths. | ||
* @return {Type} type An AST type | ||
*/ | ||
function _inferTypes(paths) { | ||
var _types = []; | ||
if (paths.length > 0 && Node.check(paths[0].node)) { | ||
var nodeType = types[paths[0].node.type]; | ||
var sameType = paths.length === 1 || | ||
paths.every(function(path) {return nodeType.check(path.node);}); | ||
if (sameType) { | ||
_types = [nodeType.toString()].concat( | ||
astTypes.getSupertypeNames(nodeType.toString()) | ||
); | ||
} else { | ||
// try to find a common type | ||
_types = _.intersection.apply( | ||
null, | ||
paths.map(function(path) {return astTypes.getSupertypeNames(path.node.type);}) | ||
); | ||
} | ||
} | ||
return _types; | ||
} | ||
function _toTypeArray(value) { | ||
value = !Array.isArray(value) ? [value] : value; | ||
value = value.map(function(v) {return v.toString();}); | ||
return _.union(value, _.intersection.apply( | ||
null, | ||
value.map(function(type) {return astTypes.getSupertypeNames(type);}) | ||
)); | ||
} | ||
/** | ||
* Creates a new collection from an array of node paths. | ||
@@ -217,28 +250,3 @@ * | ||
var collection; | ||
if (!type && paths.length > 0 && Node.check(paths[0].value)) { | ||
var nodeType = types.namedTypes[paths[0].value.type]; | ||
var sameType = paths.length === 1 || | ||
paths.every(function(path) {return nodeType.check(path.value);}); | ||
if (sameType) { | ||
type = nodeType; | ||
} else { | ||
// try to find a common type | ||
type = _.intersection.apply( | ||
null, | ||
paths.map(function(path) {return types.getSupertypeNames(path.value.type);}) | ||
)[0]; | ||
} | ||
} | ||
if (type) { | ||
collection = new (_getCollectionForType(type))(paths, parent); | ||
} | ||
if (!collection) { | ||
/*jshint newcap:false*/ | ||
collection = new _defaultCollection(paths, parent); | ||
} | ||
return collection; | ||
return new Collection(paths, parent, type); | ||
} | ||
@@ -269,2 +277,4 @@ | ||
var CPt = Collection.prototype; | ||
/** | ||
@@ -279,7 +289,26 @@ * This function adds the provided methods to the prototype of the corresponding | ||
function registerMethods(methods, type) { | ||
var constructor = type ? _getCollectionForType(type) : _defaultCollection; | ||
_.assign(constructor.prototype, methods); | ||
for (var methodName in methods) { | ||
if (CPt.hasOwnProperty(methodName)) { | ||
throw Error(("A method with name \"" + methodName + "\" already exists.")); | ||
} | ||
if (!type) { | ||
CPt[methodName] = methods[methodName]; | ||
} else { | ||
type = type.toString(); | ||
(function(methodName, method) { | ||
CPt[methodName] = function() { | ||
if (!this.isOfType(type)) { | ||
throw Error( | ||
("You have a collection of type [" + this.getTypes() + "]. ") + | ||
("\"" + methodName + "\" is is only defined for \"" + type + "\".") | ||
); | ||
} | ||
return method.apply(this, arguments); | ||
}; | ||
}(methodName, methods[methodName])); | ||
} | ||
} | ||
} | ||
var _defaultCollection = Collection; | ||
var _defaultType = []; | ||
@@ -294,3 +323,3 @@ /** | ||
function setDefaultCollectionType(type) { | ||
_defaultCollection = _getCollectionForType(type); | ||
_defaultType = _toTypeArray(type); | ||
} | ||
@@ -297,0 +326,0 @@ |
@@ -13,2 +13,3 @@ /* | ||
var _ = require('lodash'); | ||
var Collection = require('../Collection'); | ||
@@ -190,4 +191,4 @@ var NodeCollection = require('./Node'); | ||
exports.register = register; | ||
exports.register = _.once(register); | ||
exports.filters = filterMethods; | ||
exports.mappings = mappingMethods; |
@@ -13,2 +13,3 @@ /* | ||
var _ = require('lodash'); | ||
var Collection = require('../Collection'); | ||
@@ -191,2 +192,2 @@ | ||
exports.register = register; | ||
exports.register = _.once(register); |
@@ -12,2 +12,4 @@ /* | ||
"use strict"; | ||
var _ = require('lodash'); | ||
var Collection = require('../Collection'); | ||
@@ -111,3 +113,3 @@ var NodeCollection = require('./Node'); | ||
exports.register = register; | ||
exports.register = _.once(register); | ||
exports.filters = filterMethods; |
{ | ||
"name": "jscodeshift", | ||
"version": "0.1.2", | ||
"version": "0.1.3", | ||
"description": "A toolkit for JavaScript codemods", | ||
@@ -5,0 +5,0 @@ "repository": { |
@@ -1,2 +0,2 @@ | ||
# jscodeshift | ||
# jscodeshift [![Build Status](https://travis-ci.org/facebook/jscodeshift.svg?branch=master)](https://travis-ci.org/facebook/jscodeshift) | ||
@@ -3,0 +3,0 @@ jscodeshift is a toolkit for running codemods over multiple JS files. |
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
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
50199
1116
1
18