Skip to content

Commit

Permalink
Fixes #253, findNestedDependencies now fixed from regression in 2.0.5…
Browse files Browse the repository at this point in the history
… due to parser change, and inadequate test suite.
  • Loading branch information
jrburke committed Aug 14, 2012
1 parent c2cb5d6 commit 6d79f0f
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 31 deletions.
54 changes: 23 additions & 31 deletions build/jslib/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ define(['./esprima'], function (esprima) {
//about obj.arguments use, as 'reserved word'
argPropName = 'arguments';

//From an exprima example for traversing its ast.
//From an esprima example for traversing its ast.
function traverse(object, visitor) {
var key, child;

Expand Down Expand Up @@ -271,22 +271,21 @@ define(['./esprima'], function (esprima) {
var match;

traverse(node, function (node) {
var arg0, arg1,
exp = node.expression;
var arg0, arg1;

if (exp && exp.type === 'CallExpression' &&
exp.callee && exp.callee.type === 'Identifier' &&
exp.callee.name === 'define' && exp[argPropName]) {
if (node && node.type === 'CallExpression' &&
node.callee && node.callee.type === 'Identifier' &&
node.callee.name === 'define' && node[argPropName]) {

//Just the factory function passed to define
arg0 = exp[argPropName][0];
arg0 = node[argPropName][0];
if (arg0 && arg0.type === 'FunctionExpression') {
match = arg0;
return false;
}

//A string literal module ID followed by the factory function.
arg1 = exp[argPropName][1];
arg1 = node[argPropName][1];
if (arg0.type === 'Literal' &&
arg1 && arg1.type === 'FunctionExpression') {
match = arg1;
Expand Down Expand Up @@ -319,16 +318,15 @@ define(['./esprima'], function (esprima) {

traverse(astRoot, function (node) {
var arg,
exp = node.expression,
c = exp && exp.callee,
c = node && node.callee,
requireType = parse.hasRequire(node);

if (requireType && (requireType === 'require' ||
requireType === 'requirejs' ||
requireType === 'requireConfig' ||
requireType === 'requirejsConfig')) {

arg = exp[argPropName] && exp[argPropName][0];
arg = node[argPropName] && node[argPropName][0];

if (arg && arg.type === 'ObjectExpression') {
jsConfig = parse.nodeToString(fileContents, arg);
Expand Down Expand Up @@ -397,20 +395,18 @@ define(['./esprima'], function (esprima) {

//define.amd = ...
parse.hasDefineAmd = function (node) {
var exp = node.expression;
return exp && exp.type === 'AssignmentExpression' &&
exp.left && exp.left.type === 'MemberExpression' &&
exp.left.object && exp.left.object.name === 'define' &&
exp.left.property && exp.left.property.name === 'amd';
return node && node.type === 'AssignmentExpression' &&
node.left && node.left.type === 'MemberExpression' &&
node.left.object && node.left.object.name === 'define' &&
node.left.property && node.left.property.name === 'amd';
};

//require(), requirejs(), require.config() and requirejs.config()
parse.hasRequire = function (node) {
var callName,
exp = node.expression,
c = exp && exp.callee;
c = node && node.callee;

if (exp && exp.type === 'CallExpression' && c) {
if (node && node.type === 'CallExpression' && c) {
if (c.type === 'Identifier' &&
(c.name === 'require' ||
c.name === 'requirejs')) {
Expand All @@ -432,11 +428,9 @@ define(['./esprima'], function (esprima) {

//define()
parse.hasDefine = function (node) {
var exp = node.expression;

return exp && exp.type === 'CallExpression' && exp.callee &&
exp.callee.type === 'Identifier' &&
exp.callee.name === 'define';
return node && node.type === 'CallExpression' && node.callee &&
node.callee.type === 'Identifier' &&
node.callee.name === 'define';
};

/**
Expand All @@ -447,7 +441,7 @@ define(['./esprima'], function (esprima) {
var uses;

traverse(esprima.parse(fileContents), function (node) {
var type, callName, arg, exp;
var type, callName, arg;

if (parse.hasDefDefine(node)) {
//function define() {}
Expand All @@ -457,8 +451,7 @@ define(['./esprima'], function (esprima) {
} else {
callName = parse.hasRequire(node);
if (callName) {
exp = node.expression;
arg = exp[argPropName] && exp[argPropName][0];
arg = node[argPropName] && node[argPropName][0];
if (arg && (arg.type === 'ObjectExpression' ||
arg.type === 'ArrayExpression')) {
type = callName;
Expand Down Expand Up @@ -568,17 +561,16 @@ define(['./esprima'], function (esprima) {
*/
parse.parseNode = function (node, onMatch) {
var name, deps, cjsDeps, arg, factory,
exp = node.expression,
args = exp && exp[argPropName],
args = node && node[argPropName],
callName = parse.hasRequire(node);

if (callName === 'require' || callName === 'requirejs') {
//A plain require/requirejs call
arg = exp[argPropName] && exp[argPropName][0];
arg = node[argPropName] && node[argPropName][0];
if (arg.type !== 'ArrayExpression') {
if (arg.type === 'ObjectExpression') {
//A config call, try the second arg.
arg = exp[argPropName][1];
arg = node[argPropName][1];
}
}

Expand Down
22 changes: 22 additions & 0 deletions build/tests/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,28 @@ define(['parse', 'env!env/file'], function (parse, file) {
);
doh.run();


doh.register('parseFindNestedDependencies',
[
function parseFindNestedDependencies(t) {
var good1 = '(function() {\n' +
' define([\'require\', \'a\', \'b\'], function(require, a, b) {\n' +
' return require([\'c\'], function(c) {\n' +
' c(a, b);\n' +
' });\n' +
' });\n' +
'}).call(this);\n'

t.is('define("good1",["require","a","b","c"]);', parse("good1", "good1", good1, {
findNestedDependencies: true
}));
}
]
);
doh.run();



doh.register('parseHasRequire',
[
function parseHasRequire(t) {
Expand Down

0 comments on commit 6d79f0f

Please sign in to comment.