diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index dcc9fc48561..aca4091430f 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -3904,7 +3904,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge write(" = "); emit(value); }); - emitEnd(nodeForSourceMap, /*stopOverridingSpan*/true); + emitEnd(nodeForSourceMap); + sourceMap.stopOverridingSpan(); if (exportChanged) { write(")"); diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index bd9720ba257..3bcb951a932 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -102,6 +102,16 @@ namespace ts { return clone; } + /** + * Gets a clone of a node with a unique node ID. + */ + export function getUniqueClone(node: T): T { + const clone = getSynthesizedClone(node); + clone.id = undefined; + getNodeId(clone); + return clone; + } + // Literals export function createLiteral(value: string, location?: TextRange): StringLiteral; diff --git a/src/compiler/printer.ts b/src/compiler/printer.ts index c14fb3d7811..d522f54a0df 100644 --- a/src/compiler/printer.ts +++ b/src/compiler/printer.ts @@ -298,13 +298,21 @@ const _super = (function (geti, seti) { const leadingComments = getLeadingComments(node, getNotEmittedParent); const trailingComments = getTrailingComments(node, getNotEmittedParent); emitLeadingComments(node, leadingComments); - emitStart(node); + emitStart(node, shouldEmitSourceMap, shouldEmitNestedSourceMap); emitWorker(node); - emitEnd(node); + emitEnd(node, shouldEmitSourceMap, shouldEmitNestedSourceMap); emitTrailingComments(node, trailingComments); } } + function shouldEmitSourceMap(node: Node) { + return (getNodeEmitFlags(node) & NodeEmitFlags.NoSourceMap) === 0; + } + + function shouldEmitNestedSourceMap(node: Node) { + return (getNodeEmitFlags(node) & NodeEmitFlags.NoNestedSourceMaps) === 0; + } + function emitWorker(node: Node): void { const kind = node.kind; switch (kind) { @@ -1151,10 +1159,8 @@ const _super = (function (geti, seti) { } function emitExpressionWithTypeArguments(node: ExpressionWithTypeArguments) { - emitStart(node); emitExpression(node.expression); emitTypeArguments(node, node.typeArguments); - emitEnd(node); } function emitAsExpression(node: AsExpression) { @@ -1601,21 +1607,17 @@ const _super = (function (geti, seti) { } function emitImportClause(node: ImportClause) { - emitStart(node); emit(node.name); if (node.name && node.namedBindings) { write(", "); } emit(node.namedBindings); - emitEnd(node); write(" from "); } function emitNamespaceImport(node: NamespaceImport) { - emitStart(node); write("* as "); emit(node.name); - emitEnd(node); } function emitNamedImports(node: NamedImports) { @@ -1759,12 +1761,10 @@ const _super = (function (geti, seti) { } function emitHeritageClause(node: HeritageClause) { - emitStart(node); write(" "); writeToken(node.token); write(" "); emitList(node, node.types, ListFormat.HeritageClauseTypes); - emitEnd(node); } function emitCatchClause(node: CatchClause) { @@ -2207,9 +2207,9 @@ const _super = (function (geti, seti) { function writeTokenNode(node: Node) { if (node) { - emitStart(node); + emitStart(node, shouldEmitSourceMap, shouldEmitNestedSourceMap); writeTokenText(node.kind); - emitEnd(node); + emitEnd(node, shouldEmitSourceMap, shouldEmitNestedSourceMap); } } diff --git a/src/compiler/sourcemap.ts b/src/compiler/sourcemap.ts index 967fa0c715f..137becb259c 100644 --- a/src/compiler/sourcemap.ts +++ b/src/compiler/sourcemap.ts @@ -6,10 +6,10 @@ namespace ts { getSourceMapData(): SourceMapData; setSourceFile(sourceFile: SourceFile): void; emitPos(pos: number): void; - emitStart(range: TextRange): void; - emitEnd(range: TextRange): void; - /*@deprecated*/ emitEnd(range: TextRange, stopOverridingSpan: boolean): void; + emitStart(range: TextRange, shouldEmit?: (range: TextRange) => boolean, shouldEmitNested?: (range: TextRange) => boolean): void; + emitEnd(range: TextRange, shouldEmit?: (range: TextRange) => boolean, shouldEmitNested?: (range: TextRange) => boolean): void; /*@deprecated*/ changeEmitSourcePos(): void; + /*@deprecated*/ stopOverridingSpan(): void; getText(): string; getSourceMappingURL(): string; initialize(filePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean): void; @@ -34,9 +34,10 @@ namespace ts { getSourceMapData(): SourceMapData { return undefined; }, setSourceFile(sourceFile: SourceFile): void { }, emitStart(range: TextRange): void { }, - emitEnd(range: TextRange, stopOverridingSpan?: boolean): void { }, + emitEnd(range: TextRange, shouldEmit?: Function, shouldEmitNested?: Function): void { }, emitPos(pos: number): void { }, changeEmitSourcePos(): void { }, + stopOverridingSpan(): void { }, getText(): string { return undefined; }, getSourceMappingURL(): string { return undefined; }, initialize(filePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean): void { }, @@ -81,6 +82,7 @@ namespace ts { emitStart, emitEnd, changeEmitSourcePos, + stopOverridingSpan: () => stopOverridingSpan = true, getText, getSourceMappingURL, initialize, @@ -318,21 +320,26 @@ namespace ts { return range.pos !== -1 ? skipTrivia(currentSourceFile.text, rangeHasDecorators ? (range as Node).decorators.end : range.pos) : -1; } - function emitStart(range: TextRange) { - emitPos(getStartPos(range)); + function emitStart(range: TextRange, shouldEmit?: (range: TextRange) => boolean, shouldEmitNested?: (range: TextRange) => boolean) { + if (!shouldEmit || shouldEmit(range)) { + emitPos(getStartPos(range)); + } - if (range.disableSourceMap) { + if (shouldEmitNested && !shouldEmitNested(range)) { disable(); } } - function emitEnd(range: TextRange, stopOverridingEnd?: boolean) { - if (range.disableSourceMap) { + function emitEnd(range: TextRange, shouldEmit?: (range: TextRange) => boolean, shouldEmitNested?: (range: TextRange) => boolean) { + if (shouldEmitNested && !shouldEmitNested(range)) { enable(); } - emitPos(range.end); - stopOverridingSpan = stopOverridingEnd; + if (!shouldEmit || shouldEmit(range)) { + emitPos(range.end); + } + + stopOverridingSpan = false; } function changeEmitSourcePos() { diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index 59dbe0307bc..bd3bbcdfd43 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -13,6 +13,7 @@ namespace ts { * @param visitor An optional visitor to use to visit expressions. */ export function flattenDestructuringAssignment( + context: TransformationContext, node: BinaryExpression, needsValue: boolean, recordTempVariable: (node: Identifier) => void, @@ -44,7 +45,7 @@ namespace ts { location = node.right; } - flattenDestructuring(node, value, location, emitAssignment, emitTempVariableAssignment, visitor); + flattenDestructuring(context, node, value, location, emitAssignment, emitTempVariableAssignment, visitor); if (needsValue) { expressions.push(value); @@ -57,7 +58,7 @@ namespace ts { function emitAssignment(name: Identifier, value: Expression, location: TextRange) { const expression = createAssignment(name, value, location); if (isSimpleExpression(value)) { - expression.disableSourceMap = true; + context.setNodeEmitFlags(expression, NodeEmitFlags.NoNestedSourceMaps); } aggregateTransformFlags(expression); @@ -79,17 +80,21 @@ namespace ts { * @param value The rhs value for the binding pattern. * @param visitor An optional visitor to use to visit expressions. */ - export function flattenParameterDestructuring(node: ParameterDeclaration, value: Expression, visitor?: (node: Node) => VisitResult) { + export function flattenParameterDestructuring( + context: TransformationContext, + node: ParameterDeclaration, + value: Expression, + visitor?: (node: Node) => VisitResult) { const declarations: VariableDeclaration[] = []; - flattenDestructuring(node, value, node, emitAssignment, emitTempVariableAssignment, visitor); + flattenDestructuring(context, node, value, node, emitAssignment, emitTempVariableAssignment, visitor); return declarations; function emitAssignment(name: Identifier, value: Expression, location: TextRange) { const declaration = createVariableDeclaration(name, value, location); if (isSimpleExpression(value)) { - declaration.disableSourceMap = true; + context.setNodeEmitFlags(declaration, NodeEmitFlags.NoNestedSourceMaps); } aggregateTransformFlags(declaration); @@ -110,10 +115,14 @@ namespace ts { * @param value An optional rhs value for the binding pattern. * @param visitor An optional visitor to use to visit expressions. */ - export function flattenVariableDestructuring(node: VariableDeclaration, value?: Expression, visitor?: (node: Node) => VisitResult) { + export function flattenVariableDestructuring( + context: TransformationContext, + node: VariableDeclaration, + value?: Expression, + visitor?: (node: Node) => VisitResult) { const declarations: VariableDeclaration[] = []; - flattenDestructuring(node, value, node, emitAssignment, emitTempVariableAssignment, visitor); + flattenDestructuring(context, node, value, node, emitAssignment, emitTempVariableAssignment, visitor); return declarations; @@ -124,7 +133,7 @@ namespace ts { } if (isSimpleExpression(value)) { - declaration.disableSourceMap = true; + context.setNodeEmitFlags(declaration, NodeEmitFlags.NoNestedSourceMaps); } declaration.original = original; @@ -148,6 +157,7 @@ namespace ts { * @param visitor An optional visitor to use to visit expressions. */ export function flattenVariableDestructuringToExpression( + context: TransformationContext, node: VariableDeclaration, recordTempVariable: (name: Identifier) => void, nameSubstitution?: (name: Identifier) => Expression, @@ -155,7 +165,7 @@ namespace ts { const pendingAssignments: Expression[] = []; - flattenDestructuring(node, /*value*/ undefined, node, emitAssignment, emitTempVariableAssignment); + flattenDestructuring(context, node, /*value*/ undefined, node, emitAssignment, emitTempVariableAssignment); const expression = inlineExpressions(pendingAssignments); aggregateTransformFlags(expression); @@ -176,7 +186,7 @@ namespace ts { function emitPendingAssignment(name: Expression, value: Expression, location: TextRange, original: Node) { const expression = createAssignment(name, value, location); if (isSimpleExpression(value)) { - expression.disableSourceMap = true; + context.setNodeEmitFlags(expression, NodeEmitFlags.NoNestedSourceMaps); } expression.original = original; @@ -186,6 +196,7 @@ namespace ts { } function flattenDestructuring( + context: TransformationContext, root: BindingElement | BinaryExpression, value: Expression, location: TextRange, diff --git a/src/compiler/transformers/es6.ts b/src/compiler/transformers/es6.ts index 4c83312d38b..0ee50a75a35 100644 --- a/src/compiler/transformers/es6.ts +++ b/src/compiler/transformers/es6.ts @@ -522,7 +522,7 @@ namespace ts { createVariableStatement( /*modifiers*/ undefined, createVariableDeclarationList( - flattenParameterDestructuring(parameter, temp, visitor) + flattenParameterDestructuring(context, parameter, temp, visitor) ) ) ); @@ -964,7 +964,7 @@ namespace ts { function visitBinaryExpression(node: BinaryExpression, needsDestructuringValue: boolean): Expression { // If we are here it is because this is a destructuring assignment. Debug.assert(isDestructuringAssignment(node)); - return flattenDestructuringAssignment(node, needsDestructuringValue, hoistVariableDeclaration, visitor); + return flattenDestructuringAssignment(context, node, needsDestructuringValue, hoistVariableDeclaration, visitor); } /** @@ -1090,7 +1090,7 @@ namespace ts { // If we are here it is because the name contains a binding pattern. Debug.assert(isBindingPattern(node.name)); - return flattenVariableDestructuring(node, /*value*/ undefined, visitor); + return flattenVariableDestructuring(context, node, /*value*/ undefined, visitor); } function visitLabeledStatement(node: LabeledStatement) { @@ -1173,6 +1173,7 @@ namespace ts { /*modifiers*/ undefined, createVariableDeclarationList( flattenVariableDestructuring( + context, firstDeclaration, createElementAccess(rhsReference, counter), visitor @@ -1208,6 +1209,7 @@ namespace ts { statements.push( createStatement( flattenDestructuringAssignment( + context, assignment, /*needsValue*/ false, hoistVariableDeclaration, diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 70f2e60e94f..57ec7b969b5 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -330,7 +330,7 @@ namespace ts { const statements: Statement[] = []; if (moduleKind !== ModuleKind.AMD) { if (hasModifier(node, ModifierFlags.Export)) { - addNode(statements, + statements.push( createStatement( createExportAssignment( node.name, @@ -341,7 +341,7 @@ namespace ts { ); } else { - addNode(statements, + statements.push( createVariableStatement( /*modifiers*/ undefined, createVariableDeclarationList([ @@ -350,14 +350,17 @@ namespace ts { createRequireCall(node), /*location*/ node ) - ]) + ], + /*location*/ undefined, + /*flags*/ languageVersion >= ScriptTarget.ES6 ? NodeFlags.Const : NodeFlags.None), + /*location*/ node ) ); } } else { if (hasModifier(node, ModifierFlags.Export)) { - addNode(statements, + statements.push( createStatement( createExportAssignment(node.name, node.name), /*location*/ node @@ -544,6 +547,7 @@ namespace ts { const name = node.name; if (isBindingPattern(name)) { return flattenVariableDestructuringToExpression( + context, node, hoistVariableDeclaration, getModuleMemberName, diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index 57aaff71a60..7f05648df8b 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -577,7 +577,7 @@ namespace ts { } else { // If the variable has a BindingPattern, flatten the variable into multiple assignment expressions. - return flattenVariableDestructuringToExpression(node, hoistVariableDeclaration); + return flattenVariableDestructuringToExpression(context, node, hoistVariableDeclaration); } } @@ -691,7 +691,7 @@ namespace ts { const name = firstDeclaration.name; return isIdentifier(name) ? name - : flattenVariableDestructuringToExpression(firstDeclaration, hoistVariableDeclaration); + : flattenVariableDestructuringToExpression(context, firstDeclaration, hoistVariableDeclaration); } /** @@ -1026,7 +1026,7 @@ namespace ts { } function substituteDestructuring(node: BinaryExpression) { - return flattenDestructuringAssignment(node, /*needsValue*/ true, hoistVariableDeclaration); + return flattenDestructuringAssignment(context, node, /*needsValue*/ true, hoistVariableDeclaration); } function substitutePostfixUnaryExpression(node: PostfixUnaryExpression): Expression { diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 0396dbeddeb..1d25b07d3f3 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -2072,6 +2072,7 @@ namespace ts { const name = node.name; if (isBindingPattern(name)) { return flattenVariableDestructuringToExpression( + context, node, hoistVariableDeclaration, getNamespaceMemberName, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 3ce4c49f0b5..02e289d221f 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -21,7 +21,6 @@ namespace ts { export interface TextRange { pos: number; end: number; - /* @internal */ disableSourceMap?: boolean; // Whether a synthesized text range disables source maps for its contents (used by transforms). } // token > SyntaxKind.Identifer => token is a keyword @@ -2114,7 +2113,7 @@ namespace ts { jsxFlags?: JsxFlags; // flags for knowing what kind of element/attributes we're dealing with resolvedJsxType?: Type; // resolved element attributes type of a JSX openinglike element hasSuperCall?: boolean; // recorded result when we try to find super-call. We only try to find one if this flag is undefined, indicating that we haven't made an attempt. - superCall?: ExpressionStatement; // Cached first super-call found in the constructor. Used in checking whether super is called before this-accessing + superCall?: ExpressionStatement; // Cached first super-call found in the constructor. Used in checking whether super is called before this-accessing } export const enum TypeFlags { @@ -2852,6 +2851,8 @@ namespace ts { EmitCommentsOfNotEmittedParent = 1 << 9, // Emits comments of missing parent nodes. NoSubstitution = 1 << 10, // Disables further substitution of an expression. CapturesThis = 1 << 11, // The function captures a lexical `this` + NoSourceMap = 1 << 12, // Do not emit a source map location for this node. + NoNestedSourceMaps = 1 << 13, // Do not emit source map locations for children of this node. } /** Additional context provided to `visitEachChild` */ diff --git a/tests/baselines/reference/abstractProperty.js b/tests/baselines/reference/abstractProperty.js index 9564be862dc..87b5475111b 100644 --- a/tests/baselines/reference/abstractProperty.js +++ b/tests/baselines/reference/abstractProperty.js @@ -30,12 +30,6 @@ var __extends = (this && this.__extends) || function (d, b) { var B = (function () { function B() { } - Object.defineProperty(B.prototype, "readonlyProp", { - get: function () { }, - set: function (val) { }, - enumerable: true, - configurable: true - }); return B; }()); var C = (function (_super) { diff --git a/tests/baselines/reference/abstractPropertyNegative.js b/tests/baselines/reference/abstractPropertyNegative.js index 55c9aea9411..5fc340c58d0 100644 --- a/tests/baselines/reference/abstractPropertyNegative.js +++ b/tests/baselines/reference/abstractPropertyNegative.js @@ -52,18 +52,6 @@ var __extends = (this && this.__extends) || function (d, b) { var B = (function () { function B() { } - Object.defineProperty(B.prototype, "readonlyProp", { - get: function () { }, - enumerable: true, - configurable: true - }); - Object.defineProperty(B.prototype, "mismatch", { - get: function () { }, - set: function (val) { } // error, not same type - , - enumerable: true, - configurable: true - }); return B; }()); var C = (function (_super) { @@ -97,11 +85,6 @@ var WrongTypePropertyImpl = (function (_super) { var WrongTypeAccessor = (function () { function WrongTypeAccessor() { } - Object.defineProperty(WrongTypeAccessor.prototype, "num", { - get: function () { }, - enumerable: true, - configurable: true - }); return WrongTypeAccessor; }()); var WrongTypeAccessorImpl = (function (_super) { @@ -128,7 +111,6 @@ var AbstractAccessorMismatch = (function () { function AbstractAccessorMismatch() { } Object.defineProperty(AbstractAccessorMismatch.prototype, "p1", { - get: function () { }, set: function (val) { }, enumerable: true, configurable: true @@ -136,7 +118,6 @@ var AbstractAccessorMismatch = (function () { ; Object.defineProperty(AbstractAccessorMismatch.prototype, "p2", { get: function () { return "should work"; }, - set: function (val) { }, enumerable: true, configurable: true });