jsii-rosetta 5.9.16-dev.3 → 5.9.19

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 (40) hide show
  1. package/README.md +14 -0
  2. package/lib/commands/extract.d.ts +6 -0
  3. package/lib/commands/extract.js +16 -3
  4. package/lib/commands/extract.js.map +1 -1
  5. package/lib/commands/infuse.js +1 -1
  6. package/lib/commands/infuse.js.map +1 -1
  7. package/lib/commands/transliterate.d.ts +6 -0
  8. package/lib/commands/transliterate.js +1 -0
  9. package/lib/commands/transliterate.js.map +1 -1
  10. package/lib/languages/python.js +16 -7
  11. package/lib/languages/python.js.map +1 -1
  12. package/lib/logging.d.ts +3 -3
  13. package/lib/logging.js +14 -6
  14. package/lib/logging.js.map +1 -1
  15. package/lib/main.js +15 -0
  16. package/lib/main.js.map +1 -1
  17. package/lib/o-tree.d.ts +20 -6
  18. package/lib/o-tree.js +45 -4
  19. package/lib/o-tree.js.map +1 -1
  20. package/lib/renderer.d.ts +1 -1
  21. package/lib/renderer.js +1 -1
  22. package/lib/renderer.js.map +1 -1
  23. package/lib/rosetta-reader.js +2 -2
  24. package/lib/rosetta-reader.js.map +1 -1
  25. package/lib/rosetta-translator.d.ts +6 -0
  26. package/lib/rosetta-translator.js +3 -5
  27. package/lib/rosetta-translator.js.map +1 -1
  28. package/lib/translate.d.ts +73 -27
  29. package/lib/translate.js +142 -56
  30. package/lib/translate.js.map +1 -1
  31. package/lib/translate_all.d.ts +1 -1
  32. package/lib/translate_all.js +12 -4
  33. package/lib/translate_all.js.map +1 -1
  34. package/lib/translate_all_worker.d.ts +4 -0
  35. package/lib/translate_all_worker.js +22 -1
  36. package/lib/translate_all_worker.js.map +1 -1
  37. package/lib/typescript/ts-compiler.d.ts +9 -2
  38. package/lib/typescript/ts-compiler.js +42 -25
  39. package/lib/typescript/ts-compiler.js.map +1 -1
  40. package/package.json +6 -6
@@ -16,7 +16,7 @@ const tablets_1 = require("./tablets/tablets");
16
16
  * Never include 'translate_all_worker' directly, only do TypeScript type references (so that in
17
17
  * the script we may assume that 'worker_threads' successfully imports).
18
18
  */
