From 7f51f7c81d344711780ab85a9e0454440b69c61b Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 23 Mar 2016 09:40:51 -0700 Subject: [PATCH 1/6] Modified createIdentifier to track originalKeywordKind --- src/compiler/factory.ts | 1 + src/compiler/transformers/module/system.ts | 13 ++++++------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 3bcb951a932..836b367d08d 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -138,6 +138,7 @@ namespace ts { export function createIdentifier(text: string, location?: TextRange): Identifier { const node = createNode(SyntaxKind.Identifier, location); node.text = escapeIdentifier(text); + node.originalKeywordKind = stringToToken(text); return node; } diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index ef99fdcfae3..af7ff4e0031 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -26,7 +26,7 @@ namespace ts { context.enableExpressionSubstitution(SyntaxKind.PrefixUnaryExpression); context.enableExpressionSubstitution(SyntaxKind.PostfixUnaryExpression); context.expressionSubstitution = substituteExpression; - + context.enableEmitNotification(SyntaxKind.SourceFile); const exportFunctionForFileMap: Identifier[] = []; @@ -125,7 +125,7 @@ namespace ts { createStatement( createCall( createPropertyAccess(createIdentifier("System"), "register"), - node.moduleName + node.moduleName ? [createLiteral(node.moduleName), dependencies, body] : [dependencies, body] ) @@ -626,7 +626,7 @@ namespace ts { if (!hasModifier(node, ModifierFlags.Default)) { recordExportName(name); } - + node = newNode; } @@ -1073,7 +1073,7 @@ namespace ts { function substituteUnaryExpression(node: PrefixUnaryExpression | PostfixUnaryExpression): Expression { const operand = node.operand; const operator = node.operator; - const substitute = + const substitute = isIdentifier(operand) && ( node.kind === SyntaxKind.PostfixUnaryExpression || @@ -1090,7 +1090,7 @@ namespace ts { return call; } else { - return operator === SyntaxKind.PlusPlusToken + return operator === SyntaxKind.PlusPlusToken ? createSubtract(call, createLiteral(1)) : createAdd(call, createLiteral(1)) } @@ -1200,7 +1200,7 @@ namespace ts { ) ) ], - /*location*/ undefined, + /*location*/ undefined, /*multiline*/ true) ) ); @@ -1243,7 +1243,6 @@ namespace ts { if (isImportClause(importDeclaration)) { importAlias = getGeneratedNameForNode(importDeclaration.parent); name = createIdentifier("default"); - name.originalKeywordKind = SyntaxKind.DefaultKeyword; } else if (isImportSpecifier(importDeclaration)) { importAlias = getGeneratedNameForNode(importDeclaration.parent.parent.parent); From 284dacd10c81c884558e49004ecb8916ae65133d Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 23 Mar 2016 09:53:03 -0700 Subject: [PATCH 2/6] Fix import binding substitution for AMD/CJS --- src/compiler/transformers/module/module.ts | 100 ++++++++++++++------- 1 file changed, 70 insertions(+), 30 deletions(-) diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 5b8a1053e88..e8c6158c4e8 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -280,7 +280,7 @@ namespace ts { if (moduleKind !== ModuleKind.AMD) { if (!node.importClause) { // import "mod"; - addNode(statements, + statements.push( createStatement( createRequireCall(node), /*location*/ node @@ -291,7 +291,7 @@ namespace ts { const variables: VariableDeclaration[] = []; if (namespaceDeclaration && !isDefaultImport(node)) { // import * as n from "mod"; - addNode(variables, + variables.push( createVariableDeclaration( getSynthesizedClone(namespaceDeclaration.name), createRequireCall(node) @@ -303,7 +303,7 @@ namespace ts { // import { x, y } from "mod"; // import d, { x, y } from "mod"; // import d, * as n from "mod"; - addNode(variables, + variables.push( createVariableDeclaration( getGeneratedNameForNode(node), createRequireCall(node) @@ -311,7 +311,7 @@ namespace ts { ); if (namespaceDeclaration && isDefaultImport(node)) { - addNode(variables, + variables.push( createVariableDeclaration( getSynthesizedClone(namespaceDeclaration.name), getGeneratedNameForNode(node) @@ -320,7 +320,7 @@ namespace ts { } } - addNode(statements, + statements.push( createVariableStatement( /*modifiers*/ undefined, createVariableDeclarationList(variables), @@ -331,7 +331,7 @@ namespace ts { } else if (namespaceDeclaration && isDefaultImport(node)) { // import d, * as n from "mod"; - addNode(statements, + statements.push( createVariableStatement( /*modifiers*/ undefined, createVariableDeclarationList([ @@ -346,7 +346,7 @@ namespace ts { } addExportImportAssignments(statements, node); - return statements; + return singleOrMany(statements); } function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult { @@ -409,7 +409,7 @@ namespace ts { const statements: Statement[] = []; // export { x, y } from "mod"; if (moduleKind !== ModuleKind.AMD) { - addNode(statements, + statements.push( createVariableStatement( /*modifiers*/ undefined, createVariableDeclarationList([ @@ -428,7 +428,7 @@ namespace ts { generatedName, specifier.propertyName || specifier.name ); - addNode(statements, + statements.push( createStatement( createExportAssignment(specifier.name, exportedValue), /*location*/ specifier @@ -437,7 +437,7 @@ namespace ts { } } - return statements; + return singleOrMany(statements); } else { // export * from "mod"; @@ -466,8 +466,9 @@ namespace ts { } function addExportDefault(statements: Statement[], expression: Expression, location: TextRange): void { - addNode(statements, tryCreateExportDefaultCompat()); - addNode(statements, + tryAddExportDefaultCompat(statements); + + statements.push( createStatement( createExportAssignment( createIdentifier("default"), @@ -478,25 +479,29 @@ namespace ts { ); } - function tryCreateExportDefaultCompat(): Statement { + function tryAddExportDefaultCompat(statements: Statement[]) { const original = getOriginalNode(currentSourceFile); Debug.assert(original.kind === SyntaxKind.SourceFile); - if (!(original).symbol.exports["___esModule"]) { + if (!original.symbol.exports["___esModule"]) { if (languageVersion === ScriptTarget.ES3) { - return createStatement( - createExportAssignment( - createIdentifier("__esModule"), - createLiteral(true) + statements.push( + createStatement( + createExportAssignment( + createIdentifier("__esModule"), + createLiteral(true) + ) ) ); } else { - return createStatement( - createObjectDefineProperty( - createIdentifier("exports"), - createLiteral("__esModule"), - { value: createLiteral(true) } + statements.push( + createStatement( + createObjectDefineProperty( + createIdentifier("exports"), + createLiteral("__esModule"), + { value: createLiteral(true) } + ) ) ); } @@ -653,13 +658,48 @@ namespace ts { } function substituteExpressionIdentifier(node: Identifier): Expression { - const container = resolver.getReferencedExportContainer(node); - if (container && container.kind === SyntaxKind.SourceFile) { - return createPropertyAccess( - createIdentifier("exports"), - getSynthesizedClone(node), - /*location*/ node - ); + const original = getOriginalNode(node); + if (isIdentifier(original)) { + const container = resolver.getReferencedExportContainer(original); + if (container) { + if (container.kind === SyntaxKind.SourceFile) { + return createPropertyAccess( + createIdentifier("exports"), + getSynthesizedClone(node), + /*location*/ node + ); + } + } + else { + const declaration = resolver.getReferencedImportDeclaration(original); + if (declaration) { + if (declaration.kind === SyntaxKind.ImportClause) { + if (languageVersion >= ScriptTarget.ES5) { + return createPropertyAccess( + getGeneratedNameForNode(declaration.parent), + createIdentifier("default"), + /*location*/ node + ); + } + else { + return createElementAccess( + getGeneratedNameForNode(declaration.parent), + createLiteral("default"), + /*location*/ node + ); + } + } + else if (declaration.kind === SyntaxKind.ImportSpecifier) { + const name = (declaration).propertyName + || (declaration).name; + return createPropertyAccess( + getGeneratedNameForNode(declaration.parent.parent.parent), + getSynthesizedClone(name), + /*location*/ node + ); + } + } + } } return node; From bcb180a99b6dbc22b0388926801dfaa442cc6669 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 23 Mar 2016 15:48:25 -0700 Subject: [PATCH 3/6] Fixes generated names and some formatting in system modules. --- src/compiler/factory.ts | 4 +- src/compiler/printer.ts | 47 ++++++++++++++----- src/compiler/transformers/destructuring.ts | 16 +++---- src/compiler/transformers/module/system.ts | 25 +++++----- src/compiler/types.ts | 7 +-- .../reference/aliasesInSystemModule2.js | 4 +- .../allowSyntheticDefaultImports2.js | 22 ++++----- .../allowSyntheticDefaultImports3.js | 22 ++++----- .../allowSyntheticDefaultImports5.js | 14 +++--- .../allowSyntheticDefaultImports6.js | 14 +++--- .../reference/ambientDeclarationsExternal.js | 2 +- ...nalModuleInsideNonAmbientExternalModule.js | 1 - ...rnalModuleWithInternalImportDeclaration.js | 2 +- ...lModuleWithoutInternalImportDeclaration.js | 2 +- .../ambientInsideNonAmbientExternalModule.js | 1 - tests/baselines/reference/systemModule10.js | 4 +- .../baselines/reference/systemModule10_ES5.js | 4 +- tests/baselines/reference/systemModule14.js | 4 +- tests/baselines/reference/systemModule9.js | 20 ++++---- 19 files changed, 116 insertions(+), 99 deletions(-) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 836b367d08d..f2d11ef227c 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -424,11 +424,11 @@ namespace ts { return block; } - export function createVariableStatement(modifiers: Modifier[], declarationList: VariableDeclarationList, location?: TextRange): VariableStatement { + export function createVariableStatement(modifiers: Modifier[], declarationList: VariableDeclarationList | VariableDeclaration[], location?: TextRange): VariableStatement { const node = createNode(SyntaxKind.VariableStatement, location); node.decorators = undefined; node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; - node.declarationList = declarationList; + node.declarationList = isArray(declarationList) ? createVariableDeclarationList(declarationList) : declarationList; return node; } diff --git a/src/compiler/printer.ts b/src/compiler/printer.ts index da46a89b9e2..e2bef72f15a 100644 --- a/src/compiler/printer.ts +++ b/src/compiler/printer.ts @@ -2343,14 +2343,12 @@ const _super = (function (geti, seti) { return node; } - function getTextOfNode(node: Node, includeTrivia?: boolean) { - if (isIdentifier(node)) { - if (node.autoGenerateKind) { - return getGeneratedIdentifier(node); - } - else if (nodeIsSynthesized(node) || !node.parent) { - return unescapeIdentifier(node.text); - } + function getTextOfNode(node: Node, includeTrivia?: boolean): string { + if (isGeneratedIdentifier(node)) { + return getGeneratedIdentifier(node); + } + else if (isIdentifier(node) && (nodeIsSynthesized(node) || !node.parent)) { + return unescapeIdentifier(node.text); } else if (isLiteralExpression(node) && (nodeIsSynthesized(node) || !node.parent)) { return node.text; @@ -2452,7 +2450,7 @@ const _super = (function (geti, seti) { } function generateNameForModuleOrEnum(node: ModuleDeclaration | EnumDeclaration) { - const name = node.name.text; + const name = getTextOfNode(node.name); // Use module/enum name itself if it is unique, otherwise make a unique variation return isUniqueLocalName(name, node) ? name : makeUniqueName(name); } @@ -2472,10 +2470,10 @@ const _super = (function (geti, seti) { return makeUniqueName("class"); } - function generateNameForNode(node: Node) { + function generateNameForNode(node: Node): string { switch (node.kind) { case SyntaxKind.Identifier: - return makeUniqueName((node).text); + return makeUniqueName(getTextOfNode(node)); case SyntaxKind.ModuleDeclaration: case SyntaxKind.EnumDeclaration: return generateNameForModuleOrEnum(node); @@ -2502,14 +2500,37 @@ const _super = (function (geti, seti) { case GeneratedIdentifierKind.Unique: return makeUniqueName(node.text); case GeneratedIdentifierKind.Node: - return generateNameForNode(getOriginalNode(node)); + return generateNameForNode(getSourceNodeForGeneratedName(node)); } } function getGeneratedIdentifier(node: Identifier) { - const id = getOriginalNodeId(node); + const id = getNodeIdForGeneratedIdentifier(node); return nodeToGeneratedName[id] || (nodeToGeneratedName[id] = unescapeIdentifier(generateIdentifier(node))); } + + function getSourceNodeForGeneratedName(name: Identifier) { + let node: Node = name; + while (node.original !== undefined) { + node = node.original; + if (isIdentifier(node) && node.autoGenerateKind === GeneratedIdentifierKind.Node) { + break; + } + } + + return node; + } + + function getNodeIdForGeneratedIdentifier(node: Identifier) { + switch (node.autoGenerateKind) { + case GeneratedIdentifierKind.Auto: + case GeneratedIdentifierKind.Loop: + case GeneratedIdentifierKind.Unique: + return getNodeId(node); + case GeneratedIdentifierKind.Node: + return getNodeId(getSourceNodeForGeneratedName(node)); + } + } } function createDelimiterMap() { diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index bd3bbcdfd43..abe568a80f3 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -365,20 +365,18 @@ namespace ts { ensureIdentifier(propertyName.expression, /*reuseIdentifierExpressions*/ false, /*location*/ propertyName, emitTempVariableAssignment) ); } - else if (isIdentifier(propertyName)) { - return createPropertyAccess( - expression, - propertyName.text - ); - } - else { - // We create a synthetic copy of the identifier in order to avoid the rewriting that might - // otherwise occur when the identifier is emitted. + else if (isLiteralExpression(propertyName)) { return createElementAccess( expression, getSynthesizedClone(propertyName) ); } + else { + return createPropertyAccess( + expression, + isGeneratedIdentifier(propertyName) ? getSynthesizedClone(propertyName) : createIdentifier(propertyName.text) + ); + } } } diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index af7ff4e0031..4a508b3aa30 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -339,7 +339,8 @@ namespace ts { const setters: Expression[] = []; for (const group of dependencyGroups) { // derive a unique name for parameter from the first named entry in the group - const parameterName = createUniqueName(forEach(group.externalImports, getLocalNameTextForExternalImport) || ""); + const localName = forEach(group.externalImports, getLocalNameForExternalImport); + const parameterName = localName ? getGeneratedNameForNode(localName) : createUniqueName(""); const statements: Statement[] = []; for (const entry of group.externalImports) { const importVariableName = getLocalNameForExternalImport(entry); @@ -1121,11 +1122,6 @@ namespace ts { return undefined; } - function getLocalNameTextForExternalImport(node: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration): string { - const name = getLocalNameForExternalImport(node); - return name ? name.text : undefined; - } - function getLocalNameForExternalImport(node: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration): Identifier { const namespaceDeclaration = getNamespaceDeclarationNode(node); if (namespaceDeclaration && !isDefaultImport(node)) { @@ -1182,14 +1178,17 @@ namespace ts { ]), m, createBlock([ - createIf( - condition, - createStatement( - createAssignment( - createElementAccess(exports, n), - createElementAccess(m, n) + setNodeEmitFlags( + createIf( + condition, + createStatement( + createAssignment( + createElementAccess(exports, n), + createElementAccess(m, n) + ) ) - ) + ), + NodeEmitFlags.SingleLine ) ]) ), diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 02e289d221f..475d96b87f7 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -480,6 +480,7 @@ namespace ts { // @kind(SyntaxKind.StaticKeyword) export interface Modifier extends Node { } + /*@internal*/ export const enum GeneratedIdentifierKind { None, // Not automatically generated. Auto, // Automatically generated identifier. @@ -490,9 +491,9 @@ namespace ts { // @kind(SyntaxKind.Identifier) export interface Identifier extends PrimaryExpression { - text: string; // Text of identifier (with escapes converted to characters) - originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later - autoGenerateKind?: GeneratedIdentifierKind; // Specifies whether to auto-generate the text for an identifier. + text: string; // Text of identifier (with escapes converted to characters) + originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later + /*@internal*/ autoGenerateKind?: GeneratedIdentifierKind; // Specifies whether to auto-generate the text for an identifier. } // @kind(SyntaxKind.QualifiedName) diff --git a/tests/baselines/reference/aliasesInSystemModule2.js b/tests/baselines/reference/aliasesInSystemModule2.js index cb872c44e25..71fe558d43a 100644 --- a/tests/baselines/reference/aliasesInSystemModule2.js +++ b/tests/baselines/reference/aliasesInSystemModule2.js @@ -22,8 +22,8 @@ System.register(["foo"], function (exports_1, context_1) { var foo_1, cls, cls2, x, y, z, M; return { setters: [ - function (_1) { - foo_1 = _1; + function (foo_1_1) { + foo_1 = foo_1_1; } ], execute: function () { diff --git a/tests/baselines/reference/allowSyntheticDefaultImports2.js b/tests/baselines/reference/allowSyntheticDefaultImports2.js index 87e47f9c9a1..93c13617e4a 100644 --- a/tests/baselines/reference/allowSyntheticDefaultImports2.js +++ b/tests/baselines/reference/allowSyntheticDefaultImports2.js @@ -10,13 +10,13 @@ export class Foo { } //// [b.js] -System.register([], function(exports_1, context_1) { +System.register([], function (exports_1, context_1) { "use strict"; var __moduleName = context_1 && context_1.id; var Foo; return { - setters:[], - execute: function() { + setters: [], + execute: function () { Foo = (function () { function Foo() { } @@ -24,21 +24,21 @@ System.register([], function(exports_1, context_1) { }()); exports_1("Foo", Foo); } - } + }; }); //// [a.js] -System.register(["./b"], function(exports_1, context_1) { +System.register(["./b"], function (exports_1, context_1) { "use strict"; var __moduleName = context_1 && context_1.id; - var b_1; - var x; + var b_1, x; return { - setters:[ + setters: [ function (b_1_1) { b_1 = b_1_1; - }], - execute: function() { + } + ], + execute: function () { exports_1("x", x = new b_1["default"].Foo()); } - } + }; }); diff --git a/tests/baselines/reference/allowSyntheticDefaultImports3.js b/tests/baselines/reference/allowSyntheticDefaultImports3.js index 348ce42a60a..74b1dcb776d 100644 --- a/tests/baselines/reference/allowSyntheticDefaultImports3.js +++ b/tests/baselines/reference/allowSyntheticDefaultImports3.js @@ -11,13 +11,13 @@ export class Foo { //// [b.js] -System.register([], function(exports_1, context_1) { +System.register([], function (exports_1, context_1) { "use strict"; var __moduleName = context_1 && context_1.id; var Foo; return { - setters:[], - execute: function() { + setters: [], + execute: function () { Foo = (function () { function Foo() { } @@ -25,21 +25,21 @@ System.register([], function(exports_1, context_1) { }()); exports_1("Foo", Foo); } - } + }; }); //// [a.js] -System.register(["./b"], function(exports_1, context_1) { +System.register(["./b"], function (exports_1, context_1) { "use strict"; var __moduleName = context_1 && context_1.id; - var b_1; - var x; + var b_1, x; return { - setters:[ + setters: [ function (b_1_1) { b_1 = b_1_1; - }], - execute: function() { + } + ], + execute: function () { exports_1("x", x = new b_1["default"].Foo()); } - } + }; }); diff --git a/tests/baselines/reference/allowSyntheticDefaultImports5.js b/tests/baselines/reference/allowSyntheticDefaultImports5.js index f59226e152d..765d1140864 100644 --- a/tests/baselines/reference/allowSyntheticDefaultImports5.js +++ b/tests/baselines/reference/allowSyntheticDefaultImports5.js @@ -12,18 +12,18 @@ export var x = new Foo(); //// [a.js] -System.register(["./b"], function(exports_1, context_1) { +System.register(["./b"], function (exports_1, context_1) { "use strict"; var __moduleName = context_1 && context_1.id; - var b_1; - var x; + var b_1, x; return { - setters:[ + setters: [ function (b_1_1) { b_1 = b_1_1; - }], - execute: function() { + } + ], + execute: function () { exports_1("x", x = new b_1["default"]()); } - } + }; }); diff --git a/tests/baselines/reference/allowSyntheticDefaultImports6.js b/tests/baselines/reference/allowSyntheticDefaultImports6.js index d2f25e538c5..9ae7acae919 100644 --- a/tests/baselines/reference/allowSyntheticDefaultImports6.js +++ b/tests/baselines/reference/allowSyntheticDefaultImports6.js @@ -12,18 +12,18 @@ export var x = new Foo(); //// [a.js] -System.register(["./b"], function(exports_1, context_1) { +System.register(["./b"], function (exports_1, context_1) { "use strict"; var __moduleName = context_1 && context_1.id; - var b_1; - var x; + var b_1, x; return { - setters:[ + setters: [ function (b_1_1) { b_1 = b_1_1; - }], - execute: function() { + } + ], + execute: function () { exports_1("x", x = new b_1["default"]()); } - } + }; }); diff --git a/tests/baselines/reference/ambientDeclarationsExternal.js b/tests/baselines/reference/ambientDeclarationsExternal.js index 42375bc1d09..b92993128ab 100644 --- a/tests/baselines/reference/ambientDeclarationsExternal.js +++ b/tests/baselines/reference/ambientDeclarationsExternal.js @@ -29,6 +29,6 @@ var n: number; //// [consumer.js] "use strict"; // Ambient external module members are always exported with or without export keyword when module lacks export assignment -var imp3 = require('equ2'); +var imp3 = require("equ2"); var n = imp3.x; var n; diff --git a/tests/baselines/reference/ambientExternalModuleInsideNonAmbientExternalModule.js b/tests/baselines/reference/ambientExternalModuleInsideNonAmbientExternalModule.js index bb0d3a907ae..8a3e15e7c7f 100644 --- a/tests/baselines/reference/ambientExternalModuleInsideNonAmbientExternalModule.js +++ b/tests/baselines/reference/ambientExternalModuleInsideNonAmbientExternalModule.js @@ -3,5 +3,4 @@ export declare module "M" { } //// [ambientExternalModuleInsideNonAmbientExternalModule.js] define(["require", "exports"], function (require, exports) { - "use strict"; }); diff --git a/tests/baselines/reference/ambientExternalModuleWithInternalImportDeclaration.js b/tests/baselines/reference/ambientExternalModuleWithInternalImportDeclaration.js index 77d8e2d830d..c91adaff864 100644 --- a/tests/baselines/reference/ambientExternalModuleWithInternalImportDeclaration.js +++ b/tests/baselines/reference/ambientExternalModuleWithInternalImportDeclaration.js @@ -20,7 +20,7 @@ var c = new A(); //// [ambientExternalModuleWithInternalImportDeclaration_0.js] //// [ambientExternalModuleWithInternalImportDeclaration_1.js] -define(["require", "exports", 'M'], function (require, exports, A) { +define(["require", "exports", "M"], function (require, exports, A) { "use strict"; var c = new A(); }); diff --git a/tests/baselines/reference/ambientExternalModuleWithoutInternalImportDeclaration.js b/tests/baselines/reference/ambientExternalModuleWithoutInternalImportDeclaration.js index 158992234a2..4c70a338bc3 100644 --- a/tests/baselines/reference/ambientExternalModuleWithoutInternalImportDeclaration.js +++ b/tests/baselines/reference/ambientExternalModuleWithoutInternalImportDeclaration.js @@ -19,7 +19,7 @@ var c = new A(); //// [ambientExternalModuleWithoutInternalImportDeclaration_0.js] //// [ambientExternalModuleWithoutInternalImportDeclaration_1.js] -define(["require", "exports", 'M'], function (require, exports, A) { +define(["require", "exports", "M"], function (require, exports, A) { "use strict"; var c = new A(); }); diff --git a/tests/baselines/reference/ambientInsideNonAmbientExternalModule.js b/tests/baselines/reference/ambientInsideNonAmbientExternalModule.js index 0e2d08ae07b..5db44bb1ce1 100644 --- a/tests/baselines/reference/ambientInsideNonAmbientExternalModule.js +++ b/tests/baselines/reference/ambientInsideNonAmbientExternalModule.js @@ -7,5 +7,4 @@ export declare module M { } //// [ambientInsideNonAmbientExternalModule.js] define(["require", "exports"], function (require, exports) { - "use strict"; }); diff --git a/tests/baselines/reference/systemModule10.js b/tests/baselines/reference/systemModule10.js index 5e95c584345..10afa784ebb 100644 --- a/tests/baselines/reference/systemModule10.js +++ b/tests/baselines/reference/systemModule10.js @@ -16,8 +16,8 @@ System.register(["file1", "file2"], function (exports_1, context_1) { var file1_1, n2; return { setters: [ - function (_1) { - file1_1 = _1; + function (file1_1_1) { + file1_1 = file1_1_1; }, function (n2_1) { n2 = n2_1; diff --git a/tests/baselines/reference/systemModule10_ES5.js b/tests/baselines/reference/systemModule10_ES5.js index 272c8552bd4..830c611bd38 100644 --- a/tests/baselines/reference/systemModule10_ES5.js +++ b/tests/baselines/reference/systemModule10_ES5.js @@ -16,8 +16,8 @@ System.register(["file1", "file2"], function (exports_1, context_1) { var file1_1, n2; return { setters: [ - function (_1) { - file1_1 = _1; + function (file1_1_1) { + file1_1 = file1_1_1; }, function (n2_1) { n2 = n2_1; diff --git a/tests/baselines/reference/systemModule14.js b/tests/baselines/reference/systemModule14.js index 8dcd0652647..bebe9244e07 100644 --- a/tests/baselines/reference/systemModule14.js +++ b/tests/baselines/reference/systemModule14.js @@ -20,8 +20,8 @@ System.register(["foo"], function (exports_1, context_1) { var foo_1, x; return { setters: [ - function (_1) { - foo_1 = _1; + function (foo_1_1) { + foo_1 = foo_1_1; } ], execute: function () { diff --git a/tests/baselines/reference/systemModule9.js b/tests/baselines/reference/systemModule9.js index 188764a3b2d..e46b97a71a2 100644 --- a/tests/baselines/reference/systemModule9.js +++ b/tests/baselines/reference/systemModule9.js @@ -43,22 +43,22 @@ System.register(["file1", "file2", "file3", "file4", "file5", "file6", "file7"], function (ns_1) { ns = ns_1; }, + function (file2_1_1) { + file2_1 = file2_1_1; + }, + function (file3_1_1) { + file3_1 = file3_1_1; + }, function (_1) { - file2_1 = _1; }, - function (_2) { - file3_1 = _2; - }, - function (_3) { - }, - function (_4) { - file5_1 = _4; + function (file5_1_1) { + file5_1 = file5_1_1; }, function (ns3_1) { ns3 = ns3_1; }, - function (_5) { - exportStar_1(_5); + function (file7_1_1) { + exportStar_1(file7_1_1); } ], execute: function () { From 975e8212d8039b411babf14270d9b98228400d57 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 24 Mar 2016 13:32:41 -0700 Subject: [PATCH 4/6] Fixes the various TypeErrors coming from some transforms. --- .gitignore | 1 + Jakefile.js | 218 ++++++++++++++++++++- src/compiler/core.ts | 30 +-- src/compiler/transformers/module/module.ts | 11 +- src/compiler/transformers/module/system.ts | 30 +-- src/compiler/transformers/ts.ts | 11 +- src/harness/harness.ts | 96 +++++++-- src/harness/runner.ts | 7 + 8 files changed, 353 insertions(+), 51 deletions(-) diff --git a/.gitignore b/.gitignore index db8e29d903a..dc44379913a 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ tests/baselines/rwc/* tests/baselines/test262/* tests/baselines/reference/projectOutput/* tests/baselines/local/projectOutput/* +tests/baselines/reference/testresults.tap tests/services/baselines/prototyping/local/* tests/services/browser/typescriptServices.js scripts/configureNightly.js diff --git a/Jakefile.js b/Jakefile.js index e9e5fc31912..ed4751c47f4 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -5,6 +5,7 @@ var os = require("os"); var path = require("path"); var child_process = require("child_process"); var Linter = require("tslint"); +var readline = require("readline"); // Variables var compilerDirectory = "src/compiler/"; @@ -673,9 +674,14 @@ function cleanTestDirs() { } // used to pass data from jake command line directly to run.js -function writeTestConfigFile(tests, light, testConfigFile) { +function writeTestConfigFile(testConfigFile, tests, light, stackTraceLimit) { console.log('Running test(s): ' + tests); - var testConfigContents = JSON.stringify({ test: [tests], light: light }); + var testConfig = { test: [tests], light: light }; + if (/^(\d+|full)$/.test(stackTraceLimit)) { + testConfig.stackTraceLimit = stackTraceLimit; + } + + var testConfigContents = JSON.stringify(testConfig); fs.writeFileSync('test.config', testConfigContents); } @@ -685,6 +691,124 @@ function deleteTemporaryProjectOutput() { } } +function runTestsAndWriteOutput(file) { + cleanTestDirs(); + var tests = process.env.test || process.env.tests || process.env.t; + var light = process.env.light || false; + var testConfigFile = 'test.config'; + if (fs.existsSync(testConfigFile)) { + fs.unlinkSync(testConfigFile); + } + + if (tests || light) { + writeTestConfigFile(testConfigFile, tests, light, 10); + } + + if (tests && tests.toLocaleLowerCase() === "rwc") { + testTimeout = 100000; + } + + var args = []; + args.push("-R", "TAP"); + args.push("--no-colors"); + args.push("-t", testTimeout); + if (tests) { + args.push("-g", '"' + tests + '"'); + } + args.push(run); + + var cmd = "mocha " + args.join(" "); + console.log(cmd); + var ex = jake.createExec([cmd], { windowsVerbatimArguments: true }); + var out = fs.createWriteStream(file); + var tapRange = /^(\d+)\.\.(\d+)(?:$|\r\n?|\n)/; + var tapOk = /^ok\s/; + var tapNotOk = /^not\sok/; + var tapComment = /^#/; + var typeError = /^\s+TypeError:/; + var progress = new ProgressBar("Running tests..."); + var expectedTestCount = 0; + var testCount = 0; + var failureCount = 0; + var successCount = 0; + var comments = []; + var typeErrorCount = 0; + + ex.addListener("stdout", function (output) { + var m = tapRange.exec(output); + if (m) { + expectedTestCount = parseInt(m[2]); + return; + } + + out.write(output); + + if (tapOk.test(output)) { + successCount++; + } + else if (tapNotOk.test(output)) { + failureCount++; + } + else { + if (tapComment.test(output)) { + comments.push(output.toString().trim()); + } + else if (typeError.test(output)) { + typeErrorCount++; + } + return; + } + + testCount++; + + var percentComplete = testCount * 100 / expectedTestCount; + updateProgress(percentComplete); + }); + + function updateProgress(percentComplete) { + progress.update(percentComplete, + /*foregroundColor*/ failureCount > 0 + ? "red" + : successCount === expectedTestCount + ? "green" + : "cyan", + /*backgroundColor*/ "gray" + ); + } + + ex.addListener("stderr", function (output) { + progress.hide(); + process.stderr.write(output.toString().trim() + os.EOL); + progress.show(); + }); + ex.addListener("cmdEnd", function () { + if (progress.visible) { + updateProgress(100); + process.stdout.write("done." + os.EOL); + } + + console.log(comments.join(os.EOL)); + deleteTemporaryProjectOutput(); + complete(); + }); + ex.addListener("error", function (e, status) { + if (progress.visible) { + updateProgress(100); + process.stdout.write("done." + os.EOL); + } + + console.log(comments.join(os.EOL)); + + if (typeErrorCount) { + console.log("# type errors: %s", typeErrorCount); + } + + deleteTemporaryProjectOutput(); + fail("Process exited with code " + status); + }); + ex.run(); +} + function runConsoleTests(defaultReporter, defaultSubsets) { cleanTestDirs(); var debug = process.env.debug || process.env.d; @@ -696,7 +820,7 @@ function runConsoleTests(defaultReporter, defaultSubsets) { } if (tests || light) { - writeTestConfigFile(tests, light, testConfigFile); + writeTestConfigFile(testConfigFile, tests, light); } if (tests && tests.toLocaleLowerCase() === "rwc") { @@ -749,6 +873,10 @@ task("runtests", ["build-rules", "tests", builtLocalDirectory], function() { runConsoleTests('mocha-fivemat-progress-reporter', []); }, {async: true}); +task("runtests-file", ["build-rules", "tests", builtLocalDirectory], function () { + runTestsAndWriteOutput("tests/baselines/local/testresults.tap"); +}, { async: true }); + desc("Generates code coverage data via instanbul"); task("generate-code-coverage", ["tests", builtLocalDirectory], function () { var cmd = 'istanbul cover node_modules/mocha/bin/_mocha -- -R min -t ' + testTimeout + ' ' + run; @@ -780,7 +908,7 @@ task("runtests-browser", ["tests", "browserify", builtLocalDirectory, servicesFi fs.unlinkSync(testConfigFile); } if(tests || light) { - writeTestConfigFile(tests, light, testConfigFile); + writeTestConfigFile(testConfigFile, tests, light); } tests = tests ? tests : ''; @@ -1031,3 +1159,85 @@ task("lint-server", ["build-rules"], function() { lintWatchFile(lintTargets[i]); } }); + +function ProgressBar(title) { + this.title = title; +} +ProgressBar.prototype = { + progressChars: ["\u0020", "\u2591", "\u2592", "\u2593", "\u2588"], + colors: { + foreground: { + black: "\u001b[90m", + red: "\u001b[91m", + green: "\u001b[92m", + yellow: "\u001b[93m", + blue: "\u001b[94m", + magenta: "\u001b[95m", + cyan: "\u001b[96m", + white: "\u001b[97m", + gray: "\u001b[37m" + }, + background: { + black: "\u001b[40m", + red: "\u001b[41m", + green: "\u001b[42m", + yellow: "\u001b[43m", + blue: "\u001b[44m", + magenta: "\u001b[45m", + cyan: "\u001b[46m", + white: "\u001b[47m", + gray: "\u001b[100m" + }, + reset: "\u001b[0m" + }, + update: function (percentComplete, foregroundColor, backgroundColor) { + var progress = ""; + for (var i = 0; i < 100; i += 4) { + progress += this.progressChars[Math.floor(Math.max(0, Math.min(4, percentComplete - i)))]; + } + + foregroundColor = foregroundColor && this.colors.foreground[foregroundColor]; + backgroundColor = backgroundColor && this.colors.background[backgroundColor]; + if (foregroundColor || backgroundColor) { + if (foregroundColor) { + progress = foregroundColor + progress; + } + if (backgroundColor) { + progress = backgroundColor + progress; + } + + progress += this.colors.reset; + } + + if (this._lastProgress !== progress || !this.visible) { + this._print(progress); + } + }, + hide: function () { + if (this.visible) { + this._savedProgress = this._lastProgress; + this.clear(); + } + }, + show: function () { + if (this._savedProgress && !this.visible) { + this._print(this._savedProgress); + this._savedProgress = undefined; + } + }, + clear: function () { + if (this._lastProgress) { + readline.moveCursor(process.stdout, -process.stdout.columns, 0); + readline.clearLine(process.stdout, 1); + this._lastProgress = undefined; + this.visible = false; + } + }, + _print: function (progress) { + readline.moveCursor(process.stdout, -process.stdout.columns, 0); + process.stdout.write(this.title ? progress + " " + this.title : progress); + readline.clearLine(process.stdout, 1); + this._lastProgress = progress; + this.visible = true; + } +}; \ No newline at end of file diff --git a/src/compiler/core.ts b/src/compiler/core.ts index ee089e6eae4..ca3f76eeaed 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1079,12 +1079,10 @@ namespace ts { declare var process: any; declare var require: any; - const currentAssertionLevel = getDevelopmentMode() === "development" - ? AssertionLevel.Normal - : AssertionLevel.None; + let currentAssertionLevel: AssertionLevel; export function shouldAssert(level: AssertionLevel): boolean { - return currentAssertionLevel >= level; + return getCurrentAssertionLevel() >= level; } export function assert(expression: boolean, message?: string, verboseDebugInfo?: () => string): void { @@ -1102,15 +1100,21 @@ namespace ts { Debug.assert(/*expression*/ false, message); } - function getDevelopmentMode() { - return typeof require !== "undefined" - && typeof process !== "undefined" - && !process.browser - && process.nextTick - && process.env - && process.env.NODE_ENV - ? String(process.env.NODE_ENV).toLowerCase() - : undefined; + function getCurrentAssertionLevel() { + if (currentAssertionLevel !== undefined) { + return currentAssertionLevel; + } + + const developmentMode = sys && /^development$/i.test(sys.getEnvironmentVariable("NODE_ENV")); + if (developmentMode === undefined) { + return AssertionLevel.None; + } + + currentAssertionLevel = developmentMode + ? AssertionLevel.Normal + : AssertionLevel.None; + + return currentAssertionLevel; } } diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index e8c6158c4e8..8aec7598aa4 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -456,10 +456,13 @@ namespace ts { } function visitExportAssignment(node: ExportAssignment): VisitResult { - if (!node.isExportEquals && resolver.isValueAliasDeclaration(node)) { - const statements: Statement[] = []; - addExportDefault(statements, node.expression, /*location*/ node); - return statements; + if (!node.isExportEquals) { + const original = getOriginalNode(node); + if (nodeIsSynthesized(original) || resolver.isValueAliasDeclaration(original)) { + const statements: Statement[] = []; + addExportDefault(statements, node.expression, /*location*/ node); + return statements; + } } return undefined; diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index 4a508b3aa30..55fd8a1ab17 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -45,12 +45,6 @@ namespace ts { return transformSourceFile; - function onEmitNode(node: Node, emit: (node: Node) => void): void { - exportFunctionForFile = exportFunctionForFileMap[getNodeId(node)]; - previousOnEmitNode(node, emit); - exportFunctionForFile = undefined; - } - function transformSourceFile(node: SourceFile) { if (isExternalModule(node) || compilerOptions.isolatedModules) { currentSourceFile = node; @@ -548,11 +542,14 @@ namespace ts { } function visitExportAssignment(node: ExportAssignment): Statement { - if (!node.isExportEquals && resolver.isValueAliasDeclaration(node)) { - return createExportStatement( - createLiteral("default"), - node.expression - ); + if (!node.isExportEquals) { + const original = getOriginalNode(node); + if (nodeIsSynthesized(original) || resolver.isValueAliasDeclaration(original)) { + return createExportStatement( + createLiteral("default"), + node.expression + ); + } } return undefined; @@ -918,6 +915,17 @@ namespace ts { // Substitutions // + function onEmitNode(node: Node, emit: (node: Node) => void): void { + if (node.kind === SyntaxKind.SourceFile) { + exportFunctionForFile = exportFunctionForFileMap[getNodeId(node)]; + previousOnEmitNode(node, emit); + exportFunctionForFile = undefined; + } + else { + previousOnEmitNode(node, emit); + } + } + /** * Substitute the expression, if necessary. * diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 0ea026fec68..c49cdc49821 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -463,7 +463,7 @@ namespace ts { } else if (node.decorators) { if (isDefaultExternalModuleExport(node)) { - statements.push(createExportDefault(name)); + statements.push(createExportDefault(name || getGeneratedNameForNode(node))); } else if (isNamedExternalModuleExport(node)) { statements.push(createExternalModuleExport(name)); @@ -581,6 +581,10 @@ namespace ts { node ); + if (!name) { + name = getGeneratedNameForNode(node); + } + // Record an alias to avoid class double-binding. let decoratedClassAlias: Identifier; if (resolver.getNodeCheckFlags(getOriginalNode(node)) & NodeCheckFlags.DecoratedClassWithSelfReference) { @@ -2440,7 +2444,10 @@ namespace ts { * @param node The import equals declaration node. */ function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult { - Debug.assert(!isExternalModuleImportEqualsDeclaration(node)); + if (isExternalModuleImportEqualsDeclaration(node)) { + return visitEachChild(node, visitor, context); + } + if (shouldElideImportEqualsDeclaration(node)) { return undefined; } diff --git a/src/harness/harness.ts b/src/harness/harness.ts index ddaca642094..5581755d0b0 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1,7 +1,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -346,7 +346,7 @@ namespace Utils { assert.equal(node1.end, node2.end, "node1.end !== node2.end"); assert.equal(node1.kind, node2.kind, "node1.kind !== node2.kind"); - // call this on both nodes to ensure all propagated flags have been set (and thus can be + // call this on both nodes to ensure all propagated flags have been set (and thus can be // compared). assert.equal(ts.containsParseError(node1), ts.containsParseError(node2)); assert.equal(node1.flags, node2.flags, "node1.flags !== node2.flags"); @@ -391,6 +391,60 @@ namespace Utils { throw new Error("Could not find child in parent"); } + + const maxHarnessFrames = 1; + + export function filterStack(error: Error, stackTraceLimit: number = Infinity) { + const stack = (error).stack; + if (stack) { + const lines = stack.split(/\r\n?|\n/g); + const filtered: string[] = []; + let frameCount = 0; + let harnessFrameCount = 0; + for (let line of lines) { + if (isStackFrame(line)) { + if (frameCount >= stackTraceLimit + || isMocha(line) + || isNode(line)) { + continue; + } + + if (isHarness(line)) { + if (harnessFrameCount >= maxHarnessFrames) { + continue; + } + + harnessFrameCount++; + } + + line = line.replace(/\bfile:\/\/\/(.*?)(?=(:\d+)*($|\)))/, (_, path) => ts.sys.resolvePath(path)); + frameCount++; + } + + filtered.push(line); + } + + (error).stack = filtered.join(ts.sys.newLine); + } + + return error; + } + + function isStackFrame(line: string) { + return /^\s+at\s/.test(line); + } + + function isMocha(line: string) { + return /[\\/](node_modules|components)[\\/]mocha(js)?[\\/]|[\\/]mocha\.js/.test(line); + } + + function isNode(line: string) { + return /\((timers|events|node|module)\.js:/.test(line); + } + + function isHarness(line: string) { + return /[\\/]src[\\/]harness[\\/]|[\\/]run\.js/.test(line); + } } namespace Harness.Path { @@ -747,13 +801,13 @@ namespace Harness { namespace Harness { export const libFolder = "built/local/"; const tcServicesFileName = ts.combinePaths(libFolder, Utils.getExecutionEnvironment() === Utils.ExecutionEnvironment.Browser ? "typescriptServicesInBrowserTest.js" : "typescriptServices.js"); - export const tcServicesFile = IO.readFile(tcServicesFileName); + export const tcServicesFile = IO.readFile(tcServicesFileName) + IO.newLine() + `//# sourceURL=${IO.resolvePath(tcServicesFileName)}`; export interface SourceMapEmitterCallback { (emittedFile: string, emittedLine: number, emittedColumn: number, sourceFile: string, sourceLine: number, sourceColumn: number, sourceName: string): void; } - // Settings + // Settings export let userSpecifiedRoot = ""; export let lightMode = false; @@ -792,7 +846,7 @@ namespace Harness { fileName: string, sourceText: string, languageVersion: ts.ScriptTarget) { - // We'll only assert invariants outside of light mode. + // We'll only assert invariants outside of light mode. const shouldAssertInvariants = !Harness.lightMode; // Only set the parent nodes if we're asserting invariants. We don't need them otherwise. @@ -887,7 +941,7 @@ namespace Harness { libFiles?: string; } - // Additional options not already in ts.optionDeclarations + // Additional options not already in ts.optionDeclarations const harnessOptionDeclarations: ts.CommandLineOption[] = [ { name: "allowNonTsExtensions", type: "boolean" }, { name: "useCaseSensitiveFileNames", type: "boolean" }, @@ -1135,7 +1189,7 @@ namespace Harness { errLines.forEach(e => outputLines.push(e)); // do not count errors from lib.d.ts here, they are computed separately as numLibraryDiagnostics - // if lib.d.ts is explicitly included in input files and there are some errors in it (i.e. because of duplicate identifiers) + // if lib.d.ts is explicitly included in input files and there are some errors in it (i.e. because of duplicate identifiers) // then they will be added twice thus triggering 'total errors' assertion with condition // 'totalErrorsReportedInNonLibraryFiles + numLibraryDiagnostics + numTest262HarnessDiagnostics, diagnostics.length @@ -1445,7 +1499,7 @@ namespace Harness { }; testUnitData.push(newTestFile2); - // unit tests always list files explicitly + // unit tests always list files explicitly const parseConfigHost: ts.ParseConfigHost = { readDirectory: (name) => [] }; @@ -1590,17 +1644,21 @@ namespace Harness { let actual = undefined; const actualFileName = localPath(relativeFileName, opts && opts.Baselinefolder, opts && opts.Subfolder); + try { + if (runImmediately) { + actual = generateActual(actualFileName, generateContent); + const comparison = compareToBaseline(actual, relativeFileName, opts); + writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName, descriptionForDescribe); + } + else { + actual = generateActual(actualFileName, generateContent); - if (runImmediately) { - actual = generateActual(actualFileName, generateContent); - const comparison = compareToBaseline(actual, relativeFileName, opts); - writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName, descriptionForDescribe); + const comparison = compareToBaseline(actual, relativeFileName, opts); + writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName, descriptionForDescribe); + } } - else { - actual = generateActual(actualFileName, generateContent); - - const comparison = compareToBaseline(actual, relativeFileName, opts); - writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName, descriptionForDescribe); + catch (e) { + throw Utils.filterStack(e); } } } @@ -1621,5 +1679,9 @@ namespace Harness { if (Error) (Error).stackTraceLimit = 1; } +if (ts.sys.tryEnableSourceMapsForHost && /^development$/i.test(ts.sys.getEnvironmentVariable("NODE_ENV"))) { + ts.sys.tryEnableSourceMapsForHost(); +} + // TODO: not sure why Utils.evalFile isn't working with this, eventually will concat it like old compiler instead of eval eval(Harness.tcServicesFile); diff --git a/src/harness/runner.ts b/src/harness/runner.ts index ec8e1105c2f..04af7b6f066 100644 --- a/src/harness/runner.ts +++ b/src/harness/runner.ts @@ -46,6 +46,13 @@ if (testConfigFile !== "") { Harness.lightMode = true; } + if (testConfig.stackTraceLimit === "full") { + (Error).stackTraceLimit = Infinity; + } + else if ((testConfig.stackTraceLimit | 0) > 0) { + (Error).stackTraceLimit = testConfig.stackTraceLimit; + } + if (testConfig.test && testConfig.test.length > 0) { for (const option of testConfig.test) { if (!option) { From e78b64b040ff185bbcd2f9340d7fbecd6f8f386d Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 24 Mar 2016 14:00:46 -0700 Subject: [PATCH 5/6] Do not always add sourceURL for browser tests --- src/harness/harness.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 5581755d0b0..5d8e051124c 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -801,7 +801,9 @@ namespace Harness { namespace Harness { export const libFolder = "built/local/"; const tcServicesFileName = ts.combinePaths(libFolder, Utils.getExecutionEnvironment() === Utils.ExecutionEnvironment.Browser ? "typescriptServicesInBrowserTest.js" : "typescriptServices.js"); - export const tcServicesFile = IO.readFile(tcServicesFileName) + IO.newLine() + `//# sourceURL=${IO.resolvePath(tcServicesFileName)}`; + export const tcServicesFile = IO.readFile(tcServicesFileName) + (Utils.getExecutionEnvironment() !== Utils.ExecutionEnvironment.Browser + ? IO.newLine() + `//# sourceURL=${IO.resolvePath(tcServicesFileName)}` + : ""); export interface SourceMapEmitterCallback { (emittedFile: string, emittedLine: number, emittedColumn: number, sourceFile: string, sourceLine: number, sourceColumn: number, sourceName: string): void; From b60cf99c8a4cdf70f6853398bbd46ce45aea1d1d Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 24 Mar 2016 16:23:30 -0700 Subject: [PATCH 6/6] Fixed minor difference in string literal emit for AMD modules --- src/compiler/factory.ts | 11 ++++++++-- src/compiler/printer.ts | 21 +++++++++++++++++-- src/compiler/transformers/module/module.ts | 2 +- src/compiler/transformers/module/system.ts | 6 +++--- src/compiler/types.ts | 2 ++ src/compiler/utilities.ts | 4 ++-- .../reference/ambientDeclarationsExternal.js | 2 +- ...rnalModuleWithInternalImportDeclaration.js | 2 +- ...lModuleWithoutInternalImportDeclaration.js | 2 +- tests/baselines/reference/systemModule10.js | 2 +- .../baselines/reference/systemModule10_ES5.js | 2 +- 11 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index f2d11ef227c..695b999e7bf 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -114,10 +114,11 @@ namespace ts { // Literals + export function createLiteral(textSource: StringLiteral | Identifier, location?: TextRange): StringLiteral; export function createLiteral(value: string, location?: TextRange): StringLiteral; export function createLiteral(value: number, location?: TextRange): LiteralExpression; export function createLiteral(value: string | number | boolean, location?: TextRange): PrimaryExpression; - export function createLiteral(value: string | number | boolean, location?: TextRange): PrimaryExpression { + export function createLiteral(value: string | number | boolean | StringLiteral | Identifier, location?: TextRange): PrimaryExpression { if (typeof value === "number") { const node = createNode(SyntaxKind.NumericLiteral, location); node.text = value.toString(); @@ -126,9 +127,15 @@ namespace ts { else if (typeof value === "boolean") { return createNode(value ? SyntaxKind.TrueKeyword : SyntaxKind.FalseKeyword, location); } + else if (typeof value === "string") { + const node = createNode(SyntaxKind.StringLiteral, location); + node.text = value; + return node; + } else { const node = createNode(SyntaxKind.StringLiteral, location); - node.text = String(value); + node.textSourceNode = value; + node.text = value.text; return node; } } diff --git a/src/compiler/printer.ts b/src/compiler/printer.ts index e2bef72f15a..194d668686c 100644 --- a/src/compiler/printer.ts +++ b/src/compiler/printer.ts @@ -668,7 +668,7 @@ const _super = (function (geti, seti) { // SyntaxKind.TemplateMiddle // SyntaxKind.TemplateTail function emitLiteral(node: LiteralLikeNode) { - const text = getLiteralText(node, currentSourceFile, languageVersion); + const text = getLiteralTextOfNode(node); if ((compilerOptions.sourceMap || compilerOptions.inlineSourceMap) && (node.kind === SyntaxKind.StringLiteral || isTemplateLiteralKind(node.kind))) { writer.writeLiteral(text); @@ -980,7 +980,7 @@ const _super = (function (geti, seti) { function needsDotDotForPropertyAccess(expression: Expression) { if (expression.kind === SyntaxKind.NumericLiteral) { // check if numeric literal was originally written with a dot - const text = getLiteralText(expression, currentSourceFile, languageVersion); + const text = getLiteralTextOfNode(expression); return text.indexOf(tokenToString(SyntaxKind.DotToken)) < 0; } else { @@ -2350,6 +2350,9 @@ const _super = (function (geti, seti) { else if (isIdentifier(node) && (nodeIsSynthesized(node) || !node.parent)) { return unescapeIdentifier(node.text); } + else if (node.kind === SyntaxKind.StringLiteral && (node).textSourceNode) { + return getTextOfNode((node).textSourceNode, includeTrivia); + } else if (isLiteralExpression(node) && (nodeIsSynthesized(node) || !node.parent)) { return node.text; } @@ -2357,6 +2360,20 @@ const _super = (function (geti, seti) { return getSourceTextOfNodeFromSourceFile(currentSourceFile, node, includeTrivia); } + function getLiteralTextOfNode(node: LiteralLikeNode): string { + if (node.kind === SyntaxKind.StringLiteral && (node).textSourceNode) { + const textSourceNode = (node).textSourceNode; + if (isIdentifier(textSourceNode)) { + return "\"" + escapeNonAsciiCharacters(escapeString(getTextOfNode(textSourceNode))) + "\""; + } + else { + return getLiteralTextOfNode(textSourceNode); + } + } + + return getLiteralText(node, currentSourceFile, languageVersion); + } + function tryGetConstEnumValue(node: Node): number { if (compilerOptions.isolatedModules) { return undefined; diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 8aec7598aa4..3166b77c293 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -720,7 +720,7 @@ namespace ts { const moduleName = getExternalModuleName(importNode); if (moduleName.kind === SyntaxKind.StringLiteral) { return tryRenameExternalModule(moduleName) - || getSynthesizedClone(moduleName); + || createLiteral(moduleName); } return undefined; diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index 55fd8a1ab17..cc35ec22bf1 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -5,7 +5,7 @@ namespace ts { export function transformSystemModule(context: TransformationContext) { interface DependencyGroup { - name: Identifier; + name: StringLiteral; externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[]; } @@ -640,7 +640,7 @@ namespace ts { return [ node, createExportStatement(name, name) - ] + ]; } return node; } @@ -1101,7 +1101,7 @@ namespace ts { else { return operator === SyntaxKind.PlusPlusToken ? createSubtract(call, createLiteral(1)) - : createAdd(call, createLiteral(1)) + : createAdd(call, createLiteral(1)); } } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 475d96b87f7..09e60035ff3 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -804,6 +804,8 @@ namespace ts { // @kind(SyntaxKind.StringLiteral) export interface StringLiteral extends LiteralExpression { _stringLiteralBrand: any; + /* @internal */ + textSourceNode?: Identifier | StringLiteral; // Allows a StringLiteral to get its text from another node (used by transforms). } // Note: 'brands' in our syntax nodes serve to give us a small amount of nominal typing. diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 5f3899f4e24..18a95bc5ff0 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2982,7 +2982,7 @@ namespace ts { break; case SyntaxKind.ImportEqualsDeclaration: - if ((node).moduleReference.kind === SyntaxKind.ExternalModuleReference && resolver.isReferencedAliasDeclaration(node)) { + if ((node).moduleReference.kind === SyntaxKind.ExternalModuleReference && resolver.isReferencedAliasDeclaration(getOriginalNode(node))) { // import x = require("mod") where x is referenced externalImports.push(node); } @@ -2995,7 +2995,7 @@ namespace ts { externalImports.push(node); hasExportStars = true; } - else if (resolver.isValueAliasDeclaration(node)) { + else if (resolver.isValueAliasDeclaration(getOriginalNode(node))) { // export { x, y } from "mod" where at least one export is a value symbol externalImports.push(node); } diff --git a/tests/baselines/reference/ambientDeclarationsExternal.js b/tests/baselines/reference/ambientDeclarationsExternal.js index b92993128ab..42375bc1d09 100644 --- a/tests/baselines/reference/ambientDeclarationsExternal.js +++ b/tests/baselines/reference/ambientDeclarationsExternal.js @@ -29,6 +29,6 @@ var n: number; //// [consumer.js] "use strict"; // Ambient external module members are always exported with or without export keyword when module lacks export assignment -var imp3 = require("equ2"); +var imp3 = require('equ2'); var n = imp3.x; var n; diff --git a/tests/baselines/reference/ambientExternalModuleWithInternalImportDeclaration.js b/tests/baselines/reference/ambientExternalModuleWithInternalImportDeclaration.js index c91adaff864..77d8e2d830d 100644 --- a/tests/baselines/reference/ambientExternalModuleWithInternalImportDeclaration.js +++ b/tests/baselines/reference/ambientExternalModuleWithInternalImportDeclaration.js @@ -20,7 +20,7 @@ var c = new A(); //// [ambientExternalModuleWithInternalImportDeclaration_0.js] //// [ambientExternalModuleWithInternalImportDeclaration_1.js] -define(["require", "exports", "M"], function (require, exports, A) { +define(["require", "exports", 'M'], function (require, exports, A) { "use strict"; var c = new A(); }); diff --git a/tests/baselines/reference/ambientExternalModuleWithoutInternalImportDeclaration.js b/tests/baselines/reference/ambientExternalModuleWithoutInternalImportDeclaration.js index 4c70a338bc3..158992234a2 100644 --- a/tests/baselines/reference/ambientExternalModuleWithoutInternalImportDeclaration.js +++ b/tests/baselines/reference/ambientExternalModuleWithoutInternalImportDeclaration.js @@ -19,7 +19,7 @@ var c = new A(); //// [ambientExternalModuleWithoutInternalImportDeclaration_0.js] //// [ambientExternalModuleWithoutInternalImportDeclaration_1.js] -define(["require", "exports", "M"], function (require, exports, A) { +define(["require", "exports", 'M'], function (require, exports, A) { "use strict"; var c = new A(); }); diff --git a/tests/baselines/reference/systemModule10.js b/tests/baselines/reference/systemModule10.js index 10afa784ebb..356cbff33d9 100644 --- a/tests/baselines/reference/systemModule10.js +++ b/tests/baselines/reference/systemModule10.js @@ -10,7 +10,7 @@ export {n2} export {n2 as n3} //// [systemModule10.js] -System.register(["file1", "file2"], function (exports_1, context_1) { +System.register(['file1', 'file2'], function (exports_1, context_1) { "use strict"; var __moduleName = context_1 && context_1.id; var file1_1, n2; diff --git a/tests/baselines/reference/systemModule10_ES5.js b/tests/baselines/reference/systemModule10_ES5.js index 830c611bd38..068613968af 100644 --- a/tests/baselines/reference/systemModule10_ES5.js +++ b/tests/baselines/reference/systemModule10_ES5.js @@ -10,7 +10,7 @@ export {n2} export {n2 as n3} //// [systemModule10_ES5.js] -System.register(["file1", "file2"], function (exports_1, context_1) { +System.register(['file1', 'file2'], function (exports_1, context_1) { "use strict"; var __moduleName = context_1 && context_1.id; var file1_1, n2;