Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions src/compiler/transformers/ts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2639,9 +2639,6 @@ namespace ts {
/**
* Records that a declaration was emitted in the current scope, if it was the first
* declaration for the provided symbol.
*
* NOTE: if there is ever a transformation above this one, we may not be able to rely
* on symbol names.
*/
function recordEmittedDeclarationInScope(node: Node) {
const name = node.symbol && node.symbol.escapedName;
Expand All @@ -2657,18 +2654,22 @@ namespace ts {
}

/**
* Determines whether a declaration is the first declaration with the same name emitted
* in the current scope.
* Determines whether a declaration is *could* be the first declaration with
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a declaration is *could*

* the same name emitted in the current scope. Only returns false if we are absolutely
* certain a previous declaration has been emitted.
*/
function isFirstEmittedDeclarationInScope(node: Node) {
function isPotentiallyFirstEmittedDeclarationInScope(node: Node) {
// If the node has a named symbol, then we have enough knowledge to determine
// whether a prior declaration has been emitted.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should consider using getParseTreeNode here and get the symbol of the parse tree node. If there is no parse tree node, or the node does not have a symbol, we should fall back to the text of the declaration's name.

if (currentScopeFirstDeclarationsOfName) {
const name = node.symbol && node.symbol.escapedName;
if (name) {
return currentScopeFirstDeclarationsOfName.get(name) === node;
}
}

return false;
// Otherwise, we can't be sure. For example, this node could be synthetic.
return true;
}

/**
Expand All @@ -2690,7 +2691,7 @@ namespace ts {
setOriginalNode(statement, node);

recordEmittedDeclarationInScope(node);
if (isFirstEmittedDeclarationInScope(node)) {
if (isPotentiallyFirstEmittedDeclarationInScope(node)) {
// Adjust the source map emit to match the old emitter.
if (node.kind === SyntaxKind.EnumDeclaration) {
setSourceMapRange(statement.declarationList, node);
Expand Down
26 changes: 26 additions & 0 deletions src/harness/unittests/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,32 @@ namespace ts {
}
}).outputText;
});

testBaseline("synthesizedNamespace", () => {
return ts.transpileModule(`namespace Reflect { const x = 1; }`, {
transformers: {
before: [forceSyntheticModuleDeclaration],
},
compilerOptions: {
newLine: NewLineKind.CarriageReturnLineFeed,
}
}).outputText;

function forceSyntheticModuleDeclaration(context: ts.TransformationContext) {
return (sourceFile: ts.SourceFile): ts.SourceFile => {
return visitNode(sourceFile);

function visitNode<T extends ts.Node>(node: T): T {
if (node.kind === ts.SyntaxKind.ModuleBlock) {
const block = node as T & ts.ModuleBlock;
const statements = ts.createNodeArray([...block.statements]);
return ts.updateModuleBlock(block, statements) as typeof block;
}
return ts.visitEachChild(node, visitNode, context);
}
};
}
});
});
}

1 change: 1 addition & 0 deletions tests/baselines/reference/parserEnumDeclaration4.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ enum void {
}

//// [parserEnumDeclaration4.js]
var ;
(function () {
})( || ( = {}));
void {};
1 change: 1 addition & 0 deletions tests/baselines/reference/reservedWords2.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ debugger;
if ()
;
[1, 2];
var ;
(function () {
})( || ( = {}));
void {};
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
var Reflect;
(function (Reflect) {
var x = 1;
})(Reflect || (Reflect = {}));