diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 40db3736b82..a823306412a 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -22,17 +22,12 @@ namespace ts { return node; } - function updateNode(updated: T, original: T): T { - updated.original = original; - if (original.transformId) { - updated.transformId = original.transformId; - updated.emitFlags = original.emitFlags; - updated.commentRange = original.commentRange; - updated.sourceMapRange = original.sourceMapRange; - } + export function updateNode(updated: T, original: T): T { + setOriginalNode(updated, original); if (original.startsOnNewLine) { updated.startsOnNewLine = true; } + return updated; } @@ -1894,6 +1889,12 @@ namespace ts { export function setOriginalNode(node: T, original: Node): T { node.original = original; + if (original && original.transformId && !node.transformId) { + node.transformId = original.transformId; + node.emitFlags = original.emitFlags; + node.commentRange = original.commentRange; + node.sourceMapRange = original.sourceMapRange; + } return node; } diff --git a/src/compiler/transformer.ts b/src/compiler/transformer.ts index 9e58b02c208..3775ec348f7 100644 --- a/src/compiler/transformer.ts +++ b/src/compiler/transformer.ts @@ -69,15 +69,9 @@ namespace ts { const enabledSyntaxKindFeatures = new Array(SyntaxKind.Count); const sourceTreeNodesWithAnnotations: Node[] = []; - let lastNodeEmitFlagsNode: Node; - let lastNodeEmitFlags: NodeEmitFlags; - let lastSourceMapRangeNode: Node; - let lastSourceMapRange: TextRange; let lastTokenSourceMapRangeNode: Node; let lastTokenSourceMapRangeToken: SyntaxKind; let lastTokenSourceMapRange: TextRange; - let lastCommentMapRangeNode: Node; - let lastCommentMapRange: TextRange; let lexicalEnvironmentStackOffset = 0; let hoistedVariableDeclarations: VariableDeclaration[]; let hoistedFunctionDeclarations: FunctionDeclaration[]; @@ -210,18 +204,12 @@ namespace ts { * @param node The node. */ function beforeSetAnnotation(node: Node) { - if (node.transformId !== transformId) { - node.transformId = transformId; - if ((node.flags & NodeFlags.Synthesized) === 0) { - node.emitFlags = 0; - node.sourceMapRange = undefined; - node.commentRange = undefined; - - // To avoid holding onto transformation artifacts, we keep track of any - // source tree node we are annotating. This allows us to clean them up after - // all transformations have completed. - sourceTreeNodesWithAnnotations.push(node); - } + node.transformId = transformId; + if ((node.flags & NodeFlags.Synthesized) === 0) { + // To avoid holding onto transformation artifacts, we keep track of any + // source tree node we are annotating. This allows us to clean them up after + // all transformations have completed. + sourceTreeNodesWithAnnotations.push(node); } } @@ -234,31 +222,7 @@ namespace ts { * @param node The node. */ function getNodeEmitFlags(node: Node) { - // As a performance optimization, use the cached value of the most recent node. - // This helps for cases where this function is called repeatedly for the same node. - if (lastNodeEmitFlagsNode === node) { - return lastNodeEmitFlags; - } - - // Get the emit flags for a node or from one of its original nodes. - let flags: NodeEmitFlags; - let current = node; - while (current) { - if (current.transformId === transformId) { - const nodeEmitFlags = current.emitFlags; - if (nodeEmitFlags) { - flags = nodeEmitFlags & ~NodeEmitFlags.HasNodeEmitFlags; - break; - } - } - - current = current.original; - } - - // Cache the most recently requested value. - lastNodeEmitFlagsNode = node; - lastNodeEmitFlags = flags; - return flags; + return node.emitFlags & ~NodeEmitFlags.HasNodeEmitFlags; } /** @@ -268,16 +232,7 @@ namespace ts { * @param emitFlags The NodeEmitFlags for the node. */ function setNodeEmitFlags(node: T, emitFlags: NodeEmitFlags) { - // Merge existing flags. - if (emitFlags & NodeEmitFlags.Merge) { - emitFlags = getNodeEmitFlags(node) | (emitFlags & ~NodeEmitFlags.Merge); - } - beforeSetAnnotation(node); - - // Cache the most recently requested value. - lastNodeEmitFlagsNode = node; - lastNodeEmitFlags = emitFlags; node.emitFlags = emitFlags | NodeEmitFlags.HasNodeEmitFlags; return node; } @@ -291,30 +246,7 @@ namespace ts { * @param node The node. */ function getSourceMapRange(node: Node) { - // As a performance optimization, use the cached value of the most recent node. - // This helps for cases where this function is called repeatedly for the same node. - if (lastSourceMapRangeNode === node) { - return lastSourceMapRange || node; - } - - // Get the custom source map range for a node or from one of its original nodes. - let range: TextRange; - let current = node; - while (current) { - if (current.transformId === transformId) { - range = current.sourceMapRange; - if (range !== undefined) { - break; - } - } - - current = current.original; - } - - // Cache the most recently requested value. - lastSourceMapRangeNode = node; - lastSourceMapRange = range; - return range || node; + return node.sourceMapRange || node; } /** @@ -325,10 +257,6 @@ namespace ts { */ function setSourceMapRange(node: T, range: TextRange) { beforeSetAnnotation(node); - - // Cache the most recently requested value. - lastSourceMapRangeNode = node; - lastSourceMapRange = range; node.sourceMapRange = range; return node; } @@ -394,30 +322,7 @@ namespace ts { * @param node The node. */ function getCommentRange(node: Node) { - // As a performance optimization, use the cached value of the most recent node. - // This helps for cases where this function is called repeatedly for the same node. - if (lastCommentMapRangeNode === node) { - return lastCommentMapRange || node; - } - - // Get the custom comment range for a node or from one of its original nodes. - let range: TextRange; - let current = node; - while (current) { - if (current.transformId === transformId) { - range = current.commentRange; - if (range !== undefined) { - break; - } - } - - current = current.original; - } - - // Cache the most recently requested value. - lastCommentMapRangeNode = node; - lastCommentMapRange = range; - return range || node; + return node.commentRange || node; } /** @@ -425,10 +330,6 @@ namespace ts { */ function setCommentRange(node: T, range: TextRange) { beforeSetAnnotation(node); - - // Cache the most recently requested value. - lastCommentMapRangeNode = node; - lastCommentMapRange = range; node.commentRange = range; return node; } diff --git a/src/compiler/transformers/es6.ts b/src/compiler/transformers/es6.ts index 527c3b00572..16d08298f72 100644 --- a/src/compiler/transformers/es6.ts +++ b/src/compiler/transformers/es6.ts @@ -956,6 +956,7 @@ namespace ts { * @param initializer The initializer for the parameter. */ function addDefaultValueAssignmentForInitializer(statements: Statement[], parameter: ParameterDeclaration, name: Identifier, initializer: Expression): void { + initializer = visitNode(initializer, visitor, isExpression); const statement = createIf( createStrictEquality( getSynthesizedClone(name), @@ -966,7 +967,7 @@ namespace ts { createStatement( createAssignment( setNodeEmitFlags(getMutableClone(name), NodeEmitFlags.NoSourceMap), - setNodeEmitFlags(visitNode(initializer, visitor, isExpression), NodeEmitFlags.NoSourceMap | NodeEmitFlags.Merge), + setNodeEmitFlags(initializer, NodeEmitFlags.NoSourceMap | getNodeEmitFlags(initializer)), /*location*/ parameter ) ) @@ -1533,7 +1534,7 @@ namespace ts { // the source map range for the declaration list. const firstDeclaration = firstOrUndefined(declarations); const lastDeclaration = lastOrUndefined(declarations); - setSourceMapRange(node, createRange(firstDeclaration.pos, lastDeclaration.end)); + setSourceMapRange(declarationList, createRange(firstDeclaration.pos, lastDeclaration.end)); } return declarationList; diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 469c2fe8aba..e0ad54eb377 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -2243,10 +2243,10 @@ namespace ts { // While we emit the source map for the node after skipping decorators and modifiers, // we need to emit the comments for the original range. + setOriginalNode(parameter, node); setCommentRange(parameter, node); setSourceMapRange(parameter, moveRangePastModifiers(node)); setNodeEmitFlags(parameter.name, NodeEmitFlags.NoTrailingSourceMap); - setOriginalNode(parameter, node); return parameter; } @@ -2564,6 +2564,8 @@ namespace ts { ] ); + setOriginalNode(statement, /*original*/ node); + // Adjust the source map emit to match the old emitter. if (node.kind === SyntaxKind.EnumDeclaration) { setSourceMapRange(statement.declarationList, node); @@ -2592,7 +2594,6 @@ namespace ts { // setCommentRange(statement, node); setNodeEmitFlags(statement, NodeEmitFlags.NoTrailingComments); - setOriginalNode(statement, /*original*/ node); statements.push(statement); } @@ -2748,7 +2749,7 @@ namespace ts { } function disableCommentsRecursive(node: Node) { - setNodeEmitFlags(node, NodeEmitFlags.NoComments | NodeEmitFlags.Merge); + setNodeEmitFlags(node, NodeEmitFlags.NoComments | getNodeEmitFlags(node)); forEachChild(node, disableCommentsRecursive); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a7c21d4b70e..21b89707460 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3002,7 +3002,6 @@ namespace ts { ExportName = 1 << 17, // Ensure an export prefix is added for an identifier that points to an exported declaration with a local name (see SymbolFlags.ExportHasLocal). LocalName = 1 << 18, // Ensure an export prefix is not added for an identifier that points to an exported declaration. Indented = 1 << 19, // Adds an explicit extra indentation level for class and function bodies when printing (used to match old emitter). - Merge = 1 << 20, // When getting emit options, merge with existing emit options. // SourceMap Specialization. // TODO(rbuckton): These should be removed once source maps are aligned with the old diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 856571d221b..a7af4e6a1e4 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -1044,7 +1044,7 @@ namespace ts { } if (updated !== node) { - updated.original = node; + updateNode(updated, node); } // performance.measure(measureName, markName);