tsc-ts 0.0.9 → 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +1 -1
  2. package/dist/api/compiler/ast.d.ts +2 -0
  3. package/dist/api/compiler/ast.js +3 -0
  4. package/dist/api/compiler/checker-calls.js +5 -1
  5. package/dist/api/compiler/checker-grammar.js +3 -2
  6. package/dist/api/compiler/checker-inference.js +8 -2
  7. package/dist/api/compiler/checker-members.js +2 -1
  8. package/dist/api/compiler/checker-type-factory.js +8 -2
  9. package/dist/api/compiler/checker.d.ts +11 -0
  10. package/dist/api/compiler/checker.js +40 -0
  11. package/dist/api/compiler/compile-program.d.ts +26 -2
  12. package/dist/api/compiler/compile-program.js +100 -7
  13. package/dist/api/compiler/diagnostics.d.ts +22 -0
  14. package/dist/api/compiler/diagnostics.js +86 -4
  15. package/dist/api/compiler/file-loader.d.ts +11 -1
  16. package/dist/api/compiler/file-loader.js +63 -7
  17. package/dist/api/compiler/parallel-parse.d.ts +3 -2
  18. package/dist/api/compiler/parallel-parse.js +17 -5
  19. package/dist/api/compiler/printer/emit-context.d.ts +2 -0
  20. package/dist/api/compiler/printer/emit-context.js +4 -0
  21. package/dist/api/compiler/printer/printer.d.ts +48 -2
  22. package/dist/api/compiler/printer/printer.js +238 -14
  23. package/dist/api/compiler/program-checker.d.ts +4 -0
  24. package/dist/api/compiler/program-checker.js +4 -0
  25. package/dist/api/compiler/program.d.ts +2 -6
  26. package/dist/api/compiler/program.js +5 -30
  27. package/dist/api/compiler/relations.js +10 -0
  28. package/dist/api/compiler/symbol.d.ts +1 -1
  29. package/dist/api/compiler/symbol.js +8 -10
  30. package/package.json +9 -9
  31. package/src/compiler/ast.ts +3 -0
  32. package/src/compiler/checker-calls.ts +3 -1
  33. package/src/compiler/checker-grammar.ts +3 -2
  34. package/src/compiler/checker-inference.ts +7 -2
  35. package/src/compiler/checker-members.ts +3 -1
  36. package/src/compiler/checker-type-factory.ts +4 -2
  37. package/src/compiler/checker.ts +37 -0
  38. package/src/compiler/compile-program.ts +121 -7
  39. package/src/compiler/diagnostics.ts +84 -3
  40. package/src/compiler/file-loader.ts +58 -6
  41. package/src/compiler/incremental.ts +80 -13
  42. package/src/compiler/parallel-check.ts +129 -44
  43. package/src/compiler/parallel-emit.ts +320 -0
  44. package/src/compiler/parallel-parse.ts +16 -5
  45. package/src/compiler/parse-thread.ts +3 -0
  46. package/src/compiler/printer/emit-context.ts +5 -0
  47. package/src/compiler/printer/printer.ts +231 -16
  48. package/src/compiler/program-checker.ts +4 -0
  49. package/src/compiler/program.ts +5 -25
  50. package/src/compiler/relations.ts +7 -0
  51. package/src/compiler/symbol.ts +15 -10
  52. package/src/compiler/thread-entry.ts +45 -2
  53. package/src/compiler/tsc-build.ts +63 -9
  54. package/src/compiler/tsc-cli.ts +5 -0
  55. package/src/compiler/tsc-compile.ts +278 -3