19
- async function translateAll(snippets, includeCompilerDiagnostics) {
19
+ async function translateAll(snippets, includeCompilerDiagnostics, batchSize) {
20
20
  // Use about half the advertised cores because hyperthreading doesn't seem to
21
21
  // help that much, or we become I/O-bound at some point. On my machine, using
22
22
  // more than half the cores actually makes it slower.
@@ -25,12 +25,14 @@ async function translateAll(snippets, includeCompilerDiagnostics) {
25
25
  ? parseInt(process.env.JSII_ROSETTA_MAX_WORKER_COUNT)
26
26
  : Math.min(16, Math.max(1, Math.ceil(os.cpus().length / 2)));
27
27
  const snippetArr = Array.from(snippets);
28
- logging.info(`Translating ${snippetArr.length} snippets using ${N} workers`);
28
+ const batchesOf = batchSize ? ` (in batches of ${batchSize})` : '';
29
+ logging.info(`Translating ${snippetArr.length} snippets using ${N} workers${batchesOf}`);
29
30
  const pool = workerpool.pool(path.join(__dirname, 'translate_all_worker.js'), {
30
31
  maxWorkers: N,
31
32
  });
32
33
  try {
33
- const requests = batchSnippets(snippetArr, includeCompilerDiagnostics);
34
+ const shouldBatchCompilation = batchSize != null;
35
+ const requests = batchSnippets(snippetArr, includeCompilerDiagnostics, batchSize, shouldBatchCompilation);
34
36
  const responses = await Promise.all(requests.map((request) => pool.exec('translateBatch', [request])));
35
37
  const diagnostics = new Array();
36
38
  const translatedSnippets = new Array();
@@ -46,12 +48,18 @@ async function translateAll(snippets, includeCompilerDiagnostics) {
46
48
  void pool.terminate();
47
49
  }
48
50
  }
49
- function batchSnippets(snippets, includeCompilerDiagnostics, batchSize = 10) {
51
+ function batchSnippets(snippets, includeCompilerDiagnostics, batchSize = 10, shouldBatchCompilation = false) {
52
+ const logLevel = logging.current();
50
53
  const ret = [];
51
54
  for (let i = 0; i < snippets.length; i += batchSize) {
55
+ // create a unique worker name, purely for logging so can be pseudo random
56
+ const workerId = Math.random().toString(16).slice(2, 6).toUpperCase();
52
57
  ret.push({
58
+ workerName: `Worker#${workerId}`,
53
59
  snippets: snippets.slice(i, i + batchSize),
54
60
  includeCompilerDiagnostics,
61
+ logLevel,
62
+ batchSize: shouldBatchCompilation ? batchSize : undefined,
55
63
  });
56
64
  }
57
65
  return ret;
@@ -1 +1 @@
1
- {"version":3,"file":"translate_all.js","sourceRoot":"","sources":["../src/translate_all.ts"],"names":[],"mappings":";;AAoBA,oCAsCC;AA1DD,8BAA8B;AAC9B,kCAAkC;AAClC,yCAAyC;AAEzC,qCAAqC;AAErC,+CAAsD;AAItD;;;;;;;;;GASG;AACI,KAAK,UAAU,YAAY,CAChC,QAA6B,EAC7B,0BAAmC;IAEnC,6EAA6E;IAC7E,6EAA6E;IAC7E,qDAAqD;IACrD,2FAA2F;IAC3F,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,6BAA6B;QACjD,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC;QACrD,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACxC,OAAO,CAAC,IAAI,CAAC,eAAe,UAAU,CAAC,MAAM,mBAAmB,CAAC,UAAU,CAAC,CAAC;IAE7E,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,yBAAyB,CAAC,EAAE;QAC5E,UAAU,EAAE,CAAC;KACd,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,aAAa,CAAC,UAAU,EAAE,0BAA0B,CAAC,CAAC;QAEvE,MAAM,SAAS,GAA6B,MAAM,OAAO,CAAC,GAAG,CAC3D,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAClE,CAAC;QAEF,MAAM,WAAW,GAAG,IAAI,KAAK,EAAqB,CAAC;QACnD,MAAM,kBAAkB,GAAG,IAAI,KAAK,EAAqB,CAAC;QAE1D,kBAAkB;QAClB,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,WAAW,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;YAC1C,kBAAkB,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,iBAAiB,CAAC,GAAG,CAAC,2BAAiB,CAAC,UAAU,CAAC,CAAC,CAAC;QAC3F,CAAC;QACD,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC;IAC7C,CAAC;YAAS,CAAC;QACT,yBAAyB;QACzB,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;IACxB,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CACpB,QAA6B,EAC7B,0BAAmC,EACnC,SAAS,GAAG,EAAE;IAEd,MAAM,GAAG,GAAG,EAAE,CAAC;IAEf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC;QACpD,GAAG,CAAC,IAAI,CAAC;YACP,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC;YAC1C,0BAA0B;SAC3B,CAAC,CAAC;IACL,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["import * as os from 'node:os';\nimport * as path from 'node:path';\nimport * as workerpool from 'workerpool';\n\nimport * as logging from './logging';\nimport { TypeScriptSnippet } from './snippet';\nimport { TranslatedSnippet } from './tablets/tablets';\nimport { RosettaDiagnostic } from './translate';\nimport type { TranslateBatchRequest, TranslateBatchResponse } from './translate_all_worker';\n\n/**\n * Divide the work evenly over all processors by running 'translate_all_worker' in Worker Threads, then combine results\n *\n * The workers are fed small queues of work each. We used to divide the entire queue into N\n * but since the work is divided unevenly that led to some workers stopping early, idling while\n * waiting for more work.\n *\n * Never include 'translate_all_worker' directly, only do TypeScript type references (so that in\n * the script we may assume that 'worker_threads' successfully imports).\n */\nexport async function translateAll(\n snippets: TypeScriptSnippet[],\n includeCompilerDiagnostics: boolean,\n): Promise<TranslateAllResult> {\n // Use about half the advertised cores because hyperthreading doesn't seem to\n // help that much, or we become I/O-bound at some point. On my machine, using\n // more than half the cores actually makes it slower.\n // Cap to a reasonable top-level limit to prevent thrash on machines with many, many cores.\n const N = process.env.JSII_ROSETTA_MAX_WORKER_COUNT\n ? parseInt(process.env.JSII_ROSETTA_MAX_WORKER_COUNT)\n : Math.min(16, Math.max(1, Math.ceil(os.cpus().length / 2)));\n const snippetArr = Array.from(snippets);\n logging.info(`Translating ${snippetArr.length} snippets using ${N} workers`);\n\n const pool = workerpool.pool(path.join(__dirname, 'translate_all_worker.js'), {\n maxWorkers: N,\n });\n\n try {\n const requests = batchSnippets(snippetArr, includeCompilerDiagnostics);\n\n const responses: TranslateBatchResponse[] = await Promise.all(\n requests.map((request) => pool.exec('translateBatch', [request])),\n );\n\n const diagnostics = new Array<RosettaDiagnostic>();\n const translatedSnippets = new Array<TranslatedSnippet>();\n\n // Combine results\n for (const response of responses) {\n diagnostics.push(...response.diagnostics);\n translatedSnippets.push(...response.translatedSchemas.map(TranslatedSnippet.fromSchema));\n }\n return { diagnostics, translatedSnippets };\n } finally {\n // Not waiting on purpose\n void pool.terminate();\n }\n}\n\nfunction batchSnippets(\n snippets: TypeScriptSnippet[],\n includeCompilerDiagnostics: boolean,\n batchSize = 10,\n): TranslateBatchRequest[] {\n const ret = [];\n\n for (let i = 0; i < snippets.length; i += batchSize) {\n ret.push({\n snippets: snippets.slice(i, i + batchSize),\n includeCompilerDiagnostics,\n });\n }\n\n return ret;\n}\n\nexport interface TranslateAllResult {\n translatedSnippets: TranslatedSnippet[];\n diagnostics: RosettaDiagnostic[];\n}\n"]}
1
+ {"version":3,"file":"translate_all.js","sourceRoot":"","sources":["../src/translate_all.ts"],"names":[],"mappings":"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","sourcesContent":["import * as os from 'node:os';\nimport * as path from 'node:path';\nimport * as workerpool from 'workerpool';\n\nimport * as logging from './logging';\nimport { TypeScriptSnippet } from './snippet';\nimport { TranslatedSnippet } from './tablets/tablets';\nimport { RosettaDiagnostic } from './translate';\nimport type { TranslateBatchRequest, TranslateBatchResponse } from './translate_all_worker';\n\n/**\n * Divide the work evenly over all processors by running 'translate_all_worker' in Worker Threads, then combine results\n *\n * The workers are fed small queues of work each. We used to divide the entire queue into N\n * but since the work is divided unevenly that led to some workers stopping early, idling while\n * waiting for more work.\n *\n * Never include 'translate_all_worker' directly, only do TypeScript type references (so that in\n * the script we may assume that 'worker_threads' successfully imports).\n */\nexport async function translateAll(\n snippets: TypeScriptSnippet[],\n includeCompilerDiagnostics: boolean,\n batchSize?: number,\n): Promise<TranslateAllResult> {\n // Use about half the advertised cores because hyperthreading doesn't seem to\n // help that much, or we become I/O-bound at some point. On my machine, using\n // more than half the cores actually makes it slower.\n // Cap to a reasonable top-level limit to prevent thrash on machines with many, many cores.\n const N = process.env.JSII_ROSETTA_MAX_WORKER_COUNT\n ? parseInt(process.env.JSII_ROSETTA_MAX_WORKER_COUNT)\n : Math.min(16, Math.max(1, Math.ceil(os.cpus().length / 2)));\n const snippetArr = Array.from(snippets);\n const batchesOf = batchSize ? ` (in batches of ${batchSize})` : '';\n logging.info(`Translating ${snippetArr.length} snippets using ${N} workers${batchesOf}`);\n\n const pool = workerpool.pool(path.join(__dirname, 'translate_all_worker.js'), {\n maxWorkers: N,\n });\n\n try {\n const shouldBatchCompilation = batchSize != null;\n const requests = batchSnippets(snippetArr, includeCompilerDiagnostics, batchSize, shouldBatchCompilation);\n\n const responses: TranslateBatchResponse[] = await Promise.all(\n requests.map((request) => pool.exec('translateBatch', [request])),\n );\n\n const diagnostics = new Array<RosettaDiagnostic>();\n const translatedSnippets = new Array<TranslatedSnippet>();\n\n // Combine results\n for (const response of responses) {\n diagnostics.push(...response.diagnostics);\n translatedSnippets.push(...response.translatedSchemas.map(TranslatedSnippet.fromSchema));\n }\n return { diagnostics, translatedSnippets };\n } finally {\n // Not waiting on purpose\n void pool.terminate();\n }\n}\n\nfunction batchSnippets(\n snippets: TypeScriptSnippet[],\n includeCompilerDiagnostics: boolean,\n batchSize = 10,\n shouldBatchCompilation: boolean = false,\n): TranslateBatchRequest[] {\n const logLevel = logging.current();\n const ret: TranslateBatchRequest[] = [];\n\n for (let i = 0; i < snippets.length; i += batchSize) {\n // create a unique worker name, purely for logging so can be pseudo random\n const workerId = Math.random().toString(16).slice(2, 6).toUpperCase();\n ret.push({\n workerName: `Worker#${workerId}`,\n snippets: snippets.slice(i, i + batchSize),\n includeCompilerDiagnostics,\n logLevel,\n batchSize: shouldBatchCompilation ? batchSize : undefined,\n });\n }\n\n return ret;\n}\n\nexport interface TranslateAllResult {\n translatedSnippets: TranslatedSnippet[];\n diagnostics: RosettaDiagnostic[];\n}\n"]}
@@ -1,10 +1,14 @@
1
+ import * as logging from './logging';
1
2
  import { TypeScriptSnippet } from './snippet';
2
3
  import { TranslatedSnippetSchema } from './tablets/schema';
3
4
  import { RosettaDiagnostic } from './translate';
4
5
  import { TranslateAllResult } from './translate_all';
5
6
  export interface TranslateBatchRequest {
7
+ readonly workerName: string;
6
8
  readonly snippets: TypeScriptSnippet[];
7
9
  readonly includeCompilerDiagnostics: boolean;
10
+ readonly logLevel?: logging.Level;
11
+ readonly batchSize?: number;
8
12
  }
9
13
  export interface TranslateBatchResponse {
10
14
  readonly translatedSchemas: TranslatedSnippetSchema[];
@@ -5,14 +5,35 @@ exports.singleThreadedTranslateAll = singleThreadedTranslateAll;
5
5
  * Pool worker for extract.ts
6
6
  */
7
7
  const workerpool = require("workerpool");
8
+ const logging = require("./logging");
8
9
  const translate_1 = require("./translate");
9
10
  function translateBatch(request) {
10
- const result = singleThreadedTranslateAll(request.snippets, request.includeCompilerDiagnostics);
11
+ // because we are in a worker process we need to explicitly configure the log level again
12
+ logging.configure({ level: request.logLevel ?? logging.Level.QUIET, prefix: request.workerName });
13
+ const result = request.batchSize
14
+ ? batchTranslateAll(request.snippets, request.includeCompilerDiagnostics)
15
+ : singleThreadedTranslateAll(request.snippets, request.includeCompilerDiagnostics);
11
16
  return {
12
17
  translatedSchemas: result.translatedSnippets.map((s) => s.snippet),
13
18
  diagnostics: result.diagnostics,
14
19
  };
15
20
  }
21
+ function batchTranslateAll(snippets, includeCompilerDiagnostics) {
22
+ const translatedSnippets = new Array();
23
+ const failures = new Array();
24
+ const translator = new translate_1.Translator(includeCompilerDiagnostics);
25
+ try {
26
+ const results = translator.translateSnippets(snippets);
27
+ translatedSnippets.push(...results);
28
+ }
29
+ catch (e) {
30
+ failures.push((0, translate_1.makeRosettaDiagnostic)(true, `rosetta: error translating batch: ${e}\n${e.stack}`));
31
+ }
32
+ return {
33
+ translatedSnippets,
34
+ diagnostics: [...translator.diagnostics, ...failures],
35
+ };
36
+ }
16
37
  /**
17
38
  * Translate the given snippets using a single compiler
18
39
  */
@@ -1 +1 @@
1
- {"version":3,"file":"translate_all_worker.js","sourceRoot":"","sources":["../src/translate_all_worker.ts"],"names":[],"mappings":";;AAkCA,gEAuBC;AAzDD;;GAEG;AACH,yCAAyC;AAKzC,2CAAmF;AAcnF,SAAS,cAAc,CAAC,OAA8B;IACpD,MAAM,MAAM,GAAG,0BAA0B,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAEhG,OAAO;QACL,iBAAiB,EAAE,MAAM,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QAClE,WAAW,EAAE,MAAM,CAAC,WAAW;KAChC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,0BAA0B,CACxC,QAA6B,EAC7B,0BAAmC;IAEnC,MAAM,kBAAkB,GAAG,IAAI,KAAK,EAAqB,CAAC;IAE1D,MAAM,QAAQ,GAAG,IAAI,KAAK,EAAqB,CAAC;IAEhD,MAAM,UAAU,GAAG,IAAI,sBAAU,CAAC,0BAA0B,CAAC,CAAC;IAC9D,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QACvD,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,QAAQ,CAAC,IAAI,CACX,IAAA,iCAAqB,EAAC,IAAI,EAAE,uCAAuC,CAAC,KAAK,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,cAAc,EAAE,CAAC,CAC7G,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO;QACL,kBAAkB;QAClB,WAAW,EAAE,CAAC,GAAG,UAAU,CAAC,WAAW,EAAE,GAAG,QAAQ,CAAC;KACtD,CAAC;AACJ,CAAC;AAED,UAAU,CAAC,MAAM,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC","sourcesContent":["/**\n * Pool worker for extract.ts\n */\nimport * as workerpool from 'workerpool';\n\nimport { TypeScriptSnippet } from './snippet';\nimport { TranslatedSnippetSchema } from './tablets/schema';\nimport { TranslatedSnippet } from './tablets/tablets';\nimport { RosettaDiagnostic, Translator, makeRosettaDiagnostic } from './translate';\nimport { TranslateAllResult } from './translate_all';\n\nexport interface TranslateBatchRequest {\n readonly snippets: TypeScriptSnippet[];\n readonly includeCompilerDiagnostics: boolean;\n}\n\nexport interface TranslateBatchResponse {\n // Cannot be 'TranslatedSnippet' because needs to be serializable\n readonly translatedSchemas: TranslatedSnippetSchema[];\n readonly diagnostics: RosettaDiagnostic[];\n}\n\nfunction translateBatch(request: TranslateBatchRequest): TranslateBatchResponse {\n const result = singleThreadedTranslateAll(request.snippets, request.includeCompilerDiagnostics);\n\n return {\n translatedSchemas: result.translatedSnippets.map((s) => s.snippet),\n diagnostics: result.diagnostics,\n };\n}\n\n/**\n * Translate the given snippets using a single compiler\n */\nexport function singleThreadedTranslateAll(\n snippets: TypeScriptSnippet[],\n includeCompilerDiagnostics: boolean,\n): TranslateAllResult {\n const translatedSnippets = new Array<TranslatedSnippet>();\n\n const failures = new Array<RosettaDiagnostic>();\n\n const translator = new Translator(includeCompilerDiagnostics);\n for (const block of snippets) {\n try {\n translatedSnippets.push(translator.translate(block));\n } catch (e: any) {\n failures.push(\n makeRosettaDiagnostic(true, `rosetta: error translating snippet: ${e}\\n${e.stack}\\n${block.completeSource}`),\n );\n }\n }\n\n return {\n translatedSnippets,\n diagnostics: [...translator.diagnostics, ...failures],\n };\n}\n\nworkerpool.worker({ translateBatch });\n"]}
1
+ {"version":3,"file":"translate_all_worker.js","sourceRoot":"","sources":["../src/translate_all_worker.ts"],"names":[],"mappings":";;AA8DA,gEAuBC;AArFD;;GAEG;AACH,yCAAyC;AAEzC,qCAAqC;AAIrC,2CAAmF;AAiBnF,SAAS,cAAc,CAAC,OAA8B;IACpD,yFAAyF;IACzF,OAAO,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAClG,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS;QAC9B,CAAC,CAAC,iBAAiB,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,0BAA0B,CAAC;QACzE,CAAC,CAAC,0BAA0B,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAErF,OAAO;QACL,iBAAiB,EAAE,MAAM,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QAClE,WAAW,EAAE,MAAM,CAAC,WAAW;KAChC,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,QAA6B,EAAE,0BAAmC;IAC3F,MAAM,kBAAkB,GAAG,IAAI,KAAK,EAAqB,CAAC;IAE1D,MAAM,QAAQ,GAAG,IAAI,KAAK,EAAqB,CAAC;IAEhD,MAAM,UAAU,GAAG,IAAI,sBAAU,CAAC,0BAA0B,CAAC,CAAC;IAE9D,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,UAAU,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QACvD,kBAAkB,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,QAAQ,CAAC,IAAI,CAAC,IAAA,iCAAqB,EAAC,IAAI,EAAE,qCAAqC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACnG,CAAC;IAED,OAAO;QACL,kBAAkB;QAClB,WAAW,EAAE,CAAC,GAAG,UAAU,CAAC,WAAW,EAAE,GAAG,QAAQ,CAAC;KACtD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,0BAA0B,CACxC,QAA6B,EAC7B,0BAAmC;IAEnC,MAAM,kBAAkB,GAAG,IAAI,KAAK,EAAqB,CAAC;IAE1D,MAAM,QAAQ,GAAG,IAAI,KAAK,EAAqB,CAAC;IAEhD,MAAM,UAAU,GAAG,IAAI,sBAAU,CAAC,0BAA0B,CAAC,CAAC;IAC9D,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QACvD,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,QAAQ,CAAC,IAAI,CACX,IAAA,iCAAqB,EAAC,IAAI,EAAE,uCAAuC,CAAC,KAAK,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,cAAc,EAAE,CAAC,CAC7G,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO;QACL,kBAAkB;QAClB,WAAW,EAAE,CAAC,GAAG,UAAU,CAAC,WAAW,EAAE,GAAG,QAAQ,CAAC;KACtD,CAAC;AACJ,CAAC;AAED,UAAU,CAAC,MAAM,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC","sourcesContent":["/**\n * Pool worker for extract.ts\n */\nimport * as workerpool from 'workerpool';\n\nimport * as logging from './logging';\nimport { TypeScriptSnippet } from './snippet';\nimport { TranslatedSnippetSchema } from './tablets/schema';\nimport { TranslatedSnippet } from './tablets/tablets';\nimport { RosettaDiagnostic, makeRosettaDiagnostic, Translator } from './translate';\nimport { TranslateAllResult } from './translate_all';\n\nexport interface TranslateBatchRequest {\n readonly workerName: string;\n readonly snippets: TypeScriptSnippet[];\n readonly includeCompilerDiagnostics: boolean;\n readonly logLevel?: logging.Level;\n readonly batchSize?: number;\n}\n\nexport interface TranslateBatchResponse {\n // Cannot be 'TranslatedSnippet' because needs to be serializable\n readonly translatedSchemas: TranslatedSnippetSchema[];\n readonly diagnostics: RosettaDiagnostic[];\n}\n\nfunction translateBatch(request: TranslateBatchRequest): TranslateBatchResponse {\n // because we are in a worker process we need to explicitly configure the log level again\n logging.configure({ level: request.logLevel ?? logging.Level.QUIET, prefix: request.workerName });\n const result = request.batchSize\n ? batchTranslateAll(request.snippets, request.includeCompilerDiagnostics)\n : singleThreadedTranslateAll(request.snippets, request.includeCompilerDiagnostics);\n\n return {\n translatedSchemas: result.translatedSnippets.map((s) => s.snippet),\n diagnostics: result.diagnostics,\n };\n}\n\nfunction batchTranslateAll(snippets: TypeScriptSnippet[], includeCompilerDiagnostics: boolean): TranslateAllResult {\n const translatedSnippets = new Array<TranslatedSnippet>();\n\n const failures = new Array<RosettaDiagnostic>();\n\n const translator = new Translator(includeCompilerDiagnostics);\n\n try {\n const results = translator.translateSnippets(snippets);\n translatedSnippets.push(...results);\n } catch (e: any) {\n failures.push(makeRosettaDiagnostic(true, `rosetta: error translating batch: ${e}\\n${e.stack}`));\n }\n\n return {\n translatedSnippets,\n diagnostics: [...translator.diagnostics, ...failures],\n };\n}\n\n/**\n * Translate the given snippets using a single compiler\n */\nexport function singleThreadedTranslateAll(\n snippets: TypeScriptSnippet[],\n includeCompilerDiagnostics: boolean,\n): TranslateAllResult {\n const translatedSnippets = new Array<TranslatedSnippet>();\n\n const failures = new Array<RosettaDiagnostic>();\n\n const translator = new Translator(includeCompilerDiagnostics);\n for (const block of snippets) {\n try {\n translatedSnippets.push(translator.translate(block));\n } catch (e: any) {\n failures.push(\n makeRosettaDiagnostic(true, `rosetta: error translating snippet: ${e}\\n${e.stack}\\n${block.completeSource}`),\n );\n }\n }\n\n return {\n translatedSnippets,\n diagnostics: [...translator.diagnostics, ...failures],\n };\n}\n\nworkerpool.worker({ translateBatch });\n"]}
@@ -5,12 +5,19 @@ export declare class TypeScriptCompiler {
5
5
  * A compiler-scoped cache to avoid having to re-parse the same library files for every compilation
6
6
  */
7
7
  private readonly fileCache;
8
- createInMemoryCompilerHost(sourcePath: string, sourceContents: string, currentDirectory?: string): ts.CompilerHost;
9
- compileInMemory(filename: string, contents: string, currentDirectory?: string): CompilationResult;
8
+ compileBatchInMemory(sources: Array<{
9
+ filename: string;
10
+ contents: string;
11
+ }>, currentDirectory?: string): BatchCompilationResult;
12
+ private createInMemoryCompilerHost;
10
13
  }
11
14
  export interface CompilationResult {
12
15
  program: ts.Program;
13
16
  rootFile: ts.SourceFile;
14
17
  }
18
+ export interface BatchCompilationResult {
19
+ program: ts.Program;
20
+ rootFiles: ts.SourceFile[];
21
+ }
15
22
  export declare const STANDARD_COMPILER_OPTIONS: ts.CompilerOptions;
16
23
  //# sourceMappingURL=ts-compiler.d.ts.map
@@ -10,45 +10,62 @@ class TypeScriptCompiler {
10
10
  */
11
11
  this.fileCache = new Map();
12
12
  }
13
- createInMemoryCompilerHost(sourcePath, sourceContents, currentDirectory) {
13
+ compileBatchInMemory(sources, currentDirectory) {
14
+ const filenames = sources.map((s) => (s.filename.endsWith('.ts') ? s.filename : s.filename + '.ts'));
15
+ const sourceFiles = new Map();
16
+ for (const [i, source] of sources.entries()) {
17
+ // Append empty export to make each file a module with isolated scope.
18
+ // Without this, TypeScript treats all files in the same compilation as scripts
19
+ // sharing a global scope, causing "Cannot redeclare block-scoped variable" errors
20
+ // when multiple snippets use the same variable names.
21
+ // We use export {} instead of putting snippets in separate directories because
22
+ // that would break relative import paths within snippets.
23
+ // Appended (not prepended) to preserve line numbers for error reporting.
24
+ // Hide the export statement from translation since it's synthetic
25
+ sourceFiles.set(filenames[i], `${source.contents}\n/// !hide\nexport {};\n/// !show\n`);
26
+ }
27
+ const host = this.createInMemoryCompilerHost(sourceFiles, currentDirectory);
28
+ const program = ts.createProgram({
29
+ rootNames: filenames,
30
+ options: exports.STANDARD_COMPILER_OPTIONS,
31
+ host,
32
+ });
33
+ const rootFiles = filenames.map((filename) => {
34
+ const rootFile = program.getSourceFile(filename);
35
+ if (rootFile == null) {
36
+ throw new Error(`Oopsie -- couldn't find root file back: ${filename}`);
37
+ }
38
+ return rootFile;
39
+ });
40
+ return { program, rootFiles };
41
+ }
42
+ createInMemoryCompilerHost(sourceFiles, currentDirectory) {
14
43
  const realHost = this.realHost;
15
- const sourceFile = ts.createSourceFile(sourcePath, sourceContents, ts.ScriptTarget.Latest);
44
+ const parsedSources = new Map();
45
+ for (const [filename, contents] of sourceFiles) {
46
+ parsedSources.set(filename, ts.createSourceFile(filename, contents, ts.ScriptTarget.Latest));
47
+ }
16
48
  return {
17
49
  ...realHost,
18
- fileExists: (filePath) => filePath === sourcePath || this.fileCache.has(filePath) || realHost.fileExists(filePath),
50
+ fileExists: (filePath) => sourceFiles.has(filePath) || this.fileCache.has(filePath) || realHost.fileExists(filePath),
19
51
  getCurrentDirectory: currentDirectory != null ? () => currentDirectory : realHost.getCurrentDirectory,
20
52
  getSourceFile: (fileName, languageVersion, onError, shouldCreateNewSourceFile) => {
21
- if (fileName === sourcePath) {
22
- return sourceFile;
53
+ const parsed = parsedSources.get(fileName);
54
+ if (parsed) {
55
+ return parsed;
23
56
  }
24
57
  const existing = this.fileCache.get(fileName);
25
58
  if (existing) {
26
59
  return existing;
27
60
  }
28
- const parsed = realHost.getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile);
29
- this.fileCache.set(fileName, parsed);
30
- return parsed;
61
+ const result = realHost.getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile);
62
+ this.fileCache.set(fileName, result);
63
+ return result;
31
64
  },
32
- readFile: (filePath) => (filePath === sourcePath ? sourceContents : realHost.readFile(filePath)),
65
+ readFile: (filePath) => sourceFiles.get(filePath) ?? realHost.readFile(filePath),
33
66
  writeFile: () => void undefined,
34
67
  };
35
68
  }
36
- compileInMemory(filename, contents, currentDirectory) {
37
- if (!filename.endsWith('.ts')) {
38
- // Necessary or the TypeScript compiler won't compile the file.
39
- filename += '.ts';
40
- }
41
- const program = ts.createProgram({
42
- rootNames: [filename],
43
- options: exports.STANDARD_COMPILER_OPTIONS,
44
- host: this.createInMemoryCompilerHost(filename, contents, currentDirectory),
45
- });
46
- const rootFile = program.getSourceFile(filename);
47
- if (rootFile == null) {
48
- throw new Error(`Oopsie -- couldn't find root file back: ${filename}`);
49
- }
50
- return { program, rootFile };
51
- }
52
69
  }
53
70
  exports.TypeScriptCompiler = TypeScriptCompiler;
54
71
  exports.STANDARD_COMPILER_OPTIONS = {
@@ -1 +1 @@
1
- {"version":3,"file":"ts-compiler.js","sourceRoot":"","sources":["../../src/typescript/ts-compiler.ts"],"names":[],"mappings":"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","sourcesContent":["import * as ts from 'typescript';\n\nexport class TypeScriptCompiler {\n private readonly realHost = ts.createCompilerHost(STANDARD_COMPILER_OPTIONS, true);\n\n /**\n * A compiler-scoped cache to avoid having to re-parse the same library files for every compilation\n */\n private readonly fileCache = new Map<string, ts.SourceFile | undefined>();\n\n public createInMemoryCompilerHost(\n sourcePath: string,\n sourceContents: string,\n currentDirectory?: string,\n ): ts.CompilerHost {\n const realHost = this.realHost;\n const sourceFile = ts.createSourceFile(sourcePath, sourceContents, ts.ScriptTarget.Latest);\n\n return {\n ...realHost,\n fileExists: (filePath) =>\n filePath === sourcePath || this.fileCache.has(filePath) || realHost.fileExists(filePath),\n getCurrentDirectory: currentDirectory != null ? () => currentDirectory : realHost.getCurrentDirectory,\n getSourceFile: (fileName, languageVersion, onError, shouldCreateNewSourceFile) => {\n if (fileName === sourcePath) {\n return sourceFile;\n }\n\n const existing = this.fileCache.get(fileName);\n if (existing) {\n return existing;\n }\n\n const parsed = realHost.getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile);\n this.fileCache.set(fileName, parsed);\n return parsed;\n },\n readFile: (filePath) => (filePath === sourcePath ? sourceContents : realHost.readFile(filePath)),\n writeFile: () => void undefined,\n };\n }\n\n public compileInMemory(filename: string, contents: string, currentDirectory?: string): CompilationResult {\n if (!filename.endsWith('.ts')) {\n // Necessary or the TypeScript compiler won't compile the file.\n filename += '.ts';\n }\n\n const program = ts.createProgram({\n rootNames: [filename],\n options: STANDARD_COMPILER_OPTIONS,\n host: this.createInMemoryCompilerHost(filename, contents, currentDirectory),\n });\n\n const rootFile = program.getSourceFile(filename);\n if (rootFile == null) {\n throw new Error(`Oopsie -- couldn't find root file back: ${filename}`);\n }\n\n return { program, rootFile };\n }\n}\n\nexport interface CompilationResult {\n program: ts.Program;\n rootFile: ts.SourceFile;\n}\n\nexport const STANDARD_COMPILER_OPTIONS: ts.CompilerOptions = {\n alwaysStrict: true,\n charset: 'utf8',\n declaration: true,\n declarationMap: true,\n experimentalDecorators: true,\n inlineSourceMap: true,\n inlineSources: true,\n lib: ['lib.es2022.d.ts'],\n module: ts.ModuleKind.Node16,\n moduleResolution: ts.ModuleResolutionKind.Node16,\n noEmitOnError: true,\n noFallthroughCasesInSwitch: true,\n noImplicitAny: true,\n noImplicitReturns: true,\n noImplicitThis: true,\n noUnusedLocals: false, // Important, becomes super annoying without this\n noUnusedParameters: false, // Important, becomes super annoying without this\n resolveJsonModule: true,\n strict: true,\n strictNullChecks: true,\n strictPropertyInitialization: true,\n stripInternal: true,\n target: ts.ScriptTarget.ES2022,\n // Incremental builds\n incremental: true,\n tsBuildInfoFile: '.tsbuildinfo',\n};\n"]}
1
+ {"version":3,"file":"ts-compiler.js","sourceRoot":"","sources":["../../src/typescript/ts-compiler.ts"],"names":[],"mappings":";;;AAAA,iCAAiC;AAEjC,MAAa,kBAAkB;IAA/B;QACmB,aAAQ,GAAG,EAAE,CAAC,kBAAkB,CAAC,iCAAyB,EAAE,IAAI,CAAC,CAAC;QAEnF;;WAEG;QACc,cAAS,GAAG,IAAI,GAAG,EAAqC,CAAC;IAuE5E,CAAC;IArEQ,oBAAoB,CACzB,OAAsD,EACtD,gBAAyB;QAEzB,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC;QACrG,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;QAE9C,KAAK,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YAC5C,sEAAsE;YACtE,+EAA+E;YAC/E,kFAAkF;YAClF,sDAAsD;YACtD,+EAA+E;YAC/E,0DAA0D;YAC1D,yEAAyE;YACzE,kEAAkE;YAClE,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,QAAQ,sCAAsC,CAAC,CAAC;QAC1F,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,0BAA0B,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;QAC5E,MAAM,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC;YAC/B,SAAS,EAAE,SAAS;YACpB,OAAO,EAAE,iCAAyB;YAClC,IAAI;SACL,CAAC,CAAC;QAEH,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;YAC3C,MAAM,QAAQ,GAAG,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YACjD,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;gBACrB,MAAM,IAAI,KAAK,CAAC,2CAA2C,QAAQ,EAAE,CAAC,CAAC;YACzE,CAAC;YACD,OAAO,QAAQ,CAAC;QAClB,CAAC,CAAC,CAAC;QAEH,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;IAChC,CAAC;IAEO,0BAA0B,CAAC,WAAgC,EAAE,gBAAyB;QAC5F,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC/B,MAAM,aAAa,GAAG,IAAI,GAAG,EAAyB,CAAC;QAEvD,KAAK,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,WAAW,EAAE,CAAC;YAC/C,aAAa,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;QAC/F,CAAC;QAED,OAAO;YACL,GAAG,QAAQ;YACX,UAAU,EAAE,CAAC,QAAQ,EAAE,EAAE,CACvB,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC;YAC5F,mBAAmB,EAAE,gBAAgB,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,mBAAmB;YACrG,aAAa,EAAE,CAAC,QAAQ,EAAE,eAAe,EAAE,OAAO,EAAE,yBAAyB,EAAE,EAAE;gBAC/E,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;gBAC3C,IAAI,MAAM,EAAE,CAAC;oBACX,OAAO,MAAM,CAAC;gBAChB,CAAC;gBAED,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;gBAC9C,IAAI,QAAQ,EAAE,CAAC;oBACb,OAAO,QAAQ,CAAC;gBAClB,CAAC;gBAED,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,EAAE,eAAe,EAAE,OAAO,EAAE,yBAAyB,CAAC,CAAC;gBACrG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;gBACrC,OAAO,MAAM,CAAC;YAChB,CAAC;YACD,QAAQ,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAChF,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,SAAS;SAChC,CAAC;IACJ,CAAC;CACF;AA7ED,gDA6EC;AAYY,QAAA,yBAAyB,GAAuB;IAC3D,YAAY,EAAE,IAAI;IAClB,OAAO,EAAE,MAAM;IACf,WAAW,EAAE,IAAI;IACjB,cAAc,EAAE,IAAI;IACpB,sBAAsB,EAAE,IAAI;IAC5B,eAAe,EAAE,IAAI;IACrB,aAAa,EAAE,IAAI;IACnB,GAAG,EAAE,CAAC,iBAAiB,CAAC;IACxB,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM;IAC5B,gBAAgB,EAAE,EAAE,CAAC,oBAAoB,CAAC,MAAM;IAChD,aAAa,EAAE,IAAI;IACnB,0BAA0B,EAAE,IAAI;IAChC,aAAa,EAAE,IAAI;IACnB,iBAAiB,EAAE,IAAI;IACvB,cAAc,EAAE,IAAI;IACpB,cAAc,EAAE,KAAK,EAAE,iDAAiD;IACxE,kBAAkB,EAAE,KAAK,EAAE,iDAAiD;IAC5E,iBAAiB,EAAE,IAAI;IACvB,MAAM,EAAE,IAAI;IACZ,gBAAgB,EAAE,IAAI;IACtB,4BAA4B,EAAE,IAAI;IAClC,aAAa,EAAE,IAAI;IACnB,MAAM,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM;IAC9B,qBAAqB;IACrB,WAAW,EAAE,IAAI;IACjB,eAAe,EAAE,cAAc;CAChC,CAAC","sourcesContent":["import * as ts from 'typescript';\n\nexport class TypeScriptCompiler {\n private readonly realHost = ts.createCompilerHost(STANDARD_COMPILER_OPTIONS, true);\n\n /**\n * A compiler-scoped cache to avoid having to re-parse the same library files for every compilation\n */\n private readonly fileCache = new Map<string, ts.SourceFile | undefined>();\n\n public compileBatchInMemory(\n sources: Array<{ filename: string; contents: string }>,\n currentDirectory?: string,\n ): BatchCompilationResult {\n const filenames = sources.map((s) => (s.filename.endsWith('.ts') ? s.filename : s.filename + '.ts'));\n const sourceFiles = new Map<string, string>();\n\n for (const [i, source] of sources.entries()) {\n // Append empty export to make each file a module with isolated scope.\n // Without this, TypeScript treats all files in the same compilation as scripts\n // sharing a global scope, causing \"Cannot redeclare block-scoped variable\" errors\n // when multiple snippets use the same variable names.\n // We use export {} instead of putting snippets in separate directories because\n // that would break relative import paths within snippets.\n // Appended (not prepended) to preserve line numbers for error reporting.\n // Hide the export statement from translation since it's synthetic\n sourceFiles.set(filenames[i], `${source.contents}\\n/// !hide\\nexport {};\\n/// !show\\n`);\n }\n\n const host = this.createInMemoryCompilerHost(sourceFiles, currentDirectory);\n const program = ts.createProgram({\n rootNames: filenames,\n options: STANDARD_COMPILER_OPTIONS,\n host,\n });\n\n const rootFiles = filenames.map((filename) => {\n const rootFile = program.getSourceFile(filename);\n if (rootFile == null) {\n throw new Error(`Oopsie -- couldn't find root file back: ${filename}`);\n }\n return rootFile;\n });\n\n return { program, rootFiles };\n }\n\n private createInMemoryCompilerHost(sourceFiles: Map<string, string>, currentDirectory?: string): ts.CompilerHost {\n const realHost = this.realHost;\n const parsedSources = new Map<string, ts.SourceFile>();\n\n for (const [filename, contents] of sourceFiles) {\n parsedSources.set(filename, ts.createSourceFile(filename, contents, ts.ScriptTarget.Latest));\n }\n\n return {\n ...realHost,\n fileExists: (filePath) =>\n sourceFiles.has(filePath) || this.fileCache.has(filePath) || realHost.fileExists(filePath),\n getCurrentDirectory: currentDirectory != null ? () => currentDirectory : realHost.getCurrentDirectory,\n getSourceFile: (fileName, languageVersion, onError, shouldCreateNewSourceFile) => {\n const parsed = parsedSources.get(fileName);\n if (parsed) {\n return parsed;\n }\n\n const existing = this.fileCache.get(fileName);\n if (existing) {\n return existing;\n }\n\n const result = realHost.getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile);\n this.fileCache.set(fileName, result);\n return result;\n },\n readFile: (filePath) => sourceFiles.get(filePath) ?? realHost.readFile(filePath),\n writeFile: () => void undefined,\n };\n }\n}\n\nexport interface CompilationResult {\n program: ts.Program;\n rootFile: ts.SourceFile;\n}\n\nexport interface BatchCompilationResult {\n program: ts.Program;\n rootFiles: ts.SourceFile[];\n}\n\nexport const STANDARD_COMPILER_OPTIONS: ts.CompilerOptions = {\n alwaysStrict: true,\n charset: 'utf8',\n declaration: true,\n declarationMap: true,\n experimentalDecorators: true,\n inlineSourceMap: true,\n inlineSources: true,\n lib: ['lib.es2022.d.ts'],\n module: ts.ModuleKind.Node16,\n moduleResolution: ts.ModuleResolutionKind.Node16,\n noEmitOnError: true,\n noFallthroughCasesInSwitch: true,\n noImplicitAny: true,\n noImplicitReturns: true,\n noImplicitThis: true,\n noUnusedLocals: false, // Important, becomes super annoying without this\n noUnusedParameters: false, // Important, becomes super annoying without this\n resolveJsonModule: true,\n strict: true,\n strictNullChecks: true,\n strictPropertyInitialization: true,\n stripInternal: true,\n target: ts.ScriptTarget.ES2022,\n // Incremental builds\n incremental: true,\n tsBuildInfoFile: '.tsbuildinfo',\n};\n"]}
package/package.json CHANGED
@@ -56,17 +56,17 @@
56
56
  "eslint-plugin-unicorn": "^56.0.1",
57
57
  "fs-monkey": "^1.1.0",
58
58
  "jest": "^29.7.0",
59
- "memfs": "^4.51.0",
59
+ "memfs": "^4.51.1",
60
60
  "mock-fs": "^5.5.0",
61
61
  "prettier": "^2.8.8",
62
- "projen": "^0.98.15",
62
+ "projen": "^0.98.29",
63
63
  "tar": "^6.2.1",
64
- "ts-jest": "^29.4.5",
64
+ "ts-jest": "^29.4.6",
65
65
  "ts-node": "^10.9.2"
66
66
  },
67
67
  "dependencies": {
68
- "@jsii/check-node": "^1.118.0",
69
- "@jsii/spec": "^1.118.0",
68
+ "@jsii/check-node": "^1.121.0",
69
+ "@jsii/spec": "^1.121.0",
70
70
  "@xmldom/xmldom": "^0.9.8",
71
71
  "chalk": "^4",
72
72
  "commonmark": "^0.31.2",
@@ -88,7 +88,7 @@
88
88
  "publishConfig": {
89
89
  "access": "public"
90
90
  },
91
- "version": "5.9.16-dev.3",
91
+ "version": "5.9.19",
92
92
  "types": "lib/index.d.ts",
93
93
  "exports": {
94
94
  ".": "./lib/index.js",