Skip to content

Commit e703f12

Browse files
committed
Add visitReturnedFunction() for expression like call()().
1 parent 531cc65 commit e703f12

File tree

2 files changed

+67
-12
lines changed

2 files changed

+67
-12
lines changed

src/compiler/sorting.ts

Lines changed: 67 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ namespace ts {
3131
let rootFileNames: string[];
3232
let dependencyMap: Map<string[]>;
3333
let pathWeightMap: Map<number>;
34+
let visitedBlocks: Block[];
3435

3536
interface Map<T> {
3637
[index: string]: T;
@@ -57,12 +58,14 @@ namespace ts {
5758
sourceFiles = <any>program.getSourceFiles();
5859
rootFileNames = <any>program.getRootFileNames();
5960
checker = program.getTypeChecker();
61+
visitedBlocks = [];
6062
buildDependencyMap();
6163
let result = sortOnDependency();
6264
sourceFiles = null;
6365
rootFileNames = null;
6466
checker = null;
6567
dependencyMap = null;
68+
visitedBlocks = null;
6669
return result;
6770
}
6871

@@ -314,7 +317,7 @@ namespace ts {
314317

315318
function visitDecorators(decorators: NodeArray<Decorator>): void {
316319
for (let decorator of decorators) {
317-
visitExpression(decorator.expression);
320+
visitCallExpression(decorator.expression);
318321
}
319322
}
320323

@@ -325,7 +328,8 @@ namespace ts {
325328
switch (expression.kind) {
326329
case SyntaxKind.NewExpression:
327330
case SyntaxKind.CallExpression:
328-
visitCallExpression(<CallExpression>expression);
331+
visitCallArguments(<CallExpression>expression);
332+
visitCallExpression((<CallExpression>expression).expression);
329333
break;
330334
case SyntaxKind.Identifier:
331335
checkDependencyAtLocation(expression);
@@ -367,13 +371,13 @@ namespace ts {
367371
visitExpression((<TaggedTemplateExpression>expression).tag);
368372
visitExpression((<TaggedTemplateExpression>expression).template);
369373
break;
370-
case ts.SyntaxKind.ConditionalExpression:
374+
case ts.SyntaxKind.ConditionalExpression:
371375
visitExpression((<ts.ConditionalExpression>expression).condition);
372376
visitExpression((<ts.ConditionalExpression>expression).whenTrue);
373377
visitExpression((<ts.ConditionalExpression>expression).whenFalse);
374378
break;
375-
376-
case ts.SyntaxKind.SpreadElement:
379+
380+
case ts.SyntaxKind.SpreadElement:
377381
visitExpression((<SpreadElement>expression).expression);
378382
break;
379383
case ts.SyntaxKind.VoidExpression:
@@ -452,14 +456,16 @@ namespace ts {
452456
});
453457
}
454458

455-
function visitCallExpression(callExpression: CallExpression): void {
459+
function visitCallArguments(callExpression: CallExpression): void {
456460
if (callExpression.arguments) {
457461
callExpression.arguments.forEach(argument => {
458462
visitExpression(argument);
459463
});
460464
}
465+
}
461466

462-
let expression = escapeParenthesized(callExpression.expression);
467+
function visitCallExpression(expression: Expression): void {
468+
expression = escapeParenthesized(expression);
463469
visitExpression(expression);
464470
switch (expression.kind) {
465471
case SyntaxKind.FunctionExpression:
@@ -468,11 +474,60 @@ namespace ts {
468474
break;
469475
case SyntaxKind.PropertyAccessExpression:
470476
case SyntaxKind.Identifier:
471-
let callerFileName = getSourceFileOfNode(callExpression).fileName;
477+
let callerFileName = getSourceFileOfNode(expression).fileName;
472478
checkCallTarget(callerFileName, expression);
473479
break;
480+
case SyntaxKind.CallExpression:
481+
visitReturnedFunction((<CallExpression>expression).expression);
482+
break;
474483
}
484+
}
475485

486+
function visitReturnedFunction(expression: Expression): Expression[] {
487+
expression = escapeParenthesized(expression);
488+
let returnExpressions: Expression[] = [];
489+
if (expression.kind === SyntaxKind.CallExpression) {
490+
let expressions = visitReturnedFunction((<CallExpression>expression).expression);
491+
for (let returnExpression of expressions) {
492+
let returns = visitReturnedFunction(returnExpression);
493+
returnExpressions = returnExpressions.concat(returns);
494+
}
495+
return returnExpressions;
496+
}
497+
498+
let functionBlocks: Block[] = [];
499+
switch (expression.kind) {
500+
case SyntaxKind.FunctionExpression:
501+
functionBlocks.push((<FunctionExpression>expression).body);
502+
break;
503+
case SyntaxKind.PropertyAccessExpression:
504+
case SyntaxKind.Identifier:
505+
let callerFileName = getSourceFileOfNode(expression).fileName;
506+
let declarations: Declaration[] = [];
507+
getForwardDeclarations(expression, declarations, callerFileName);
508+
for (let declaration of declarations) {
509+
let sourceFile = getSourceFileOfNode(declaration);
510+
if (!sourceFile || sourceFile.isDeclarationFile) {
511+
continue;
512+
}
513+
if (declaration.kind === SyntaxKind.FunctionDeclaration ||
514+
declaration.kind === SyntaxKind.MethodDeclaration) {
515+
functionBlocks.push((<FunctionDeclaration>declaration).body);
516+
}
517+
}
518+
break;
519+
}
520+
521+
for (let block of functionBlocks) {
522+
for (let statement of block.statements) {
523+
if (statement.kind === SyntaxKind.ReturnStatement) {
524+
let returnExpression = (<ReturnStatement>statement).expression;
525+
returnExpressions.push(returnExpression);
526+
visitCallExpression(returnExpression);
527+
}
528+
}
529+
}
530+
return returnExpressions;
476531
}
477532

478533
function escapeParenthesized(expression: Expression): Expression {
@@ -488,7 +543,7 @@ namespace ts {
488543
for (let declaration of declarations) {
489544
let sourceFile = getSourceFileOfNode(declaration);
490545
if (!sourceFile || sourceFile.isDeclarationFile) {
491-
return;
546+
continue;
492547
}
493548
addDependency(callerFileName, sourceFile.fileName);
494549
if (declaration.kind === SyntaxKind.FunctionDeclaration ||
@@ -568,13 +623,14 @@ namespace ts {
568623
}
569624

570625
function visitBlock(block: Block): void {
571-
if (!block || block.visitedBySorting) {
626+
if (!block || visitedBlocks.indexOf(block) != -1) {
572627
return;
573628
}
574-
block.visitedBySorting = true;
629+
visitedBlocks.push(block);
575630
for (let statement of block.statements) {
576631
visitStatement(statement);
577632
}
633+
visitedBlocks.pop();
578634
}
579635

580636
function visitVariableList(variables: VariableDeclarationList) {

src/compiler/types.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1866,7 +1866,6 @@ namespace ts {
18661866
kind: SyntaxKind.Block;
18671867
statements: NodeArray<Statement>;
18681868
/*@internal*/ multiLine?: boolean;
1869-
/*@internal*/ visitedBySorting?: boolean;
18701869
}
18711870

18721871
export interface VariableStatement extends Statement, JSDocContainer {

0 commit comments

Comments
 (0)