Skip to content

Commit 3ef9ab4

Browse files
committed
Adjusts source maps and comment emit for decorators
1 parent 719705f commit 3ef9ab4

13 files changed

Lines changed: 377 additions & 211 deletions

src/compiler/binder.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2154,12 +2154,11 @@ namespace ts {
21542154
transformFlags = TransformFlags.AssertES6;
21552155

21562156
// A MethodDeclaration is TypeScript syntax if it is either async, abstract, overloaded,
2157-
// generic, or has both a computed property name and a decorator.
2157+
// generic, or has a decorator.
21582158
if ((<MethodDeclaration>node).body === undefined
21592159
|| (<MethodDeclaration>node).typeParameters !== undefined
21602160
|| hasModifier(node, ModifierFlags.Async | ModifierFlags.Abstract)
2161-
|| (subtreeFlags & TransformFlags.ContainsDecorators
2162-
&& subtreeFlags & TransformFlags.ContainsComputedPropertyName)) {
2161+
|| subtreeFlags & TransformFlags.ContainsDecorators) {
21632162
transformFlags |= TransformFlags.AssertTypeScript;
21642163
}
21652164

@@ -2171,11 +2170,10 @@ namespace ts {
21712170
excludeFlags = TransformFlags.MethodOrAccessorExcludes;
21722171

21732172
// A GetAccessor or SetAccessor is TypeScript syntax if it is either abstract,
2174-
// or has both a computed property name and a decorator.
2173+
// or has a decorator.
21752174
if ((<AccessorDeclaration>node).body === undefined
21762175
|| hasModifier(node, ModifierFlags.Abstract)
2177-
|| (subtreeFlags & TransformFlags.ContainsDecorators
2178-
&& subtreeFlags & TransformFlags.ContainsComputedPropertyName)) {
2176+
|| subtreeFlags & TransformFlags.ContainsDecorators) {
21792177
transformFlags = TransformFlags.AssertTypeScript;
21802178
}
21812179

@@ -2269,7 +2267,8 @@ namespace ts {
22692267
}
22702268

22712269
// If the parameter's name is 'this', then it is TypeScript syntax.
2272-
if (node.name && (node.name as Identifier).originalKeywordKind === SyntaxKind.ThisKeyword) {
2270+
if (subtreeFlags & TransformFlags.ContainsDecorators
2271+
|| (node.name && isIdentifier(node.name) && (node.name as Identifier).originalKeywordKind === SyntaxKind.ThisKeyword)) {
22732272
transformFlags |= TransformFlags.AssertTypeScript;
22742273
}
22752274

src/compiler/comments.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ namespace ts {
55
export interface CommentWriter {
66
reset(): void;
77
setSourceFile(sourceFile: SourceFile): void;
8-
getLeadingComments(range: Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean): CommentRange[];
8+
getLeadingComments(range: Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean, getCustomCommentRangeForNodeCallback?: (node: Node) => TextRange): CommentRange[];
99
getLeadingComments(range: TextRange): CommentRange[];
1010
getLeadingCommentsOfPosition(pos: number): CommentRange[];
11-
getTrailingComments(range: Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean): CommentRange[];
11+
getTrailingComments(range: Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean, getCustomCommentRangeForNodeCallback?: (node: Node) => TextRange): CommentRange[];
1212
getTrailingComments(range: TextRange): CommentRange[];
1313
getTrailingCommentsOfPosition(pos: number): CommentRange[];
1414
emitLeadingComments(range: TextRange, comments: CommentRange[]): void;
@@ -43,9 +43,9 @@ namespace ts {
4343
return {
4444
reset,
4545
setSourceFile,
46-
getLeadingComments(range: TextRange, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean): CommentRange[] { return undefined; },
46+
getLeadingComments(range: TextRange, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean, getCustomCommentRangeForNodeCallback?: (node: Node) => TextRange): CommentRange[] { return undefined; },
4747
getLeadingCommentsOfPosition(pos: number): CommentRange[] { return undefined; },
48-
getTrailingComments(range: TextRange, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean): CommentRange[] { return undefined; },
48+
getTrailingComments(range: TextRange, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean, getCustomCommentRangeForNodeCallback?: (node: Node) => TextRange): CommentRange[] { return undefined; },
4949
getTrailingCommentsOfPosition(pos: number): CommentRange[] { return undefined; },
5050
emitLeadingComments(range: TextRange, comments: CommentRange[]): void { },
5151
emitTrailingComments(range: TextRange, comments: CommentRange[]): void { },
@@ -77,9 +77,9 @@ namespace ts {
7777
emitTrailingDetachedComments
7878
};
7979

80-
function getLeadingComments(range: Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean): CommentRange[];
80+
function getLeadingComments(range: Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean, getCustomCommentRangeForNodeCallback?: (node: Node) => TextRange): CommentRange[];
8181
function getLeadingComments(range: TextRange): CommentRange[];
82-
function getLeadingComments(range: TextRange | Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean) {
82+
function getLeadingComments(range: TextRange | Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean, getCustomCommentRangeForNodeCallback?: (node: Node) => TextRange) {
8383
if (shouldSkipCommentsForNodeCallback && shouldSkipCommentsForNodeCallback(<Node>range)) {
8484
// If the node will not be emitted in JS, remove all the comments (normal,
8585
// pinned and `///`) associated with the node, unless it is a triple slash
@@ -100,6 +100,10 @@ namespace ts {
100100
return undefined;
101101
}
102102

103+
if (getCustomCommentRangeForNodeCallback) {
104+
range = getCustomCommentRangeForNodeCallback(<Node>range) || range;
105+
}
106+
103107
return getLeadingCommentsOfPosition(range.pos);
104108
}
105109

@@ -119,13 +123,17 @@ namespace ts {
119123
return false;
120124
}
121125

122-
function getTrailingComments(range: Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean): CommentRange[];
126+
function getTrailingComments(range: Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean, getCustomCommentRangeForNodeCallback?: (node: Node) => TextRange): CommentRange[];
123127
function getTrailingComments(range: TextRange): CommentRange[];
124-
function getTrailingComments(range: TextRange | Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean) {
128+
function getTrailingComments(range: TextRange | Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean, getCustomCommentRangeForNodeCallback?: (node: Node) => TextRange) {
125129
if (shouldSkipCommentsForNodeCallback && shouldSkipCommentsForNodeCallback(<Node>range)) {
126130
return undefined;
127131
}
128132

133+
if (getCustomCommentRangeForNodeCallback) {
134+
range = getCustomCommentRangeForNodeCallback(<Node>range) || range;
135+
}
136+
129137
return getTrailingCommentsOfPosition(range.end);
130138
}
131139

src/compiler/factory.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -867,13 +867,14 @@ namespace ts {
867867
);
868868
}
869869

870-
export function createParamHelper(expression: Expression, parameterOffset: number) {
870+
export function createParamHelper(expression: Expression, parameterOffset: number, location?: TextRange) {
871871
return createCall(
872872
createIdentifier("__param"),
873873
[
874874
createLiteral(parameterOffset),
875875
expression
876-
]
876+
],
877+
location
877878
);
878879
}
879880

@@ -887,7 +888,7 @@ namespace ts {
887888
);
888889
}
889890

890-
export function createDecorateHelper(decoratorExpressions: Expression[], target: Expression, memberName?: Expression, descriptor?: Expression) {
891+
export function createDecorateHelper(decoratorExpressions: Expression[], target: Expression, memberName?: Expression, descriptor?: Expression, location?: TextRange) {
891892
const argumentsArray: Expression[] = [];
892893
argumentsArray.push(createArrayLiteral(decoratorExpressions, /*location*/ undefined, /*multiLine*/ true));
893894
argumentsArray.push(target);
@@ -898,7 +899,7 @@ namespace ts {
898899
}
899900
}
900901

901-
return createCall(createIdentifier("__decorate"), argumentsArray);
902+
return createCall(createIdentifier("__decorate"), argumentsArray, location);
902903
}
903904

904905
export function createAwaiterHelper(hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression, body: Block) {
@@ -947,6 +948,7 @@ namespace ts {
947948

948949
export interface PropertyDescriptorExtendedOption {
949950
location?: TextRange;
951+
original?: Node;
950952
emitFlags?: NodeEmitFlags;
951953
newLine?: boolean;
952954
}
@@ -986,11 +988,13 @@ namespace ts {
986988
if (value !== undefined) {
987989
let options: PropertyDescriptorExtendedOption;
988990
let location: TextRange;
991+
let original: Node;
989992
let emitFlags: NodeEmitFlags;
990993
if (descriptorExtendedOptions !== undefined) {
991994
options = getProperty(descriptorExtendedOptions, name);
992995
if (options !== undefined) {
993996
location = options.location;
997+
original = options.original;
994998
emitFlags = options.emitFlags;
995999
if (options.newLine !== undefined) {
9961000
preferNewLine = options.newLine;
@@ -1009,6 +1013,10 @@ namespace ts {
10091013
context.setNodeEmitFlags(property, emitFlags);
10101014
}
10111015

1016+
if (original) {
1017+
property.original = original;
1018+
}
1019+
10121020
if (preferNewLine) {
10131021
startOnNewLine(property);
10141022
}

src/compiler/printer.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ const _super = (function (geti, seti) {
172172
let context: TransformationContext;
173173
let getNodeEmitFlags: (node: Node) => NodeEmitFlags;
174174
let setNodeEmitFlags: (node: Node, flags: NodeEmitFlags) => void;
175+
let getNodeCustomCommentRange: (node: Node) => TextRange;
175176
let isSubstitutionEnabled: (node: Node) => boolean;
176177
let isEmitNotificationEnabled: (node: Node) => boolean;
177178
let onSubstituteNode: (node: Node, isExpression: boolean) => Node;
@@ -232,6 +233,7 @@ const _super = (function (geti, seti) {
232233

233234
getNodeEmitFlags = undefined;
234235
setNodeEmitFlags = undefined;
236+
getNodeCustomCommentRange = undefined;
235237
isSubstitutionEnabled = undefined;
236238
isEmitNotificationEnabled = undefined;
237239
onSubstituteNode = undefined;
@@ -251,6 +253,7 @@ const _super = (function (geti, seti) {
251253
context = _context;
252254
getNodeEmitFlags = context.getNodeEmitFlags;
253255
setNodeEmitFlags = context.setNodeEmitFlags;
256+
getNodeCustomCommentRange = context.getNodeCustomCommentRange;
254257
isSubstitutionEnabled = context.isSubstitutionEnabled;
255258
isEmitNotificationEnabled = context.isEmitNotificationEnabled;
256259
onSubstituteNode = context.onSubstituteNode;
@@ -334,8 +337,8 @@ const _super = (function (geti, seti) {
334337

335338
function emitNodeWithWorker(node: Node, emitWorker: (node: Node) => void) {
336339
if (node) {
337-
const leadingComments = getLeadingComments(node, shouldSkipLeadingCommentsForNode);
338-
const trailingComments = getTrailingComments(node, shouldSkipTrailingCommentsForNode);
340+
const leadingComments = getLeadingComments(node, shouldSkipLeadingCommentsForNode, getNodeCustomCommentRange);
341+
const trailingComments = getTrailingComments(node, shouldSkipTrailingCommentsForNode, getNodeCustomCommentRange);
339342
emitLeadingComments(node, leadingComments);
340343
emitStart(node, shouldSkipLeadingSourceMapForNode, shouldSkipSourceMapForChildren);
341344
emitWorker(node);

src/compiler/transformer.ts

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ namespace ts {
5555
*/
5656
export function transformFiles(resolver: EmitResolver, host: EmitHost, sourceFiles: SourceFile[], transformers: Transformer[]) {
5757
const nodeEmitFlags: NodeEmitFlags[] = [];
58+
const nodeCustomCommentRange: TextRange[] = [];
5859
const lexicalEnvironmentVariableDeclarationsStack: VariableDeclaration[][] = [];
5960
const lexicalEnvironmentFunctionDeclarationsStack: FunctionDeclaration[][] = [];
6061
const enabledSyntaxKindFeatures = new Array<SyntaxKindFeatureFlags>(SyntaxKind.Count);
@@ -72,6 +73,8 @@ namespace ts {
7273
getEmitHost: () => host,
7374
getNodeEmitFlags,
7475
setNodeEmitFlags,
76+
getNodeCustomCommentRange,
77+
setNodeCustomCommentRange,
7578
hoistVariableDeclaration,
7679
hoistFunctionDeclaration,
7780
startLexicalEnvironment,
@@ -156,8 +159,8 @@ namespace ts {
156159
*/
157160
function getNodeEmitFlags(node: Node) {
158161
while (node) {
159-
const nodeId = getNodeId(node);
160-
if (nodeEmitFlags[nodeId] !== undefined) {
162+
const nodeId = node.id;
163+
if (nodeId && nodeEmitFlags[nodeId] !== undefined) {
161164
return nodeEmitFlags[nodeId];
162165
}
163166

@@ -175,6 +178,29 @@ namespace ts {
175178
return node;
176179
}
177180

181+
/**
182+
* Gets a custom text range to use when emitting comments.
183+
*/
184+
function getNodeCustomCommentRange(node: Node) {
185+
while (node) {
186+
const nodeId = node.id;
187+
if (nodeId && nodeCustomCommentRange[nodeId] !== undefined) {
188+
return nodeCustomCommentRange[nodeId];
189+
}
190+
191+
node = node.original;
192+
}
193+
194+
return undefined;
195+
}
196+
197+
/**
198+
* Sets a custom text range to use when emitting comments.
199+
*/
200+
function setNodeCustomCommentRange(node: Node, range: TextRange) {
201+
nodeCustomCommentRange[getNodeId(node)] = range;
202+
}
203+
178204
/**
179205
* Records a hoisted variable declaration for the provided name within a lexical environment.
180206
*/

src/compiler/transformers/es6.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,6 +1137,8 @@ namespace ts {
11371137
/*location*/ member
11381138
);
11391139

1140+
setOriginalNode(statement, member);
1141+
11401142
// The location for the statement is used to emit comments only.
11411143
// No source map should be emitted for this statement to align with the
11421144
// old emitter.
@@ -1203,8 +1205,8 @@ namespace ts {
12031205
/*preferNewLine*/ true,
12041206
/*location*/ undefined,
12051207
/*descriptorLocations*/ {
1206-
get: { location: getAccessor, emitFlags: NodeEmitFlags.NoSourceMap },
1207-
set: { location: setAccessor, emitFlags: NodeEmitFlags.NoSourceMap }
1208+
get: { location: getAccessor, emitFlags: NodeEmitFlags.NoSourceMap, original: getAccessor },
1209+
set: { location: setAccessor, emitFlags: NodeEmitFlags.NoSourceMap, original: getAccessor }
12081210
},
12091211
context
12101212
),

0 commit comments

Comments
 (0)