diff --git a/src/compiler/transformers/es6.ts b/src/compiler/transformers/es6.ts index d7e38611b93..620eebc5888 100644 --- a/src/compiler/transformers/es6.ts +++ b/src/compiler/transformers/es6.ts @@ -612,7 +612,6 @@ namespace ts { enableSubstitutionsForBlockScopedBindings(); } - const closingBraceLocation = { pos: node.end - 1, end: node.end }; const baseTypeNode = getClassExtendsHeritageClauseElement(node); const classFunction = createFunctionExpression( /*asteriskToken*/ undefined, @@ -663,23 +662,23 @@ namespace ts { // Create a synthetic text range for the return statement. const closingBraceLocation = createTokenRange(skipTrivia(currentText, node.members.end), SyntaxKind.CloseBraceToken); - const name = getDeclarationName(node); + const localName = getLocalName(node); // The following partially-emitted expression exists purely to align our sourcemap // emit with the original emitter. - const outer = createPartiallyEmittedExpression(name); + const outer = createPartiallyEmittedExpression(localName); outer.end = closingBraceLocation.end; setNodeEmitFlags(outer, NodeEmitFlags.NoComments); const statement = createReturn(outer); statement.pos = closingBraceLocation.pos; - statements.push(statement); setNodeEmitFlags(statement, NodeEmitFlags.NoComments | NodeEmitFlags.NoTokenSourceMaps); + statements.push(statement); addRange(statements, endLexicalEnvironment()); + const block = createBlock(createNodeArray(statements, /*location*/ node.members), /*location*/ undefined, /*multiLine*/ true); setNodeEmitFlags(block, NodeEmitFlags.NoComments); - return block; } @@ -2769,21 +2768,53 @@ namespace ts { return node; } + /** + * Gets the local name for a declaration for use in expressions. + * + * A local name will *never* be prefixed with an module or namespace export modifier like + * "exports.". + * + * @param node The declaration. + * @param allowComments A value indicating whether comments may be emitted for the name. + * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. + */ + function getLocalName(node: ClassDeclaration | ClassExpression | FunctionDeclaration, allowComments?: boolean, allowSourceMaps?: boolean) { + return getDeclarationName(node, allowComments, allowSourceMaps, NodeEmitFlags.LocalName); + } + + /** + * Gets the export name for a declaration for use in expressions. + * + * An export name will *always* be prefixed with an module or namespace export modifier + * like "exports." if one is required. + * + * @param node The declaration. + * @param allowComments A value indicating whether comments may be emitted for the name. + * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. + */ + function getExportName(node: ClassDeclaration | ClassExpression | FunctionDeclaration, allowComments?: boolean, allowSourceMaps?: boolean) { + return getDeclarationName(node, allowComments, allowSourceMaps, NodeEmitFlags.ExportName); + } + /** * Gets the name of a declaration, without source map or comments. * * @param node The declaration. * @param allowComments Allow comments for the name. */ - function getDeclarationName(node: DeclarationStatement | ClassExpression, allowComments?: boolean) { - if (node.name) { - const name = getMutableClone(node.name); - let flags = NodeEmitFlags.NoSourceMap; + function getDeclarationName(node: DeclarationStatement | ClassExpression, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: NodeEmitFlags) { + if (node.name && !isGeneratedIdentifier(node.name)) { + const name = getUniqueClone(node.name); + emitFlags |= getNodeEmitFlags(node.name); + if (!allowSourceMaps) { + emitFlags |= NodeEmitFlags.NoSourceMap; + } if (!allowComments) { - flags |= NodeEmitFlags.NoComments; + emitFlags |= NodeEmitFlags.NoComments; + } + if (emitFlags) { + setNodeEmitFlags(name, emitFlags); } - - setNodeEmitFlags(name, flags | getNodeEmitFlags(name)); return name; } @@ -2791,7 +2822,7 @@ namespace ts { } function getClassMemberPrefix(node: ClassExpression | ClassDeclaration, member: ClassElement) { - const expression = getDeclarationName(node); + const expression = getLocalName(node); return hasModifier(member, ModifierFlags.Static) ? expression : createPropertyAccess(expression, "prototype"); } diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 83604946102..ca5534c2bdd 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -647,12 +647,15 @@ namespace ts { setNodeEmitFlags(name, NodeEmitFlags.NoSubstitution); if (hasModifier(node, ModifierFlags.Export)) { statements.push( - createClassDeclaration( - /*modifiers*/ undefined, - name, - node.heritageClauses, - node.members, - /*location*/ node + setOriginalNode( + createClassDeclaration( + /*modifiers*/ undefined, + name, + node.heritageClauses, + node.members, + /*location*/ node + ), + /*original*/ node ) ); diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index c34ead8dd63..efc7aeddf2c 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -480,7 +480,7 @@ namespace ts { } else if (node.decorators) { if (isDefaultExternalModuleExport(node)) { - statements.push(createExportDefault(name || getGeneratedNameForNode(node))); + statements.push(createExportDefault(getLocalName(node))); } else if (isNamedExternalModuleExport(node)) { statements.push(createExternalModuleExport(name)); diff --git a/tests/baselines/reference/duplicateAnonymousInners1.js b/tests/baselines/reference/duplicateAnonymousInners1.js index 5bb73bf68ed..24f79566d56 100644 --- a/tests/baselines/reference/duplicateAnonymousInners1.js +++ b/tests/baselines/reference/duplicateAnonymousInners1.js @@ -49,4 +49,6 @@ var Foo; } return Helper; }()); + // Inner should not show up in intellisense + // Outer should show up in intellisense })(Foo || (Foo = {})); diff --git a/tests/baselines/reference/privacyGloImport.js b/tests/baselines/reference/privacyGloImport.js index 407ac5bb8d5..ecafec9d639 100644 --- a/tests/baselines/reference/privacyGloImport.js +++ b/tests/baselines/reference/privacyGloImport.js @@ -235,6 +235,8 @@ var m1; //var m1_im4_private_v4_private = m1_im4_private.f1(); m1.m1_im1_public = m1_M1_public; m1.m1_im2_public = m1_M2_private; + //export import m1_im3_public = require("m1_M3_public"); + //export import m1_im4_public = require("m1_M4_private"); })(m1 || (m1 = {})); var glo_M1_public; (function (glo_M1_public) { @@ -256,5 +258,6 @@ var m2; var m4; (function (m4) { var a = 10; + //import m2 = require("use_glo_M1_public"); })(m4 || (m4 = {})); })(m2 || (m2 = {})); diff --git a/tests/baselines/reference/tsxEmit3.js b/tests/baselines/reference/tsxEmit3.js index 9501df4e237..33e1975cdbc 100644 --- a/tests/baselines/reference/tsxEmit3.js +++ b/tests/baselines/reference/tsxEmit3.js @@ -58,6 +58,8 @@ var M; return Bar; }()); S.Bar = Bar; + // Emit Foo + // Foo, ; })(S = M.S || (M.S = {})); })(M || (M = {})); var M;