diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 11985e17de8..6fbc4f13037 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -898,22 +898,23 @@ namespace ts { ); } - function createPropertyDescriptor({ get, set, value, enumerable, configurable, writable }: PropertyDescriptorOptions, preferNewLine?: boolean, location?: TextRange) { + function createPropertyDescriptor({ get, set, value, enumerable, configurable, writable }: PropertyDescriptorOptions, preferNewLine?: boolean, location?: TextRange, descriptorLocations?: PropertyDescriptorLocations) { const properties: ObjectLiteralElement[] = []; - addPropertyAssignment(properties, "get", get, preferNewLine); - addPropertyAssignment(properties, "set", set, preferNewLine); - addPropertyAssignment(properties, "value", value, preferNewLine); - addPropertyAssignment(properties, "enumerable", enumerable, preferNewLine); - addPropertyAssignment(properties, "configurable", configurable, preferNewLine); - addPropertyAssignment(properties, "writable", writable, preferNewLine); - return createObjectLiteral(properties, location); + addPropertyAssignment(properties, "get", get, preferNewLine, descriptorLocations); + addPropertyAssignment(properties, "set", set, preferNewLine, descriptorLocations); + addPropertyAssignment(properties, "value", value, preferNewLine, descriptorLocations); + addPropertyAssignment(properties, "enumerable", enumerable, preferNewLine, descriptorLocations); + addPropertyAssignment(properties, "configurable", configurable, preferNewLine, descriptorLocations); + addPropertyAssignment(properties, "writable", writable, preferNewLine, descriptorLocations); + return createObjectLiteral(properties, location, preferNewLine); } - function addPropertyAssignment(properties: ObjectLiteralElement[], name: string, value: boolean | Expression, preferNewLine: boolean) { + function addPropertyAssignment(properties: ObjectLiteralElement[], name: string, value: boolean | Expression, preferNewLine: boolean, descriptorLocations?: PropertyDescriptorLocations) { if (value !== undefined) { const property = createPropertyAssignment( name, - typeof value === "boolean" ? createLiteral(value) : value + typeof value === "boolean" ? createLiteral(value) : value, + descriptorLocations ? descriptorLocations[name] : undefined ); if (preferNewLine) { @@ -933,7 +934,17 @@ namespace ts { writable?: boolean | Expression; } - export function createObjectDefineProperty(target: Expression, memberName: Expression, descriptor: PropertyDescriptorOptions, preferNewLine?: boolean, location?: TextRange) { + export interface PropertyDescriptorLocations { + [key: string]: TextRange; + get?: TextRange; + set?: TextRange; + value?: TextRange; + enumerable?: TextRange; + configurable?: TextRange; + writable?: TextRange; + } + + export function createObjectDefineProperty(target: Expression, memberName: Expression, descriptor: PropertyDescriptorOptions, preferNewLine?: boolean, location?: TextRange, descriptorLocations?: PropertyDescriptorLocations) { return createCall( createPropertyAccess( createIdentifier("Object"), @@ -942,7 +953,7 @@ namespace ts { [ target, memberName, - createPropertyDescriptor(descriptor, preferNewLine) + createPropertyDescriptor(descriptor, preferNewLine, /*location*/ undefined, descriptorLocations) ], location ); diff --git a/src/compiler/printer.ts b/src/compiler/printer.ts index 438fe445109..ab8c2fdccce 100644 --- a/src/compiler/printer.ts +++ b/src/compiler/printer.ts @@ -295,8 +295,8 @@ const _super = (function (geti, seti) { function emitNodeWithWorker(node: Node, emitWorker: (node: Node) => void) { if (node) { - const leadingComments = getLeadingComments(node, isNotEmittedStatement); - const trailingComments = getTrailingComments(node, isNotEmittedStatement); + const leadingComments = getLeadingComments(node, shouldSkipCommentsForNode); + const trailingComments = getTrailingComments(node, shouldSkipCommentsForNode); emitLeadingComments(node, leadingComments); emitStart(node, shouldIgnoreSourceMapForNode, shouldIgnoreSourceMapForChildren); emitWorker(node); @@ -305,6 +305,11 @@ const _super = (function (geti, seti) { } } + function shouldSkipCommentsForNode(node: Node) { + return isNotEmittedStatement(node) + || (getNodeEmitFlags(node) & NodeEmitFlags.NoComments) !== 0; + } + function shouldIgnoreSourceMapForNode(node: Node) { return isNotEmittedOrPartiallyEmittedNode(node) || (getNodeEmitFlags(node) & NodeEmitFlags.NoSourceMap) !== 0; @@ -2307,7 +2312,8 @@ const _super = (function (geti, seti) { if (format & ListFormat.MultiLine) { return true; } - else if (format & ListFormat.PreserveLines) { + + if (format & ListFormat.PreserveLines) { if (format & ListFormat.PreferNewLine) { return true; } diff --git a/src/compiler/transformers/es6.ts b/src/compiler/transformers/es6.ts index 91f5147f941..aba5b209e61 100644 --- a/src/compiler/transformers/es6.ts +++ b/src/compiler/transformers/es6.ts @@ -1094,20 +1094,27 @@ namespace ts { * @param receiver The receiver for the member. */ function transformAccessorsToExpression(receiver: LeftHandSideExpression, { firstAccessor, getAccessor, setAccessor }: AllAccessorDeclarations): Expression { - return createObjectDefineProperty( - receiver, - createExpressionForPropertyName( - visitNode(firstAccessor.name, visitor, isPropertyName), - /*location*/ firstAccessor.name + return setNodeEmitFlags( + createObjectDefineProperty( + receiver, + createExpressionForPropertyName( + visitNode(firstAccessor.name, visitor, isPropertyName), + /*location*/ firstAccessor.name + ), + /*descriptor*/ { + get: getAccessor && transformFunctionLikeToExpression(getAccessor, /*location*/ getAccessor, /*name*/ undefined), + set: setAccessor && transformFunctionLikeToExpression(setAccessor, /*location*/ setAccessor, /*name*/ undefined), + enumerable: true, + configurable: true + }, + /*preferNewLine*/ true, + /*location*/ firstAccessor, + /*descriptorLocations*/ { + get: getAccessor, + set: setAccessor + } ), - { - get: getAccessor && transformFunctionLikeToExpression(getAccessor, /*location*/ getAccessor, /*name*/ undefined), - set: setAccessor && transformFunctionLikeToExpression(setAccessor, /*location*/ setAccessor, /*name*/ undefined), - enumerable: true, - configurable: true - }, - /*preferNewLine*/ true, - /*location*/ firstAccessor + NodeEmitFlags.NoComments ); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index d9d456273b0..ad304ac8150 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2867,14 +2867,15 @@ namespace ts { EmitAdvancedSuperHelper = 1 << 3, // Emit the advanced _super helper for async methods. UMDDefine = 1 << 4, // This node should be replaced with the UMD define helper. NoLexicalEnvironment = 1 << 5, // A new LexicalEnvironment should *not* be introduced when emitting this node, this is primarily used when printing a SystemJS module. - SingleLine = 1 << 6, // The contents of this node should be emit on a single line. - AdviseOnEmitNode = 1 << 7, // The node printer should invoke the onBeforeEmitNode and onAfterEmitNode callbacks when printing this node. + SingleLine = 1 << 6, // The contents of this node should be emitted on a single line. + AdviseOnEmitNode = 1 << 7, // The printer should invoke the onEmitNode callback when printing this node. NoSubstitution = 1 << 8, // Disables further substitution of an expression. CapturesThis = 1 << 9, // The function captures a lexical `this` NoSourceMap = 1 << 10, // Do not emit a source map location for this node. NoNestedSourceMaps = 1 << 11, // Do not emit source map locations for children of this node. - PrefixExportedLocal = 1 << 12, // Ensure an export prefix is added for an identifier that points to an exported declaration with a local name (see SymbolFlags.ExportHasLocal). - Indented = 1 << 13, // Adds an explicit extra indentation level for class and function bodies when printing (used to match old emitter). + NoComments = 1 << 12, // Do not emit comments for this node. + PrefixExportedLocal = 1 << 13, // Ensure an export prefix is added for an identifier that points to an exported declaration with a local name (see SymbolFlags.ExportHasLocal). + Indented = 1 << 14, // Adds an explicit extra indentation level for class and function bodies when printing (used to match old emitter). } /** Additional context provided to `visitEachChild` */