Skip to content

Commit 950fe9e

Browse files
author
Andrew Schmadel
committed
test all the things; pass all the tests
1 parent 210df1d commit 950fe9e

10 files changed

Lines changed: 114 additions & 543 deletions

File tree

babel-ng-annotate.js

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import { match, isFunctionExpressionWithArgs, isFunctionDeclarationWithArgs,
2-
isAnnotatedArray, addModuleContextDependentSuspect, addModuleContextIndependentSuspect,
3-
stringify, matchResolve, matchProp, last, judgeSuspects, matchDirectiveReturnObject,
1+
import { match, addModuleContextDependentSuspect, addModuleContextIndependentSuspect,
2+
judgeSuspects, matchDirectiveReturnObject,
43
matchProviderGet } from './ng-annotate-main.js'
54

65
import ngInject from './nginject';
@@ -10,7 +9,6 @@ export default function({ types: t }) {
109

1110
var options = {};
1211

13-
const quot = options.single_quotes ? "'" : '"';
1412
const re = (options.regexp ? new RegExp(options.regexp) : /^[a-zA-Z0-9_\$\.\s]+$/);
1513

1614
// suspects is built up with suspect nodes by match.
@@ -25,23 +23,12 @@ export default function({ types: t }) {
2523
// in blocked will be ignored by judgeSuspects
2624
const blocked = [];
2725

28-
// scopeTools.setupScopeAndReferences(ast);
29-
3026
const ctx = {
31-
mode: "add",
32-
quot: quot,
3327
re: re,
3428
suspects: suspects,
3529
blocked: blocked,
36-
isFunctionExpressionWithArgs: isFunctionExpressionWithArgs,
37-
isFunctionDeclarationWithArgs: isFunctionDeclarationWithArgs,
38-
isAnnotatedArray: isAnnotatedArray,
3930
addModuleContextDependentSuspect: addModuleContextDependentSuspect,
40-
addModuleContextIndependentSuspect: addModuleContextIndependentSuspect,
41-
stringify: stringify,
42-
matchResolve: matchResolve,
43-
matchProp: matchProp,
44-
last: last
31+
addModuleContextIndependentSuspect: addModuleContextIndependentSuspect
4532
};
4633

4734
var addTargets = function(targets) {
@@ -117,7 +104,7 @@ export default function({ types: t }) {
117104
return file.file.code.slice(node.start, node.end);
118105
};
119106
},
120-
exit(path, file) {
107+
exit(path) {
121108
judgeSuspects(ctx);
122109
}
123110
}

ng-annotate-main.js

Lines changed: 31 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -63,25 +63,25 @@ function matchMaterialShowModalOpen(path) {
6363
return false;
6464
}
6565

66-
function matchDirectiveReturnObject(pathOrNode) {
67-
const node = pathOrNode.node || pathOrNode;
66+
function matchDirectiveReturnObject(path) {
67+
const node = path.node;
6868

6969
// only matches inside directives
7070
// return { .. controller: function($scope, $timeout), ...}
7171

7272
return limit("directive", t.isReturnStatement(node) &&
7373
node.argument && t.isObjectExpression(node.argument) &&
74-
matchProp("controller", (pathOrNode.get && pathOrNode.get("argument.properties") || node.argument.properties)));
74+
matchProp("controller", (path.get && path.get("argument.properties") || node.argument.properties)));
7575
}
7676

77-
function limit(name, pathOrNode) {
78-
const node = (pathOrNode && pathOrNode.node) || pathOrNode;
77+
function limit(name, path) {
78+
const node = (path && path.node) || path;
7979

80-
if (node && !node.$limitToMethodName) {
81-
pathOrNode.$limitToMethodName = name;
80+
if (node && !path.$limitToMethodName) {
81+
path.$limitToMethodName = name;
8282
// node.$limitToMethodName = name;
8383
}
84-
return pathOrNode;
84+
return path;
8585
}
8686

8787
function matchProviderGet(path) {
@@ -456,12 +456,6 @@ function renamedString(ctx, originalString) {
456456
return originalString;
457457
}
458458

459-
function stringify(ctx, arr, quot) {
460-
return "[" + arr.map(function(arg) {
461-
return quot + renamedString(ctx, arg.name) + quot;
462-
}).join(", ") + "]";
463-
}
464-
465459
function insertArray(ctx, path) {
466460
if(!path.node){
467461
console.warn("Not a path", path, path.loc.start, path.loc.end);
@@ -499,7 +493,6 @@ function renameProviderDeclarationSite(ctx, literalNode, fragments) {
499493
}
500494

501495
function judgeSuspects(ctx) {
502-
const mode = ctx.mode;
503496
const blocked = ctx.blocked;
504497

505498
const suspects = makeUnique(ctx.suspects, 1);
@@ -529,20 +522,20 @@ function judgeSuspects(ctx) {
529522
return jumpedAndFollowed;
530523
}).filter(Boolean), 2);
531524

532-
finalSuspects.forEach(function(nodeOrPath) {
533-
let target = nodeOrPath.node || nodeOrPath;
525+
finalSuspects.forEach(function(path) {
526+
let target = path.node || path;
534527
if (target.$chained !== chainedRegular) {
535528
return;
536529
}
537530

538-
if (is.someof(mode, ["add", "rebuild"]) && isFunctionExpressionWithArgs(target)) {
539-
insertArray(ctx, nodeOrPath);
531+
if (isFunctionExpressionWithArgs(target) && !t.isVariableDeclarator(path.parent)) {
532+
insertArray(ctx, path);
540533
} else if (isGenericProviderName(target)) {
541534
// console.warn("Generic provider rename disabled");
542535
// renameProviderDeclarationSite(ctx, target, fragments);
543536
} else {
544537
// if it's not array or function-expression, then it's a candidate for foo.$inject = [..]
545-
judgeInjectArraySuspect(nodeOrPath, ctx);
538+
judgeInjectArraySuspect(path, ctx);
546539
}
547540
});
548541

@@ -620,17 +613,13 @@ function judgeSuspects(ctx) {
620613
}
621614

622615
function followReference(path) {
623-
if(!path || !path.node){
624-
console.warn("not a path");
625-
}
626616
const node = path.node;
627617
if (!scopeTools.isReference(path)) {
628618
return null;
629619
}
630620

631621
const binding = path.scope.getBinding(node.name);
632622
if(!binding){
633-
console.warn("invalid binding");
634623
return null;
635624
}
636625

@@ -656,22 +645,6 @@ function followReference(path) {
656645
return null;
657646
}
658647

659-
660-
function firstNonPrologueStatement(body) {
661-
for (let i = 0; i < body.length; i++) {
662-
if (!t.isExpressionStatement(body[i])) {
663-
return body[i];
664-
}
665-
666-
const expr = body[i].expression;
667-
const isStringLiteral = (t.isLiteral(expr) && typeof expr.value === "string");
668-
if (!isStringLiteral) {
669-
return body[i];
670-
}
671-
}
672-
return null;
673-
}
674-
675648
function judgeInjectArraySuspect(path, ctx) {
676649
let node = path.node;
677650

@@ -713,9 +686,10 @@ function judgeInjectArraySuspect(path, ctx) {
713686
return;
714687
}
715688

716-
// node = jumpOverIife(node);
689+
path = jumpOverIife(path);
690+
node = path.node;
717691

718-
if (ctx.isFunctionExpressionWithArgs(node)) {
692+
if (isFunctionExpressionWithArgs(node)) {
719693
// var x = 1, y = function(a,b) {}, z;
720694

721695
if(node.id && node.id.name !== declaratorName){
@@ -725,44 +699,43 @@ function judgeInjectArraySuspect(path, ctx) {
725699
assert(declaratorName);
726700
addInjectArrayAfterPath(node.params, opath, declaratorName);
727701

728-
} else if (ctx.isFunctionDeclarationWithArgs(node)) {
702+
} else if (isFunctionDeclarationWithArgs(node)) {
729703
// /*@ngInject*/ function foo($scope) {}
730704
addInjectArrayBeforePath(node.params,path,node.id.name);
731705

732706
} else if (t.isExpressionStatement(node) && t.isAssignmentExpression(node.expression) &&
733-
ctx.isFunctionExpressionWithArgs(node.expression.right)) {
707+
isFunctionExpressionWithArgs(node.expression.right) && !path.get("expression.right").$seen) {
734708
// /*@ngInject*/ foo.bar[0] = function($scope) {}
735-
736-
const name = ctx.srcForRange(node.expression.left.range);
737-
console.warn("Expression statement unimplemented");
738-
// addRemoveInjectArray(
739-
// node.expression.right.params,
740-
// isSemicolonTerminated ? insertPos : {
741-
// pos: node.expression.right.range[1],
742-
// loc: node.expression.right.loc.end
743-
// },
744-
// name);
709+
let inject = buildInjectExpression(node.expression.right.params, t.cloneDeep(node.expression.left));
710+
path.insertAfter(inject);
745711

746712
} else if (path = followReference(path)) {
747713
// node was a reference and followed node now is either a
748714
// FunctionDeclaration or a VariableDeclarator
749715
// => recurse
750716

751-
judgeInjectArraySuspect(path, ctx);
717+
!path.$seen && judgeInjectArraySuspect(path, ctx);
752718
}
753719

754720
function buildInjectExpression(params, name){
721+
let left = t.isNode(name) ? name : t.identifier(name);
755722
let paramStrings = params.map(param => t.stringLiteral(param.name));
756723
let arr = t.arrayExpression(paramStrings); // ["$scope"]
757-
let member = t.memberExpression(t.identifier(name), t.identifier("$inject")); // foo.$inject =
724+
let member = t.memberExpression(left, t.identifier("$inject")); // foo.$inject =
758725
return t.expressionStatement(t.assignmentExpression("=", member , arr));
759726
}
760727

761728
function addInjectArrayBeforePath(params, path, name){
762729
const binding = path.scope.getBinding(name);
763730
if(binding && binding.kind === 'hoisted'){
764-
let block = t.isProgram(binding.scope.block) ? binding.scope.block : binding.scope.block.body;
765-
block.body.unshift(buildInjectExpression(params, name));
731+
// let block = t.isProgram(binding.scope.block) ? binding.scope.block : binding.scope.block.body;
732+
// block.body.unshift(buildInjectExpression(params, name));
733+
let expr = buildInjectExpression(params, name);
734+
let block = binding.scope.getBlockParent().path;
735+
if(block.isFunction()){
736+
block = block.get("body");
737+
}
738+
block.unshiftContainer("body", [expr]);
766739
} else {
767740
path.insertBefore(buildInjectExpression(params, name));
768741
}
@@ -810,27 +783,6 @@ function addModuleContextIndependentSuspect(target, ctx) {
810783
ctx.suspects.push(target);
811784
}
812785

813-
function isAnnotatedArray(node) {
814-
if (!t.isArrayExpression(node)) {
815-
return false;
816-
}
817-
const elements = node.elements;
818-
819-
// last should be a function expression
820-
if (elements.length === 0 || !t.isFunctionExpression(last(elements))) {
821-
return false;
822-
}
823-
824-
// all but last should be string literals
825-
for (let i = 0; i < elements.length - 1; i++) {
826-
const n = elements[i];
827-
if (!t.isLiteral(n) || !is.string(n.value)) {
828-
return false;
829-
}
830-
}
831-
832-
return true;
833-
}
834786
function isFunctionExpressionWithArgs(node) {
835787
return t.isFunctionExpression(node) && node.params.length >= 1;
836788
}
@@ -842,16 +794,8 @@ function isGenericProviderName(node) {
842794
}
843795

844796
module.exports.match = match;
845-
module.exports.isFunctionExpressionWithArgs = isFunctionExpressionWithArgs;
846-
module.exports.isFunctionDeclarationWithArgs = isFunctionDeclarationWithArgs;
847-
module.exports.isGenericProviderName = isGenericProviderName;
848-
module.exports.isAnnotatedArray = isAnnotatedArray;
849797
module.exports.addModuleContextDependentSuspect = addModuleContextDependentSuspect;
850798
module.exports.addModuleContextIndependentSuspect = addModuleContextIndependentSuspect;
851-
module.exports.stringify = stringify;
852-
module.exports.matchResolve = matchResolve;
853-
module.exports.matchProp = matchProp;
854-
module.exports.last = last;
855799
module.exports.judgeSuspects = judgeSuspects;
856800
module.exports.matchDirectiveReturnObject = matchDirectiveReturnObject;
857801
module.exports.matchProviderGet = matchProviderGet;

0 commit comments

Comments
 (0)