From abf270a9b4498e1f7d41fad503e3f606d043ff12 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Thu, 22 Oct 2015 14:12:57 -0700 Subject: [PATCH] do not look into nested es6 exports / imports when collecting external modules --- src/compiler/program.ts | 87 ++++++++++++++++++--------------------- src/compiler/utilities.ts | 2 +- 2 files changed, 42 insertions(+), 47 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 13d939c8ac7..583db7850b9 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -689,61 +689,56 @@ namespace ts { let imports: LiteralExpression[]; for (let node of file.statements) { - collect(node, /* allowRelativeModuleNames */ true); + collect(node, /* allowRelativeModuleNames */ true, /* collectOnlyRequireCalls */ false); } file.imports = imports || emptyArray; - function collect(node: Node, allowRelativeModuleNames: boolean): void { - switch (node.kind) { - case SyntaxKind.ImportDeclaration: - case SyntaxKind.ImportEqualsDeclaration: - case SyntaxKind.ExportDeclaration: - let moduleNameExpr = getExternalModuleName(node); - if (!moduleNameExpr || moduleNameExpr.kind !== SyntaxKind.StringLiteral) { - break; - } - if (!(moduleNameExpr).text) { - break; - } + return; - if (allowRelativeModuleNames || !isExternalModuleNameRelative((moduleNameExpr).text)) { - (imports || (imports = [])).push(moduleNameExpr); - } - break; - case SyntaxKind.CallExpression: - if (isJavaScriptFile && isRequireCall(node)) { - - let jsImports = (node).arguments; - if (jsImports) { - imports = (imports || []); - for (var i = 0; i < jsImports.length; i++) { - if (jsImports[i].kind === SyntaxKind.StringLiteral) { - imports.push(jsImports[i]); - } - } + function collect(node: Node, allowRelativeModuleNames: boolean, collectOnlyRequireCalls: boolean): void { + if (!collectOnlyRequireCalls) { + switch (node.kind) { + case SyntaxKind.ImportDeclaration: + case SyntaxKind.ImportEqualsDeclaration: + case SyntaxKind.ExportDeclaration: + let moduleNameExpr = getExternalModuleName(node); + if (!moduleNameExpr || moduleNameExpr.kind !== SyntaxKind.StringLiteral) { + break; } - } - break; - case SyntaxKind.ModuleDeclaration: - if ((node).name.kind === SyntaxKind.StringLiteral && (node.flags & NodeFlags.Ambient || isDeclarationFile(file))) { - // TypeScript 1.0 spec (April 2014): 12.1.6 - // An AmbientExternalModuleDeclaration declares an external module. - // This type of declaration is permitted only in the global module. - // The StringLiteral must specify a top - level external module name. - // Relative external module names are not permitted - forEachChild((node).body, node => { + if (!(moduleNameExpr).text) { + break; + } + + if (allowRelativeModuleNames || !isExternalModuleNameRelative((moduleNameExpr).text)) { + (imports || (imports = [])).push(moduleNameExpr); + } + break; + case SyntaxKind.ModuleDeclaration: + if ((node).name.kind === SyntaxKind.StringLiteral && (node.flags & NodeFlags.Ambient || isDeclarationFile(file))) { // TypeScript 1.0 spec (April 2014): 12.1.6 - // An ExternalImportDeclaration in anAmbientExternalModuleDeclaration may reference other external modules - // only through top - level external module names. Relative external module names are not permitted. - collect(node, /* allowRelativeModuleNames */ false); - }); - } - break; + // An AmbientExternalModuleDeclaration declares an external module. + // This type of declaration is permitted only in the global module. + // The StringLiteral must specify a top - level external module name. + // Relative external module names are not permitted + forEachChild((node).body, node => { + // TypeScript 1.0 spec (April 2014): 12.1.6 + // An ExternalImportDeclaration in anAmbientExternalModuleDeclaration may reference other external modules + // only through top - level external module names. Relative external module names are not permitted. + collect(node, /* allowRelativeModuleNames */ false, collectOnlyRequireCalls); + }); + } + break; + } } - if (isSourceFileJavaScript(file)) { - forEachChild(node, node => collect(node, allowRelativeModuleNames)); + if (isJavaScriptFile) { + if (isRequireCall(node)) { + (imports || (imports = [])).push((node).arguments[0]); + } + else { + forEachChild(node, node => collect(node, allowRelativeModuleNames, /* collectOnlyRequireCalls */ true)); + } } } } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 9eff4370ec2..5506a1d5e3d 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1045,7 +1045,7 @@ namespace ts { /** * Returns true if the node is a CallExpression to the identifier 'require' with - * exactly one argument. + * exactly one string literal argument. * This function does not test if the node is in a JavaScript file or not. */ export function isRequireCall(expression: Node): expression is CallExpression {