Comparing version 0.1.2 to 0.1.3
"use strict"; | ||
var _ = require("underscore"); | ||
var assert = require("assert"); | ||
var utils = require("../utils.js"); | ||
@@ -8,65 +10,30 @@ function compileCallMatcher(args) { | ||
var len = args.length; | ||
var groups = args.map(function (arg) { | ||
if (typeof arg === "string" && arg.substr(0, 2) === "??") { | ||
return { | ||
type: "multi", | ||
name: arg.substr(2), | ||
}; | ||
} else { | ||
return { | ||
type: "single", | ||
matcher: this.matcher(arg), | ||
}; | ||
} | ||
}, this); | ||
var multi = false; | ||
for (var i = 0; i < len; i++) { | ||
if (typeof args[i] === "string" && args[i].substr(0, 2) === "??") { | ||
if (multi === false) { | ||
multi = i; | ||
} else { | ||
throw new Error("Only single multi-pattern allowed in (call)"); | ||
} | ||
var minArgumentsCount = 0; | ||
var multiGroupsCount = 0; | ||
for (var i = 0; i < groups.length; i++) { | ||
if (groups[i].type === "single") { | ||
minArgumentsCount += 1; | ||
} else { | ||
multiGroupsCount += 1; | ||
} | ||
} | ||
var argumentsMatcher; | ||
if (multi === false) { | ||
var argumentMatchers = args.map(this.matcher, this); | ||
argumentsMatcher = function (nodes) { | ||
var result = {}; | ||
for (var j = 0; j < len; j++) { | ||
var argumentM = argumentMatchers[j](nodes[j]); | ||
if (argumentM === undefined) { return undefined; } | ||
result = _.extend(result, argumentM); | ||
} | ||
return result; | ||
}; | ||
} else { | ||
var prefixMatchers = args.slice(0, multi).map(this.matcher, this); | ||
var postfixMatchers = args.slice(multi + 1).map(this.matcher, this); | ||
var postfixLen = postfixMatchers.length; | ||
argumentsMatcher = function (nodes) { | ||
var j; | ||
var argumentM; | ||
var result = {}; | ||
for (j = 0; j < multi; j++) { | ||
argumentM = prefixMatchers[j](nodes[j]); | ||
if (argumentM === undefined) { return undefined; } | ||
result = _.extend(result, argumentM); | ||
} | ||
var shift = nodes.length - postfixLen; | ||
if (args[multi] !== "??") { | ||
var multiVar = args[multi].substr(2); | ||
result[multiVar] = nodes.slice(multi, shift); | ||
} | ||
for (j = 0; j < postfixMatchers.length; j++) { | ||
argumentM = postfixMatchers[j](nodes[shift + j]); | ||
if (argumentM === undefined) { return undefined; } | ||
result = _.extend(result, argumentM); | ||
} | ||
return result; | ||
}; | ||
} | ||
return { | ||
argumentsMatcher: argumentsMatcher, | ||
minArguments: args.length, | ||
variableArguments: multi !== false, | ||
groups: groups, | ||
minArgumentsCount: minArgumentsCount, | ||
multiGroupsCount: multiGroupsCount, | ||
}; | ||
@@ -96,26 +63,80 @@ } | ||
var compiled = compileCallMatcher.call(this, args); | ||
var argumentsMatcher = compiled.argumentsMatcher; | ||
var minArguments = compiled.minArguments; | ||
var variableArguments = compiled.variableArguments; | ||
return function (node) { | ||
if (!node || node.type !== (callnew ? "CallExpression" : "NewExpression")) { return undefined; } | ||
// destruct | ||
var groups = compiled.groups; | ||
var groupsCount = groups.length; | ||
var multiGroupsCount = compiled.multiGroupsCount; | ||
var minArgumentsCount = compiled.minArgumentsCount; | ||
var variableArguments = multiGroupsCount !== 0; | ||
// Check the length of arguments list | ||
if (variableArguments) { | ||
if (node.arguments.length < minArguments) { return undefined; } | ||
} else { | ||
if (node.arguments.length !== minArguments) { return undefined; } | ||
} | ||
if (variableArguments) { | ||
assert(minArgumentsCount < groupsCount, "variable arguments: minArgumentsCount should be less than groupsCount"); | ||
assert(multiGroupsCount > 0, "groups count should be greater than zero"); | ||
// callee | ||
var calleeM = calleeMatcher(node.callee); | ||
if (calleeM === undefined) { return undefined; } | ||
return function (node) { | ||
if (!node || node.type !== (callnew ? "CallExpression" : "NewExpression")) { return undefined; } | ||
// arguments | ||
var argumentsM = argumentsMatcher(node.arguments); | ||
if (argumentsM === undefined) { return undefined; } | ||
// Check the length of arguments list | ||
if (node.arguments.length < minArgumentsCount) { return undefined; } | ||
return _.extend(calleeM, argumentsM); | ||
}; | ||
// callee | ||
var calleeM = calleeMatcher(node.callee); | ||
if (calleeM === undefined) { return undefined; } | ||
// arguments | ||
var argumentsLength = node.arguments.length; | ||
var parts = utils.partitions(argumentsLength - minArgumentsCount, multiGroupsCount); | ||
var argumentsM = utils.some(parts, function (part) { | ||
// console.log("part", part); | ||
var resultM = {}; | ||
var argumentIdx = 0; | ||
var multiIdx = 0; | ||
for (var groupIdx = 0; groupIdx < groupsCount; groupIdx++) { | ||
var group = groups[groupIdx]; | ||
// console.log("LOOP", groupIdx, group.type, argumentIdx, multiIdx); | ||
if (group.type === "single") { | ||
var groupM = group.matcher(node.arguments[argumentIdx]); | ||
if (groupM === undefined) { return undefined; } | ||
_.extend(resultM, groupM); | ||
argumentIdx += 1; | ||
} else { | ||
var mgSize = part[multiIdx]; | ||
if (group.name !== "") { | ||
resultM[group.name] = node.arguments.slice(argumentIdx, argumentIdx + mgSize); | ||
} | ||
argumentIdx += mgSize; | ||
multiIdx += 1; | ||
} | ||
} | ||
return resultM; | ||
}); | ||
if (argumentsM === undefined) { 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; } | ||
// Check the length of arguments list | ||
if (node.arguments.length !== minArgumentsCount) { return undefined; } | ||
// callee | ||
var calleeM = calleeMatcher(node.callee); | ||
if (calleeM === undefined) { return undefined; } | ||
// arguments | ||
for (var i = 0; i < groupsCount; i++) { | ||
var group = groups[i]; | ||
assert(group.type === "single"); | ||
var groupM = group.matcher(node.arguments[i]); | ||
if (groupM === undefined) { return undefined; } | ||
_.extend(calleeM, groupM); | ||
} | ||
return calleeM; | ||
}; | ||
} | ||
} | ||
@@ -122,0 +143,0 @@ |
{ | ||
"name": "jsstana", | ||
"description": "s-expression match patterns for Mozilla Parser AST", | ||
"version": "0.1.2", | ||
"version": "0.1.3", | ||
"homepage": "https://github.com/phadej/jsstana", | ||
@@ -35,2 +35,3 @@ "author": { | ||
"devDependencies": { | ||
"chai": "^1.9.2", | ||
"david": "^5.0.0", | ||
@@ -42,2 +43,3 @@ "escodegen": "~1.4.0", | ||
"jshint": "~2.5.1", | ||
"jsverify": "^0.4.3", | ||
"ljs": "~0.2.0", | ||
@@ -44,0 +46,0 @@ "mocha": "~2.0.1" |
@@ -276,2 +276,6 @@ # jsstana | ||
- 0.1.3 Multiple multi-param matching groups in `(call)` | ||
Example: `(call ? ?? 0 ??)` checks whether function has zero as any argument. | ||
- 0.1.2 Fix bug, identifier could start with underscore: `_` | ||
@@ -278,0 +282,0 @@ - 0.1.1 New (call) syntax |
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
55607
21
1243
363
10