@@ -197,6 +197,8 @@ class ParseTask {
197
197
  jsxRuntimeImport = undefined;
198
198
  /** The task of the same file name that was loaded instead of this one. */
199
199
  loadedTask = undefined;
200
+ /** Whether an import or a type reference directive adds the file (`ProcessedFiles.addedFiles`). */
201
+ byImport;
200
202
  constructor(normalizedFilePath, libFile, includeReason, isForAutomaticTypeDirective, increaseDepth,
201
203
  /** A JavaScript file found in `node_modules`, loaded only within `maxNodeModuleJsDepth`. */
202
204
  elideOnDepth, packageId) {
@@ -207,6 +209,8 @@ class ParseTask {
207
209
  this.increaseDepth = increaseDepth;
208
210
  this.elideOnDepth = elideOnDepth;
209
211
  this.packageId = packageId;
212
+ const kind = includeReason !== undefined ? includeReason.kind : -1;
213
+ this.byImport = kind === 0 /* FileIncludeKind.Import */ || kind === 2 /* FileIncludeKind.TypeReferenceDirective */;
210
214
  }
211
215
  addSubTask(fileName, libFile, reason, increaseDepth, elideOnDepth, packageId) {
212
216
  (this.subTasks ??= []).push(new ParseTask(normalizePath(fileName), libFile, reason, false, increaseDepth, elideOnDepth, packageId));
@@ -223,12 +227,19 @@ class ParseTask {
223
227
  return trace ? (this.typeResolutionsTrace ??= []) : undefined;
224
228
  }
225
229
  }
230
+ const noData = [];
226
231
  /** The tasks of one path, by file name casing. */
227
232
  class ParseTaskData {
228
233
  tasks = new Map();
229
234
  lowestDepth = Number.MAX_SAFE_INTEGER;
230
235
  startedSubTasks = false;
231
236
  packageId = undefined;
237
+ /** The index of this path's file in the program's files, once collected; -1 for none. */
238
+ index = -1;
239
+ /** For a deduplicated package's path, the tasks of the copy kept (`collect`). */
240
+ keptCopy = undefined;
241
+ /** The paths the file's imports and type reference directives add, once collected. */
242
+ added = noData;
232
243
  constructor(task) {
233
244
  this.tasks.set(task.normalizedFilePath, task);
234
245
  }
@@ -340,6 +351,7 @@ export class ProcessedFiles {
340
351
  redirectFilesByPath;
341
352
  projectReferenceMapper;
342
353
  preparedPackageJsons;
354
+ addedFiles;
343
355
  constructor(resolver,
344
356
  /** Libraries first, sorted, then other files in load order. */
345
357
  files, filesByPath, missingFiles, resolvedModules, typeResolutionsInFile, sourceFileMetadata, jsxRuntimeImports, importHelpersImportSpecifiers, libFiles,
@@ -351,7 +363,12 @@ export class ProcessedFiles {
351
363
  * The `package.json` lookups made resolving the files whose resolutions were taken from parse
352
364
  * threads (`preparedPackageJsonLookups`); `undefined` where they may miss some.
353
365
  */
354
- preparedPackageJsons) {
366
+ preparedPackageJsons,
367
+ /**
368
+ * The files each file's imports and type reference directives added to the program, by index into
369
+ * `files`, without the file itself.
370
+ */
371
+ addedFiles) {
355
372
  this.resolver = resolver;
356
373
  this.files = files;
357
374
  this.filesByPath = filesByPath;
@@ -369,6 +386,7 @@ export class ProcessedFiles {
369
386
  this.redirectFilesByPath = redirectFilesByPath;
370
387
  this.projectReferenceMapper = projectReferenceMapper;
371
388
  this.preparedPackageJsons = preparedPackageJsons;
389
+ this.addedFiles = addedFiles;
372
390
  }
373
391
  }
374
392
  /** The files of `processed` with `file` in place of the file at its path, for `Program.updateFile`. */
@@ -377,7 +395,9 @@ export function withReplacedFile(processed, file) {
377
395
  files[files.findIndex((f) => f.path === file.path)] = file;
378
396
  const filesByPath = new Map(processed.filesByPath);
379
397
  filesByPath.set(file.path, file);
380
- return new ProcessedFiles(processed.resolver, files, filesByPath, processed.missingFiles, processed.resolvedModules, processed.typeResolutionsInFile, processed.sourceFileMetadata, processed.jsxRuntimeImports, processed.importHelpersImportSpecifiers, processed.libFiles, processed.sourceFilesFoundSearchingNodeModules, processed.includeProcessor.copy(file.path), processed.outputFileToProjectReferenceSource, processed.redirectTargets, processed.redirectFilesByPath, processed.projectReferenceMapper, processed.preparedPackageJsons);
398
+ return new ProcessedFiles(processed.resolver, files, filesByPath, processed.missingFiles, processed.resolvedModules, processed.typeResolutionsInFile, processed.sourceFileMetadata, processed.jsxRuntimeImports, processed.importHelpersImportSpecifiers, processed.libFiles, processed.sourceFilesFoundSearchingNodeModules, processed.includeProcessor.copy(file.path), processed.outputFileToProjectReferenceSource, processed.redirectTargets, processed.redirectFilesByPath, processed.projectReferenceMapper, processed.preparedPackageJsons,
399
+ // The file has the same references (`canReplaceFile`), and keeps its index.
400
+ processed.addedFiles);
381
401
  }
382
402
  /** Whether `file` imports the `importHelpers` module (tslib) under `options`. */
383
403
  export function needsImportHelpersImportSpecifier(file, options) {
@@ -1154,9 +1174,16 @@ export class FileLoader {
1154
1174
  const packageIdToSourceFile = new Map();
1155
1175
  const checkCasing = this.options.forceConsistentCasingInFileNames !== false;
1156
1176
  const seen = new Map();
1157
- const collectFiles = (tasks) => {
1177
+ // The paths each file's imports and type reference directives add (the tasks of each path), for
1178
+ // `ProcessedFiles.addedFiles`: recorded while collecting visits them, as their files are only known
1179
+ // once every file is collected.
1180
+ const fileData = [];
1181
+ const libData = new Map();
1182
+ const packageIdToData = new Map();
1183
+ const collectFiles = (tasks, added) => {
1158
1184
  for (let task of tasks) {
1159
1185
  const includeReason = task.includeReason;
1186
+ const byImport = task.byImport;
1160
1187
  // Automatic type directive tasks are an implementation detail, not a reason.
1161
1188
  if (task.redirectedParseTask === undefined && !task.isForAutomaticTypeDirective) {
1162
1189
  if (task.loadedTask !== undefined)
@@ -1165,6 +1192,8 @@ export class FileLoader {
1165
1192
  addIncludeReason(includeProcessor, task, includeReason);
1166
1193
  }
1167
1194
  const data = this.taskDataByPath.get(task.path);
1195
+ if (added !== undefined && data !== undefined && byImport)
1196
+ added.push(data);
1168
1197
  if (!task.loaded || data === undefined)
1169
1198
  continue;
1170
1199
  const checkedName = seen.get(data);
@@ -1206,15 +1235,19 @@ export class FileLoader {
1206
1235
  targets.push(task.normalizedFilePath);
1207
1236
  redirectFilesByPath.set(task.path, new RedirectFile(files.length + redirectFilesByPath.size, task.normalizedFilePath, task.path, packageIdFile.path));
1208
1237
  filesByPath.set(task.path, packageIdFile);
1238
+ data.keptCopy = packageIdToData.get(key);
1209
1239
  if (data.lowestDepth > 0)
1210
1240
  sourceFilesFoundSearchingNodeModules.add(task.path);
1211
1241
  continue;
1212
1242
  }
1213
- if (file !== undefined)
1243
+ if (file !== undefined) {
1214
1244
  packageIdToSourceFile.set(key, file);
1245
+ packageIdToData.set(key, data);
1246
+ }
1215
1247
  }
1248
+ let own = undefined;
1216
1249
  if (task.subTasks !== undefined && task.subTasks.length > 0)
1217
- collectFiles(task.subTasks);
1250
+ collectFiles(task.subTasks, (own = []));
1218
1251
  const redirected = task.redirectedParseTask;
1219
1252
  if (redirected !== undefined) {
1220
1253
  outputFileToProjectReferenceSource.set(redirected.path, task.normalizedFilePath);
@@ -1235,11 +1268,15 @@ export class FileLoader {
1235
1268
  }
1236
1269
  if (task.libFile !== undefined) {
1237
1270
  libFiles.push(file);
1271
+ libData.set(file, data);
1238
1272
  libFilesByPath.set(path, task.libFile);
1239
1273
  }
1240
1274
  else {
1241
1275
  files.push(file);
1276
+ fileData.push(data);
1242
1277
  }
1278
+ if (own !== undefined)
1279
+ data.added = own;
1243
1280
  filesByPath.set(path, file);
1244
1281
  resolvedModules.set(path, task.resolutionsInFile);
1245
1282
  typeResolutionsInFile.set(path, task.typeResolutionsInFile);
@@ -1253,7 +1290,7 @@ export class FileLoader {
1253
1290
  sourceFilesFoundSearchingNodeModules.add(path);
1254
1291
  }
1255
1292
  };
1256
- collectFiles(this.rootTasks);
1293
+ collectFiles(this.rootTasks, undefined);
1257
1294
  const priorities = new Map();
1258
1295
  for (const file of libFiles)
1259
1296
  priorities.set(file, this.libFilePriority(file));
@@ -1261,6 +1298,25 @@ export class FileLoader {
1261
1298
  const allFiles = [...libFiles, ...files];
1262
1299
  for (const redirect of redirectFilesByPath.values())
1263
1300
  redirect.index += libFiles.length;
1301
+ // The files a file adds, without reading its resolutions again or looking up their paths.
1302
+ const dataOfFiles = [];
1303
+ for (const file of libFiles)
1304
+ dataOfFiles.push(libData.get(file));
1305
+ for (const data of fileData)
1306
+ dataOfFiles.push(data);
1307
+ for (let i = 0; i < dataOfFiles.length; i++)
1308
+ dataOfFiles[i].index = i;
1309
+ const addedFiles = [];
1310
+ for (let i = 0; i < dataOfFiles.length; i++) {
1311
+ const added = [];
1312
+ for (const data of dataOfFiles[i].added) {
1313
+ const kept = data.keptCopy;
1314
+ const k = kept !== undefined ? kept.index : data.index;
1315
+ if (k >= 0 && k !== i)
1316
+ added.push(k);
1317
+ }
1318
+ addedFiles.push(added);
1319
+ }
1264
1320
  const keys = [...this.libResolutions.keys()].sort();
1265
1321
  for (const key of keys) {
1266
1322
  const resolution = this.libResolutions.get(key);
@@ -1272,7 +1328,7 @@ export class FileLoader {
1272
1328
  for (const trace of resolution.trace)
1273
1329
  host.trace(trace);
1274
1330
  }
1275
- return new ProcessedFiles(this.resolver, allFiles, filesByPath, missingFiles, resolvedModules, typeResolutionsInFile, sourceFileMetadata, jsxRuntimeImports, importHelpersImportSpecifiers, libFilesByPath, sourceFilesFoundSearchingNodeModules, includeProcessor, outputFileToProjectReferenceSource, redirectTargets, redirectFilesByPath, this.mapper, this.tookPreparedResolutions ? preparedPackageJsonLookups() : noPackageJsonLookups);
1331
+ return new ProcessedFiles(this.resolver, allFiles, filesByPath, missingFiles, resolvedModules, typeResolutionsInFile, sourceFileMetadata, jsxRuntimeImports, importHelpersImportSpecifiers, libFilesByPath, sourceFilesFoundSearchingNodeModules, includeProcessor, outputFileToProjectReferenceSource, redirectTargets, redirectFilesByPath, this.mapper, this.tookPreparedResolutions ? preparedPackageJsonLookups() : noPackageJsonLookups, addedFiles);
1276
1332
  }
1277
1333
  }
1278
1334
  const noPackageJsonLookups = [];
@@ -128,7 +128,7 @@ export declare function fileSize(fileName: string): number;
128
128
  * Then, for the same reason, large files, one per chunk: root files (TypeScript's 3 MB `checker.ts`,
129
129
  * which in a chunk of root files kept one thread busy after the others were done) and the files the
130
130
  * parse threads found (`csstype`'s 0.9 MB of declarations, found through React's). The other files go
131
- * out in program order, in chunks of up to `maxChunk`.
131
+ * out in program order, in chunks of up to `maxChunk` files and about `maxChunkBytes` of text.
132
132
  */
133
133
  export declare class ParseQueue {
134
134
  private readonly libraries;
@@ -148,7 +148,8 @@ export declare class ParseQueue {
148
148
  left(): number;
149
149
  /**
150
150
  * The next chunk for one of `threads` parse threads, or `undefined` when nothing is left. With
151
- * `full`, other files only go out `maxChunk` at a time, and stay queued until there are as many.
151
+ * `full`, other files only go out in full chunks, `maxChunk` files or `maxChunkBytes` of text, and stay
152
+ * queued until there are as many.
152
153
  */
153
154
  next(threads: number, full?: boolean): LoadMessage | undefined;
154
155
  }
@@ -187,6 +187,12 @@ export function fileSize(fileName) {
187
187
  const maxChunk = 16;
188
188
  /** Files from this size (bytes) on take a parse thread 25 ms or more, and go out ahead of others. */
189
189
  const largeFile = 256 * 1024;
190
+ /**
191
+ * The most text (bytes) a chunk of other files holds, about one large file's: a chunk ends with the file
192
+ * that reaches it. Sixteen of tsc-ts's own compiler sources, 50-200 KB each, made one chunk that kept its
193
+ * thread busy for 30-45 ms after the others were done.
194
+ */
195
+ const maxChunkBytes = largeFile;
190
196
  /**
191
197
  * The files to hand out to parse threads, each queued once. Library files go out first, one per
192
198
  * chunk, also those found later through `/// <reference lib>`: a large one (`lib.dom.d.ts`) takes a
@@ -194,7 +200,7 @@ const largeFile = 256 * 1024;
194
200
  * Then, for the same reason, large files, one per chunk: root files (TypeScript's 3 MB `checker.ts`,
195
201
  * which in a chunk of root files kept one thread busy after the others were done) and the files the
196
202
  * parse threads found (`csstype`'s 0.9 MB of declarations, found through React's). The other files go
197
- * out in program order, in chunks of up to `maxChunk`.
203
+ * out in program order, in chunks of up to `maxChunk` files and about `maxChunkBytes` of text.
198
204
  */
199
205
  export class ParseQueue {
200
206
  libraries = new LoadJobs();
@@ -238,7 +244,8 @@ export class ParseQueue {
238
244
  }
239
245
  /**
240
246
  * The next chunk for one of `threads` parse threads, or `undefined` when nothing is left. With
241
- * `full`, other files only go out `maxChunk` at a time, and stay queued until there are as many.
247
+ * `full`, other files only go out in full chunks, `maxChunk` files or `maxChunkBytes` of text, and stay
248
+ * queued until there are as many.
242
249
  */
243
250
  next(threads, full = false) {
244
251
  const libraries = this.libraries;
@@ -263,11 +270,16 @@ export class ParseQueue {
263
270
  }
264
271
  const queue = this.others;
265
272
  const left = queue.names.length - this.head;
266
- if (left <= 0 || (full && left < maxChunk))
273
+ if (left <= 0)
267
274
  return undefined;
268
- const size = full ? maxChunk : Math.min(maxChunk, Math.max(1, Math.floor(left / threads)));
275
+ const most = full ? maxChunk : Math.min(maxChunk, Math.max(1, Math.floor(left / threads)));
269
276
  const start = this.head;
270
- const end = start + size;
277
+ let end = start;
278
+ let bytes = 0;
279
+ while (end < queue.names.length && end - start < most && bytes < maxChunkBytes)
280
+ bytes += queue.sizes[end++];
281
+ if (full && end - start < maxChunk && bytes < maxChunkBytes)
282
+ return undefined;
271
283
  this.head = end;
272
284
  return {
273
285
  stop: false,
@@ -91,6 +91,8 @@ export declare class EmitContext extends NodeFactory {
91
91
  getAutoGenerateInfo(node: Node): AutoGenerateInfo | undefined;
92
92
  /** The node a generated name is based on, following clones of generated names. */
93
93
  getNodeForGeneratedName(name: Node): Node;
94
+ /** Whether `node` has emit data: flags, ranges, helpers or synthesized comments. */
95
+ hasEmitNode(node: Node): boolean;
94
96
  getEmitFlags(node: Node): EmitFlags;
95
97
  setEmitFlags(node: Node, flags: EmitFlags): Node;
96
98
  addEmitFlags(node: Node, flags: EmitFlags): Node;
@@ -228,6 +228,10 @@ export class EmitContext extends NodeFactory {
228
228
  return node;
229
229
  }
230
230
  // Emit data
231
+ /** Whether `node` has emit data: flags, ranges, helpers or synthesized comments. */
232
+ hasEmitNode(node) {
233
+ return this.lookup(node) !== undefined;
234
+ }
231
235
  getEmitFlags(node) {
232
236
  const emitNode = this.lookup(node);
233
237
  return emitNode === undefined ? 0 /* EmitFlags.None */ : emitNode.emitFlags;
@@ -101,6 +101,13 @@ export declare class Printer extends NameGeneratorHost {
101
101
  currentSourceFile: SourceFile | undefined;
102
102
  private sourceText;
103
103
  private lineStarts;
104
+ /**
105
+ * The line of the last `lineOf` lookup, `lookupLine`, and the positions it spans, `[lookupLineStart, lookupLineEnd)`,
106
+ * with `lookupLineEnd` -1 after the last line: printing reads positions mostly in order, so most lookups fall on that line.
107
+ */
108
+ private lookupLine;
109
+ private lookupLineStart;
110
+ private lookupLineEnd;
104
111
  private writer;
105
112
  private ownWriter;
106
113
  private uniqueHelperNames;
@@ -114,8 +121,25 @@ export declare class Printer extends NameGeneratorHost {
114
121
  private commentsDisabled;
115
122
  /** Emitting the `extends` clause of a conditional or infer type. */
116
123
  private inExtends;
117
- /** Saved comment state: emit flags, comment pos, comment end, container pos, container end, declaration list end. */
118
- private readonly commentStack;
124
+ /**
125
+ * Saved comment state, 32-bit values: emit flags, comment pos, comment end, container pos, container end,
126
+ * declaration list end.
127
+ * Flags are `commentFreeNode` for a node that `emitCommentsBeforeNode` handled in a comment-free range.
128
+ */
129
+ private commentStack;
130
+ /** The used length of `commentStack`: entries are written in place and kept for reuse once popped. */
131
+ private commentDepth;
132
+ /** Start positions of `//` and `/*` in `sourceText`, ascending; made on first use for each file. */
133
+ private commentStarts;
134
+ /**
135
+ * A range of `sourceText`, `[freeStart, freeEnd)`, where no comment starts and the last character is not trivia,
136
+ * so no comment is found from any position in it; -1 when there is none. `freeOwner` is the node it was made for.
137
+ */
138
+ private freeStart;
139
+ private freeEnd;
140
+ /** Whether no trailing comment follows `freeEnd`. */
141
+ private freeEndTrailingNone;
142
+ private freeOwner;
119
143
  /** Saved source map state: emit flags, pos, end, has token range. */
120
144
  private readonly sourceMapStack;
121
145
  /** The token position after `enterToken` skipped trivia. */
@@ -143,6 +167,13 @@ export declare class Printer extends NameGeneratorHost {
143
167
  private getLiteralTextOfNode;
144
168
  /** The text of an identifier, private identifier, literal or JSX namespaced name as printed. */
145
169
  getTextOfNode(node: Node): string;
170
+ /**
171
+ * Whether the source text of an identifier or private identifier of the current file, from the end of its leading
172
+ * trivia to its end, is its text: the text ends the node, and the character before it is not part of the token, as
173
+ * it would be in an identifier written with escapes. Nodes from JSDoc may span other text, so they are left to the
174
+ * general path.
175
+ */
176
+ private textIsSourceText;
146
177
  private isInCurrentSourceFile;
147
178
  private write1;
148
179
  private space;
@@ -155,6 +186,8 @@ export declare class Printer extends NameGeneratorHost {
155
186
  private writeLineSeparatorsAndIndentBefore;
156
187
  private writeLineSeparatorsAfter;
157
188
  private positionsAreOnSameLine;
189
+ /** The zero-based line of `pos` (-1 before the first line), which becomes the line of the last lookup. */
190
+ private lineOf;
158
191
  private rangeStart;
159
192
  private rangeIsOnSingleLine;
160
193
  private rangeEndIsOnSameLineAsRangeStart;
@@ -363,7 +396,20 @@ export declare class Printer extends NameGeneratorHost {
363
396
  private emitListItems;
364
397
  private emitAnyNode;
365
398
  private emitCommentsBeforeNode;
399
+ /** Saves the comment state of a node: its emit flags (or `commentFreeNode`), comment range and the containers. */
400
+ private pushCommentState;
366
401
  private emitCommentsAfterNode;
402
+ /**
403
+ * Whether `node` has no emit data and lies in a range of the source text where no comment is found, so that its
404
+ * comments need not be looked for. Outside such a range, a node whose own range is one starts it (`freeOwner`).
405
+ */
406
+ private inCommentFreeRange;
407
+ private endCommentFreeRange;
408
+ /** Whether the comment-free range shows that no trailing comment follows `pos`. */
409
+ private noCommentsAfter;
410
+ /** Makes `[pos, end)` the comment-free range if no comment starts in it and its last character is not trivia. */
411
+ private startCommentFreeRange;
412
+ private commentStartsOfFile;
367
413
  /** Emits comments before a token; returns whether `emitCommentsAfterToken` applies, with the token's position in `tokenPos`. */
368
414
  private emitCommentsBeforeToken;
369
415
  private emitCommentsAfterToken;