@@ -60,6 +60,15 @@ namespace ts {
60
60
const lexicalEnvironmentVariableDeclarationsStack : VariableDeclaration [ ] [ ] = [ ] ;
61
61
const lexicalEnvironmentFunctionDeclarationsStack : FunctionDeclaration [ ] [ ] = [ ] ;
62
62
const enabledSyntaxKindFeatures = new Array < SyntaxKindFeatureFlags > ( SyntaxKind . Count ) ;
63
+ let lastNodeEmitFlagsNode : Node ;
64
+ let lastNodeEmitFlags : NodeEmitFlags ;
65
+ let lastSourceMapRangeNode : Node ;
66
+ let lastSourceMapRange : TextRange ;
67
+ let lastTokenSourceMapRangeNode : Node ;
68
+ let lastTokenSourceMapRangeToken : SyntaxKind ;
69
+ let lastTokenSourceMapRange : TextRange ;
70
+ let lastCommentMapRangeNode : Node ;
71
+ let lastCommentMapRange : TextRange ;
63
72
let lexicalEnvironmentStackOffset = 0 ;
64
73
let hoistedVariableDeclarations : VariableDeclaration [ ] ;
65
74
let hoistedFunctionDeclarations : FunctionDeclaration [ ] ;
@@ -174,103 +183,189 @@ namespace ts {
174
183
175
184
/**
176
185
* Gets flags that control emit behavior of a node.
186
+ *
187
+ * If the node does not have its own NodeEmitFlags set, the node emit flags of its
188
+ * original pointer are used.
189
+ *
190
+ * @param node The node.
177
191
*/
178
192
function getNodeEmitFlags ( node : Node ) {
193
+ // As a performance optimization, use the cached value of the most recent node.
194
+ // This helps for cases where this function is called repeatedly for the same node.
195
+ if ( lastNodeEmitFlagsNode === node ) {
196
+ return lastNodeEmitFlags ;
197
+ }
198
+
199
+
200
+ let flags : NodeEmitFlags ;
179
201
while ( node ) {
180
- let flags = nodeEmitFlags [ getNodeId ( node ) ] ;
202
+ let flags = node . id ? nodeEmitFlags [ node . id ] : undefined ;
181
203
if ( flags !== undefined ) {
182
- return flags ;
204
+ break ;
183
205
}
184
206
185
207
node = node . original ;
186
208
}
187
209
188
- return undefined ;
210
+ // Cache the most recently requested value.
211
+ lastNodeEmitFlagsNode = node ;
212
+ lastNodeEmitFlags = flags ;
213
+ return flags ;
189
214
}
190
215
191
216
/**
192
217
* Sets flags that control emit behavior of a node.
218
+ *
219
+ * @param node The node.
220
+ * @param emitFlags The NodeEmitFlags for the node.
193
221
*/
194
- function setNodeEmitFlags < T extends Node > ( node : T , flags : NodeEmitFlags ) {
195
- if ( flags & NodeEmitFlags . Merge ) {
196
- flags = getNodeEmitFlags ( node ) | ( flags & ~ NodeEmitFlags . Merge ) ;
222
+ function setNodeEmitFlags < T extends Node > ( node : T , emitFlags : NodeEmitFlags ) {
223
+ if ( emitFlags & NodeEmitFlags . Merge ) {
224
+ emitFlags = getNodeEmitFlags ( node ) | ( emitFlags & ~ NodeEmitFlags . Merge ) ;
197
225
}
198
226
199
- nodeEmitFlags [ getNodeId ( node ) ] = flags ;
227
+ // Cache the most recently requested value.
228
+ lastNodeEmitFlagsNode = node ;
229
+ lastNodeEmitFlags = emitFlags ;
230
+ nodeEmitFlags [ getNodeId ( node ) ] = emitFlags ;
200
231
return node ;
201
232
}
202
233
203
234
/**
204
235
* Gets a custom text range to use when emitting source maps.
236
+ *
237
+ * If a node does not have its own custom source map text range, the custom source map
238
+ * text range of its original pointer is used.
239
+ *
240
+ * @param node The node.
205
241
*/
206
242
function getSourceMapRange ( node : Node ) {
243
+ // As a performance optimization, use the cached value of the most recent node.
244
+ // This helps for cases where this function is called repeatedly for the same node.
245
+ if ( lastSourceMapRangeNode === node ) {
246
+ return lastSourceMapRange || node ;
247
+ }
248
+
249
+ let range : TextRange ;
207
250
let current = node ;
208
251
while ( current ) {
209
- const sourceMapRange = sourceMapRanges [ getNodeId ( current ) ] ;
210
- if ( sourceMapRange !== undefined ) {
211
- return sourceMapRange ;
252
+ range = current . id ? sourceMapRanges [ current . id ] : undefined ;
253
+ if ( range !== undefined ) {
254
+ break ;
212
255
}
213
256
214
257
current = current . original ;
215
258
}
216
259
217
- return node ;
260
+ // Cache the most recently requested value.
261
+ lastSourceMapRangeNode = node ;
262
+ lastSourceMapRange = range ;
263
+ return range || node ;
218
264
}
219
265
220
266
/**
221
267
* Sets a custom text range to use when emitting source maps.
268
+ *
269
+ * @param node The node.
270
+ * @param range The text range.
222
271
*/
223
272
function setSourceMapRange < T extends Node > ( node : T , range : TextRange ) {
273
+ // Cache the most recently requested value.
274
+ lastSourceMapRangeNode = node ;
275
+ lastSourceMapRange = range ;
224
276
sourceMapRanges [ getNodeId ( node ) ] = range ;
225
277
return node ;
226
278
}
227
279
228
280
/**
229
281
* Gets the TextRange to use for source maps for a token of a node.
282
+ *
283
+ * If a node does not have its own custom source map text range for a token, the custom
284
+ * source map text range for the token of its original pointer is used.
285
+ *
286
+ * @param node The node.
287
+ * @param token The token.
230
288
*/
231
289
function getTokenSourceMapRange ( node : Node , token : SyntaxKind ) {
290
+ // As a performance optimization, use the cached value of the most recent node.
291
+ // This helps for cases where this function is called repeatedly for the same node.
292
+ if ( lastTokenSourceMapRangeNode === node && lastTokenSourceMapRangeToken === token ) {
293
+ return lastSourceMapRange ;
294
+ }
295
+
296
+ let range : TextRange ;
232
297
let current = node ;
233
298
while ( current ) {
234
- const tokenSourceMapRange = sourceMapRanges [ getNodeId ( node ) + "-" + token ] ;
235
- if ( tokenSourceMapRange !== undefined ) {
236
- return tokenSourceMapRange ;
299
+ range = current . id ? sourceMapRanges [ current . id + "-" + token ] : undefined ;
300
+ if ( range !== undefined ) {
301
+ break ;
237
302
}
238
303
239
304
current = current . original ;
240
305
}
241
306
242
- return undefined ;
307
+ // Cache the most recently requested value.
308
+ lastTokenSourceMapRangeNode = node ;
309
+ lastTokenSourceMapRangeToken = token ;
310
+ lastTokenSourceMapRange = range ;
311
+ return range ;
243
312
}
244
313
245
314
/**
246
315
* Sets the TextRange to use for source maps for a token of a node.
316
+ *
317
+ * @param node The node.
318
+ * @param token The token.
319
+ * @param range The text range.
247
320
*/
248
321
function setTokenSourceMapRange < T extends Node > ( node : T , token : SyntaxKind , range : TextRange ) {
322
+ // Cache the most recently requested value.
323
+ lastTokenSourceMapRangeNode = node ;
324
+ lastTokenSourceMapRangeToken = token ;
325
+ lastTokenSourceMapRange = range ;
249
326
sourceMapRanges [ getNodeId ( node ) + "-" + token ] = range ;
250
327
return node ;
251
328
}
252
329
253
330
/**
254
331
* Gets a custom text range to use when emitting comments.
332
+ *
333
+ * If a node does not have its own custom source map text range, the custom source map
334
+ * text range of its original pointer is used.
335
+ *
336
+ * @param node The node.
255
337
*/
256
338
function getCommentRange ( node : Node ) {
339
+ // As a performance optimization, use the cached value of the most recent node.
340
+ // This helps for cases where this function is called repeatedly for the same node.
341
+ if ( lastCommentMapRangeNode === node ) {
342
+ return lastCommentMapRange || node ;
343
+ }
344
+
345
+ let range : TextRange ;
257
346
let current = node ;
258
347
while ( current ) {
259
- const commentRange = commentRanges [ getNodeId ( current ) ] ;
260
- if ( commentRange !== undefined ) {
261
- return commentRange ;
348
+ range = current . id ? commentRanges [ current . id ] : undefined ;
349
+ if ( range !== undefined ) {
350
+ break ;
262
351
}
263
352
264
353
current = current . original ;
265
354
}
266
355
267
- return node ;
356
+ // Cache the most recently requested value.
357
+ lastCommentMapRangeNode = node ;
358
+ lastCommentMapRange = range ;
359
+ return range || node ;
268
360
}
269
361
270
362
/**
271
363
* Sets a custom text range to use when emitting comments.
272
364
*/
273
365
function setCommentRange < T extends Node > ( node : T , range : TextRange ) {
366
+ // Cache the most recently requested value.
367
+ lastCommentMapRangeNode = node ;
368
+ lastCommentMapRange = range ;
274
369
commentRanges [ getNodeId ( node ) ] = range ;
275
370
return node ;
276
371
}
0 commit comments