Comparing version 0.1.3 to 0.1.4
@@ -200,3 +200,5 @@ #!/usr/bin/env node | ||
var ret = cli(process.argv); | ||
process.exit(ret); | ||
var returnCode = cli(process.argv); | ||
/* eslint-disable no-process-exit */ | ||
process.exit(returnCode); | ||
/* eslint-enable no-process-exit */ |
@@ -53,5 +53,5 @@ /** | ||
var sexprParse = require("./sexpr.js").parse; | ||
var levenshtein = require("levenshtein"); | ||
var Levenshtein = require("levenshtein"); | ||
var misc = require("./misc.js"); | ||
var literalMatchers = require("./matchers/literal.js"); | ||
var literal = require("./matchers/literal.js"); | ||
@@ -92,2 +92,3 @@ // Generic traversing function | ||
_.extend(builtInMatchers, require("./matchers/fn.js")); | ||
_.extend(builtInMatchers, require("./matchers/object.js")); | ||
@@ -98,3 +99,3 @@ function unknownNodeType(rator) { | ||
function findClose(key) { | ||
var d = new levenshtein(rator, key).distance; | ||
var d = new Levenshtein(rator, key).distance; | ||
@@ -142,5 +143,5 @@ if (d <= 2) { | ||
} else if (sexpr === "this") { | ||
return literalMatchers["this"].call(that); | ||
return literal["this"].call(that); | ||
} else if (_.has(misc.CONSTANTS, sexpr)) { | ||
return literalMatchers[sexpr].call(that); | ||
return literal[sexpr].call(that); | ||
} else { | ||
@@ -246,2 +247,3 @@ return function (node) { | ||
/// include matchers/fn.js | ||
/// include matchers/object.js | ||
@@ -304,2 +306,24 @@ /** | ||
/** | ||
### eslintRule(pattern, f) | ||
*/ | ||
function eslintRule(pattern, f) { | ||
/* jshint validthis:true */ | ||
var compiled = this.match(pattern); | ||
return function (context) { | ||
var ruleCheck = function (node) { | ||
var m = compiled(node); | ||
if (m) { | ||
f(context, node, m); | ||
} | ||
}; | ||
var res = {}; | ||
_.each(compiled.nodeTypes, function (nodeType) { | ||
res[nodeType] = ruleCheck; | ||
}); | ||
return res; | ||
}; | ||
} | ||
/** | ||
### new jsstana() | ||
@@ -335,2 +359,3 @@ | ||
JsstanaContext.prototype.match = match; | ||
JsstanaContext.prototype.eslintRule = eslintRule; | ||
JsstanaContext.prototype.createMatcher = createMatcher; | ||
@@ -345,2 +370,3 @@ JsstanaContext.prototype.addMatcher = function (name, f) { | ||
JsstanaContext.match = match; | ||
JsstanaContext.eslintRule = eslintRule; | ||
JsstanaContext.createMatcher = createMatcher; | ||
@@ -347,0 +373,0 @@ |
@@ -6,2 +6,3 @@ "use strict"; | ||
var utils = require("../utils.js"); | ||
var misc = require("../misc.js"); | ||
@@ -75,5 +76,3 @@ function compileCallMatcher(args) { | ||
return function (node) { | ||
if (!node || node.type !== (callnew ? "CallExpression" : "NewExpression")) { return undefined; } | ||
return misc.nodeMatcher(callnew ? "CallExpression" : "NewExpression", function (node) { | ||
// Check the length of arguments list | ||
@@ -117,8 +116,6 @@ if (node.arguments.length < minArgumentsCount) { return undefined; } | ||
return _.extend(calleeM, argumentsM); | ||
}; | ||
}); | ||
} else { | ||
assert(minArgumentsCount === groupsCount, "no variable arguments: minArgumentsCount should equal groupsCount"); | ||
return function (node) { | ||
if (!node || node.type !== (callnew ? "CallExpression" : "NewExpression")) { return undefined; } | ||
return misc.nodeMatcher(callnew ? "CallExpression" : "NewExpression", function (node) { | ||
// Check the length of arguments list | ||
@@ -141,3 +138,3 @@ if (node.arguments.length !== minArgumentsCount) { return undefined; } | ||
return calleeM; | ||
}; | ||
}); | ||
} | ||
@@ -144,0 +141,0 @@ } |
"use strict"; | ||
var misc = require("../misc.js"); | ||
/** | ||
@@ -9,5 +11,5 @@ #### (fn-expr) | ||
function fnExprMatcher() { | ||
return function (node) { | ||
return node !== null && node.type === "FunctionExpression" ? {} : undefined; | ||
}; | ||
return misc.nodeMatcher("FunctionExpression", function () { | ||
return {}; | ||
}); | ||
} | ||
@@ -14,0 +16,0 @@ |
@@ -5,2 +5,3 @@ "use strict"; | ||
var assert = require("assert"); | ||
var misc = require("../misc.js"); | ||
@@ -45,7 +46,3 @@ function identifierMatcher(sexpr) { | ||
return function (node) { | ||
if (!node || node.type !== "Identifier") { return undefined; } | ||
return nameMatcher(node); | ||
}; | ||
return misc.nodeMatcher("Identifier", nameMatcher); | ||
} | ||
@@ -69,10 +66,7 @@ | ||
return function (node) { | ||
if (!node || node.type !== "VariableDeclarator") { return undefined; } | ||
return misc.nodeMatcher("VariableDeclarator", function (node) { | ||
var idM = idMatcher(node.id); | ||
var initM = initMatcher(node.init); | ||
return that.combineMatches(idM, initM); | ||
}; | ||
}); | ||
} | ||
@@ -79,0 +73,0 @@ |
@@ -33,10 +33,10 @@ "use strict"; | ||
var value = misc.CONSTANTS[type]; | ||
return function (node) { | ||
return node && node.type === "Literal" && node.value === value ? {} : undefined; | ||
}; | ||
return misc.nodeMatcher("Literal", function (node) { | ||
return node.value === value ? {} : undefined; | ||
}); | ||
} else { | ||
var ident = misc.LITERALS[type]; | ||
return function (node) { | ||
return node && node.type === "Identifier" && node.name === ident ? {} : undefined; | ||
}; | ||
return misc.nodeMatcher("Identifier", function (node) { | ||
return node.name === ident ? {} : undefined; | ||
}); | ||
} | ||
@@ -54,5 +54,5 @@ } | ||
return function (node) { | ||
return node && node.type === "ThisExpression" ? {} : undefined; | ||
}; | ||
return misc.nodeMatcher("ThisExpression", function (/* node */) { | ||
return {}; | ||
}); | ||
} | ||
@@ -82,7 +82,6 @@ | ||
return function (node) { | ||
if (node.type !== "Literal") { return undefined; } | ||
return misc.nodeMatcher("Literal", function (node) { | ||
if (!valueCheck(node.value)) { return undefined; } | ||
return valueCapture(node.value); | ||
}; | ||
}); | ||
} | ||
@@ -125,14 +124,12 @@ | ||
if (type === "regexp") { | ||
return function (node) { | ||
if (!node || node.type !== "Literal") { return undefined; } | ||
return misc.nodeMatcher("Literal", function (node) { | ||
if (!_.isRegExp(node.value)) { return undefined; } | ||
return node.value.toString() === value ? {} : undefined; | ||
}; | ||
}); | ||
} else { | ||
value = literalValue(type, value); | ||
return function (node) { | ||
if (node.type !== "Literal") { return undefined; } | ||
return misc.nodeMatcher("Literal", function (node) { | ||
return node.value === value ? {} : undefined; | ||
}; | ||
}); | ||
} | ||
@@ -139,0 +136,0 @@ } |
"use strict"; | ||
var _ = require("underscore"); | ||
var misc = require("../misc.js"); | ||
function notMatch(matcher) { | ||
return function (node) { | ||
var types = _.difference(misc.NODETYPES, matcher.nodetypes); | ||
return misc.nodeMatcher(types, function (node) { | ||
return matcher(node) ? undefined : {}; | ||
}; | ||
}); | ||
} | ||
@@ -34,3 +37,10 @@ | ||
return function (node) { | ||
var types = _.chain(argsMatchers) | ||
.pluck("nodeTypes") | ||
.flatten() | ||
.sortBy() | ||
.uniq(true) | ||
.value(); | ||
return misc.nodeMatcher(types, function (node) { | ||
for (var i = 0; i < argsMatchers.length; i++) { | ||
@@ -44,3 +54,3 @@ var m = argsMatchers[i](node); | ||
return undefined; | ||
}; | ||
}); | ||
} | ||
@@ -58,3 +68,8 @@ | ||
return function (node) { | ||
var types = _.chain(argsMatchers) | ||
.pluck("nodeTypes") | ||
.reduce(function (a, b) { return _.intersection(a, b); }, misc.NODETYPES) | ||
.value(); | ||
return misc.nodeMatcher(types, function (node) { | ||
var res = {}; | ||
@@ -72,3 +87,3 @@ | ||
return res; | ||
}; | ||
}); | ||
} | ||
@@ -75,0 +90,0 @@ |
@@ -5,2 +5,3 @@ "use strict"; | ||
var assert = require("assert"); | ||
var misc = require("../misc.js"); | ||
@@ -26,4 +27,3 @@ /** | ||
return function (node) { | ||
if (!node || node.type !== "MemberExpression") { return undefined; } | ||
return misc.nodeMatcher("MemberExpression", function (node) { | ||
if (computed !== undefined && node.computed !== computed) { return undefined; } | ||
@@ -35,3 +35,3 @@ | ||
return that.combineMatches(objectM, propertyM); | ||
}; | ||
}); | ||
} | ||
@@ -38,0 +38,0 @@ |
@@ -13,5 +13,7 @@ "use strict"; | ||
return function (node) { | ||
var f = function (node) { | ||
return node === null ? {} : undefined; | ||
}; | ||
f.nodeTypes = []; | ||
return f; | ||
} | ||
@@ -18,0 +20,0 @@ |
@@ -5,2 +5,3 @@ "use strict"; | ||
var assert = require("assert"); | ||
var misc = require("../misc.js"); | ||
@@ -85,5 +86,3 @@ function operatorMatcher(operator, validOperators) { | ||
return function (node) { | ||
if (!node || node.type !== exprType) { return undefined; } | ||
return misc.nodeMatcher(exprType, function (node) { | ||
var opM = opMatcher(node.operator); | ||
@@ -94,3 +93,3 @@ var lhsM = lhsMatcher(node.left); | ||
return that.combineMatches(opM, lhsM, rhsM); | ||
}; | ||
}); | ||
} | ||
@@ -121,5 +120,3 @@ | ||
return function (node) { | ||
if (!node || node.type !== "UnaryExpression") { return undefined; } | ||
return misc.nodeMatcher("UnaryExpression", function (node) { | ||
var opM = opMatcher(node.operator); | ||
@@ -129,3 +126,3 @@ var valueM = valueMatcher(node.argument); | ||
return that.combineMatches(opM, valueM); | ||
}; | ||
}); | ||
} | ||
@@ -153,4 +150,3 @@ | ||
return function (node) { | ||
if (!node || node.type !== "UpdateExpression") { return undefined; } | ||
return misc.nodeMatcher("UpdateExpression", function (node) { | ||
if (prefix !== undefined && node.prefix !== prefix) { return undefined; } | ||
@@ -162,3 +158,3 @@ | ||
return that.combineMatches(opM, valueM); | ||
}; | ||
}); | ||
} | ||
@@ -165,0 +161,0 @@ |
"use strict"; | ||
var _ = require("underscore"); | ||
var misc = require("../misc.js"); | ||
@@ -12,7 +13,5 @@ function simpleMatcher(rator, statement, prop, expr) { | ||
return function (node) { | ||
if (node.type !== statement) { return undefined; } | ||
return misc.nodeMatcher(statement, function (node) { | ||
return exprMatcher(node[prop]); | ||
}; | ||
}); | ||
} | ||
@@ -24,5 +23,5 @@ | ||
return function (node) { | ||
return node && node.type === statement ? {} : undefined; | ||
}; | ||
return misc.nodeMatcher(statement, function (/* node */) { | ||
return {}; | ||
}); | ||
} | ||
@@ -29,0 +28,0 @@ |
"use strict"; | ||
var misc = require("../misc.js"); | ||
/** | ||
@@ -21,5 +23,3 @@ #### (ternary test con alt) | ||
return function (node) { | ||
if (!node || node.type !== "ConditionalExpression") { return undefined; } | ||
return misc.nodeMatcher("ConditionalExpression", function (node) { | ||
var testM = testMatcher(node.test); | ||
@@ -30,3 +30,3 @@ var consequentM = consequentMatcher(node.consequent); | ||
return that.combineMatches(testM, consequentM, alternateM); | ||
}; | ||
}); | ||
} | ||
@@ -33,0 +33,0 @@ |
"use strict"; | ||
var _ = require("underscore"); | ||
var CONSTANTS = { | ||
@@ -20,5 +22,74 @@ "true": true, | ||
/* Fetched on 2014-11-09 */ | ||
var NODETYPES = [ | ||
"Program", | ||
"EmptyStatement", | ||
"BlockStatement", | ||
"ExpressionStatement", | ||
"IfStatement", | ||
"LabeledStatement", | ||
"BreakStatement", | ||
"ContinueStatement", | ||
"WithStatement", | ||
"SwitchStatement", | ||
"ReturnStatement", | ||
"ThrowStatement", | ||
"TryStatement", | ||
"WhileStatement", | ||
"DoWhileStatement", | ||
"ForStatement", | ||
"ForInStatement", | ||
"ForOfStatement", | ||
"LetStatement", | ||
"DebuggerStatement", | ||
"FunctionDeclaration", | ||
"VariableDeclaration", | ||
"VariableDeclarator", | ||
"ThisExpression", | ||
"ArrayExpression", | ||
"ObjectExpression", | ||
"Property", | ||
"FunctionExpression", | ||
"ArrowExpression", | ||
"SequenceExpression", | ||
"UnaryExpression", | ||
"BinaryExpression", | ||
"AssignmentExpression", | ||
"UpdateExpression", | ||
"LogicalExpression", | ||
"ConditionalExpression", | ||
"NewExpression", | ||
"CallExpression", | ||
"MemberExpression", | ||
"YieldExpression", | ||
"ComprehensionExpression", | ||
"GeneratorExpression", | ||
"ObjectPattern", | ||
"ArrayPattern", | ||
"SwitchCase", | ||
"CatchClause", | ||
"ComprehensionBlock", | ||
"Identifier", | ||
"Literal", | ||
]; | ||
function nodeMatcher(nodeTypes, matcher) { | ||
if (typeof nodeTypes === "string") { | ||
nodeTypes = [nodeTypes]; | ||
} | ||
var f = function (node) { | ||
if (!node || !_.contains(nodeTypes, node.type)) { return undefined; } | ||
return matcher(node); | ||
}; | ||
f.nodeTypes = nodeTypes; | ||
return f; | ||
} | ||
module.exports = { | ||
CONSTANTS: CONSTANTS, | ||
LITERALS: LITERALS, | ||
NODETYPES: NODETYPES, | ||
nodeMatcher: nodeMatcher, | ||
}; |
{ | ||
"name": "jsstana", | ||
"description": "s-expression match patterns for Mozilla Parser AST", | ||
"version": "0.1.3", | ||
"version": "0.1.4", | ||
"homepage": "https://github.com/phadej/jsstana", | ||
@@ -6,0 +6,0 @@ "author": { |
@@ -220,2 +220,8 @@ # jsstana | ||
#### (object) | ||
Matches `ObjectExpression`. | ||
## API | ||
@@ -247,2 +253,5 @@ | ||
### eslintRule(pattern, f) | ||
### new jsstana() | ||
@@ -278,2 +287,4 @@ | ||
- 0.1.4 – *2014-11-09* – jsstana.eslintRule | ||
- `(object)` matcher | ||
- 0.1.3 Multiple multi-param matching groups in `(call)` | ||
@@ -280,0 +291,0 @@ |
Sorry, the diff of this file is not supported yet
63615
38
1493
374