diff --git a/Jakefile.js b/Jakefile.js index 087bbb67511..ff4b90f4a40 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -69,6 +69,7 @@ var compilerSources = [ "factory.ts", "visitor.ts", "transformers/destructuring.ts", + "transformers/utilities.ts", "transformers/ts.ts", "transformers/jsx.ts", "transformers/esnext.ts", @@ -106,6 +107,7 @@ var servicesSources = [ "factory.ts", "visitor.ts", "transformers/destructuring.ts", + "transformers/utilities.ts", "transformers/ts.ts", "transformers/jsx.ts", "transformers/esnext.ts", diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3d25fc8bbbb..3a53f61e0e4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -27,6 +27,12 @@ namespace ts { return symbol.id; } + export function isInstantiatedModule(node: ModuleDeclaration, preserveConstEnums: boolean) { + const moduleState = getModuleInstanceState(node); + return moduleState === ModuleInstanceState.Instantiated || + (preserveConstEnums && moduleState === ModuleInstanceState.ConstEnumOnly); + } + export function createTypeChecker(host: TypeCheckerHost, produceDiagnostics: boolean): TypeChecker { // Cancellation that controls whether or not we can cancel in the middle of type checking. // In general cancelling is *not* safe for the type checker. We might be in the middle of diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index d273f59411f..43a1e804e1d 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -2,7 +2,7 @@ /// /// /// -/// +/// namespace ts { /* @internal */ diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index d797fff92f4..09a048811a6 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -2595,16 +2595,6 @@ namespace ts { return node; } - export function skipPartiallyEmittedExpressions(node: Expression): Expression; - export function skipPartiallyEmittedExpressions(node: Node): Node; - export function skipPartiallyEmittedExpressions(node: Node) { - while (node.kind === SyntaxKind.PartiallyEmittedExpression) { - node = (node).expression; - } - - return node; - } - export function startOnNewLine(node: T): T { node.startsOnNewLine = true; return node; @@ -3264,165 +3254,4 @@ namespace ts { Debug.assertNode(node, isExpression); return node; } - - export interface ExternalModuleInfo { - externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[]; // imports of other external modules - externalHelpersImportDeclaration: ImportDeclaration | undefined; // import of external helpers - exportSpecifiers: Map; // export specifiers by name - exportedBindings: Map; // exported names of local declarations - exportedNames: Identifier[]; // all exported names local to module - exportEquals: ExportAssignment | undefined; // an export= declaration if one was present - hasExportStarsToExportValues: boolean; // whether this module contains export* - } - - export function collectExternalModuleInfo(sourceFile: SourceFile, resolver: EmitResolver, compilerOptions: CompilerOptions): ExternalModuleInfo { - const externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[] = []; - const exportSpecifiers = createMap(); - const exportedBindings = createMap(); - const uniqueExports = createMap(); - let exportedNames: Identifier[]; - let hasExportDefault = false; - let exportEquals: ExportAssignment = undefined; - let hasExportStarsToExportValues = false; - - const externalHelpersModuleName = getOrCreateExternalHelpersModuleNameIfNeeded(sourceFile, compilerOptions); - const externalHelpersImportDeclaration = externalHelpersModuleName && createImportDeclaration( - /*decorators*/ undefined, - /*modifiers*/ undefined, - createImportClause(/*name*/ undefined, createNamespaceImport(externalHelpersModuleName)), - createLiteral(externalHelpersModuleNameText)); - - if (externalHelpersImportDeclaration) { - externalImports.push(externalHelpersImportDeclaration); - } - - for (const node of sourceFile.statements) { - switch (node.kind) { - case SyntaxKind.ImportDeclaration: - // import "mod" - // import x from "mod" - // import * as x from "mod" - // import { x, y } from "mod" - externalImports.push(node); - break; - - case SyntaxKind.ImportEqualsDeclaration: - if ((node).moduleReference.kind === SyntaxKind.ExternalModuleReference) { - // import x = require("mod") - externalImports.push(node); - } - - break; - - case SyntaxKind.ExportDeclaration: - if ((node).moduleSpecifier) { - if (!(node).exportClause) { - // export * from "mod" - externalImports.push(node); - hasExportStarsToExportValues = true; - } - else { - // export { x, y } from "mod" - externalImports.push(node); - } - } - else { - // export { x, y } - for (const specifier of (node).exportClause.elements) { - if (!uniqueExports[specifier.name.text]) { - const name = specifier.propertyName || specifier.name; - multiMapAdd(exportSpecifiers, name.text, specifier); - - const decl = resolver.getReferencedImportDeclaration(name) - || resolver.getReferencedValueDeclaration(name); - - if (decl) { - multiMapAdd(exportedBindings, getOriginalNodeId(decl), specifier.name); - } - - uniqueExports[specifier.name.text] = true; - exportedNames = append(exportedNames, specifier.name); - } - } - } - break; - - case SyntaxKind.ExportAssignment: - if ((node).isExportEquals && !exportEquals) { - // export = x - exportEquals = node; - } - break; - - case SyntaxKind.VariableStatement: - if (hasModifier(node, ModifierFlags.Export)) { - for (const decl of (node).declarationList.declarations) { - exportedNames = collectExportedVariableInfo(decl, uniqueExports, exportedNames); - } - } - break; - - case SyntaxKind.FunctionDeclaration: - if (hasModifier(node, ModifierFlags.Export)) { - if (hasModifier(node, ModifierFlags.Default)) { - // export default function() { } - if (!hasExportDefault) { - multiMapAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(node)); - hasExportDefault = true; - } - } - else { - // export function x() { } - const name = (node).name; - if (!uniqueExports[name.text]) { - multiMapAdd(exportedBindings, getOriginalNodeId(node), name); - uniqueExports[name.text] = true; - exportedNames = append(exportedNames, name); - } - } - } - break; - - case SyntaxKind.ClassDeclaration: - if (hasModifier(node, ModifierFlags.Export)) { - if (hasModifier(node, ModifierFlags.Default)) { - // export default class { } - if (!hasExportDefault) { - multiMapAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(node)); - hasExportDefault = true; - } - } - else { - // export class x { } - const name = (node).name; - if (!uniqueExports[name.text]) { - multiMapAdd(exportedBindings, getOriginalNodeId(node), name); - uniqueExports[name.text] = true; - exportedNames = append(exportedNames, name); - } - } - } - break; - } - } - - return { externalImports, exportSpecifiers, exportEquals, hasExportStarsToExportValues, exportedBindings, exportedNames, externalHelpersImportDeclaration }; - } - - function collectExportedVariableInfo(decl: VariableDeclaration | BindingElement, uniqueExports: Map, exportedNames: Identifier[]) { - if (isBindingPattern(decl.name)) { - for (const element of decl.name.elements) { - if (!isOmittedExpression(element)) { - exportedNames = collectExportedVariableInfo(element, uniqueExports, exportedNames); - } - } - } - else if (!isGeneratedIdentifier(decl.name)) { - if (!uniqueExports[decl.name.text]) { - uniqueExports[decl.name.text] = true; - exportedNames = append(exportedNames, decl.name); - } - } - return exportedNames; - } } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index c2cf2d5bfbb..11b42097926 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1,6 +1,5 @@ /// /// -/// namespace ts { let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; diff --git a/src/compiler/transformer.ts b/src/compiler/transformer.ts index 10a718448e9..0f241f3ef75 100644 --- a/src/compiler/transformer.ts +++ b/src/compiler/transformer.ts @@ -1,4 +1,5 @@ /// +/// /// /// /// diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts new file mode 100644 index 00000000000..1338a30e368 --- /dev/null +++ b/src/compiler/transformers/utilities.ts @@ -0,0 +1,168 @@ +/* @internal */ +namespace ts { + export function getOriginalNodeId(node: Node) { + node = getOriginalNode(node); + return node ? getNodeId(node) : 0; + } + + export interface ExternalModuleInfo { + externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[]; // imports of other external modules + externalHelpersImportDeclaration: ImportDeclaration | undefined; // import of external helpers + exportSpecifiers: Map; // export specifiers by name + exportedBindings: Map; // exported names of local declarations + exportedNames: Identifier[]; // all exported names local to module + exportEquals: ExportAssignment | undefined; // an export= declaration if one was present + hasExportStarsToExportValues: boolean; // whether this module contains export* + } + + export function collectExternalModuleInfo(sourceFile: SourceFile, resolver: EmitResolver, compilerOptions: CompilerOptions): ExternalModuleInfo { + const externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[] = []; + const exportSpecifiers = createMap(); + const exportedBindings = createMap(); + const uniqueExports = createMap(); + let exportedNames: Identifier[]; + let hasExportDefault = false; + let exportEquals: ExportAssignment = undefined; + let hasExportStarsToExportValues = false; + + const externalHelpersModuleName = getOrCreateExternalHelpersModuleNameIfNeeded(sourceFile, compilerOptions); + const externalHelpersImportDeclaration = externalHelpersModuleName && createImportDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + createImportClause(/*name*/ undefined, createNamespaceImport(externalHelpersModuleName)), + createLiteral(externalHelpersModuleNameText)); + + if (externalHelpersImportDeclaration) { + externalImports.push(externalHelpersImportDeclaration); + } + + for (const node of sourceFile.statements) { + switch (node.kind) { + case SyntaxKind.ImportDeclaration: + // import "mod" + // import x from "mod" + // import * as x from "mod" + // import { x, y } from "mod" + externalImports.push(node); + break; + + case SyntaxKind.ImportEqualsDeclaration: + if ((node).moduleReference.kind === SyntaxKind.ExternalModuleReference) { + // import x = require("mod") + externalImports.push(node); + } + + break; + + case SyntaxKind.ExportDeclaration: + if ((node).moduleSpecifier) { + if (!(node).exportClause) { + // export * from "mod" + externalImports.push(node); + hasExportStarsToExportValues = true; + } + else { + // export { x, y } from "mod" + externalImports.push(node); + } + } + else { + // export { x, y } + for (const specifier of (node).exportClause.elements) { + if (!uniqueExports[specifier.name.text]) { + const name = specifier.propertyName || specifier.name; + multiMapAdd(exportSpecifiers, name.text, specifier); + + const decl = resolver.getReferencedImportDeclaration(name) + || resolver.getReferencedValueDeclaration(name); + + if (decl) { + multiMapAdd(exportedBindings, getOriginalNodeId(decl), specifier.name); + } + + uniqueExports[specifier.name.text] = true; + exportedNames = append(exportedNames, specifier.name); + } + } + } + break; + + case SyntaxKind.ExportAssignment: + if ((node).isExportEquals && !exportEquals) { + // export = x + exportEquals = node; + } + break; + + case SyntaxKind.VariableStatement: + if (hasModifier(node, ModifierFlags.Export)) { + for (const decl of (node).declarationList.declarations) { + exportedNames = collectExportedVariableInfo(decl, uniqueExports, exportedNames); + } + } + break; + + case SyntaxKind.FunctionDeclaration: + if (hasModifier(node, ModifierFlags.Export)) { + if (hasModifier(node, ModifierFlags.Default)) { + // export default function() { } + if (!hasExportDefault) { + multiMapAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(node)); + hasExportDefault = true; + } + } + else { + // export function x() { } + const name = (node).name; + if (!uniqueExports[name.text]) { + multiMapAdd(exportedBindings, getOriginalNodeId(node), name); + uniqueExports[name.text] = true; + exportedNames = append(exportedNames, name); + } + } + } + break; + + case SyntaxKind.ClassDeclaration: + if (hasModifier(node, ModifierFlags.Export)) { + if (hasModifier(node, ModifierFlags.Default)) { + // export default class { } + if (!hasExportDefault) { + multiMapAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(node)); + hasExportDefault = true; + } + } + else { + // export class x { } + const name = (node).name; + if (!uniqueExports[name.text]) { + multiMapAdd(exportedBindings, getOriginalNodeId(node), name); + uniqueExports[name.text] = true; + exportedNames = append(exportedNames, name); + } + } + } + break; + } + } + + return { externalImports, exportSpecifiers, exportEquals, hasExportStarsToExportValues, exportedBindings, exportedNames, externalHelpersImportDeclaration }; + } + + function collectExportedVariableInfo(decl: VariableDeclaration | BindingElement, uniqueExports: Map, exportedNames: Identifier[]) { + if (isBindingPattern(decl.name)) { + for (const element of decl.name.elements) { + if (!isOmittedExpression(element)) { + exportedNames = collectExportedVariableInfo(element, uniqueExports, exportedNames); + } + } + } + else if (!isGeneratedIdentifier(decl.name)) { + if (!uniqueExports[decl.name.text]) { + uniqueExports[decl.name.text] = true; + exportedNames = append(exportedNames, decl.name); + } + } + return exportedNames; + } +} diff --git a/src/compiler/tsconfig.json b/src/compiler/tsconfig.json index bd70a0afb10..002cd167f38 100644 --- a/src/compiler/tsconfig.json +++ b/src/compiler/tsconfig.json @@ -25,6 +25,7 @@ "checker.ts", "factory.ts", "visitor.ts", + "transformers/utilities.ts", "transformers/ts.ts", "transformers/jsx.ts", "transformers/esnext.ts", diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 546416884f1..9af6c9b921c 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1261,12 +1261,6 @@ namespace ts { return false; } - export function isInstantiatedModule(node: ModuleDeclaration, preserveConstEnums: boolean) { - const moduleState = getModuleInstanceState(node); - return moduleState === ModuleInstanceState.Instantiated || - (preserveConstEnums && moduleState === ModuleInstanceState.ConstEnumOnly); - } - export function isExternalModuleImportEqualsDeclaration(node: Node) { return node.kind === SyntaxKind.ImportEqualsDeclaration && (node).moduleReference.kind === SyntaxKind.ExternalModuleReference; } @@ -2042,11 +2036,6 @@ namespace ts { return originalSourceFiles; } - export function getOriginalNodeId(node: Node) { - node = getOriginalNode(node); - return node ? getNodeId(node) : 0; - } - export const enum Associativity { Left, Right @@ -3930,6 +3919,16 @@ namespace ts { || kind === SyntaxKind.RawExpression; } + export function skipPartiallyEmittedExpressions(node: Expression): Expression; + export function skipPartiallyEmittedExpressions(node: Node): Node; + export function skipPartiallyEmittedExpressions(node: Node) { + while (node.kind === SyntaxKind.PartiallyEmittedExpression) { + node = (node).expression; + } + + return node; + } + export function isLeftHandSideExpression(node: Node): node is LeftHandSideExpression { return isLeftHandSideExpressionKind(skipPartiallyEmittedExpressions(node).kind); } diff --git a/src/harness/tsconfig.json b/src/harness/tsconfig.json index d3a814f26ca..2211dbee7e0 100644 --- a/src/harness/tsconfig.json +++ b/src/harness/tsconfig.json @@ -27,6 +27,7 @@ "../compiler/checker.ts", "../compiler/factory.ts", "../compiler/visitor.ts", + "../compiler/transformers/utilities.ts", "../compiler/transformers/ts.ts", "../compiler/transformers/jsx.ts", "../compiler/transformers/esnext.ts", diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index 502381b8be8..fdab9006046 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -27,6 +27,7 @@ "../compiler/checker.ts", "../compiler/factory.ts", "../compiler/visitor.ts", + "../compiler/transformers/utilities.ts", "../compiler/transformers/ts.ts", "../compiler/transformers/jsx.ts", "../compiler/transformers/esnext.ts",