已合并
add PerformanceDotting diagnostics for structureIsReused decision points #872
add PerformanceDotting diagnostics for structureIsReused decision points #872
已合并
liyancheng创建于 8月27日
共 15 个文件变更+949-86
@@ -40,6 +40,7 @@ Where to look(任务 → 路径):
40- Linter 规则 / 增量 lint 改动 → 读 `docs/knowledge/arkts-linter.md`40- Linter 规则 / 增量 lint 改动 → 读 `docs/knowledge/arkts-linter.md`
41- 错误码增删或语义变更 → 读 `docs/knowledge/error-codes.md`41- 错误码增删或语义变更 → 读 `docs/knowledge/error-codes.md`
42- 构建 / 基线 / 测试体系改动 → 读 `docs/knowledge/build-test-baseline.md`42- 构建 / 基线 / 测试体系改动 → 读 `docs/knowledge/build-test-baseline.md`
43+- 增量编译 / 结构复用 / `structureIsReused` / `tryReuseStructureFromOldProgram` → 读 `docs/knowledge/incremental-structure-reuse.md`
43 44 
44### Path-based routing(按修改路径)45### Path-based routing(按修改路径)
45 46 
@@ -48,6 +49,7 @@ Where to look(任务 → 路径):
48- `src/linter/` → 读 `arkts-linter.md`49- `src/linter/` → 读 `arkts-linter.md`
49- `lib/` 或 `scripts/dtsBundler.mjs` → 读 `lib-declarations.md`50- `lib/` 或 `scripts/dtsBundler.mjs` → 读 `lib-declarations.md`
50- `tests/baselines/` 或 `tests/cases/` → 读 `build-test-baseline.md`51- `tests/baselines/` 或 `tests/cases/` → 读 `build-test-baseline.md`
52+- `src/compiler/program.ts` / `src/compiler/builder.ts` → 读 `incremental-structure-reuse.md`
51 53 
52### Vocabulary-based routing(按术语)54### Vocabulary-based routing(按术语)
53 55 
@@ -63,6 +65,7 @@ Where to look(任务 → 路径):
63| linter / ArkTSLinter / `LinterRunner` / 增量 lint / `.tsbuildinfo` | 规则跨 1.0/1.1,行为差异易错 | `arkts-linter.md` |65| linter / ArkTSLinter / `LinterRunner` / 增量 lint / `.tsbuildinfo` | 规则跨 1.0/1.1,行为差异易错 | `arkts-linter.md` |
64| 错误码 / 10505114 / 28000 / `ErrorInfo` / `getErrorCode` | 错误码是公共契约,改动需问人 | `error-codes.md` |66| 错误码 / 10505114 / 28000 / `ErrorInfo` / `getErrorCode` | 错误码是公共契约,改动需问人 | `error-codes.md` |
65| hereby / BUILD.gn / bundle.json / baseline / runtests / `arkTSTest` / `system_api_test` | 构建测试体系,基线变更必须接受 | `build-test-baseline.md` |67| hereby / BUILD.gn / bundle.json / baseline / runtests / `arkTSTest` / `system_api_test` | 构建测试体系,基线变更必须接受 | `build-test-baseline.md` |
68+| `structureIsReused` / `tryReuseStructureFromOldProgram` / `SafeModules` / `Completely` / `.tsbuildinfo` | 增量判定错会漏检 modified files 或脏缓存 | `incremental-structure-reuse.md` |
66 69 
67### Plan 阶段声明70### Plan 阶段声明
68 71 
@@ -152,4 +155,4 @@ node tests/arkTSTest/run.js -v1.1 -D
152 155 
153## 附:知识文档清单156## 附:知识文档清单
154 157 
155-`docs/knowledge/`:`ets-language-extensions.md`、`oh-module-system.md`、`type-checker-and-compat.md`、`api-availability.md`、`lib-declarations.md`、`arkts-linter.md`、`error-codes.md`、`build-test-baseline.md`。158+`docs/knowledge/`:`ets-language-extensions.md`、`oh-module-system.md`、`type-checker-and-compat.md`、`api-availability.md`、`lib-declarations.md`、`arkts-linter.md`、`error-codes.md`、`build-test-baseline.md`、`incremental-structure-reuse.md`。
@@ -8,8 +8,8 @@ ArkTS Linter 是 ArkTS(TS 变体)的静态分析器,按版本分两套实
8 8 
9```9```
10src/linter/10src/linter/
11-├── ArkTSLinter_1_0/ # ArkTS 1.011+├── ArkTSLinter_1_0/ # ArkTS 1.0(早期 API,无 Sendable/版本感知/打点)
12-├── ArkTSLinter_1_1/ # ArkTS 1.112+├── ArkTSLinter_1_1/ # ArkTS 1.1(API 12+,含 @Sendable 规则、compatibleSdkVersion 感知、PerformanceDotting)
13├── Common/ # 共享工具13├── Common/ # 共享工具
14└── _namespaces/ # TS namespace 定义14└── _namespaces/ # TS namespace 定义
15```15```
@@ -31,7 +31,7 @@ src/linter/
31| 版本感知 | ArkTS 版本变更触发全量 | 忽略版本切换导致旧诊断残留 |31| 版本感知 | ArkTS 版本变更触发全量 | 忽略版本切换导致旧诊断残留 |
32| `.tsbuildinfo` | 诊断缓存 | 改规则后不失效缓存 |32| `.tsbuildinfo` | 诊断缓存 | 改规则后不失效缓存 |
33| strict / non-strict | 两路 TSC 诊断 | 只执行一路会漏报 |33| strict / non-strict | 两路 TSC 诊断 | 只执行一路会漏报 |
34-| 1.0 / 1.1 | 两套实现 | 规则只改一边导致两版不一致 |34+| 1.0 / 1.1 | v1.1 面向 API 12+,v1.0 面向早期 API | 规则只改一边导致两版不一致 |
35 35 
36## 约束36## 约束
37 37 
@@ -0,0 +1,179 @@
1+# 增量编译与结构复用知识
2+ 
3+本文只记录 program 增量编译的结构复用判定(`tryReuseStructureFromOldProgram` / `StructureIsReused`)。类型检查见 `type-checker-and-compat.md`,API 可用性见 `api-availability.md`,构建/基线见 `build-test-baseline.md`。
4+ 
5+## 核心模型
6+ 
7+`tryReuseStructureFromOldProgram`(`src/compiler/program.ts`)在新一轮编译时决定旧 program 的结构能复用到什么程度,返回 `StructureIsReused` 三态(`src/compiler/types.ts`):
8+ 
9+| 值 | 语义 | 全量/增量 | 复用范围 |
10+|---|---|---|---|
11+| `Not` | 完全不复用 | 全量 | 重建 `files`/`filesByName`/`fileReasons`/`resolvedTypeReferenceDirectives` 等 |
12+| `SafeModules` | 复用文件结构、重做模块解析 | 增量(部分) | 复用 source files 列表,重做 modified files 的 `resolvedModules` |
13+| `Completely` | 最大化复用 | 增量(完全) | 连 modified files 的 `resolvedModules` 都复用旧值,仅重做内容变化文件的 bind/check/emit |
14+ 
15+核心判据:**修改是否影响 program 的"结构"**(文件集合 / 模块依赖图 / 解析策略)。影响 → `Not` 或 `SafeModules`;仅内容变而结构不变 → `Completely`。
16+ 
17+## 触发全量(`Not`)的场景
18+ 
19+任一命中即提前 `return Not`,连 `newSourceFiles` 都可能未遍历完;后续 `createProgram` 重建 program 级结构。判定顺序即代码中 `if` 出现的先后,改顺序会影响结果(见约束)。
20+ 
21+| # | 修改场景 | 判定函数/变量 | 原理 |
22+|---|---|---|---|
23+| 1 | 首次编译 / `.tsbuildinfo` 缺失或损坏 / 无 oldProgram | `!oldProgram` | 没有旧 program 可复用 |
24+| 2 | `compilerOptions` 中影响模块解析的选项变化(`module`/`moduleResolution`/`paths`/`baseUrl`/`target`/`configFilePath` 等) | `changesAffectModuleResolution` | 解析策略变了,旧解析结果全部失效 |
25+| 3 | root 文件列表增删(`rootNames` 变化) | `!arrayIsEqualTo(oldRootNames, rootNames)` | 根文件集变了,文件集合需重建 |
26+| 4 | project references 不可复用(引用的 tsconfig 变化) | `tryReuseProjectReferences` 返回非 undefined | 项目引用结构变了 |
27+| 5 | 之前缺失的文件现在存在了 | `nowExistingMissingFilePath` | 缺失文件出现会改变 program 结构 |
28+| 6 | 某个旧 source file 现在被删除/读不到 | `!newSourceFile` | 文件集合缩减 |
29+| 7 | redirect 源文件的「底层实际文件」内容变化 | `newSourceFile !== oldSourceFile.redirectInfo.unredirected` | redirect 关系可能断裂 |
30+| 8 | 被 redirect 指向的目标文件内容变化 | `oldProgram.redirectTargetsMap.has` + `newSourceFile !== oldSourceFile` | redirect 目标变化同样可能断裂 |
31+| 9 | 同一 package 名下有两个源文件且至少一个变化 | `seenPackageNames` 冲突检测 | 可能产生新 redirect,结构不确定 |
32+ 
33+## 触发 `SafeModules`(增量-部分)的场景
34+ 
35+文件内容变化(`fileChanged=true`)但未命中上述 `Not` 条件时,进入结构属性比对;任一命中设 `SafeModules`,提前 `return`。判定在 `for (const oldSourceFile of oldSourceFiles)` 遍历内逐文件进行。
36+ 
37+| # | 修改场景 | 判定条件 | 原理 |
38+|---|---|---|---|
39+| 10 | `impliedNodeFormat` 变化(ESM↔CJS 切换) | `oldSourceFile.impliedNodeFormat !== newSourceFile.impliedNodeFormat` | 模块格式影响解析与 emit |
40+| 11 | `lib` reference directives 变化(`/// <reference lib=".." />`) | `!arrayIsEqualTo(oldSourceFile.libReferenceDirectives, ...)` | 影响注入的默认库集合 |
41+| 12 | `hasNoDefaultLib` 变化 | `oldSourceFile.hasNoDefaultLib !== newSourceFile.hasNoDefaultLib` | 影响默认库是否注入 |
42+| 13 | tripleslash `referencedFiles` 变化(`/// <reference path=".." />`) | `!arrayIsEqualTo(oldSourceFile.referencedFiles, ...)` | 影响文件包含集合 |
43+| 14 | `imports` 列表变化(import/require 的模块名) | `!arrayIsEqualTo(oldSourceFile.imports, newSourceFile.imports, ...)` | 模块依赖图变化 |
44+| 15 | `moduleAugmentations` 变化 | `!arrayIsEqualTo(oldSourceFile.moduleAugmentations, ...)` | 模块扩展声明变化 |
45+| 16 | `PermanentlySetIncrementalFlags` 变化(含 dynamicImport) | `(oldSourceFile.flags & NodeFlags.PermanentlySetIncrementalFlags) !== (...)` | 影响 emit/加载方式 |
46+| 17 | `typeReferenceDirectives` 变化(`/// <reference types=".." />`) | `!arrayIsEqualTo(oldSourceFile.typeReferenceDirectives, ...)` | 类型库包含集合变化 |
47+| 18 | 文件内容未变但被 `hasInvalidatedResolutions` 标记失效 | `hasInvalidatedResolutions(oldSourceFile.path)` | watch 场景显式失效解析,需重解析 |
48+| 19 | modified files 重解析后模块解析结果变化 | `hasChangesInResolutions` (module) | 内容变了导致解析目标变了 |
49+| 20 | modified files 的 type-reference 解析结果变化 | `hasChangesInResolutions` (typeReference) | 类型库解析目标变了 |
50+| 21 | `changesAffectingProgramStructure` 或 `hasChangedAutomaticTypeDirectiveNames` | `changesAffectingProgramStructure(oldOptions, options) \|\| host.hasChangedAutomaticTypeDirectiveNames?.()` | options 变化影响 program 结构但不影响模块解析策略,故仅 `SafeModules` |
51+ 
52+## 触发 `Completely`(增量-完全)的场景
53+ 
54+| # | 修改场景 | 判定条件 | 原理 |
55+|---|---|---|---|
56+| 22 | 文件内容未变(`fileChanged=false`)且无 `hasInvalidatedResolutions`,所有结构选项不变 | 初始即 `Completely`,遍历未将其降级 | — |
57+| 23 | 文件内容变了(`fileChanged=true`)但所有结构相关属性均未变,且重解析模块名结果一致 | `else` 分支(所有 10-17 未命中)+ `hasChangesInResolutions` 返回 false | 改的只是函数体实现等非结构内容,`resolvedModules` 复用旧值 |
58+ 
59+**关键优化(场景 23)**:改文件内容但不碰结构相关语法(如只改函数体)仍走 `Completely`,只重做该文件的 bind/check/emit,是最优增量路径。`Completely` 路径直接复用 oldProgram 的 `fileReasons`/`filesByName`/`resolvedTypeReferenceDirectives`/`sourceFileToPackageName`/`redirectTargetsMap`。
60+ 
61+## 三态复用差异
62+ 
63+| 维度 | `Not`(全量) | `SafeModules`(增量-部分) | `Completely`(增量-完全) |
64+|---|---|---|---|
65+| source files 列表 | 重建 | 复用遍历结果 | 复用 |
66+| 模块解析结果 `resolvedModules` | 全重做 | 重做 modified 部分 | 复用旧值 |
67+| program 结构(`filesByName`/`fileReasons`/`resolvedTypeRef` 等) | 重建 | 重建 | 复用 oldProgram |
68+| bind/check/emit 范围 | 全部文件 | modified + 受影响 | modified + 受影响 |
69+ 
70+## 日志速查表(按打点显示反查分支)
71+ 
72+`PerformanceDotting` 每条记录含 `name`(事件名)+ `fileName`(详情)+ `duration`(纳秒)。`getEventData()` 按 `fullPath-fileName-parentId` 合并同父事件下相同条目的 `duration`。默认关闭,需 host 开启 `VERBOSE`/`TRACE`。
73+ 
74+**速查**:先看 `name` 定大类(`Not`/`SafeModules`/`Completely`),再看 `fileName` 的 `#1`-`#9` 编号或描述定具体分支。`start`/`stop`(trace 级)仅 `TRACE` 可见,`startAdvanced`/`stopAdvanced` 在 `VERBOSE` 及以上可见。
75+ 
76+### `program.ts` — `tryReuseStructureFromOldProgram` 区间
77+ 
78+| name | fileName | 含义 |
79+|---|---|---|
80+| `tryReuseStructureFromOldProgram` | (空) | 整个函数调用区间,仅看耗时,无分支含义 |
81+| `structureIsReused: {Completely/SafeModules/Not}` | (空) | `tryReuseStructureFromOldProgram` 返回值汇总,`const enum` 被内联为数字,此处用三元映射输出枚举名 |
82+ 
83+### `program.ts` — `Not` 分支(全量)
84+ 
85+| name | fileName 模式 | # | 原因 |
86+|---|---|---|---|
87+| `structureIsReused: Not` | `#1 oldProgram is undefined (first build or .tsbuildinfo missing/deleted/corrupt)` | 1 | 无旧 program / `.tsbuildinfo` 缺失或损坏 |
88+| `structureIsReused: Not` | `#2 changesAffectModuleResolution - changedOptions: [{选项名列表}], configFilePath: {旧} -> {新}` | 2 | `module`/`moduleResolution`/`paths`/`baseUrl`/`target` 等模块解析选项变化(含具体变更选项名列表) |
89+| `structureIsReused: Not` | `#3 rootNames changed - oldCount={n}, newCount={n}, added=[{文件列表, 上限10}], removed=[{文件列表, 上限10}]` | 3 | 根文件列表增删(含具体增删文件路径,超过 10 个显示 `... and N more`) |
90+| `structureIsReused: Not` | `#4 tryReuseProjectReferences failed: {子原因+路径}` | 4 | 引用的 tsconfig 变化(子原因:resolved ref 丢失 / sourceFile 变 / fileNames 变 / 新增 resolved / references 数组变,含 project reference 路径) |
91+| `structureIsReused: Not` | `#5 a previously missing file now exists: {文件路径}` | 5 | 之前缺失的文件现在存在(含具体文件路径) |
92+| `structureIsReused: Not` | `#6 source file no longer exists: {文件}` | 6 | 源文件被删/读不到(含路径) |
93+| `structureIsReused: Not` | `#7 redirect underlying file changed: {文件}` | 7 | redirect 底层文件变(含路径) |
94+| `structureIsReused: Not` | `#8 redirected-to file changed: {文件}` | 8 | redirect 目标文件变(含路径) |
95+| `structureIsReused: Not` | `#9 package name conflict (two files for package "{包名}", at least one changed): {文件}` | 9 | 同包名两文件且至少一个变(含包名+路径) |
96+ 
97+### `program.ts` — `SafeModules` 分支(增量-部分)
98+ 
99+| name | fileName 模式 | 对应场景 | 原因 |
100+|---|---|---|---|
101+| `structureIsReused: SafeModules` | `属性 changed: {文件}`(遍历内每设置点详情)+ `file content changed but module resolution reusable, modifiedFiles={n}`(汇总,仅 count) | 10-18 | 文件遍历中触发:结构属性变(`imports`/`moduleAugmentations`/`typeReferenceDirectives`/`referencedFiles`/`libReferenceDirectives`/`impliedNodeFormat`/`hasNoDefaultLib`/`PermanentlySetIncrementalFlags`)或 `hasInvalidatedResolutions`;每个触发文件+属性各成一条详情,汇总仅含 modifiedFiles 数量(不含文件列表,避免 report 膨胀;触发文件已由各详情条目单独打印) |
102+| `structureIsReused: SafeModules` | `{类型} resolution changed: {文件}`(重解析详情)+ `module resolution changed for modified files, modifiedFiles={n}`(汇总) | 19-20 | modified files 重解析后 `resolutionsChanged`(module)或 `typeReferenceResolutionsChanged`(typeReference);每个变化文件各成一条详情,末尾再打汇总 |
103+| `structureIsReused: SafeModules` | `#10 changesAffectingProgramStructure: [{选项名列表}]; hasChangedAutomaticTypeDirectiveNames` | 21 | `changesAffectingProgramStructure`(含具体变更选项名)或 `hasChangedAutomaticTypeDirectiveNames`,分号分隔各自原因 |
104+ 
105+### `program.ts` — `Completely` 分支(增量-完全)
106+ 
107+| name | fileName | 对应场景 | 原因 |
108+|---|---|---|---|
109+| `structureIsReused: Completely` | `structure fully reused from old program` | 22-23 | 文件未变,或内容变但结构属性均未变且重解析结果一致 |
110+ 
111+### `program.ts` — `createProgram` 阶段子区间
112+ 
113+用于排查子阶段耗时之和与 `createProgram` 总耗时的差距。仅列出 `startAdvanced`(VERBOSE+ 可见)。
114+ 
115+| name | fileName | 阶段 |
116+|---|---|---|
117+| `tryReuseStructureFromOldProgram` | (空) | 增量判定 |
118+| `structureIsReused: {name}` | (空) | 返回值汇总(枚举名) |
119+| `resolveModuleNames` | `modifiedFiles={n}` | SafeModules 路径模块重解析总耗时 |
120+| `processRootFiles` | `rootNames={n}` | Not 路径主工作(递归读文件+解析+模块解析) |
121+| `processTypeReferences` | `count={n}` | `@types` 解析(文件系统 I/O) |
122+| `processDefaultLib` | (空) | 默认库读取/解析 |
123+| `processingDiagnostics` | (空) | 预处理诊断转换 |
124+ 
125+### `builder.ts` — `getBuilderCreationParameters`
126+ 
127+| name | fileName 模式 | 分支 | 原因 |
128+|---|---|---|---|
129+| `getBuilderCreationParameters: reuseProgramFromOldProgram` | `newProgramOrRootNames undefined, no createProgram call` | 复用旧 program | `newProgramOrRootNames` 未提供 |
130+| `getBuilderCreationParameters: createProgram` | `oldProgram={bool}, hasOldProgram={bool}, rootNames={n}` | 新建 program | 走 `createProgram`,含状态 |
131+| `getBuilderCreationParameters: newProgramProvided` | `newProgram={bool}, host={bool}, oldProgram={bool}, configFileParsingDiagnostics={bool}` | 外部提供 | 外部已建好 program |
132+ 
133+### `watchPublic.ts` — `readBuilderProgram`
134+ 
135+| name | fileName 模式 | 分支 | 原因 |
136+|---|---|---|---|
137+| `readBuilderProgram: buildInfoNotFound` | `{buildInfoPath} not found` | 缺失 | `.tsbuildinfo` 读不到(含路径) |
138+| `readBuilderProgram: invalidBuildInfo` | `path={p}, version={v}, hasProgram={bool}` | 无效 | buildInfo 版本不符或缺少 program 段 |
139+| `readBuilderProgram: loaded` | (空) | 成功 | buildInfo 加载成功(`name` 本身够用) |
140+ 
141+### `tsbuildPublic.ts` — `getOldProgram`
142+ 
143+| name | fileName 模式 | 分支 | 原因 |
144+|---|---|---|---|
145+| `getOldProgram: force` | `--force flag set, returning undefined for {proj}` | force | `--force` 强制重建(含项目路径) |
146+| `getOldProgram: cachedBuilderProgram` | `reused from builderPrograms map for {proj}` | 缓存命中 | `builderPrograms` 已有(含项目路径) |
147+ 
148+### 速查局限
149+ 
150+- **SafeModules 遍历触发**:仅结构属性变化的文件产生条目(`属性 changed: {文件}`,通常 1-20 条);汇总仅含 `modifiedFiles={n}` 数量,不含文件列表(触发文件已由详情条目单独打印)。
151+- **空 `fileName` 条目**:`tryReuseStructureFromOldProgram` 区间、`structureIsReused: {name}` 汇总只能看耗时。
152+- **文件列表上限**:`#3 rootNames` 的 `added=[]`/`removed=[]` 最多 10 个路径,超过显示 `... and N more`。
153+ 
154+## 约束
155+ 
156+- 改动 `tryReuseStructureFromOldProgram` 的判定顺序或条件**必须**逐场景评估:提前 `return` 会跳过后续检查,可能把本应 `Not` 的场景误判为 `SafeModules`/`Completely`,导致脏缓存(modified files 未重检)。
157+- **不要**在加诊断/打点时意外删除分支的 `return` 语句:`SafeModules` 结果若 fall through 到 `Completely`,会跳过 modified files 的 re-check,静默漏报。
158+- `StructureIsReused` 是 `const enum`(`src/compiler/types.ts`,`Not=0`/`SafeModules=1`/`Completely=2`),改动枚举值会改变持久化与跨版本兼容,**先问人**。
159+- `PerformanceDotting.startAdvanced/stopAdvanced` 默认关闭(`src/compiler/performanceDotting.ts`),开关关闭时是 no-op,**不要**依赖打点调用的副作用来驱动逻辑。
160+- 增量路径的正确性依赖 `.tsbuildinfo` 的完整性;`.tsbuildinfo` 损坏会落到场景 1(`Not`)。
161+ 
162+## 修改前检查
163+ 
164+- [ ] 是否改动了 `tryReuseStructureFromOldProgram` 的判定顺序/条件/`return`?
165+- [ ] 每个分支的 `return` 是否保留?加打点时是否误删了 `return`?
166+- [ ] 改 `Not`/`SafeModules`/`Completely` 的归属是否评估了 modified files 的 re-check 覆盖?
167+- [ ] `const enum` 值是否未变(避免破坏持久化兼容)?
168+- [ ] `PerformanceDotting` 调用是否在开关关闭时仍保持 no-op(无副作用)?
169+- [ ] 是否执行了 `tests/cases/compiler/` 增量用例 + `npm run test`?
170+ 
171+## 代码和测试
172+ 
173+- 代码入口:`src/compiler/program.ts`(`tryReuseStructureFromOldProgram`、`createProgram`、`StructureIsReused` 消费、`processRootFiles`/`processTypeReferences`/`processDefaultLib`/`resolveModuleNames` 阶段打点)
174+- 枚举:`src/compiler/types.ts`(`StructureIsReused`,`const enum`,编译时内联为数字)
175+- 枚举名映射:`src/compiler/program.ts` `tryReuseStructureFromOldProgram` 调用方(三元映射 `const enum` 值 → 字符串,用于 report 可读性)
176+- 选项变更检测:`src/compiler/commandLineParser.ts`(`moduleResolutionOptionDeclarations`、`optionsAffectingProgramStructure`);`src/compiler/utilities.ts`(`changesAffectModuleResolution`、`changesAffectingProgramStructure`、`optionsHaveChanges`、`getCompilerOptionValue`)
177+- builder/watch 复用入口:`src/compiler/builder.ts`(`getBuilderCreationParameters`)、`src/compiler/watchPublic.ts`(`readBuilderProgram`)、`src/compiler/tsbuildPublic.ts`(`getOldProgram`)
178+- 性能打点:`src/compiler/performanceDotting.ts`(开关、`getEventData`、`layerCount=5` 嵌套深度限制)
179+- 测试:`tests/cases/compiler/`(增量用例)、`tests/baselines/local/`(`npm run baseline`)
Mlib/tsc.js+139-15
@@ -106319,6 +106319,7 @@ function createCreateProgramOptions(rootNames, options, host, oldProgram, config
106319function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _configFileParsingDiagnostics) {106319function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _configFileParsingDiagnostics) {
106320 var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;106320 var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
106321 PerformanceDotting.start("createProgram");106321 PerformanceDotting.start("createProgram");
106322+ PerformanceDotting.startAdvanced("createProgram");
106322 const createProgramOptions = isArray(rootNamesOrOptions) ? createCreateProgramOptions(rootNamesOrOptions, _options, _host, _oldProgram, _configFileParsingDiagnostics) : rootNamesOrOptions;106323 const createProgramOptions = isArray(rootNamesOrOptions) ? createCreateProgramOptions(rootNamesOrOptions, _options, _host, _oldProgram, _configFileParsingDiagnostics) : rootNamesOrOptions;
106323 const { rootNames, options, configFileParsingDiagnostics, projectReferences } = createProgramOptions;106324 const { rootNames, options, configFileParsingDiagnostics, projectReferences } = createProgramOptions;
106324 let { oldProgram } = createProgramOptions;106325 let { oldProgram } = createProgramOptions;
@@ -106421,9 +106422,12 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
106421 let structureIsReused;106422 let structureIsReused;
106422 (_f = tracing) == null ? void 0 : _f.push(tracing.Phase.Program, "tryReuseStructureFromOldProgram", {});106423 (_f = tracing) == null ? void 0 : _f.push(tracing.Phase.Program, "tryReuseStructureFromOldProgram", {});
106423 PerformanceDotting.start("tryReuseStructureFromOldProgram");106424 PerformanceDotting.start("tryReuseStructureFromOldProgram");
106425+ PerformanceDotting.startAdvanced("tryReuseStructureFromOldProgram");
106424 structureIsReused = tryReuseStructureFromOldProgram();106426 structureIsReused = tryReuseStructureFromOldProgram();
106425- PerformanceDotting.startAdvanced("structureIsReused: " + structureIsReused);106427+ const structureIsReusedName = structureIsReused === 2 /* Completely */ ? "Completely" : structureIsReused === 1 /* SafeModules */ ? "SafeModules" : "Not";
106426- PerformanceDotting.stopAdvanced("structureIsReused: " + structureIsReused);106428+ PerformanceDotting.startAdvanced("structureIsReused: " + structureIsReusedName);
106429+ PerformanceDotting.stopAdvanced("structureIsReused: " + structureIsReusedName);
106430+ PerformanceDotting.stopAdvanced("tryReuseStructureFromOldProgram");
106427 PerformanceDotting.stop("tryReuseStructureFromOldProgram");106431 PerformanceDotting.stop("tryReuseStructureFromOldProgram");
106428 (_g = tracing) == null ? void 0 : _g.pop();106432 (_g = tracing) == null ? void 0 : _g.pop();
106429 if (structureIsReused !== 2 /* Completely */) {106433 if (structureIsReused !== 2 /* Completely */) {
@@ -106461,23 +106465,28 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
106461 }106465 }
106462 (_h = tracing) == null ? void 0 : _h.push(tracing.Phase.Program, "processRootFiles", { count: rootNames.length });106466 (_h = tracing) == null ? void 0 : _h.push(tracing.Phase.Program, "processRootFiles", { count: rootNames.length });
106463 PerformanceDotting.start("processRootFiles");106467 PerformanceDotting.start("processRootFiles");
106468+ PerformanceDotting.startAdvanced("processRootFiles", `rootNames=${rootNames.length}`);
106464 forEach(rootNames, (name, index) => processRootFile(name, false, false, { kind: 0 /* RootFile */, index }));106469 forEach(rootNames, (name, index) => processRootFile(name, false, false, { kind: 0 /* RootFile */, index }));
106470+ PerformanceDotting.stopAdvanced("processRootFiles");
106465 PerformanceDotting.stop("processRootFiles");106471 PerformanceDotting.stop("processRootFiles");
106466 (_i = tracing) == null ? void 0 : _i.pop();106472 (_i = tracing) == null ? void 0 : _i.pop();
106467 const typeReferences = rootNames.length ? getAutomaticTypeDirectiveNames(options, host) : emptyArray;106473 const typeReferences = rootNames.length ? getAutomaticTypeDirectiveNames(options, host) : emptyArray;
106468 if (typeReferences.length) {106474 if (typeReferences.length) {
106469 (_j = tracing) == null ? void 0 : _j.push(tracing.Phase.Program, "processTypeReferences", { count: typeReferences.length });106475 (_j = tracing) == null ? void 0 : _j.push(tracing.Phase.Program, "processTypeReferences", { count: typeReferences.length });
106470 PerformanceDotting.start("processTypeReferences");106476 PerformanceDotting.start("processTypeReferences");
106477+ PerformanceDotting.startAdvanced("processTypeReferences", `count=${typeReferences.length}`);
106471 const containingDirectory = options.configFilePath ? getDirectoryPath(options.configFilePath) : host.getCurrentDirectory();106478 const containingDirectory = options.configFilePath ? getDirectoryPath(options.configFilePath) : host.getCurrentDirectory();
106472 const containingFilename = combinePaths(containingDirectory, inferredTypesContainingFile);106479 const containingFilename = combinePaths(containingDirectory, inferredTypesContainingFile);
106473 const resolutions = resolveTypeReferenceDirectiveNamesWorker(typeReferences, containingFilename);106480 const resolutions = resolveTypeReferenceDirectiveNamesWorker(typeReferences, containingFilename);
106474 for (let i = 0; i < typeReferences.length; i++) {106481 for (let i = 0; i < typeReferences.length; i++) {
106475 processTypeReferenceDirective(typeReferences[i], void 0, resolutions[i], { kind: 8 /* AutomaticTypeDirectiveFile */, typeReference: typeReferences[i], packageId: (_k = resolutions[i]) == null ? void 0 : _k.packageId });106482 processTypeReferenceDirective(typeReferences[i], void 0, resolutions[i], { kind: 8 /* AutomaticTypeDirectiveFile */, typeReference: typeReferences[i], packageId: (_k = resolutions[i]) == null ? void 0 : _k.packageId });
106476 }106483 }
106484+ PerformanceDotting.stopAdvanced("processTypeReferences");
106477 PerformanceDotting.stop("processTypeReferences");106485 PerformanceDotting.stop("processTypeReferences");
106478 (_l = tracing) == null ? void 0 : _l.pop();106486 (_l = tracing) == null ? void 0 : _l.pop();
106479 }106487 }
106480 PerformanceDotting.start("processDefaultLib");106488 PerformanceDotting.start("processDefaultLib");
106489+ PerformanceDotting.startAdvanced("processDefaultLib");
106481 if (rootNames.length && !skipDefaultLib) {106490 if (rootNames.length && !skipDefaultLib) {
106482 const defaultLibraryFileName = getDefaultLibraryFileName();106491 const defaultLibraryFileName = getDefaultLibraryFileName();
106483 if (!options.lib && defaultLibraryFileName) {106492 if (!options.lib && defaultLibraryFileName) {
@@ -106494,6 +106503,7 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
106494 }106503 }
106495 }106504 }
106496 }106505 }
106506+ PerformanceDotting.stopAdvanced("processDefaultLib");
106497 PerformanceDotting.stop("processDefaultLib");106507 PerformanceDotting.stop("processDefaultLib");
106498 missingFilePaths = arrayFrom(mapDefinedIterator(filesByName.entries(), ([path, file]) => file === void 0 ? path : void 0));106508 missingFilePaths = arrayFrom(mapDefinedIterator(filesByName.entries(), ([path, file]) => file === void 0 ? path : void 0));
106499 files = stableSort(processingDefaultLibFiles, compareDefaultLibFiles).concat(processingOtherFiles);106509 files = stableSort(processingDefaultLibFiles, compareDefaultLibFiles).concat(processingOtherFiles);
@@ -106632,6 +106642,7 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
106632 MemoryDotting.stopRecordStage(recordInfo);106642 MemoryDotting.stopRecordStage(recordInfo);
106633 measure("Program", "beforeProgram", "afterProgram");106643 measure("Program", "beforeProgram", "afterProgram");
106634 (_p = tracing) == null ? void 0 : _p.pop();106644 (_p = tracing) == null ? void 0 : _p.pop();
106645+ PerformanceDotting.stopAdvanced("createProgram");
106635 PerformanceDotting.stop("createProgram");106646 PerformanceDotting.stop("createProgram");
106636 return program;106647 return program;
106637 function addResolutionDiagnostics(list) {106648 function addResolutionDiagnostics(list) {
@@ -106855,39 +106866,71 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
106855 return true;106866 return true;
106856 }106867 }
106857 }106868 }
106858- function canReuseProjectReferences() {106869+ function tryReuseProjectReferences() {
106859- return !forEachProjectReference(106870+ return forEachProjectReference(
106860 oldProgram.getProjectReferences(),106871 oldProgram.getProjectReferences(),
106861 oldProgram.getResolvedProjectReferences(),106872 oldProgram.getResolvedProjectReferences(),
106862 (oldResolvedRef, parent, index) => {106873 (oldResolvedRef, parent, index) => {
106874+ var _a3, _b2, _c2, _d2;
106863 const newRef = (parent ? parent.commandLine.projectReferences : projectReferences)[index];106875 const newRef = (parent ? parent.commandLine.projectReferences : projectReferences)[index];
106864 const newResolvedRef = parseProjectReferenceConfigFile(newRef);106876 const newResolvedRef = parseProjectReferenceConfigFile(newRef);
106877+ const refPath = (_d2 = (_c2 = (_a3 = newRef == null ? void 0 : newRef.originalPath) != null ? _a3 : newRef == null ? void 0 : newRef.path) != null ? _c2 : (_b2 = oldResolvedRef == null ? void 0 : oldResolvedRef.sourceFile) == null ? void 0 : _b2.fileName) != null ? _d2 : "(unknown project reference)";
106865 if (oldResolvedRef) {106878 if (oldResolvedRef) {
106866- return !newResolvedRef || newResolvedRef.sourceFile !== oldResolvedRef.sourceFile || !arrayIsEqualTo(oldResolvedRef.commandLine.fileNames, newResolvedRef.commandLine.fileNames);106879+ if (!newResolvedRef) {
106880+ return `resolved project reference no longer resolvable: ${refPath}`;
106881+ }
106882+ if (newResolvedRef.sourceFile !== oldResolvedRef.sourceFile) {
106883+ return `project reference sourceFile changed: ${refPath}`;
106884+ }
106885+ if (!arrayIsEqualTo(oldResolvedRef.commandLine.fileNames, newResolvedRef.commandLine.fileNames)) {
106886+ return `project reference fileNames changed: ${refPath}`;
106887+ }
106888+ return void 0;
106867 } else {106889 } else {
106868- return newResolvedRef !== void 0;106890+ if (newResolvedRef !== void 0) {
106891+ return `previously-unresolved project reference now resolved: ${refPath}`;
106892+ }
106893+ return void 0;
106869 }106894 }
106870 },106895 },
106871 (oldProjectReferences, parent) => {106896 (oldProjectReferences, parent) => {
106872 const newReferences = parent ? getResolvedProjectReferenceByPath(parent.sourceFile.path).commandLine.projectReferences : projectReferences;106897 const newReferences = parent ? getResolvedProjectReferenceByPath(parent.sourceFile.path).commandLine.projectReferences : projectReferences;
106873- return !arrayIsEqualTo(oldProjectReferences, newReferences, projectReferenceIsEqualTo);106898+ if (!arrayIsEqualTo(oldProjectReferences, newReferences, projectReferenceIsEqualTo)) {
106899+ const owner = parent ? parent.sourceFile.fileName : "(root)";
106900+ return `project references array changed in: ${owner}`;
106901+ }
106902+ return void 0;
106874 }106903 }
106875 );106904 );
106876 }106905 }
106877 function tryReuseStructureFromOldProgram() {106906 function tryReuseStructureFromOldProgram() {
106878- var _a3, _b2;106907+ var _a3, _b2, _c2;
106879 if (!oldProgram) {106908 if (!oldProgram) {
106909+ PerformanceDotting.startAdvanced("structureIsReused: Not", "#1 oldProgram is undefined (first build or .tsbuildinfo missing/deleted/corrupt)");
106910+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
106880 return 0 /* Not */;106911 return 0 /* Not */;
106881 }106912 }
106882 const oldOptions = oldProgram.getCompilerOptions();106913 const oldOptions = oldProgram.getCompilerOptions();
106883 if (changesAffectModuleResolution(oldOptions, options)) {106914 if (changesAffectModuleResolution(oldOptions, options)) {
106915+ const changedOptions = moduleResolutionOptionDeclarations.filter((o) => !isJsonEqual(getCompilerOptionValue(oldOptions, o), getCompilerOptionValue(options, o))).map((o) => o.name);
106916+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#2 changesAffectModuleResolution - changedOptions: [${changedOptions.join(", ")}], configFilePath: ${oldOptions.configFilePath} -> ${options.configFilePath}`);
106917+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
106884 return 0 /* Not */;106918 return 0 /* Not */;
106885 }106919 }
106886 const oldRootNames = oldProgram.getRootFileNames();106920 const oldRootNames = oldProgram.getRootFileNames();
106887 if (!arrayIsEqualTo(oldRootNames, rootNames)) {106921 if (!arrayIsEqualTo(oldRootNames, rootNames)) {
106922+ const addedFiles = rootNames.filter((f) => !oldRootNames.includes(f));
106923+ const removedFiles = oldRootNames.filter((f) => !rootNames.includes(f));
106924+ const addedList = addedFiles.length > 10 ? addedFiles.slice(0, 10).join(", ") + `, ... and ${addedFiles.length - 10} more` : addedFiles.join(", ");
106925+ const removedList = removedFiles.length > 10 ? removedFiles.slice(0, 10).join(", ") + `, ... and ${removedFiles.length - 10} more` : removedFiles.join(", ");
106926+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#3 rootNames changed - oldCount=${oldRootNames.length}, newCount=${rootNames.length}, added=[${addedList}], removed=[${removedList}]`);
106927+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
106888 return 0 /* Not */;106928 return 0 /* Not */;
106889 }106929 }
106890- if (!canReuseProjectReferences()) {106930+ const projectReferenceReuseFailReason = tryReuseProjectReferences();
106931+ if (projectReferenceReuseFailReason !== void 0) {
106932+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#4 tryReuseProjectReferences failed: ${projectReferenceReuseFailReason}`);
106933+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
106891 return 0 /* Not */;106934 return 0 /* Not */;
106892 }106935 }
106893 if (projectReferences) {106936 if (projectReferences) {
@@ -106896,7 +106939,10 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
106896 const newSourceFiles = [];106939 const newSourceFiles = [];
106897 const modifiedSourceFiles = [];106940 const modifiedSourceFiles = [];
106898 structureIsReused = 2 /* Completely */;106941 structureIsReused = 2 /* Completely */;
106899- if (oldProgram.getMissingFilePaths().some((missingFilePath) => host.fileExists(missingFilePath))) {106942+ const nowExistingMissingFilePath = oldProgram.getMissingFilePaths().find((missingFilePath) => host.fileExists(missingFilePath));
106943+ if (nowExistingMissingFilePath !== void 0) {
106944+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#5 a previously missing file now exists: ${nowExistingMissingFilePath}`);
106945+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
106900 return 0 /* Not */;106946 return 0 /* Not */;
106901 }106947 }
106902 const oldSourceFiles = oldProgram.getSourceFiles();106948 const oldSourceFiles = oldProgram.getSourceFiles();
@@ -106910,6 +106956,8 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
106910 const sourceFileOptions = getCreateSourceFileOptions(oldSourceFile.fileName, moduleResolutionCache, host, options);106956 const sourceFileOptions = getCreateSourceFileOptions(oldSourceFile.fileName, moduleResolutionCache, host, options);
106911 let newSourceFile = host.getSourceFileByPath ? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.resolvedPath, sourceFileOptions, void 0, shouldCreateNewSourceFile || sourceFileOptions.impliedNodeFormat !== oldSourceFile.impliedNodeFormat) : host.getSourceFile(oldSourceFile.fileName, sourceFileOptions, void 0, shouldCreateNewSourceFile || sourceFileOptions.impliedNodeFormat !== oldSourceFile.impliedNodeFormat);106957 let newSourceFile = host.getSourceFileByPath ? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.resolvedPath, sourceFileOptions, void 0, shouldCreateNewSourceFile || sourceFileOptions.impliedNodeFormat !== oldSourceFile.impliedNodeFormat) : host.getSourceFile(oldSourceFile.fileName, sourceFileOptions, void 0, shouldCreateNewSourceFile || sourceFileOptions.impliedNodeFormat !== oldSourceFile.impliedNodeFormat);
106912 if (!newSourceFile) {106958 if (!newSourceFile) {
106959+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#6 source file no longer exists: ${oldSourceFile.fileName}`);
106960+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
106913 return 0 /* Not */;106961 return 0 /* Not */;
106914 }106962 }
106915 newSourceFile.packageJsonLocations = ((_a3 = sourceFileOptions.packageJsonLocations) == null ? void 0 : _a3.length) ? sourceFileOptions.packageJsonLocations : void 0;106963 newSourceFile.packageJsonLocations = ((_a3 = sourceFileOptions.packageJsonLocations) == null ? void 0 : _a3.length) ? sourceFileOptions.packageJsonLocations : void 0;
@@ -106918,12 +106966,16 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
106918 let fileChanged;106966 let fileChanged;
106919 if (oldSourceFile.redirectInfo) {106967 if (oldSourceFile.redirectInfo) {
106920 if (newSourceFile !== oldSourceFile.redirectInfo.unredirected) {106968 if (newSourceFile !== oldSourceFile.redirectInfo.unredirected) {
106969+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#7 redirect underlying file changed: ${oldSourceFile.fileName}`);
106970+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
106921 return 0 /* Not */;106971 return 0 /* Not */;
106922 }106972 }
106923 fileChanged = false;106973 fileChanged = false;
106924 newSourceFile = oldSourceFile;106974 newSourceFile = oldSourceFile;
106925 } else if (oldProgram.redirectTargetsMap.has(oldSourceFile.path)) {106975 } else if (oldProgram.redirectTargetsMap.has(oldSourceFile.path)) {
106926 if (newSourceFile !== oldSourceFile) {106976 if (newSourceFile !== oldSourceFile) {
106977+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#8 redirected-to file changed: ${oldSourceFile.fileName}`);
106978+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
106927 return 0 /* Not */;106979 return 0 /* Not */;
106928 }106980 }
106929 fileChanged = false;106981 fileChanged = false;
@@ -106939,39 +106991,61 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
106939 const prevKind = seenPackageNames.get(packageName);106991 const prevKind = seenPackageNames.get(packageName);
106940 const newKind = fileChanged ? 1 /* Modified */ : 0 /* Exists */;106992 const newKind = fileChanged ? 1 /* Modified */ : 0 /* Exists */;
106941 if (prevKind !== void 0 && newKind === 1 /* Modified */ || prevKind === 1 /* Modified */) {106993 if (prevKind !== void 0 && newKind === 1 /* Modified */ || prevKind === 1 /* Modified */) {
106994+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#9 package name conflict (two files for package "${packageName}", at least one changed): ${oldSourceFile.fileName}`);
106995+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
106942 return 0 /* Not */;106996 return 0 /* Not */;
106943 }106997 }
106944 seenPackageNames.set(packageName, newKind);106998 seenPackageNames.set(packageName, newKind);
106945 }106999 }
106946 if (fileChanged) {107000 if (fileChanged) {
106947 if (oldSourceFile.impliedNodeFormat !== newSourceFile.impliedNodeFormat) {107001 if (oldSourceFile.impliedNodeFormat !== newSourceFile.impliedNodeFormat) {
107002+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `impliedNodeFormat changed: ${oldSourceFile.fileName}`);
107003+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
106948 structureIsReused = 1 /* SafeModules */;107004 structureIsReused = 1 /* SafeModules */;
106949 } else if (!arrayIsEqualTo(oldSourceFile.libReferenceDirectives, newSourceFile.libReferenceDirectives, fileReferenceIsEqualTo)) {107005 } else if (!arrayIsEqualTo(oldSourceFile.libReferenceDirectives, newSourceFile.libReferenceDirectives, fileReferenceIsEqualTo)) {
107006+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `libReferenceDirectives changed: ${oldSourceFile.fileName}`);
107007+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
106950 structureIsReused = 1 /* SafeModules */;107008 structureIsReused = 1 /* SafeModules */;
106951 } else if (oldSourceFile.hasNoDefaultLib !== newSourceFile.hasNoDefaultLib) {107009 } else if (oldSourceFile.hasNoDefaultLib !== newSourceFile.hasNoDefaultLib) {
107010+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `hasNoDefaultLib changed: ${oldSourceFile.fileName}`);
107011+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
106952 structureIsReused = 1 /* SafeModules */;107012 structureIsReused = 1 /* SafeModules */;
106953 } else if (!arrayIsEqualTo(oldSourceFile.referencedFiles, newSourceFile.referencedFiles, fileReferenceIsEqualTo)) {107013 } else if (!arrayIsEqualTo(oldSourceFile.referencedFiles, newSourceFile.referencedFiles, fileReferenceIsEqualTo)) {
107014+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `referencedFiles changed: ${oldSourceFile.fileName}`);
107015+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
106954 structureIsReused = 1 /* SafeModules */;107016 structureIsReused = 1 /* SafeModules */;
106955 } else {107017 } else {
106956 collectExternalModuleReferences(newSourceFile);107018 collectExternalModuleReferences(newSourceFile);
106957 if (!arrayIsEqualTo(oldSourceFile.imports, newSourceFile.imports, moduleNameIsEqualTo)) {107019 if (!arrayIsEqualTo(oldSourceFile.imports, newSourceFile.imports, moduleNameIsEqualTo)) {
107020+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `imports changed: ${oldSourceFile.fileName}`);
107021+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
106958 structureIsReused = 1 /* SafeModules */;107022 structureIsReused = 1 /* SafeModules */;
106959 } else if (!arrayIsEqualTo(oldSourceFile.moduleAugmentations, newSourceFile.moduleAugmentations, moduleNameIsEqualTo)) {107023 } else if (!arrayIsEqualTo(oldSourceFile.moduleAugmentations, newSourceFile.moduleAugmentations, moduleNameIsEqualTo)) {
107024+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `moduleAugmentations changed: ${oldSourceFile.fileName}`);
107025+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
106960 structureIsReused = 1 /* SafeModules */;107026 structureIsReused = 1 /* SafeModules */;
106961 } else if ((oldSourceFile.flags & 6291456 /* PermanentlySetIncrementalFlags */) !== (newSourceFile.flags & 6291456 /* PermanentlySetIncrementalFlags */)) {107027 } else if ((oldSourceFile.flags & 6291456 /* PermanentlySetIncrementalFlags */) !== (newSourceFile.flags & 6291456 /* PermanentlySetIncrementalFlags */)) {
107028+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `PermanentlySetIncrementalFlags changed: ${oldSourceFile.fileName}`);
107029+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
106962 structureIsReused = 1 /* SafeModules */;107030 structureIsReused = 1 /* SafeModules */;
106963 } else if (!arrayIsEqualTo(oldSourceFile.typeReferenceDirectives, newSourceFile.typeReferenceDirectives, fileReferenceIsEqualTo)) {107031 } else if (!arrayIsEqualTo(oldSourceFile.typeReferenceDirectives, newSourceFile.typeReferenceDirectives, fileReferenceIsEqualTo)) {
107032+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `typeReferenceDirectives changed: ${oldSourceFile.fileName}`);
107033+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
106964 structureIsReused = 1 /* SafeModules */;107034 structureIsReused = 1 /* SafeModules */;
106965 }107035 }
106966 }107036 }
106967 modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });107037 modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });
106968 } else if (hasInvalidatedResolutions(oldSourceFile.path)) {107038 } else if (hasInvalidatedResolutions(oldSourceFile.path)) {
107039+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `hasInvalidatedResolutions: ${oldSourceFile.fileName}`);
107040+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
106969 structureIsReused = 1 /* SafeModules */;107041 structureIsReused = 1 /* SafeModules */;
106970 modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });107042 modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });
106971 }107043 }
106972 newSourceFiles.push(newSourceFile);107044 newSourceFiles.push(newSourceFile);
106973 }107045 }
106974 if (structureIsReused !== 2 /* Completely */) {107046 if (structureIsReused !== 2 /* Completely */) {
107047+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `file content changed but module resolution reusable, modifiedFiles=${modifiedSourceFiles.length}`);
107048+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
106975 return structureIsReused;107049 return structureIsReused;
106976 }107050 }
106977 const modifiedFiles = modifiedSourceFiles.map((f) => f.oldFile);107051 const modifiedFiles = modifiedSourceFiles.map((f) => f.oldFile);
@@ -106982,11 +107056,14 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
106982 }107056 }
106983 }107057 }
106984 }107058 }
107059+ PerformanceDotting.startAdvanced("resolveModuleNames", `modifiedFiles=${modifiedSourceFiles.length}`);
106985 for (const { oldFile: oldSourceFile, newFile: newSourceFile } of modifiedSourceFiles) {107060 for (const { oldFile: oldSourceFile, newFile: newSourceFile } of modifiedSourceFiles) {
106986 const moduleNames = getModuleNames(newSourceFile);107061 const moduleNames = getModuleNames(newSourceFile);
106987 const resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFile);107062 const resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFile);
106988 const resolutionsChanged = hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, oldSourceFile, moduleResolutionIsEqualTo);107063 const resolutionsChanged = hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, oldSourceFile, moduleResolutionIsEqualTo);
106989 if (resolutionsChanged) {107064 if (resolutionsChanged) {
107065+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `module resolution changed: ${newSourceFile.fileName}`);
107066+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
106990 structureIsReused = 1 /* SafeModules */;107067 structureIsReused = 1 /* SafeModules */;
106991 newSourceFile.resolvedModules = zipToModeAwareCache(newSourceFile, moduleNames, resolutions);107068 newSourceFile.resolvedModules = zipToModeAwareCache(newSourceFile, moduleNames, resolutions);
106992 } else {107069 } else {
@@ -106996,16 +107073,31 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
106996 const typeReferenceResolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFile);107073 const typeReferenceResolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFile);
106997 const typeReferenceResolutionsChanged = hasChangesInResolutions(typesReferenceDirectives, typeReferenceResolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, oldSourceFile, typeDirectiveIsEqualTo);107074 const typeReferenceResolutionsChanged = hasChangesInResolutions(typesReferenceDirectives, typeReferenceResolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, oldSourceFile, typeDirectiveIsEqualTo);
106998 if (typeReferenceResolutionsChanged) {107075 if (typeReferenceResolutionsChanged) {
107076+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `typeReference resolution changed: ${newSourceFile.fileName}`);
107077+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
106999 structureIsReused = 1 /* SafeModules */;107078 structureIsReused = 1 /* SafeModules */;
107000 newSourceFile.resolvedTypeReferenceDirectiveNames = zipToModeAwareCache(newSourceFile, typesReferenceDirectives, typeReferenceResolutions);107079 newSourceFile.resolvedTypeReferenceDirectiveNames = zipToModeAwareCache(newSourceFile, typesReferenceDirectives, typeReferenceResolutions);
107001 } else {107080 } else {
107002 newSourceFile.resolvedTypeReferenceDirectiveNames = oldSourceFile.resolvedTypeReferenceDirectiveNames;107081 newSourceFile.resolvedTypeReferenceDirectiveNames = oldSourceFile.resolvedTypeReferenceDirectiveNames;
107003 }107082 }
107004 }107083 }
107084+ PerformanceDotting.stopAdvanced("resolveModuleNames");
107005 if (structureIsReused !== 2 /* Completely */) {107085 if (structureIsReused !== 2 /* Completely */) {
107086+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `module resolution changed for modified files, modifiedFiles=${modifiedSourceFiles.length}`);
107087+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
107006 return structureIsReused;107088 return structureIsReused;
107007 }107089 }
107008 if (changesAffectingProgramStructure(oldOptions, options) || ((_b2 = host.hasChangedAutomaticTypeDirectiveNames) == null ? void 0 : _b2.call(host))) {107090 if (changesAffectingProgramStructure(oldOptions, options) || ((_b2 = host.hasChangedAutomaticTypeDirectiveNames) == null ? void 0 : _b2.call(host))) {
107091+ const reasons = [];
107092+ if (changesAffectingProgramStructure(oldOptions, options)) {
107093+ const changedOpts = optionsAffectingProgramStructure.filter((o) => !isJsonEqual(getCompilerOptionValue(oldOptions, o), getCompilerOptionValue(options, o))).map((o) => o.name);
107094+ reasons.push(`changesAffectingProgramStructure: [${changedOpts.join(", ")}]`);
107095+ }
107096+ if ((_c2 = host.hasChangedAutomaticTypeDirectiveNames) == null ? void 0 : _c2.call(host)) {
107097+ reasons.push("hasChangedAutomaticTypeDirectiveNames");
107098+ }
107099+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `#10 ${reasons.join("; ")}`);
107100+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
107009 return 1 /* SafeModules */;107101 return 1 /* SafeModules */;
107010 }107102 }
107011 missingFilePaths = oldProgram.getMissingFilePaths();107103 missingFilePaths = oldProgram.getMissingFilePaths();
@@ -107034,6 +107126,8 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
107034 sourceFileToPackageName = oldProgram.sourceFileToPackageName;107126 sourceFileToPackageName = oldProgram.sourceFileToPackageName;
107035 redirectTargetsMap = oldProgram.redirectTargetsMap;107127 redirectTargetsMap = oldProgram.redirectTargetsMap;
107036 usesUriStyleNodeCoreModules = oldProgram.usesUriStyleNodeCoreModules;107128 usesUriStyleNodeCoreModules = oldProgram.usesUriStyleNodeCoreModules;
107129+ PerformanceDotting.startAdvanced("structureIsReused: Completely", "structure fully reused from old program");
107130+ PerformanceDotting.stopAdvanced("structureIsReused: Completely");
107037 return 2 /* Completely */;107131 return 2 /* Completely */;
107038 }107132 }
107039 function getEmitHost(writeFileCallback) {107133 function getEmitHost(writeFileCallback) {
@@ -110245,13 +110339,21 @@ function getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldP
110245 oldProgram = configFileParsingDiagnosticsOrOldProgram;110339 oldProgram = configFileParsingDiagnosticsOrOldProgram;
110246 Debug.assert(!!oldProgram);110340 Debug.assert(!!oldProgram);
110247 newProgram = oldProgram.getProgram();110341 newProgram = oldProgram.getProgram();
110342+ PerformanceDotting.startAdvanced("getBuilderCreationParameters: reuseProgramFromOldProgram", "newProgramOrRootNames undefined, no createProgram call");
110343+ PerformanceDotting.stopAdvanced("getBuilderCreationParameters: reuseProgramFromOldProgram");
110248 } else if (isArray(newProgramOrRootNames)) {110344 } else if (isArray(newProgramOrRootNames)) {
110249 oldProgram = configFileParsingDiagnosticsOrOldProgram;110345 oldProgram = configFileParsingDiagnosticsOrOldProgram;
110346+ const oldProgramForCreate = oldProgram && oldProgram.getProgramOrUndefined();
110347+ PerformanceDotting.startAdvanced(
110348+ "getBuilderCreationParameters: createProgram",
110349+ `oldProgram=${!!oldProgram}, hasOldProgram=${!!oldProgramForCreate}, rootNames=${newProgramOrRootNames.length}`
110350+ );
110351+ PerformanceDotting.stopAdvanced("getBuilderCreationParameters: createProgram");
110250 newProgram = createProgram({110352 newProgram = createProgram({
110251 rootNames: newProgramOrRootNames,110353 rootNames: newProgramOrRootNames,
110252 options: hostOrOptions,110354 options: hostOrOptions,
110253 host: oldProgramOrHost,110355 host: oldProgramOrHost,
110254- oldProgram: oldProgram && oldProgram.getProgramOrUndefined(),110356+ oldProgram: oldProgramForCreate,
110255 configFileParsingDiagnostics,110357 configFileParsingDiagnostics,
110256 projectReferences110358 projectReferences
110257 });110359 });
@@ -110261,6 +110363,8 @@ function getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldP
110261 host = hostOrOptions;110363 host = hostOrOptions;
110262 oldProgram = oldProgramOrHost;110364 oldProgram = oldProgramOrHost;
110263 configFileParsingDiagnostics = configFileParsingDiagnosticsOrOldProgram;110365 configFileParsingDiagnostics = configFileParsingDiagnosticsOrOldProgram;
110366+ PerformanceDotting.startAdvanced("getBuilderCreationParameters: newProgramProvided", `newProgram=${!!newProgram}, host=${!!host}, oldProgram=${!!oldProgram}, configFileParsingDiagnostics=${!!configFileParsingDiagnostics}`);
110367+ PerformanceDotting.stopAdvanced("getBuilderCreationParameters: newProgramProvided");
110264 }110368 }
110265 return { host, newProgram, oldProgram, configFileParsingDiagnostics: configFileParsingDiagnostics || emptyArray };110369 return { host, newProgram, oldProgram, configFileParsingDiagnostics: configFileParsingDiagnostics || emptyArray };
110266}110370}
@@ -110750,6 +110854,7 @@ function createEmitAndSemanticDiagnosticsBuilderProgram(newProgramOrRootNames, h
110750}110854}
110751function createEmitAndSemanticDiagnosticsBuilderProgramForArkTs(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences) {110855function createEmitAndSemanticDiagnosticsBuilderProgramForArkTs(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences) {
110752 PerformanceDotting.start("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");110856 PerformanceDotting.start("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");
110857+ PerformanceDotting.startAdvanced("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");
110753 PerformanceDotting.start("getBuilderCreationParameters");110858 PerformanceDotting.start("getBuilderCreationParameters");
110754 let builderCreatetionParameters = getBuilderCreationParameters(110859 let builderCreatetionParameters = getBuilderCreationParameters(
110755 newProgramOrRootNames,110860 newProgramOrRootNames,
@@ -110762,22 +110867,27 @@ function createEmitAndSemanticDiagnosticsBuilderProgramForArkTs(newProgramOrRoot
110762 PerformanceDotting.stop("getBuilderCreationParameters");110867 PerformanceDotting.stop("getBuilderCreationParameters");
110763 let newProgram = builderCreatetionParameters.newProgram;110868 let newProgram = builderCreatetionParameters.newProgram;
110764 PerformanceDotting.start("createBuilderProgram");110869 PerformanceDotting.start("createBuilderProgram");
110870+ PerformanceDotting.startAdvanced("createBuilderProgram");
110765 let builderProgram = createBuilderProgram(110871 let builderProgram = createBuilderProgram(
110766 1 /* EmitAndSemanticDiagnosticsBuilderProgram */,110872 1 /* EmitAndSemanticDiagnosticsBuilderProgram */,
110767 builderCreatetionParameters110873 builderCreatetionParameters
110768 );110874 );
110875+ PerformanceDotting.stopAdvanced("createBuilderProgram");
110769 PerformanceDotting.stop("createBuilderProgram");110876 PerformanceDotting.stop("createBuilderProgram");
110770 let oldProgramForLinter = readBuilderProgram(hostOrOptions, oldProgramOrHost, true);110877 let oldProgramForLinter = readBuilderProgram(hostOrOptions, oldProgramOrHost, true);
110771 builderCreatetionParameters.oldProgram = oldProgramForLinter;110878 builderCreatetionParameters.oldProgram = oldProgramForLinter;
110772 builderCreatetionParameters.newProgram = newProgram;110879 builderCreatetionParameters.newProgram = newProgram;
110773 PerformanceDotting.start("createBuilderProgramForLinter");110880 PerformanceDotting.start("createBuilderProgramForLinter");
110881+ PerformanceDotting.startAdvanced("createBuilderProgramForLinter");
110774 let builderProgramForLinter = createBuilderProgram(110882 let builderProgramForLinter = createBuilderProgram(
110775 1 /* EmitAndSemanticDiagnosticsBuilderProgram */,110883 1 /* EmitAndSemanticDiagnosticsBuilderProgram */,
110776 builderCreatetionParameters,110884 builderCreatetionParameters,
110777 true110885 true
110778 );110886 );
110887+ PerformanceDotting.stopAdvanced("createBuilderProgramForLinter");
110779 PerformanceDotting.stop("createBuilderProgramForLinter");110888 PerformanceDotting.stop("createBuilderProgramForLinter");
110780 builderProgram.builderProgramForLinter = builderProgramForLinter;110889 builderProgram.builderProgramForLinter = builderProgramForLinter;
110890+ PerformanceDotting.stopAdvanced("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");
110781 PerformanceDotting.stop("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");110891 PerformanceDotting.stop("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");
110782 return builderProgram;110892 return builderProgram;
110783}110893}
@@ -112192,12 +112302,20 @@ function readBuilderProgram(compilerOptions, host, isForLinter) {
112192 buildInfo = host.getBuildInfo(buildInfoPath, compilerOptions.configFilePath);112302 buildInfo = host.getBuildInfo(buildInfoPath, compilerOptions.configFilePath);
112193 } else {112303 } else {
112194 const content = host.readFile(buildInfoPath);112304 const content = host.readFile(buildInfoPath);
112195- if (!content)112305+ if (!content) {
112306+ PerformanceDotting.startAdvanced("readBuilderProgram: buildInfoNotFound", `${buildInfoPath} not found`);
112307+ PerformanceDotting.stopAdvanced("readBuilderProgram: buildInfoNotFound");
112196 return void 0;112308 return void 0;
112309+ }
112197 buildInfo = getBuildInfo(buildInfoPath, content);112310 buildInfo = getBuildInfo(buildInfoPath, content);
112198 }112311 }
112199- if (!buildInfo || buildInfo.version !== version || !buildInfo.program)112312+ if (!buildInfo || buildInfo.version !== version || !buildInfo.program) {
112313+ PerformanceDotting.startAdvanced("readBuilderProgram: invalidBuildInfo", `path=${buildInfoPath}, version=${buildInfo == null ? void 0 : buildInfo.version}, hasProgram=${!!(buildInfo == null ? void 0 : buildInfo.program)}`);
112314+ PerformanceDotting.stopAdvanced("readBuilderProgram: invalidBuildInfo");
112200 return void 0;112315 return void 0;
112316+ }
112317+ PerformanceDotting.startAdvanced("readBuilderProgram: loaded");
112318+ PerformanceDotting.stopAdvanced("readBuilderProgram: loaded");
112201 return createBuilderProgramUsingProgramBuildInfo(buildInfo.program, buildInfoPath, host);112319 return createBuilderProgramUsingProgramBuildInfo(buildInfo.program, buildInfoPath, host);
112202}112320}
112203function createIncrementalCompilerHost(options, system = sys) {112321function createIncrementalCompilerHost(options, system = sys) {
@@ -113846,11 +113964,17 @@ function listEmittedFile({ write }, proj, file) {
113846 }113964 }
113847}113965}
113848function getOldProgram({ options, builderPrograms, compilerHost }, proj, parsed) {113966function getOldProgram({ options, builderPrograms, compilerHost }, proj, parsed) {
113849- if (options.force)113967+ if (options.force) {
113968+ PerformanceDotting.startAdvanced("getOldProgram: force", `--force flag set, returning undefined for ${proj}`);
113969+ PerformanceDotting.stopAdvanced("getOldProgram: force");
113850 return void 0;113970 return void 0;
113971+ }
113851 const value = builderPrograms.get(proj);113972 const value = builderPrograms.get(proj);
113852- if (value)113973+ if (value) {
113974+ PerformanceDotting.startAdvanced("getOldProgram: cachedBuilderProgram", `reused from builderPrograms map for ${proj}`);
113975+ PerformanceDotting.stopAdvanced("getOldProgram: cachedBuilderProgram");
113853 return value;113976 return value;
113977+ }
113854 return readBuilderProgram(parsed.options, compilerHost);113978 return readBuilderProgram(parsed.options, compilerHost);
113855}113979}
113856function afterProgramDone(state, program, config) {113980function afterProgramDone(state, program, config) {
@@ -108676,6 +108676,7 @@ function createCreateProgramOptions(rootNames, options, host, oldProgram, config
108676function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _configFileParsingDiagnostics) {108676function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _configFileParsingDiagnostics) {
108677 var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;108677 var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
108678 PerformanceDotting.start("createProgram");108678 PerformanceDotting.start("createProgram");
108679+ PerformanceDotting.startAdvanced("createProgram");
108679 const createProgramOptions = isArray(rootNamesOrOptions) ? createCreateProgramOptions(rootNamesOrOptions, _options, _host, _oldProgram, _configFileParsingDiagnostics) : rootNamesOrOptions;108680 const createProgramOptions = isArray(rootNamesOrOptions) ? createCreateProgramOptions(rootNamesOrOptions, _options, _host, _oldProgram, _configFileParsingDiagnostics) : rootNamesOrOptions;
108680 const { rootNames, options, configFileParsingDiagnostics, projectReferences } = createProgramOptions;108681 const { rootNames, options, configFileParsingDiagnostics, projectReferences } = createProgramOptions;
108681 let { oldProgram } = createProgramOptions;108682 let { oldProgram } = createProgramOptions;
@@ -108778,9 +108779,12 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
108778 let structureIsReused;108779 let structureIsReused;
108779 (_f = tracing) == null ? void 0 : _f.push(tracing.Phase.Program, "tryReuseStructureFromOldProgram", {});108780 (_f = tracing) == null ? void 0 : _f.push(tracing.Phase.Program, "tryReuseStructureFromOldProgram", {});
108780 PerformanceDotting.start("tryReuseStructureFromOldProgram");108781 PerformanceDotting.start("tryReuseStructureFromOldProgram");
108782+ PerformanceDotting.startAdvanced("tryReuseStructureFromOldProgram");
108781 structureIsReused = tryReuseStructureFromOldProgram();108783 structureIsReused = tryReuseStructureFromOldProgram();
108782- PerformanceDotting.startAdvanced("structureIsReused: " + structureIsReused);108784+ const structureIsReusedName = structureIsReused === 2 /* Completely */ ? "Completely" : structureIsReused === 1 /* SafeModules */ ? "SafeModules" : "Not";
108783- PerformanceDotting.stopAdvanced("structureIsReused: " + structureIsReused);108785+ PerformanceDotting.startAdvanced("structureIsReused: " + structureIsReusedName);
108786+ PerformanceDotting.stopAdvanced("structureIsReused: " + structureIsReusedName);
108787+ PerformanceDotting.stopAdvanced("tryReuseStructureFromOldProgram");
108784 PerformanceDotting.stop("tryReuseStructureFromOldProgram");108788 PerformanceDotting.stop("tryReuseStructureFromOldProgram");
108785 (_g = tracing) == null ? void 0 : _g.pop();108789 (_g = tracing) == null ? void 0 : _g.pop();
108786 if (structureIsReused !== 2 /* Completely */) {108790 if (structureIsReused !== 2 /* Completely */) {
@@ -108818,23 +108822,28 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
108818 }108822 }
108819 (_h = tracing) == null ? void 0 : _h.push(tracing.Phase.Program, "processRootFiles", { count: rootNames.length });108823 (_h = tracing) == null ? void 0 : _h.push(tracing.Phase.Program, "processRootFiles", { count: rootNames.length });
108820 PerformanceDotting.start("processRootFiles");108824 PerformanceDotting.start("processRootFiles");
108825+ PerformanceDotting.startAdvanced("processRootFiles", `rootNames=${rootNames.length}`);
108821 forEach(rootNames, (name, index) => processRootFile(name, false, false, { kind: 0 /* RootFile */, index }));108826 forEach(rootNames, (name, index) => processRootFile(name, false, false, { kind: 0 /* RootFile */, index }));
108827+ PerformanceDotting.stopAdvanced("processRootFiles");
108822 PerformanceDotting.stop("processRootFiles");108828 PerformanceDotting.stop("processRootFiles");
108823 (_i = tracing) == null ? void 0 : _i.pop();108829 (_i = tracing) == null ? void 0 : _i.pop();
108824 const typeReferences = rootNames.length ? getAutomaticTypeDirectiveNames(options, host) : emptyArray;108830 const typeReferences = rootNames.length ? getAutomaticTypeDirectiveNames(options, host) : emptyArray;
108825 if (typeReferences.length) {108831 if (typeReferences.length) {
108826 (_j = tracing) == null ? void 0 : _j.push(tracing.Phase.Program, "processTypeReferences", { count: typeReferences.length });108832 (_j = tracing) == null ? void 0 : _j.push(tracing.Phase.Program, "processTypeReferences", { count: typeReferences.length });
108827 PerformanceDotting.start("processTypeReferences");108833 PerformanceDotting.start("processTypeReferences");
108834+ PerformanceDotting.startAdvanced("processTypeReferences", `count=${typeReferences.length}`);
108828 const containingDirectory = options.configFilePath ? getDirectoryPath(options.configFilePath) : host.getCurrentDirectory();108835 const containingDirectory = options.configFilePath ? getDirectoryPath(options.configFilePath) : host.getCurrentDirectory();
108829 const containingFilename = combinePaths(containingDirectory, inferredTypesContainingFile);108836 const containingFilename = combinePaths(containingDirectory, inferredTypesContainingFile);
108830 const resolutions = resolveTypeReferenceDirectiveNamesWorker(typeReferences, containingFilename);108837 const resolutions = resolveTypeReferenceDirectiveNamesWorker(typeReferences, containingFilename);
108831 for (let i = 0; i < typeReferences.length; i++) {108838 for (let i = 0; i < typeReferences.length; i++) {
108832 processTypeReferenceDirective(typeReferences[i], void 0, resolutions[i], { kind: 8 /* AutomaticTypeDirectiveFile */, typeReference: typeReferences[i], packageId: (_k = resolutions[i]) == null ? void 0 : _k.packageId });108839 processTypeReferenceDirective(typeReferences[i], void 0, resolutions[i], { kind: 8 /* AutomaticTypeDirectiveFile */, typeReference: typeReferences[i], packageId: (_k = resolutions[i]) == null ? void 0 : _k.packageId });
108833 }108840 }
108841+ PerformanceDotting.stopAdvanced("processTypeReferences");
108834 PerformanceDotting.stop("processTypeReferences");108842 PerformanceDotting.stop("processTypeReferences");
108835 (_l = tracing) == null ? void 0 : _l.pop();108843 (_l = tracing) == null ? void 0 : _l.pop();
108836 }108844 }
108837 PerformanceDotting.start("processDefaultLib");108845 PerformanceDotting.start("processDefaultLib");
108846+ PerformanceDotting.startAdvanced("processDefaultLib");
108838 if (rootNames.length && !skipDefaultLib) {108847 if (rootNames.length && !skipDefaultLib) {
108839 const defaultLibraryFileName = getDefaultLibraryFileName();108848 const defaultLibraryFileName = getDefaultLibraryFileName();
108840 if (!options.lib && defaultLibraryFileName) {108849 if (!options.lib && defaultLibraryFileName) {
@@ -108851,6 +108860,7 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
108851 }108860 }
108852 }108861 }
108853 }108862 }
108863+ PerformanceDotting.stopAdvanced("processDefaultLib");
108854 PerformanceDotting.stop("processDefaultLib");108864 PerformanceDotting.stop("processDefaultLib");
108855 missingFilePaths = arrayFrom(mapDefinedIterator(filesByName.entries(), ([path, file]) => file === void 0 ? path : void 0));108865 missingFilePaths = arrayFrom(mapDefinedIterator(filesByName.entries(), ([path, file]) => file === void 0 ? path : void 0));
108856 files = stableSort(processingDefaultLibFiles, compareDefaultLibFiles).concat(processingOtherFiles);108866 files = stableSort(processingDefaultLibFiles, compareDefaultLibFiles).concat(processingOtherFiles);
@@ -108989,6 +108999,7 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
108989 MemoryDotting.stopRecordStage(recordInfo);108999 MemoryDotting.stopRecordStage(recordInfo);
108990 measure("Program", "beforeProgram", "afterProgram");109000 measure("Program", "beforeProgram", "afterProgram");
108991 (_p = tracing) == null ? void 0 : _p.pop();109001 (_p = tracing) == null ? void 0 : _p.pop();
109002+ PerformanceDotting.stopAdvanced("createProgram");
108992 PerformanceDotting.stop("createProgram");109003 PerformanceDotting.stop("createProgram");
108993 return program;109004 return program;
108994 function addResolutionDiagnostics(list) {109005 function addResolutionDiagnostics(list) {
@@ -109212,39 +109223,71 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109212 return true;109223 return true;
109213 }109224 }
109214 }109225 }
109215- function canReuseProjectReferences() {109226+ function tryReuseProjectReferences() {
109216- return !forEachProjectReference(109227+ return forEachProjectReference(
109217 oldProgram.getProjectReferences(),109228 oldProgram.getProjectReferences(),
109218 oldProgram.getResolvedProjectReferences(),109229 oldProgram.getResolvedProjectReferences(),
109219 (oldResolvedRef, parent2, index) => {109230 (oldResolvedRef, parent2, index) => {
109231+ var _a3, _b2, _c2, _d2;
109220 const newRef = (parent2 ? parent2.commandLine.projectReferences : projectReferences)[index];109232 const newRef = (parent2 ? parent2.commandLine.projectReferences : projectReferences)[index];
109221 const newResolvedRef = parseProjectReferenceConfigFile(newRef);109233 const newResolvedRef = parseProjectReferenceConfigFile(newRef);
109234+ const refPath = (_d2 = (_c2 = (_a3 = newRef == null ? void 0 : newRef.originalPath) != null ? _a3 : newRef == null ? void 0 : newRef.path) != null ? _c2 : (_b2 = oldResolvedRef == null ? void 0 : oldResolvedRef.sourceFile) == null ? void 0 : _b2.fileName) != null ? _d2 : "(unknown project reference)";
109222 if (oldResolvedRef) {109235 if (oldResolvedRef) {
109223- return !newResolvedRef || newResolvedRef.sourceFile !== oldResolvedRef.sourceFile || !arrayIsEqualTo(oldResolvedRef.commandLine.fileNames, newResolvedRef.commandLine.fileNames);109236+ if (!newResolvedRef) {
109237+ return `resolved project reference no longer resolvable: ${refPath}`;
109238+ }
109239+ if (newResolvedRef.sourceFile !== oldResolvedRef.sourceFile) {
109240+ return `project reference sourceFile changed: ${refPath}`;
109241+ }
109242+ if (!arrayIsEqualTo(oldResolvedRef.commandLine.fileNames, newResolvedRef.commandLine.fileNames)) {
109243+ return `project reference fileNames changed: ${refPath}`;
109244+ }
109245+ return void 0;
109224 } else {109246 } else {
109225- return newResolvedRef !== void 0;109247+ if (newResolvedRef !== void 0) {
109248+ return `previously-unresolved project reference now resolved: ${refPath}`;
109249+ }
109250+ return void 0;
109226 }109251 }
109227 },109252 },
109228 (oldProjectReferences, parent2) => {109253 (oldProjectReferences, parent2) => {
109229 const newReferences = parent2 ? getResolvedProjectReferenceByPath(parent2.sourceFile.path).commandLine.projectReferences : projectReferences;109254 const newReferences = parent2 ? getResolvedProjectReferenceByPath(parent2.sourceFile.path).commandLine.projectReferences : projectReferences;
109230- return !arrayIsEqualTo(oldProjectReferences, newReferences, projectReferenceIsEqualTo);109255+ if (!arrayIsEqualTo(oldProjectReferences, newReferences, projectReferenceIsEqualTo)) {
109256+ const owner = parent2 ? parent2.sourceFile.fileName : "(root)";
109257+ return `project references array changed in: ${owner}`;
109258+ }
109259+ return void 0;
109231 }109260 }
109232 );109261 );
109233 }109262 }
109234 function tryReuseStructureFromOldProgram() {109263 function tryReuseStructureFromOldProgram() {
109235- var _a3, _b2;109264+ var _a3, _b2, _c2;
109236 if (!oldProgram) {109265 if (!oldProgram) {
109266+ PerformanceDotting.startAdvanced("structureIsReused: Not", "#1 oldProgram is undefined (first build or .tsbuildinfo missing/deleted/corrupt)");
109267+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
109237 return 0 /* Not */;109268 return 0 /* Not */;
109238 }109269 }
109239 const oldOptions = oldProgram.getCompilerOptions();109270 const oldOptions = oldProgram.getCompilerOptions();
109240 if (changesAffectModuleResolution(oldOptions, options)) {109271 if (changesAffectModuleResolution(oldOptions, options)) {
109272+ const changedOptions = moduleResolutionOptionDeclarations.filter((o) => !isJsonEqual(getCompilerOptionValue(oldOptions, o), getCompilerOptionValue(options, o))).map((o) => o.name);
109273+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#2 changesAffectModuleResolution - changedOptions: [${changedOptions.join(", ")}], configFilePath: ${oldOptions.configFilePath} -> ${options.configFilePath}`);
109274+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
109241 return 0 /* Not */;109275 return 0 /* Not */;
109242 }109276 }
109243 const oldRootNames = oldProgram.getRootFileNames();109277 const oldRootNames = oldProgram.getRootFileNames();
109244 if (!arrayIsEqualTo(oldRootNames, rootNames)) {109278 if (!arrayIsEqualTo(oldRootNames, rootNames)) {
109279+ const addedFiles = rootNames.filter((f) => !oldRootNames.includes(f));
109280+ const removedFiles = oldRootNames.filter((f) => !rootNames.includes(f));
109281+ const addedList = addedFiles.length > 10 ? addedFiles.slice(0, 10).join(", ") + `, ... and ${addedFiles.length - 10} more` : addedFiles.join(", ");
109282+ const removedList = removedFiles.length > 10 ? removedFiles.slice(0, 10).join(", ") + `, ... and ${removedFiles.length - 10} more` : removedFiles.join(", ");
109283+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#3 rootNames changed - oldCount=${oldRootNames.length}, newCount=${rootNames.length}, added=[${addedList}], removed=[${removedList}]`);
109284+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
109245 return 0 /* Not */;109285 return 0 /* Not */;
109246 }109286 }
109247- if (!canReuseProjectReferences()) {109287+ const projectReferenceReuseFailReason = tryReuseProjectReferences();
109288+ if (projectReferenceReuseFailReason !== void 0) {
109289+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#4 tryReuseProjectReferences failed: ${projectReferenceReuseFailReason}`);
109290+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
109248 return 0 /* Not */;109291 return 0 /* Not */;
109249 }109292 }
109250 if (projectReferences) {109293 if (projectReferences) {
@@ -109253,7 +109296,10 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109253 const newSourceFiles = [];109296 const newSourceFiles = [];
109254 const modifiedSourceFiles = [];109297 const modifiedSourceFiles = [];
109255 structureIsReused = 2 /* Completely */;109298 structureIsReused = 2 /* Completely */;
109256- if (oldProgram.getMissingFilePaths().some((missingFilePath) => host.fileExists(missingFilePath))) {109299+ const nowExistingMissingFilePath = oldProgram.getMissingFilePaths().find((missingFilePath) => host.fileExists(missingFilePath));
109300+ if (nowExistingMissingFilePath !== void 0) {
109301+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#5 a previously missing file now exists: ${nowExistingMissingFilePath}`);
109302+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
109257 return 0 /* Not */;109303 return 0 /* Not */;
109258 }109304 }
109259 const oldSourceFiles = oldProgram.getSourceFiles();109305 const oldSourceFiles = oldProgram.getSourceFiles();
@@ -109267,6 +109313,8 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109267 const sourceFileOptions = getCreateSourceFileOptions(oldSourceFile.fileName, moduleResolutionCache, host, options);109313 const sourceFileOptions = getCreateSourceFileOptions(oldSourceFile.fileName, moduleResolutionCache, host, options);
109268 let newSourceFile = host.getSourceFileByPath ? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.resolvedPath, sourceFileOptions, void 0, shouldCreateNewSourceFile || sourceFileOptions.impliedNodeFormat !== oldSourceFile.impliedNodeFormat) : host.getSourceFile(oldSourceFile.fileName, sourceFileOptions, void 0, shouldCreateNewSourceFile || sourceFileOptions.impliedNodeFormat !== oldSourceFile.impliedNodeFormat);109314 let newSourceFile = host.getSourceFileByPath ? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.resolvedPath, sourceFileOptions, void 0, shouldCreateNewSourceFile || sourceFileOptions.impliedNodeFormat !== oldSourceFile.impliedNodeFormat) : host.getSourceFile(oldSourceFile.fileName, sourceFileOptions, void 0, shouldCreateNewSourceFile || sourceFileOptions.impliedNodeFormat !== oldSourceFile.impliedNodeFormat);
109269 if (!newSourceFile) {109315 if (!newSourceFile) {
109316+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#6 source file no longer exists: ${oldSourceFile.fileName}`);
109317+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
109270 return 0 /* Not */;109318 return 0 /* Not */;
109271 }109319 }
109272 newSourceFile.packageJsonLocations = ((_a3 = sourceFileOptions.packageJsonLocations) == null ? void 0 : _a3.length) ? sourceFileOptions.packageJsonLocations : void 0;109320 newSourceFile.packageJsonLocations = ((_a3 = sourceFileOptions.packageJsonLocations) == null ? void 0 : _a3.length) ? sourceFileOptions.packageJsonLocations : void 0;
@@ -109275,12 +109323,16 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109275 let fileChanged;109323 let fileChanged;
109276 if (oldSourceFile.redirectInfo) {109324 if (oldSourceFile.redirectInfo) {
109277 if (newSourceFile !== oldSourceFile.redirectInfo.unredirected) {109325 if (newSourceFile !== oldSourceFile.redirectInfo.unredirected) {
109326+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#7 redirect underlying file changed: ${oldSourceFile.fileName}`);
109327+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
109278 return 0 /* Not */;109328 return 0 /* Not */;
109279 }109329 }
109280 fileChanged = false;109330 fileChanged = false;
109281 newSourceFile = oldSourceFile;109331 newSourceFile = oldSourceFile;
109282 } else if (oldProgram.redirectTargetsMap.has(oldSourceFile.path)) {109332 } else if (oldProgram.redirectTargetsMap.has(oldSourceFile.path)) {
109283 if (newSourceFile !== oldSourceFile) {109333 if (newSourceFile !== oldSourceFile) {
109334+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#8 redirected-to file changed: ${oldSourceFile.fileName}`);
109335+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
109284 return 0 /* Not */;109336 return 0 /* Not */;
109285 }109337 }
109286 fileChanged = false;109338 fileChanged = false;
@@ -109296,39 +109348,61 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109296 const prevKind = seenPackageNames.get(packageName);109348 const prevKind = seenPackageNames.get(packageName);
109297 const newKind = fileChanged ? 1 /* Modified */ : 0 /* Exists */;109349 const newKind = fileChanged ? 1 /* Modified */ : 0 /* Exists */;
109298 if (prevKind !== void 0 && newKind === 1 /* Modified */ || prevKind === 1 /* Modified */) {109350 if (prevKind !== void 0 && newKind === 1 /* Modified */ || prevKind === 1 /* Modified */) {
109351+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#9 package name conflict (two files for package "${packageName}", at least one changed): ${oldSourceFile.fileName}`);
109352+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
109299 return 0 /* Not */;109353 return 0 /* Not */;
109300 }109354 }
109301 seenPackageNames.set(packageName, newKind);109355 seenPackageNames.set(packageName, newKind);
109302 }109356 }
109303 if (fileChanged) {109357 if (fileChanged) {
109304 if (oldSourceFile.impliedNodeFormat !== newSourceFile.impliedNodeFormat) {109358 if (oldSourceFile.impliedNodeFormat !== newSourceFile.impliedNodeFormat) {
109359+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `impliedNodeFormat changed: ${oldSourceFile.fileName}`);
109360+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109305 structureIsReused = 1 /* SafeModules */;109361 structureIsReused = 1 /* SafeModules */;
109306 } else if (!arrayIsEqualTo(oldSourceFile.libReferenceDirectives, newSourceFile.libReferenceDirectives, fileReferenceIsEqualTo)) {109362 } else if (!arrayIsEqualTo(oldSourceFile.libReferenceDirectives, newSourceFile.libReferenceDirectives, fileReferenceIsEqualTo)) {
109363+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `libReferenceDirectives changed: ${oldSourceFile.fileName}`);
109364+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109307 structureIsReused = 1 /* SafeModules */;109365 structureIsReused = 1 /* SafeModules */;
109308 } else if (oldSourceFile.hasNoDefaultLib !== newSourceFile.hasNoDefaultLib) {109366 } else if (oldSourceFile.hasNoDefaultLib !== newSourceFile.hasNoDefaultLib) {
109367+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `hasNoDefaultLib changed: ${oldSourceFile.fileName}`);
109368+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109309 structureIsReused = 1 /* SafeModules */;109369 structureIsReused = 1 /* SafeModules */;
109310 } else if (!arrayIsEqualTo(oldSourceFile.referencedFiles, newSourceFile.referencedFiles, fileReferenceIsEqualTo)) {109370 } else if (!arrayIsEqualTo(oldSourceFile.referencedFiles, newSourceFile.referencedFiles, fileReferenceIsEqualTo)) {
109371+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `referencedFiles changed: ${oldSourceFile.fileName}`);
109372+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109311 structureIsReused = 1 /* SafeModules */;109373 structureIsReused = 1 /* SafeModules */;
109312 } else {109374 } else {
109313 collectExternalModuleReferences(newSourceFile);109375 collectExternalModuleReferences(newSourceFile);
109314 if (!arrayIsEqualTo(oldSourceFile.imports, newSourceFile.imports, moduleNameIsEqualTo)) {109376 if (!arrayIsEqualTo(oldSourceFile.imports, newSourceFile.imports, moduleNameIsEqualTo)) {
109377+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `imports changed: ${oldSourceFile.fileName}`);
109378+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109315 structureIsReused = 1 /* SafeModules */;109379 structureIsReused = 1 /* SafeModules */;
109316 } else if (!arrayIsEqualTo(oldSourceFile.moduleAugmentations, newSourceFile.moduleAugmentations, moduleNameIsEqualTo)) {109380 } else if (!arrayIsEqualTo(oldSourceFile.moduleAugmentations, newSourceFile.moduleAugmentations, moduleNameIsEqualTo)) {
109381+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `moduleAugmentations changed: ${oldSourceFile.fileName}`);
109382+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109317 structureIsReused = 1 /* SafeModules */;109383 structureIsReused = 1 /* SafeModules */;
109318 } else if ((oldSourceFile.flags & 6291456 /* PermanentlySetIncrementalFlags */) !== (newSourceFile.flags & 6291456 /* PermanentlySetIncrementalFlags */)) {109384 } else if ((oldSourceFile.flags & 6291456 /* PermanentlySetIncrementalFlags */) !== (newSourceFile.flags & 6291456 /* PermanentlySetIncrementalFlags */)) {
109385+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `PermanentlySetIncrementalFlags changed: ${oldSourceFile.fileName}`);
109386+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109319 structureIsReused = 1 /* SafeModules */;109387 structureIsReused = 1 /* SafeModules */;
109320 } else if (!arrayIsEqualTo(oldSourceFile.typeReferenceDirectives, newSourceFile.typeReferenceDirectives, fileReferenceIsEqualTo)) {109388 } else if (!arrayIsEqualTo(oldSourceFile.typeReferenceDirectives, newSourceFile.typeReferenceDirectives, fileReferenceIsEqualTo)) {
109389+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `typeReferenceDirectives changed: ${oldSourceFile.fileName}`);
109390+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109321 structureIsReused = 1 /* SafeModules */;109391 structureIsReused = 1 /* SafeModules */;
109322 }109392 }
109323 }109393 }
109324 modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });109394 modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });
109325 } else if (hasInvalidatedResolutions(oldSourceFile.path)) {109395 } else if (hasInvalidatedResolutions(oldSourceFile.path)) {
109396+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `hasInvalidatedResolutions: ${oldSourceFile.fileName}`);
109397+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109326 structureIsReused = 1 /* SafeModules */;109398 structureIsReused = 1 /* SafeModules */;
109327 modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });109399 modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });
109328 }109400 }
109329 newSourceFiles.push(newSourceFile);109401 newSourceFiles.push(newSourceFile);
109330 }109402 }
109331 if (structureIsReused !== 2 /* Completely */) {109403 if (structureIsReused !== 2 /* Completely */) {
109404+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `file content changed but module resolution reusable, modifiedFiles=${modifiedSourceFiles.length}`);
109405+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109332 return structureIsReused;109406 return structureIsReused;
109333 }109407 }
109334 const modifiedFiles = modifiedSourceFiles.map((f) => f.oldFile);109408 const modifiedFiles = modifiedSourceFiles.map((f) => f.oldFile);
@@ -109339,11 +109413,14 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109339 }109413 }
109340 }109414 }
109341 }109415 }
109416+ PerformanceDotting.startAdvanced("resolveModuleNames", `modifiedFiles=${modifiedSourceFiles.length}`);
109342 for (const { oldFile: oldSourceFile, newFile: newSourceFile } of modifiedSourceFiles) {109417 for (const { oldFile: oldSourceFile, newFile: newSourceFile } of modifiedSourceFiles) {
109343 const moduleNames = getModuleNames(newSourceFile);109418 const moduleNames = getModuleNames(newSourceFile);
109344 const resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFile);109419 const resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFile);
109345 const resolutionsChanged = hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, oldSourceFile, moduleResolutionIsEqualTo);109420 const resolutionsChanged = hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, oldSourceFile, moduleResolutionIsEqualTo);
109346 if (resolutionsChanged) {109421 if (resolutionsChanged) {
109422+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `module resolution changed: ${newSourceFile.fileName}`);
109423+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109347 structureIsReused = 1 /* SafeModules */;109424 structureIsReused = 1 /* SafeModules */;
109348 newSourceFile.resolvedModules = zipToModeAwareCache(newSourceFile, moduleNames, resolutions);109425 newSourceFile.resolvedModules = zipToModeAwareCache(newSourceFile, moduleNames, resolutions);
109349 } else {109426 } else {
@@ -109353,16 +109430,31 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109353 const typeReferenceResolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFile);109430 const typeReferenceResolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFile);
109354 const typeReferenceResolutionsChanged = hasChangesInResolutions(typesReferenceDirectives, typeReferenceResolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, oldSourceFile, typeDirectiveIsEqualTo);109431 const typeReferenceResolutionsChanged = hasChangesInResolutions(typesReferenceDirectives, typeReferenceResolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, oldSourceFile, typeDirectiveIsEqualTo);
109355 if (typeReferenceResolutionsChanged) {109432 if (typeReferenceResolutionsChanged) {
109433+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `typeReference resolution changed: ${newSourceFile.fileName}`);
109434+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109356 structureIsReused = 1 /* SafeModules */;109435 structureIsReused = 1 /* SafeModules */;
109357 newSourceFile.resolvedTypeReferenceDirectiveNames = zipToModeAwareCache(newSourceFile, typesReferenceDirectives, typeReferenceResolutions);109436 newSourceFile.resolvedTypeReferenceDirectiveNames = zipToModeAwareCache(newSourceFile, typesReferenceDirectives, typeReferenceResolutions);
109358 } else {109437 } else {
109359 newSourceFile.resolvedTypeReferenceDirectiveNames = oldSourceFile.resolvedTypeReferenceDirectiveNames;109438 newSourceFile.resolvedTypeReferenceDirectiveNames = oldSourceFile.resolvedTypeReferenceDirectiveNames;
109360 }109439 }
109361 }109440 }
109441+ PerformanceDotting.stopAdvanced("resolveModuleNames");
109362 if (structureIsReused !== 2 /* Completely */) {109442 if (structureIsReused !== 2 /* Completely */) {
109443+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `module resolution changed for modified files, modifiedFiles=${modifiedSourceFiles.length}`);
109444+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109363 return structureIsReused;109445 return structureIsReused;
109364 }109446 }
109365 if (changesAffectingProgramStructure(oldOptions, options) || ((_b2 = host.hasChangedAutomaticTypeDirectiveNames) == null ? void 0 : _b2.call(host))) {109447 if (changesAffectingProgramStructure(oldOptions, options) || ((_b2 = host.hasChangedAutomaticTypeDirectiveNames) == null ? void 0 : _b2.call(host))) {
109448+ const reasons = [];
109449+ if (changesAffectingProgramStructure(oldOptions, options)) {
109450+ const changedOpts = optionsAffectingProgramStructure.filter((o) => !isJsonEqual(getCompilerOptionValue(oldOptions, o), getCompilerOptionValue(options, o))).map((o) => o.name);
109451+ reasons.push(`changesAffectingProgramStructure: [${changedOpts.join(", ")}]`);
109452+ }
109453+ if ((_c2 = host.hasChangedAutomaticTypeDirectiveNames) == null ? void 0 : _c2.call(host)) {
109454+ reasons.push("hasChangedAutomaticTypeDirectiveNames");
109455+ }
109456+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `#10 ${reasons.join("; ")}`);
109457+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109366 return 1 /* SafeModules */;109458 return 1 /* SafeModules */;
109367 }109459 }
109368 missingFilePaths = oldProgram.getMissingFilePaths();109460 missingFilePaths = oldProgram.getMissingFilePaths();
@@ -109391,6 +109483,8 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109391 sourceFileToPackageName = oldProgram.sourceFileToPackageName;109483 sourceFileToPackageName = oldProgram.sourceFileToPackageName;
109392 redirectTargetsMap = oldProgram.redirectTargetsMap;109484 redirectTargetsMap = oldProgram.redirectTargetsMap;
109393 usesUriStyleNodeCoreModules = oldProgram.usesUriStyleNodeCoreModules;109485 usesUriStyleNodeCoreModules = oldProgram.usesUriStyleNodeCoreModules;
109486+ PerformanceDotting.startAdvanced("structureIsReused: Completely", "structure fully reused from old program");
109487+ PerformanceDotting.stopAdvanced("structureIsReused: Completely");
109394 return 2 /* Completely */;109488 return 2 /* Completely */;
109395 }109489 }
109396 function getEmitHost(writeFileCallback) {109490 function getEmitHost(writeFileCallback) {
@@ -112602,13 +112696,21 @@ function getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldP
112602 oldProgram = configFileParsingDiagnosticsOrOldProgram;112696 oldProgram = configFileParsingDiagnosticsOrOldProgram;
112603 Debug.assert(!!oldProgram);112697 Debug.assert(!!oldProgram);
112604 newProgram = oldProgram.getProgram();112698 newProgram = oldProgram.getProgram();
112699+ PerformanceDotting.startAdvanced("getBuilderCreationParameters: reuseProgramFromOldProgram", "newProgramOrRootNames undefined, no createProgram call");
112700+ PerformanceDotting.stopAdvanced("getBuilderCreationParameters: reuseProgramFromOldProgram");
112605 } else if (isArray(newProgramOrRootNames)) {112701 } else if (isArray(newProgramOrRootNames)) {
112606 oldProgram = configFileParsingDiagnosticsOrOldProgram;112702 oldProgram = configFileParsingDiagnosticsOrOldProgram;
112703+ const oldProgramForCreate = oldProgram && oldProgram.getProgramOrUndefined();
112704+ PerformanceDotting.startAdvanced(
112705+ "getBuilderCreationParameters: createProgram",
112706+ `oldProgram=${!!oldProgram}, hasOldProgram=${!!oldProgramForCreate}, rootNames=${newProgramOrRootNames.length}`
112707+ );
112708+ PerformanceDotting.stopAdvanced("getBuilderCreationParameters: createProgram");
112607 newProgram = createProgram({112709 newProgram = createProgram({
112608 rootNames: newProgramOrRootNames,112710 rootNames: newProgramOrRootNames,
112609 options: hostOrOptions,112711 options: hostOrOptions,
112610 host: oldProgramOrHost,112712 host: oldProgramOrHost,
112611- oldProgram: oldProgram && oldProgram.getProgramOrUndefined(),112713+ oldProgram: oldProgramForCreate,
112612 configFileParsingDiagnostics,112714 configFileParsingDiagnostics,
112613 projectReferences112715 projectReferences
112614 });112716 });
@@ -112618,6 +112720,8 @@ function getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldP
112618 host = hostOrOptions;112720 host = hostOrOptions;
112619 oldProgram = oldProgramOrHost;112721 oldProgram = oldProgramOrHost;
112620 configFileParsingDiagnostics = configFileParsingDiagnosticsOrOldProgram;112722 configFileParsingDiagnostics = configFileParsingDiagnosticsOrOldProgram;
112723+ PerformanceDotting.startAdvanced("getBuilderCreationParameters: newProgramProvided", `newProgram=${!!newProgram}, host=${!!host}, oldProgram=${!!oldProgram}, configFileParsingDiagnostics=${!!configFileParsingDiagnostics}`);
112724+ PerformanceDotting.stopAdvanced("getBuilderCreationParameters: newProgramProvided");
112621 }112725 }
112622 return { host, newProgram, oldProgram, configFileParsingDiagnostics: configFileParsingDiagnostics || emptyArray };112726 return { host, newProgram, oldProgram, configFileParsingDiagnostics: configFileParsingDiagnostics || emptyArray };
112623}112727}
@@ -113107,6 +113211,7 @@ function createEmitAndSemanticDiagnosticsBuilderProgram(newProgramOrRootNames, h
113107}113211}
113108function createEmitAndSemanticDiagnosticsBuilderProgramForArkTs(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences) {113212function createEmitAndSemanticDiagnosticsBuilderProgramForArkTs(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences) {
113109 PerformanceDotting.start("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");113213 PerformanceDotting.start("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");
113214+ PerformanceDotting.startAdvanced("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");
113110 PerformanceDotting.start("getBuilderCreationParameters");113215 PerformanceDotting.start("getBuilderCreationParameters");
113111 let builderCreatetionParameters = getBuilderCreationParameters(113216 let builderCreatetionParameters = getBuilderCreationParameters(
113112 newProgramOrRootNames,113217 newProgramOrRootNames,
@@ -113119,22 +113224,27 @@ function createEmitAndSemanticDiagnosticsBuilderProgramForArkTs(newProgramOrRoot
113119 PerformanceDotting.stop("getBuilderCreationParameters");113224 PerformanceDotting.stop("getBuilderCreationParameters");
113120 let newProgram = builderCreatetionParameters.newProgram;113225 let newProgram = builderCreatetionParameters.newProgram;
113121 PerformanceDotting.start("createBuilderProgram");113226 PerformanceDotting.start("createBuilderProgram");
113227+ PerformanceDotting.startAdvanced("createBuilderProgram");
113122 let builderProgram = createBuilderProgram(113228 let builderProgram = createBuilderProgram(
113123 1 /* EmitAndSemanticDiagnosticsBuilderProgram */,113229 1 /* EmitAndSemanticDiagnosticsBuilderProgram */,
113124 builderCreatetionParameters113230 builderCreatetionParameters
113125 );113231 );
113232+ PerformanceDotting.stopAdvanced("createBuilderProgram");
113126 PerformanceDotting.stop("createBuilderProgram");113233 PerformanceDotting.stop("createBuilderProgram");
113127 let oldProgramForLinter = readBuilderProgram(hostOrOptions, oldProgramOrHost, true);113234 let oldProgramForLinter = readBuilderProgram(hostOrOptions, oldProgramOrHost, true);
113128 builderCreatetionParameters.oldProgram = oldProgramForLinter;113235 builderCreatetionParameters.oldProgram = oldProgramForLinter;
113129 builderCreatetionParameters.newProgram = newProgram;113236 builderCreatetionParameters.newProgram = newProgram;
113130 PerformanceDotting.start("createBuilderProgramForLinter");113237 PerformanceDotting.start("createBuilderProgramForLinter");
113238+ PerformanceDotting.startAdvanced("createBuilderProgramForLinter");
113131 let builderProgramForLinter = createBuilderProgram(113239 let builderProgramForLinter = createBuilderProgram(
113132 1 /* EmitAndSemanticDiagnosticsBuilderProgram */,113240 1 /* EmitAndSemanticDiagnosticsBuilderProgram */,
113133 builderCreatetionParameters,113241 builderCreatetionParameters,
113134 true113242 true
113135 );113243 );
113244+ PerformanceDotting.stopAdvanced("createBuilderProgramForLinter");
113136 PerformanceDotting.stop("createBuilderProgramForLinter");113245 PerformanceDotting.stop("createBuilderProgramForLinter");
113137 builderProgram.builderProgramForLinter = builderProgramForLinter;113246 builderProgram.builderProgramForLinter = builderProgramForLinter;
113247+ PerformanceDotting.stopAdvanced("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");
113138 PerformanceDotting.stop("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");113248 PerformanceDotting.stop("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");
113139 return builderProgram;113249 return builderProgram;
113140}113250}
@@ -114549,12 +114659,20 @@ function readBuilderProgram(compilerOptions, host, isForLinter) {
114549 buildInfo = host.getBuildInfo(buildInfoPath, compilerOptions.configFilePath);114659 buildInfo = host.getBuildInfo(buildInfoPath, compilerOptions.configFilePath);
114550 } else {114660 } else {
114551 const content = host.readFile(buildInfoPath);114661 const content = host.readFile(buildInfoPath);
114552- if (!content)114662+ if (!content) {
114663+ PerformanceDotting.startAdvanced("readBuilderProgram: buildInfoNotFound", `${buildInfoPath} not found`);
114664+ PerformanceDotting.stopAdvanced("readBuilderProgram: buildInfoNotFound");
114553 return void 0;114665 return void 0;
114666+ }
114554 buildInfo = getBuildInfo(buildInfoPath, content);114667 buildInfo = getBuildInfo(buildInfoPath, content);
114555 }114668 }
114556- if (!buildInfo || buildInfo.version !== version || !buildInfo.program)114669+ if (!buildInfo || buildInfo.version !== version || !buildInfo.program) {
114670+ PerformanceDotting.startAdvanced("readBuilderProgram: invalidBuildInfo", `path=${buildInfoPath}, version=${buildInfo == null ? void 0 : buildInfo.version}, hasProgram=${!!(buildInfo == null ? void 0 : buildInfo.program)}`);
114671+ PerformanceDotting.stopAdvanced("readBuilderProgram: invalidBuildInfo");
114557 return void 0;114672 return void 0;
114673+ }
114674+ PerformanceDotting.startAdvanced("readBuilderProgram: loaded");
114675+ PerformanceDotting.stopAdvanced("readBuilderProgram: loaded");
114558 return createBuilderProgramUsingProgramBuildInfo(buildInfo.program, buildInfoPath, host);114676 return createBuilderProgramUsingProgramBuildInfo(buildInfo.program, buildInfoPath, host);
114559}114677}
114560function createIncrementalCompilerHost(options, system = sys) {114678function createIncrementalCompilerHost(options, system = sys) {
@@ -116179,11 +116297,17 @@ function listEmittedFile({ write }, proj, file) {
116179 }116297 }
116180}116298}
116181function getOldProgram({ options, builderPrograms, compilerHost }, proj, parsed) {116299function getOldProgram({ options, builderPrograms, compilerHost }, proj, parsed) {
116182- if (options.force)116300+ if (options.force) {
116301+ PerformanceDotting.startAdvanced("getOldProgram: force", `--force flag set, returning undefined for ${proj}`);
116302+ PerformanceDotting.stopAdvanced("getOldProgram: force");
116183 return void 0;116303 return void 0;
116304+ }
116184 const value = builderPrograms.get(proj);116305 const value = builderPrograms.get(proj);
116185- if (value)116306+ if (value) {
116307+ PerformanceDotting.startAdvanced("getOldProgram: cachedBuilderProgram", `reused from builderPrograms map for ${proj}`);
116308+ PerformanceDotting.stopAdvanced("getOldProgram: cachedBuilderProgram");
116186 return value;116309 return value;
116310+ }
116187 return readBuilderProgram(parsed.options, compilerHost);116311 return readBuilderProgram(parsed.options, compilerHost);
116188}116312}
116189function afterProgramDone(state, program, config) {116313function afterProgramDone(state, program, config) {
@@ -127946,7 +128070,9 @@ function createLanguageService(host, documentRegistry = createDocumentRegistry(h
127946 };128070 };
127947 const documentRegistryBucketKey = documentRegistry.getKeyForCompilationSettings(newSettings);128071 const documentRegistryBucketKey = documentRegistry.getKeyForCompilationSettings(newSettings);
127948 PerformanceDotting.start("isProgramUptoDate");128072 PerformanceDotting.start("isProgramUptoDate");
128073+ PerformanceDotting.startAdvanced("isProgramUptoDate");
127949 if (isProgramUptoDate(program, rootFileNames, newSettings, (_path, fileName) => host.getScriptVersion(fileName), (fileName) => compilerHost.fileExists(fileName), hasInvalidatedResolutions, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) {128074 if (isProgramUptoDate(program, rootFileNames, newSettings, (_path, fileName) => host.getScriptVersion(fileName), (fileName) => compilerHost.fileExists(fileName), hasInvalidatedResolutions, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) {
128075+ PerformanceDotting.stopAdvanced("isProgramUptoDate");
127950 PerformanceDotting.stop("isProgramUptoDate");128076 PerformanceDotting.stop("isProgramUptoDate");
127951 host.clearFileCache && host.clearFileCache();128077 host.clearFileCache && host.clearFileCache();
127952 if (isCreateIncrementalProgramMode && (builderProgram == null ? void 0 : builderProgram.resetConstEnumRelateUpdateFlag)) {128078 if (isCreateIncrementalProgramMode && (builderProgram == null ? void 0 : builderProgram.resetConstEnumRelateUpdateFlag)) {
@@ -127954,6 +128080,7 @@ function createLanguageService(host, documentRegistry = createDocumentRegistry(h
127954 }128080 }
127955 return;128081 return;
127956 }128082 }
128083+ PerformanceDotting.stopAdvanced("isProgramUptoDate");
127957 PerformanceDotting.stop("isProgramUptoDate");128084 PerformanceDotting.stop("isProgramUptoDate");
127958 host.clearProps && host.clearProps();128085 host.clearProps && host.clearProps();
127959 compilerHost.getLastCompiledProgram = () => {128086 compilerHost.getLastCompiledProgram = () => {
@@ -127981,7 +128108,9 @@ function createLanguageService(host, documentRegistry = createDocumentRegistry(h
127981 compilerHost = void 0;128108 compilerHost = void 0;
127982 parsedCommandLines = void 0;128109 parsedCommandLines = void 0;
127983 sourceMapper.clearCache();128110 sourceMapper.clearCache();
128111+ PerformanceDotting.startAdvanced("getTypeChecker");
127984 program.getTypeChecker();128112 program.getTypeChecker();
128113+ PerformanceDotting.stopAdvanced("getTypeChecker");
127985 host.clearFileCache && host.clearFileCache();128114 host.clearFileCache && host.clearFileCache();
127986 return;128115 return;
127987 function getParsedCommandLine(fileName) {128116 function getParsedCommandLine(fileName) {
@@ -177507,7 +177636,7 @@ function runArkTSLinter2(tsBuilderProgram, srcFile, buildInfoWriteFile, arkTSVer
177507 const tscStrictDiagnostics = getTscDiagnostics2(tscDiagnosticsLinter, srcFiles.filter((file) => changedFiles.has(file.resolvedPath)));177636 const tscStrictDiagnostics = getTscDiagnostics2(tscDiagnosticsLinter, srcFiles.filter((file) => changedFiles.has(file.resolvedPath)));
177508 timePrinterInstance.appendTime("getTscDiagnostics" /* GET_TSC_DIAGNOSTICS */);177637 timePrinterInstance.appendTime("getTscDiagnostics" /* GET_TSC_DIAGNOSTICS */);
177509 PerformanceDotting.stopAdvanced("getTscDiagnostics" /* GET_TSC_DIAGNOSTICS */);177638 PerformanceDotting.stopAdvanced("getTscDiagnostics" /* GET_TSC_DIAGNOSTICS */);
177510- const lintRecordLog = "lint" /* LINT */ + "(checkedFilesNum: " + changedFiles.size + ")";177639+ const lintRecordLog = "lint" /* LINT */ + "(checkedFilesNum: " + changedFiles.size + ", totalFilesNum: " + srcFiles.length + ")";
177511 PerformanceDotting.startAdvanced(lintRecordLog);177640 PerformanceDotting.startAdvanced(lintRecordLog);
177512 TypeScriptLinter2.initGlobals(compilerOptions);177641 TypeScriptLinter2.initGlobals(compilerOptions);
177513 InteropTypescriptLinter.initGlobals();177642 InteropTypescriptLinter.initGlobals();
@@ -108578,6 +108578,7 @@ function createCreateProgramOptions(rootNames, options, host, oldProgram, config
108578function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _configFileParsingDiagnostics) {108578function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _configFileParsingDiagnostics) {
108579 var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;108579 var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
108580 PerformanceDotting.start("createProgram");108580 PerformanceDotting.start("createProgram");
108581+ PerformanceDotting.startAdvanced("createProgram");
108581 const createProgramOptions = isArray(rootNamesOrOptions) ? createCreateProgramOptions(rootNamesOrOptions, _options, _host, _oldProgram, _configFileParsingDiagnostics) : rootNamesOrOptions;108582 const createProgramOptions = isArray(rootNamesOrOptions) ? createCreateProgramOptions(rootNamesOrOptions, _options, _host, _oldProgram, _configFileParsingDiagnostics) : rootNamesOrOptions;
108582 const { rootNames, options, configFileParsingDiagnostics, projectReferences } = createProgramOptions;108583 const { rootNames, options, configFileParsingDiagnostics, projectReferences } = createProgramOptions;
108583 let { oldProgram } = createProgramOptions;108584 let { oldProgram } = createProgramOptions;
@@ -108680,9 +108681,12 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
108680 let structureIsReused;108681 let structureIsReused;
108681 (_f = tracing) == null ? void 0 : _f.push(tracing.Phase.Program, "tryReuseStructureFromOldProgram", {});108682 (_f = tracing) == null ? void 0 : _f.push(tracing.Phase.Program, "tryReuseStructureFromOldProgram", {});
108682 PerformanceDotting.start("tryReuseStructureFromOldProgram");108683 PerformanceDotting.start("tryReuseStructureFromOldProgram");
108684+ PerformanceDotting.startAdvanced("tryReuseStructureFromOldProgram");
108683 structureIsReused = tryReuseStructureFromOldProgram();108685 structureIsReused = tryReuseStructureFromOldProgram();
108684- PerformanceDotting.startAdvanced("structureIsReused: " + structureIsReused);108686+ const structureIsReusedName = structureIsReused === 2 /* Completely */ ? "Completely" : structureIsReused === 1 /* SafeModules */ ? "SafeModules" : "Not";
108685- PerformanceDotting.stopAdvanced("structureIsReused: " + structureIsReused);108687+ PerformanceDotting.startAdvanced("structureIsReused: " + structureIsReusedName);
108688+ PerformanceDotting.stopAdvanced("structureIsReused: " + structureIsReusedName);
108689+ PerformanceDotting.stopAdvanced("tryReuseStructureFromOldProgram");
108686 PerformanceDotting.stop("tryReuseStructureFromOldProgram");108690 PerformanceDotting.stop("tryReuseStructureFromOldProgram");
108687 (_g = tracing) == null ? void 0 : _g.pop();108691 (_g = tracing) == null ? void 0 : _g.pop();
108688 if (structureIsReused !== 2 /* Completely */) {108692 if (structureIsReused !== 2 /* Completely */) {
@@ -108720,23 +108724,28 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
108720 }108724 }
108721 (_h = tracing) == null ? void 0 : _h.push(tracing.Phase.Program, "processRootFiles", { count: rootNames.length });108725 (_h = tracing) == null ? void 0 : _h.push(tracing.Phase.Program, "processRootFiles", { count: rootNames.length });
108722 PerformanceDotting.start("processRootFiles");108726 PerformanceDotting.start("processRootFiles");
108727+ PerformanceDotting.startAdvanced("processRootFiles", `rootNames=${rootNames.length}`);
108723 forEach(rootNames, (name, index) => processRootFile(name, false, false, { kind: 0 /* RootFile */, index }));108728 forEach(rootNames, (name, index) => processRootFile(name, false, false, { kind: 0 /* RootFile */, index }));
108729+ PerformanceDotting.stopAdvanced("processRootFiles");
108724 PerformanceDotting.stop("processRootFiles");108730 PerformanceDotting.stop("processRootFiles");
108725 (_i = tracing) == null ? void 0 : _i.pop();108731 (_i = tracing) == null ? void 0 : _i.pop();
108726 const typeReferences = rootNames.length ? getAutomaticTypeDirectiveNames(options, host) : emptyArray;108732 const typeReferences = rootNames.length ? getAutomaticTypeDirectiveNames(options, host) : emptyArray;
108727 if (typeReferences.length) {108733 if (typeReferences.length) {
108728 (_j = tracing) == null ? void 0 : _j.push(tracing.Phase.Program, "processTypeReferences", { count: typeReferences.length });108734 (_j = tracing) == null ? void 0 : _j.push(tracing.Phase.Program, "processTypeReferences", { count: typeReferences.length });
108729 PerformanceDotting.start("processTypeReferences");108735 PerformanceDotting.start("processTypeReferences");
108736+ PerformanceDotting.startAdvanced("processTypeReferences", `count=${typeReferences.length}`);
108730 const containingDirectory = options.configFilePath ? getDirectoryPath(options.configFilePath) : host.getCurrentDirectory();108737 const containingDirectory = options.configFilePath ? getDirectoryPath(options.configFilePath) : host.getCurrentDirectory();
108731 const containingFilename = combinePaths(containingDirectory, inferredTypesContainingFile);108738 const containingFilename = combinePaths(containingDirectory, inferredTypesContainingFile);
108732 const resolutions = resolveTypeReferenceDirectiveNamesWorker(typeReferences, containingFilename);108739 const resolutions = resolveTypeReferenceDirectiveNamesWorker(typeReferences, containingFilename);
108733 for (let i = 0; i < typeReferences.length; i++) {108740 for (let i = 0; i < typeReferences.length; i++) {
108734 processTypeReferenceDirective(typeReferences[i], void 0, resolutions[i], { kind: 8 /* AutomaticTypeDirectiveFile */, typeReference: typeReferences[i], packageId: (_k = resolutions[i]) == null ? void 0 : _k.packageId });108741 processTypeReferenceDirective(typeReferences[i], void 0, resolutions[i], { kind: 8 /* AutomaticTypeDirectiveFile */, typeReference: typeReferences[i], packageId: (_k = resolutions[i]) == null ? void 0 : _k.packageId });
108735 }108742 }
108743+ PerformanceDotting.stopAdvanced("processTypeReferences");
108736 PerformanceDotting.stop("processTypeReferences");108744 PerformanceDotting.stop("processTypeReferences");
108737 (_l = tracing) == null ? void 0 : _l.pop();108745 (_l = tracing) == null ? void 0 : _l.pop();
108738 }108746 }
108739 PerformanceDotting.start("processDefaultLib");108747 PerformanceDotting.start("processDefaultLib");
108748+ PerformanceDotting.startAdvanced("processDefaultLib");
108740 if (rootNames.length && !skipDefaultLib) {108749 if (rootNames.length && !skipDefaultLib) {
108741 const defaultLibraryFileName = getDefaultLibraryFileName();108750 const defaultLibraryFileName = getDefaultLibraryFileName();
108742 if (!options.lib && defaultLibraryFileName) {108751 if (!options.lib && defaultLibraryFileName) {
@@ -108753,6 +108762,7 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
108753 }108762 }
108754 }108763 }
108755 }108764 }
108765+ PerformanceDotting.stopAdvanced("processDefaultLib");
108756 PerformanceDotting.stop("processDefaultLib");108766 PerformanceDotting.stop("processDefaultLib");
108757 missingFilePaths = arrayFrom(mapDefinedIterator(filesByName.entries(), ([path, file]) => file === void 0 ? path : void 0));108767 missingFilePaths = arrayFrom(mapDefinedIterator(filesByName.entries(), ([path, file]) => file === void 0 ? path : void 0));
108758 files = stableSort(processingDefaultLibFiles, compareDefaultLibFiles).concat(processingOtherFiles);108768 files = stableSort(processingDefaultLibFiles, compareDefaultLibFiles).concat(processingOtherFiles);
@@ -108891,6 +108901,7 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
108891 MemoryDotting.stopRecordStage(recordInfo);108901 MemoryDotting.stopRecordStage(recordInfo);
108892 measure("Program", "beforeProgram", "afterProgram");108902 measure("Program", "beforeProgram", "afterProgram");
108893 (_p = tracing) == null ? void 0 : _p.pop();108903 (_p = tracing) == null ? void 0 : _p.pop();
108904+ PerformanceDotting.stopAdvanced("createProgram");
108894 PerformanceDotting.stop("createProgram");108905 PerformanceDotting.stop("createProgram");
108895 return program;108906 return program;
108896 function addResolutionDiagnostics(list) {108907 function addResolutionDiagnostics(list) {
@@ -109114,39 +109125,71 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109114 return true;109125 return true;
109115 }109126 }
109116 }109127 }
109117- function canReuseProjectReferences() {109128+ function tryReuseProjectReferences() {
109118- return !forEachProjectReference(109129+ return forEachProjectReference(
109119 oldProgram.getProjectReferences(),109130 oldProgram.getProjectReferences(),
109120 oldProgram.getResolvedProjectReferences(),109131 oldProgram.getResolvedProjectReferences(),
109121 (oldResolvedRef, parent2, index) => {109132 (oldResolvedRef, parent2, index) => {
109133+ var _a3, _b2, _c2, _d2;
109122 const newRef = (parent2 ? parent2.commandLine.projectReferences : projectReferences)[index];109134 const newRef = (parent2 ? parent2.commandLine.projectReferences : projectReferences)[index];
109123 const newResolvedRef = parseProjectReferenceConfigFile(newRef);109135 const newResolvedRef = parseProjectReferenceConfigFile(newRef);
109136+ const refPath = (_d2 = (_c2 = (_a3 = newRef == null ? void 0 : newRef.originalPath) != null ? _a3 : newRef == null ? void 0 : newRef.path) != null ? _c2 : (_b2 = oldResolvedRef == null ? void 0 : oldResolvedRef.sourceFile) == null ? void 0 : _b2.fileName) != null ? _d2 : "(unknown project reference)";
109124 if (oldResolvedRef) {109137 if (oldResolvedRef) {
109125- return !newResolvedRef || newResolvedRef.sourceFile !== oldResolvedRef.sourceFile || !arrayIsEqualTo(oldResolvedRef.commandLine.fileNames, newResolvedRef.commandLine.fileNames);109138+ if (!newResolvedRef) {
109139+ return `resolved project reference no longer resolvable: ${refPath}`;
109140+ }
109141+ if (newResolvedRef.sourceFile !== oldResolvedRef.sourceFile) {
109142+ return `project reference sourceFile changed: ${refPath}`;
109143+ }
109144+ if (!arrayIsEqualTo(oldResolvedRef.commandLine.fileNames, newResolvedRef.commandLine.fileNames)) {
109145+ return `project reference fileNames changed: ${refPath}`;
109146+ }
109147+ return void 0;
109126 } else {109148 } else {
109127- return newResolvedRef !== void 0;109149+ if (newResolvedRef !== void 0) {
109150+ return `previously-unresolved project reference now resolved: ${refPath}`;
109151+ }
109152+ return void 0;
109128 }109153 }
109129 },109154 },
109130 (oldProjectReferences, parent2) => {109155 (oldProjectReferences, parent2) => {
109131 const newReferences = parent2 ? getResolvedProjectReferenceByPath(parent2.sourceFile.path).commandLine.projectReferences : projectReferences;109156 const newReferences = parent2 ? getResolvedProjectReferenceByPath(parent2.sourceFile.path).commandLine.projectReferences : projectReferences;
109132- return !arrayIsEqualTo(oldProjectReferences, newReferences, projectReferenceIsEqualTo);109157+ if (!arrayIsEqualTo(oldProjectReferences, newReferences, projectReferenceIsEqualTo)) {
109158+ const owner = parent2 ? parent2.sourceFile.fileName : "(root)";
109159+ return `project references array changed in: ${owner}`;
109160+ }
109161+ return void 0;
109133 }109162 }
109134 );109163 );
109135 }109164 }
109136 function tryReuseStructureFromOldProgram() {109165 function tryReuseStructureFromOldProgram() {
109137- var _a3, _b2;109166+ var _a3, _b2, _c2;
109138 if (!oldProgram) {109167 if (!oldProgram) {
109168+ PerformanceDotting.startAdvanced("structureIsReused: Not", "#1 oldProgram is undefined (first build or .tsbuildinfo missing/deleted/corrupt)");
109169+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
109139 return 0 /* Not */;109170 return 0 /* Not */;
109140 }109171 }
109141 const oldOptions = oldProgram.getCompilerOptions();109172 const oldOptions = oldProgram.getCompilerOptions();
109142 if (changesAffectModuleResolution(oldOptions, options)) {109173 if (changesAffectModuleResolution(oldOptions, options)) {
109174+ const changedOptions = moduleResolutionOptionDeclarations.filter((o) => !isJsonEqual(getCompilerOptionValue(oldOptions, o), getCompilerOptionValue(options, o))).map((o) => o.name);
109175+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#2 changesAffectModuleResolution - changedOptions: [${changedOptions.join(", ")}], configFilePath: ${oldOptions.configFilePath} -> ${options.configFilePath}`);
109176+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
109143 return 0 /* Not */;109177 return 0 /* Not */;
109144 }109178 }
109145 const oldRootNames = oldProgram.getRootFileNames();109179 const oldRootNames = oldProgram.getRootFileNames();
109146 if (!arrayIsEqualTo(oldRootNames, rootNames)) {109180 if (!arrayIsEqualTo(oldRootNames, rootNames)) {
109181+ const addedFiles = rootNames.filter((f) => !oldRootNames.includes(f));
109182+ const removedFiles = oldRootNames.filter((f) => !rootNames.includes(f));
109183+ const addedList = addedFiles.length > 10 ? addedFiles.slice(0, 10).join(", ") + `, ... and ${addedFiles.length - 10} more` : addedFiles.join(", ");
109184+ const removedList = removedFiles.length > 10 ? removedFiles.slice(0, 10).join(", ") + `, ... and ${removedFiles.length - 10} more` : removedFiles.join(", ");
109185+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#3 rootNames changed - oldCount=${oldRootNames.length}, newCount=${rootNames.length}, added=[${addedList}], removed=[${removedList}]`);
109186+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
109147 return 0 /* Not */;109187 return 0 /* Not */;
109148 }109188 }
109149- if (!canReuseProjectReferences()) {109189+ const projectReferenceReuseFailReason = tryReuseProjectReferences();
109190+ if (projectReferenceReuseFailReason !== void 0) {
109191+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#4 tryReuseProjectReferences failed: ${projectReferenceReuseFailReason}`);
109192+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
109150 return 0 /* Not */;109193 return 0 /* Not */;
109151 }109194 }
109152 if (projectReferences) {109195 if (projectReferences) {
@@ -109155,7 +109198,10 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109155 const newSourceFiles = [];109198 const newSourceFiles = [];
109156 const modifiedSourceFiles = [];109199 const modifiedSourceFiles = [];
109157 structureIsReused = 2 /* Completely */;109200 structureIsReused = 2 /* Completely */;
109158- if (oldProgram.getMissingFilePaths().some((missingFilePath) => host.fileExists(missingFilePath))) {109201+ const nowExistingMissingFilePath = oldProgram.getMissingFilePaths().find((missingFilePath) => host.fileExists(missingFilePath));
109202+ if (nowExistingMissingFilePath !== void 0) {
109203+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#5 a previously missing file now exists: ${nowExistingMissingFilePath}`);
109204+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
109159 return 0 /* Not */;109205 return 0 /* Not */;
109160 }109206 }
109161 const oldSourceFiles = oldProgram.getSourceFiles();109207 const oldSourceFiles = oldProgram.getSourceFiles();
@@ -109169,6 +109215,8 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109169 const sourceFileOptions = getCreateSourceFileOptions(oldSourceFile.fileName, moduleResolutionCache, host, options);109215 const sourceFileOptions = getCreateSourceFileOptions(oldSourceFile.fileName, moduleResolutionCache, host, options);
109170 let newSourceFile = host.getSourceFileByPath ? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.resolvedPath, sourceFileOptions, void 0, shouldCreateNewSourceFile || sourceFileOptions.impliedNodeFormat !== oldSourceFile.impliedNodeFormat) : host.getSourceFile(oldSourceFile.fileName, sourceFileOptions, void 0, shouldCreateNewSourceFile || sourceFileOptions.impliedNodeFormat !== oldSourceFile.impliedNodeFormat);109216 let newSourceFile = host.getSourceFileByPath ? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.resolvedPath, sourceFileOptions, void 0, shouldCreateNewSourceFile || sourceFileOptions.impliedNodeFormat !== oldSourceFile.impliedNodeFormat) : host.getSourceFile(oldSourceFile.fileName, sourceFileOptions, void 0, shouldCreateNewSourceFile || sourceFileOptions.impliedNodeFormat !== oldSourceFile.impliedNodeFormat);
109171 if (!newSourceFile) {109217 if (!newSourceFile) {
109218+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#6 source file no longer exists: ${oldSourceFile.fileName}`);
109219+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
109172 return 0 /* Not */;109220 return 0 /* Not */;
109173 }109221 }
109174 newSourceFile.packageJsonLocations = ((_a3 = sourceFileOptions.packageJsonLocations) == null ? void 0 : _a3.length) ? sourceFileOptions.packageJsonLocations : void 0;109222 newSourceFile.packageJsonLocations = ((_a3 = sourceFileOptions.packageJsonLocations) == null ? void 0 : _a3.length) ? sourceFileOptions.packageJsonLocations : void 0;
@@ -109177,12 +109225,16 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109177 let fileChanged;109225 let fileChanged;
109178 if (oldSourceFile.redirectInfo) {109226 if (oldSourceFile.redirectInfo) {
109179 if (newSourceFile !== oldSourceFile.redirectInfo.unredirected) {109227 if (newSourceFile !== oldSourceFile.redirectInfo.unredirected) {
109228+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#7 redirect underlying file changed: ${oldSourceFile.fileName}`);
109229+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
109180 return 0 /* Not */;109230 return 0 /* Not */;
109181 }109231 }
109182 fileChanged = false;109232 fileChanged = false;
109183 newSourceFile = oldSourceFile;109233 newSourceFile = oldSourceFile;
109184 } else if (oldProgram.redirectTargetsMap.has(oldSourceFile.path)) {109234 } else if (oldProgram.redirectTargetsMap.has(oldSourceFile.path)) {
109185 if (newSourceFile !== oldSourceFile) {109235 if (newSourceFile !== oldSourceFile) {
109236+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#8 redirected-to file changed: ${oldSourceFile.fileName}`);
109237+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
109186 return 0 /* Not */;109238 return 0 /* Not */;
109187 }109239 }
109188 fileChanged = false;109240 fileChanged = false;
@@ -109198,39 +109250,61 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109198 const prevKind = seenPackageNames.get(packageName);109250 const prevKind = seenPackageNames.get(packageName);
109199 const newKind = fileChanged ? 1 /* Modified */ : 0 /* Exists */;109251 const newKind = fileChanged ? 1 /* Modified */ : 0 /* Exists */;
109200 if (prevKind !== void 0 && newKind === 1 /* Modified */ || prevKind === 1 /* Modified */) {109252 if (prevKind !== void 0 && newKind === 1 /* Modified */ || prevKind === 1 /* Modified */) {
109253+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#9 package name conflict (two files for package "${packageName}", at least one changed): ${oldSourceFile.fileName}`);
109254+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
109201 return 0 /* Not */;109255 return 0 /* Not */;
109202 }109256 }
109203 seenPackageNames.set(packageName, newKind);109257 seenPackageNames.set(packageName, newKind);
109204 }109258 }
109205 if (fileChanged) {109259 if (fileChanged) {
109206 if (oldSourceFile.impliedNodeFormat !== newSourceFile.impliedNodeFormat) {109260 if (oldSourceFile.impliedNodeFormat !== newSourceFile.impliedNodeFormat) {
109261+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `impliedNodeFormat changed: ${oldSourceFile.fileName}`);
109262+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109207 structureIsReused = 1 /* SafeModules */;109263 structureIsReused = 1 /* SafeModules */;
109208 } else if (!arrayIsEqualTo(oldSourceFile.libReferenceDirectives, newSourceFile.libReferenceDirectives, fileReferenceIsEqualTo)) {109264 } else if (!arrayIsEqualTo(oldSourceFile.libReferenceDirectives, newSourceFile.libReferenceDirectives, fileReferenceIsEqualTo)) {
109265+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `libReferenceDirectives changed: ${oldSourceFile.fileName}`);
109266+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109209 structureIsReused = 1 /* SafeModules */;109267 structureIsReused = 1 /* SafeModules */;
109210 } else if (oldSourceFile.hasNoDefaultLib !== newSourceFile.hasNoDefaultLib) {109268 } else if (oldSourceFile.hasNoDefaultLib !== newSourceFile.hasNoDefaultLib) {
109269+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `hasNoDefaultLib changed: ${oldSourceFile.fileName}`);
109270+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109211 structureIsReused = 1 /* SafeModules */;109271 structureIsReused = 1 /* SafeModules */;
109212 } else if (!arrayIsEqualTo(oldSourceFile.referencedFiles, newSourceFile.referencedFiles, fileReferenceIsEqualTo)) {109272 } else if (!arrayIsEqualTo(oldSourceFile.referencedFiles, newSourceFile.referencedFiles, fileReferenceIsEqualTo)) {
109273+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `referencedFiles changed: ${oldSourceFile.fileName}`);
109274+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109213 structureIsReused = 1 /* SafeModules */;109275 structureIsReused = 1 /* SafeModules */;
109214 } else {109276 } else {
109215 collectExternalModuleReferences(newSourceFile);109277 collectExternalModuleReferences(newSourceFile);
109216 if (!arrayIsEqualTo(oldSourceFile.imports, newSourceFile.imports, moduleNameIsEqualTo)) {109278 if (!arrayIsEqualTo(oldSourceFile.imports, newSourceFile.imports, moduleNameIsEqualTo)) {
109279+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `imports changed: ${oldSourceFile.fileName}`);
109280+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109217 structureIsReused = 1 /* SafeModules */;109281 structureIsReused = 1 /* SafeModules */;
109218 } else if (!arrayIsEqualTo(oldSourceFile.moduleAugmentations, newSourceFile.moduleAugmentations, moduleNameIsEqualTo)) {109282 } else if (!arrayIsEqualTo(oldSourceFile.moduleAugmentations, newSourceFile.moduleAugmentations, moduleNameIsEqualTo)) {
109283+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `moduleAugmentations changed: ${oldSourceFile.fileName}`);
109284+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109219 structureIsReused = 1 /* SafeModules */;109285 structureIsReused = 1 /* SafeModules */;
109220 } else if ((oldSourceFile.flags & 6291456 /* PermanentlySetIncrementalFlags */) !== (newSourceFile.flags & 6291456 /* PermanentlySetIncrementalFlags */)) {109286 } else if ((oldSourceFile.flags & 6291456 /* PermanentlySetIncrementalFlags */) !== (newSourceFile.flags & 6291456 /* PermanentlySetIncrementalFlags */)) {
109287+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `PermanentlySetIncrementalFlags changed: ${oldSourceFile.fileName}`);
109288+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109221 structureIsReused = 1 /* SafeModules */;109289 structureIsReused = 1 /* SafeModules */;
109222 } else if (!arrayIsEqualTo(oldSourceFile.typeReferenceDirectives, newSourceFile.typeReferenceDirectives, fileReferenceIsEqualTo)) {109290 } else if (!arrayIsEqualTo(oldSourceFile.typeReferenceDirectives, newSourceFile.typeReferenceDirectives, fileReferenceIsEqualTo)) {
109291+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `typeReferenceDirectives changed: ${oldSourceFile.fileName}`);
109292+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109223 structureIsReused = 1 /* SafeModules */;109293 structureIsReused = 1 /* SafeModules */;
109224 }109294 }
109225 }109295 }
109226 modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });109296 modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });
109227 } else if (hasInvalidatedResolutions(oldSourceFile.path)) {109297 } else if (hasInvalidatedResolutions(oldSourceFile.path)) {
109298+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `hasInvalidatedResolutions: ${oldSourceFile.fileName}`);
109299+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109228 structureIsReused = 1 /* SafeModules */;109300 structureIsReused = 1 /* SafeModules */;
109229 modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });109301 modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });
109230 }109302 }
109231 newSourceFiles.push(newSourceFile);109303 newSourceFiles.push(newSourceFile);
109232 }109304 }
109233 if (structureIsReused !== 2 /* Completely */) {109305 if (structureIsReused !== 2 /* Completely */) {
109306+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `file content changed but module resolution reusable, modifiedFiles=${modifiedSourceFiles.length}`);
109307+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109234 return structureIsReused;109308 return structureIsReused;
109235 }109309 }
109236 const modifiedFiles = modifiedSourceFiles.map((f) => f.oldFile);109310 const modifiedFiles = modifiedSourceFiles.map((f) => f.oldFile);
@@ -109241,11 +109315,14 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109241 }109315 }
109242 }109316 }
109243 }109317 }
109318+ PerformanceDotting.startAdvanced("resolveModuleNames", `modifiedFiles=${modifiedSourceFiles.length}`);
109244 for (const { oldFile: oldSourceFile, newFile: newSourceFile } of modifiedSourceFiles) {109319 for (const { oldFile: oldSourceFile, newFile: newSourceFile } of modifiedSourceFiles) {
109245 const moduleNames = getModuleNames(newSourceFile);109320 const moduleNames = getModuleNames(newSourceFile);
109246 const resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFile);109321 const resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFile);
109247 const resolutionsChanged = hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, oldSourceFile, moduleResolutionIsEqualTo);109322 const resolutionsChanged = hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, oldSourceFile, moduleResolutionIsEqualTo);
109248 if (resolutionsChanged) {109323 if (resolutionsChanged) {
109324+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `module resolution changed: ${newSourceFile.fileName}`);
109325+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109249 structureIsReused = 1 /* SafeModules */;109326 structureIsReused = 1 /* SafeModules */;
109250 newSourceFile.resolvedModules = zipToModeAwareCache(newSourceFile, moduleNames, resolutions);109327 newSourceFile.resolvedModules = zipToModeAwareCache(newSourceFile, moduleNames, resolutions);
109251 } else {109328 } else {
@@ -109255,16 +109332,31 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109255 const typeReferenceResolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFile);109332 const typeReferenceResolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFile);
109256 const typeReferenceResolutionsChanged = hasChangesInResolutions(typesReferenceDirectives, typeReferenceResolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, oldSourceFile, typeDirectiveIsEqualTo);109333 const typeReferenceResolutionsChanged = hasChangesInResolutions(typesReferenceDirectives, typeReferenceResolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, oldSourceFile, typeDirectiveIsEqualTo);
109257 if (typeReferenceResolutionsChanged) {109334 if (typeReferenceResolutionsChanged) {
109335+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `typeReference resolution changed: ${newSourceFile.fileName}`);
109336+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109258 structureIsReused = 1 /* SafeModules */;109337 structureIsReused = 1 /* SafeModules */;
109259 newSourceFile.resolvedTypeReferenceDirectiveNames = zipToModeAwareCache(newSourceFile, typesReferenceDirectives, typeReferenceResolutions);109338 newSourceFile.resolvedTypeReferenceDirectiveNames = zipToModeAwareCache(newSourceFile, typesReferenceDirectives, typeReferenceResolutions);
109260 } else {109339 } else {
109261 newSourceFile.resolvedTypeReferenceDirectiveNames = oldSourceFile.resolvedTypeReferenceDirectiveNames;109340 newSourceFile.resolvedTypeReferenceDirectiveNames = oldSourceFile.resolvedTypeReferenceDirectiveNames;
109262 }109341 }
109263 }109342 }
109343+ PerformanceDotting.stopAdvanced("resolveModuleNames");
109264 if (structureIsReused !== 2 /* Completely */) {109344 if (structureIsReused !== 2 /* Completely */) {
109345+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `module resolution changed for modified files, modifiedFiles=${modifiedSourceFiles.length}`);
109346+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109265 return structureIsReused;109347 return structureIsReused;
109266 }109348 }
109267 if (changesAffectingProgramStructure(oldOptions, options) || ((_b2 = host.hasChangedAutomaticTypeDirectiveNames) == null ? void 0 : _b2.call(host))) {109349 if (changesAffectingProgramStructure(oldOptions, options) || ((_b2 = host.hasChangedAutomaticTypeDirectiveNames) == null ? void 0 : _b2.call(host))) {
109350+ const reasons = [];
109351+ if (changesAffectingProgramStructure(oldOptions, options)) {
109352+ const changedOpts = optionsAffectingProgramStructure.filter((o) => !isJsonEqual(getCompilerOptionValue(oldOptions, o), getCompilerOptionValue(options, o))).map((o) => o.name);
109353+ reasons.push(`changesAffectingProgramStructure: [${changedOpts.join(", ")}]`);
109354+ }
109355+ if ((_c2 = host.hasChangedAutomaticTypeDirectiveNames) == null ? void 0 : _c2.call(host)) {
109356+ reasons.push("hasChangedAutomaticTypeDirectiveNames");
109357+ }
109358+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `#10 ${reasons.join("; ")}`);
109359+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109268 return 1 /* SafeModules */;109360 return 1 /* SafeModules */;
109269 }109361 }
109270 missingFilePaths = oldProgram.getMissingFilePaths();109362 missingFilePaths = oldProgram.getMissingFilePaths();
@@ -109293,6 +109385,8 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109293 sourceFileToPackageName = oldProgram.sourceFileToPackageName;109385 sourceFileToPackageName = oldProgram.sourceFileToPackageName;
109294 redirectTargetsMap = oldProgram.redirectTargetsMap;109386 redirectTargetsMap = oldProgram.redirectTargetsMap;
109295 usesUriStyleNodeCoreModules = oldProgram.usesUriStyleNodeCoreModules;109387 usesUriStyleNodeCoreModules = oldProgram.usesUriStyleNodeCoreModules;
109388+ PerformanceDotting.startAdvanced("structureIsReused: Completely", "structure fully reused from old program");
109389+ PerformanceDotting.stopAdvanced("structureIsReused: Completely");
109296 return 2 /* Completely */;109390 return 2 /* Completely */;
109297 }109391 }
109298 function getEmitHost(writeFileCallback) {109392 function getEmitHost(writeFileCallback) {
@@ -112504,13 +112598,21 @@ function getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldP
112504 oldProgram = configFileParsingDiagnosticsOrOldProgram;112598 oldProgram = configFileParsingDiagnosticsOrOldProgram;
112505 Debug.assert(!!oldProgram);112599 Debug.assert(!!oldProgram);
112506 newProgram = oldProgram.getProgram();112600 newProgram = oldProgram.getProgram();
112601+ PerformanceDotting.startAdvanced("getBuilderCreationParameters: reuseProgramFromOldProgram", "newProgramOrRootNames undefined, no createProgram call");
112602+ PerformanceDotting.stopAdvanced("getBuilderCreationParameters: reuseProgramFromOldProgram");
112507 } else if (isArray(newProgramOrRootNames)) {112603 } else if (isArray(newProgramOrRootNames)) {
112508 oldProgram = configFileParsingDiagnosticsOrOldProgram;112604 oldProgram = configFileParsingDiagnosticsOrOldProgram;
112605+ const oldProgramForCreate = oldProgram && oldProgram.getProgramOrUndefined();
112606+ PerformanceDotting.startAdvanced(
112607+ "getBuilderCreationParameters: createProgram",
112608+ `oldProgram=${!!oldProgram}, hasOldProgram=${!!oldProgramForCreate}, rootNames=${newProgramOrRootNames.length}`
112609+ );
112610+ PerformanceDotting.stopAdvanced("getBuilderCreationParameters: createProgram");
112509 newProgram = createProgram({112611 newProgram = createProgram({
112510 rootNames: newProgramOrRootNames,112612 rootNames: newProgramOrRootNames,
112511 options: hostOrOptions,112613 options: hostOrOptions,
112512 host: oldProgramOrHost,112614 host: oldProgramOrHost,
112513- oldProgram: oldProgram && oldProgram.getProgramOrUndefined(),112615+ oldProgram: oldProgramForCreate,
112514 configFileParsingDiagnostics,112616 configFileParsingDiagnostics,
112515 projectReferences112617 projectReferences
112516 });112618 });
@@ -112520,6 +112622,8 @@ function getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldP
112520 host = hostOrOptions;112622 host = hostOrOptions;
112521 oldProgram = oldProgramOrHost;112623 oldProgram = oldProgramOrHost;
112522 configFileParsingDiagnostics = configFileParsingDiagnosticsOrOldProgram;112624 configFileParsingDiagnostics = configFileParsingDiagnosticsOrOldProgram;
112625+ PerformanceDotting.startAdvanced("getBuilderCreationParameters: newProgramProvided", `newProgram=${!!newProgram}, host=${!!host}, oldProgram=${!!oldProgram}, configFileParsingDiagnostics=${!!configFileParsingDiagnostics}`);
112626+ PerformanceDotting.stopAdvanced("getBuilderCreationParameters: newProgramProvided");
112523 }112627 }
112524 return { host, newProgram, oldProgram, configFileParsingDiagnostics: configFileParsingDiagnostics || emptyArray };112628 return { host, newProgram, oldProgram, configFileParsingDiagnostics: configFileParsingDiagnostics || emptyArray };
112525}112629}
@@ -113009,6 +113113,7 @@ function createEmitAndSemanticDiagnosticsBuilderProgram(newProgramOrRootNames, h
113009}113113}
113010function createEmitAndSemanticDiagnosticsBuilderProgramForArkTs(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences) {113114function createEmitAndSemanticDiagnosticsBuilderProgramForArkTs(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences) {
113011 PerformanceDotting.start("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");113115 PerformanceDotting.start("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");
113116+ PerformanceDotting.startAdvanced("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");
113012 PerformanceDotting.start("getBuilderCreationParameters");113117 PerformanceDotting.start("getBuilderCreationParameters");
113013 let builderCreatetionParameters = getBuilderCreationParameters(113118 let builderCreatetionParameters = getBuilderCreationParameters(
113014 newProgramOrRootNames,113119 newProgramOrRootNames,
@@ -113021,22 +113126,27 @@ function createEmitAndSemanticDiagnosticsBuilderProgramForArkTs(newProgramOrRoot
113021 PerformanceDotting.stop("getBuilderCreationParameters");113126 PerformanceDotting.stop("getBuilderCreationParameters");
113022 let newProgram = builderCreatetionParameters.newProgram;113127 let newProgram = builderCreatetionParameters.newProgram;
113023 PerformanceDotting.start("createBuilderProgram");113128 PerformanceDotting.start("createBuilderProgram");
113129+ PerformanceDotting.startAdvanced("createBuilderProgram");
113024 let builderProgram = createBuilderProgram(113130 let builderProgram = createBuilderProgram(
113025 1 /* EmitAndSemanticDiagnosticsBuilderProgram */,113131 1 /* EmitAndSemanticDiagnosticsBuilderProgram */,
113026 builderCreatetionParameters113132 builderCreatetionParameters
113027 );113133 );
113134+ PerformanceDotting.stopAdvanced("createBuilderProgram");
113028 PerformanceDotting.stop("createBuilderProgram");113135 PerformanceDotting.stop("createBuilderProgram");
113029 let oldProgramForLinter = readBuilderProgram(hostOrOptions, oldProgramOrHost, true);113136 let oldProgramForLinter = readBuilderProgram(hostOrOptions, oldProgramOrHost, true);
113030 builderCreatetionParameters.oldProgram = oldProgramForLinter;113137 builderCreatetionParameters.oldProgram = oldProgramForLinter;
113031 builderCreatetionParameters.newProgram = newProgram;113138 builderCreatetionParameters.newProgram = newProgram;
113032 PerformanceDotting.start("createBuilderProgramForLinter");113139 PerformanceDotting.start("createBuilderProgramForLinter");
113140+ PerformanceDotting.startAdvanced("createBuilderProgramForLinter");
113033 let builderProgramForLinter = createBuilderProgram(113141 let builderProgramForLinter = createBuilderProgram(
113034 1 /* EmitAndSemanticDiagnosticsBuilderProgram */,113142 1 /* EmitAndSemanticDiagnosticsBuilderProgram */,
113035 builderCreatetionParameters,113143 builderCreatetionParameters,
113036 true113144 true
113037 );113145 );
113146+ PerformanceDotting.stopAdvanced("createBuilderProgramForLinter");
113038 PerformanceDotting.stop("createBuilderProgramForLinter");113147 PerformanceDotting.stop("createBuilderProgramForLinter");
113039 builderProgram.builderProgramForLinter = builderProgramForLinter;113148 builderProgram.builderProgramForLinter = builderProgramForLinter;
113149+ PerformanceDotting.stopAdvanced("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");
113040 PerformanceDotting.stop("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");113150 PerformanceDotting.stop("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");
113041 return builderProgram;113151 return builderProgram;
113042}113152}
@@ -114451,12 +114561,20 @@ function readBuilderProgram(compilerOptions, host, isForLinter) {
114451 buildInfo = host.getBuildInfo(buildInfoPath, compilerOptions.configFilePath);114561 buildInfo = host.getBuildInfo(buildInfoPath, compilerOptions.configFilePath);
114452 } else {114562 } else {
114453 const content = host.readFile(buildInfoPath);114563 const content = host.readFile(buildInfoPath);
114454- if (!content)114564+ if (!content) {
114565+ PerformanceDotting.startAdvanced("readBuilderProgram: buildInfoNotFound", `${buildInfoPath} not found`);
114566+ PerformanceDotting.stopAdvanced("readBuilderProgram: buildInfoNotFound");
114455 return void 0;114567 return void 0;
114568+ }
114456 buildInfo = getBuildInfo(buildInfoPath, content);114569 buildInfo = getBuildInfo(buildInfoPath, content);
114457 }114570 }
114458- if (!buildInfo || buildInfo.version !== version || !buildInfo.program)114571+ if (!buildInfo || buildInfo.version !== version || !buildInfo.program) {
114572+ PerformanceDotting.startAdvanced("readBuilderProgram: invalidBuildInfo", `path=${buildInfoPath}, version=${buildInfo == null ? void 0 : buildInfo.version}, hasProgram=${!!(buildInfo == null ? void 0 : buildInfo.program)}`);
114573+ PerformanceDotting.stopAdvanced("readBuilderProgram: invalidBuildInfo");
114459 return void 0;114574 return void 0;
114575+ }
114576+ PerformanceDotting.startAdvanced("readBuilderProgram: loaded");
114577+ PerformanceDotting.stopAdvanced("readBuilderProgram: loaded");
114460 return createBuilderProgramUsingProgramBuildInfo(buildInfo.program, buildInfoPath, host);114578 return createBuilderProgramUsingProgramBuildInfo(buildInfo.program, buildInfoPath, host);
114461}114579}
114462function createIncrementalCompilerHost(options, system = sys) {114580function createIncrementalCompilerHost(options, system = sys) {
@@ -116081,11 +116199,17 @@ function listEmittedFile({ write }, proj, file) {
116081 }116199 }
116082}116200}
116083function getOldProgram({ options, builderPrograms, compilerHost }, proj, parsed) {116201function getOldProgram({ options, builderPrograms, compilerHost }, proj, parsed) {
116084- if (options.force)116202+ if (options.force) {
116203+ PerformanceDotting.startAdvanced("getOldProgram: force", `--force flag set, returning undefined for ${proj}`);
116204+ PerformanceDotting.stopAdvanced("getOldProgram: force");
116085 return void 0;116205 return void 0;
116206+ }
116086 const value = builderPrograms.get(proj);116207 const value = builderPrograms.get(proj);
116087- if (value)116208+ if (value) {
116209+ PerformanceDotting.startAdvanced("getOldProgram: cachedBuilderProgram", `reused from builderPrograms map for ${proj}`);
116210+ PerformanceDotting.stopAdvanced("getOldProgram: cachedBuilderProgram");
116088 return value;116211 return value;
116212+ }
116089 return readBuilderProgram(parsed.options, compilerHost);116213 return readBuilderProgram(parsed.options, compilerHost);
116090}116214}
116091function afterProgramDone(state, program, config) {116215function afterProgramDone(state, program, config) {
@@ -125154,7 +125278,9 @@ function createLanguageService(host, documentRegistry = createDocumentRegistry(h
125154 };125278 };
125155 const documentRegistryBucketKey = documentRegistry.getKeyForCompilationSettings(newSettings);125279 const documentRegistryBucketKey = documentRegistry.getKeyForCompilationSettings(newSettings);
125156 PerformanceDotting.start("isProgramUptoDate");125280 PerformanceDotting.start("isProgramUptoDate");
125281+ PerformanceDotting.startAdvanced("isProgramUptoDate");
125157 if (isProgramUptoDate(program, rootFileNames, newSettings, (_path, fileName) => host.getScriptVersion(fileName), (fileName) => compilerHost.fileExists(fileName), hasInvalidatedResolutions, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) {125282 if (isProgramUptoDate(program, rootFileNames, newSettings, (_path, fileName) => host.getScriptVersion(fileName), (fileName) => compilerHost.fileExists(fileName), hasInvalidatedResolutions, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) {
125283+ PerformanceDotting.stopAdvanced("isProgramUptoDate");
125158 PerformanceDotting.stop("isProgramUptoDate");125284 PerformanceDotting.stop("isProgramUptoDate");
125159 host.clearFileCache && host.clearFileCache();125285 host.clearFileCache && host.clearFileCache();
125160 if (isCreateIncrementalProgramMode && (builderProgram == null ? void 0 : builderProgram.resetConstEnumRelateUpdateFlag)) {125286 if (isCreateIncrementalProgramMode && (builderProgram == null ? void 0 : builderProgram.resetConstEnumRelateUpdateFlag)) {
@@ -125162,6 +125288,7 @@ function createLanguageService(host, documentRegistry = createDocumentRegistry(h
125162 }125288 }
125163 return;125289 return;
125164 }125290 }
125291+ PerformanceDotting.stopAdvanced("isProgramUptoDate");
125165 PerformanceDotting.stop("isProgramUptoDate");125292 PerformanceDotting.stop("isProgramUptoDate");
125166 host.clearProps && host.clearProps();125293 host.clearProps && host.clearProps();
125167 compilerHost.getLastCompiledProgram = () => {125294 compilerHost.getLastCompiledProgram = () => {
@@ -125189,7 +125316,9 @@ function createLanguageService(host, documentRegistry = createDocumentRegistry(h
125189 compilerHost = void 0;125316 compilerHost = void 0;
125190 parsedCommandLines = void 0;125317 parsedCommandLines = void 0;
125191 sourceMapper.clearCache();125318 sourceMapper.clearCache();
125319+ PerformanceDotting.startAdvanced("getTypeChecker");
125192 program.getTypeChecker();125320 program.getTypeChecker();
125321+ PerformanceDotting.stopAdvanced("getTypeChecker");
125193 host.clearFileCache && host.clearFileCache();125322 host.clearFileCache && host.clearFileCache();
125194 return;125323 return;
125195 function getParsedCommandLine(fileName) {125324 function getParsedCommandLine(fileName) {
@@ -177223,7 +177352,7 @@ function runArkTSLinter2(tsBuilderProgram, srcFile, buildInfoWriteFile, arkTSVer
177223 const tscStrictDiagnostics = getTscDiagnostics2(tscDiagnosticsLinter, srcFiles.filter((file) => changedFiles.has(file.resolvedPath)));177352 const tscStrictDiagnostics = getTscDiagnostics2(tscDiagnosticsLinter, srcFiles.filter((file) => changedFiles.has(file.resolvedPath)));
177224 timePrinterInstance.appendTime("getTscDiagnostics" /* GET_TSC_DIAGNOSTICS */);177353 timePrinterInstance.appendTime("getTscDiagnostics" /* GET_TSC_DIAGNOSTICS */);
177225 PerformanceDotting.stopAdvanced("getTscDiagnostics" /* GET_TSC_DIAGNOSTICS */);177354 PerformanceDotting.stopAdvanced("getTscDiagnostics" /* GET_TSC_DIAGNOSTICS */);
177226- const lintRecordLog = "lint" /* LINT */ + "(checkedFilesNum: " + changedFiles.size + ")";177355+ const lintRecordLog = "lint" /* LINT */ + "(checkedFilesNum: " + changedFiles.size + ", totalFilesNum: " + srcFiles.length + ")";
177227 PerformanceDotting.startAdvanced(lintRecordLog);177356 PerformanceDotting.startAdvanced(lintRecordLog);
177228 TypeScriptLinter2.initGlobals(compilerOptions);177357 TypeScriptLinter2.initGlobals(compilerOptions);
177229 InteropTypescriptLinter.initGlobals();177358 InteropTypescriptLinter.initGlobals();
@@ -108940,6 +108940,7 @@ function createCreateProgramOptions(rootNames, options, host, oldProgram, config
108940function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _configFileParsingDiagnostics) {108940function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _configFileParsingDiagnostics) {
108941 var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;108941 var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
108942 PerformanceDotting.start("createProgram");108942 PerformanceDotting.start("createProgram");
108943+ PerformanceDotting.startAdvanced("createProgram");
108943 const createProgramOptions = isArray(rootNamesOrOptions) ? createCreateProgramOptions(rootNamesOrOptions, _options, _host, _oldProgram, _configFileParsingDiagnostics) : rootNamesOrOptions;108944 const createProgramOptions = isArray(rootNamesOrOptions) ? createCreateProgramOptions(rootNamesOrOptions, _options, _host, _oldProgram, _configFileParsingDiagnostics) : rootNamesOrOptions;
108944 const { rootNames, options, configFileParsingDiagnostics, projectReferences } = createProgramOptions;108945 const { rootNames, options, configFileParsingDiagnostics, projectReferences } = createProgramOptions;
108945 let { oldProgram } = createProgramOptions;108946 let { oldProgram } = createProgramOptions;
@@ -109042,9 +109043,12 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109042 let structureIsReused;109043 let structureIsReused;
109043 (_f = tracing) == null ? void 0 : _f.push(tracing.Phase.Program, "tryReuseStructureFromOldProgram", {});109044 (_f = tracing) == null ? void 0 : _f.push(tracing.Phase.Program, "tryReuseStructureFromOldProgram", {});
109044 PerformanceDotting.start("tryReuseStructureFromOldProgram");109045 PerformanceDotting.start("tryReuseStructureFromOldProgram");
109046+ PerformanceDotting.startAdvanced("tryReuseStructureFromOldProgram");
109045 structureIsReused = tryReuseStructureFromOldProgram();109047 structureIsReused = tryReuseStructureFromOldProgram();
109046- PerformanceDotting.startAdvanced("structureIsReused: " + structureIsReused);109048+ const structureIsReusedName = structureIsReused === 2 /* Completely */ ? "Completely" : structureIsReused === 1 /* SafeModules */ ? "SafeModules" : "Not";
109047- PerformanceDotting.stopAdvanced("structureIsReused: " + structureIsReused);109049+ PerformanceDotting.startAdvanced("structureIsReused: " + structureIsReusedName);
109050+ PerformanceDotting.stopAdvanced("structureIsReused: " + structureIsReusedName);
109051+ PerformanceDotting.stopAdvanced("tryReuseStructureFromOldProgram");
109048 PerformanceDotting.stop("tryReuseStructureFromOldProgram");109052 PerformanceDotting.stop("tryReuseStructureFromOldProgram");
109049 (_g = tracing) == null ? void 0 : _g.pop();109053 (_g = tracing) == null ? void 0 : _g.pop();
109050 if (structureIsReused !== 2 /* Completely */) {109054 if (structureIsReused !== 2 /* Completely */) {
@@ -109082,23 +109086,28 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109082 }109086 }
109083 (_h = tracing) == null ? void 0 : _h.push(tracing.Phase.Program, "processRootFiles", { count: rootNames.length });109087 (_h = tracing) == null ? void 0 : _h.push(tracing.Phase.Program, "processRootFiles", { count: rootNames.length });
109084 PerformanceDotting.start("processRootFiles");109088 PerformanceDotting.start("processRootFiles");
109089+ PerformanceDotting.startAdvanced("processRootFiles", `rootNames=${rootNames.length}`);
109085 forEach(rootNames, (name, index) => processRootFile(name, false, false, { kind: 0 /* RootFile */, index }));109090 forEach(rootNames, (name, index) => processRootFile(name, false, false, { kind: 0 /* RootFile */, index }));
109091+ PerformanceDotting.stopAdvanced("processRootFiles");
109086 PerformanceDotting.stop("processRootFiles");109092 PerformanceDotting.stop("processRootFiles");
109087 (_i = tracing) == null ? void 0 : _i.pop();109093 (_i = tracing) == null ? void 0 : _i.pop();
109088 const typeReferences = rootNames.length ? getAutomaticTypeDirectiveNames(options, host) : emptyArray;109094 const typeReferences = rootNames.length ? getAutomaticTypeDirectiveNames(options, host) : emptyArray;
109089 if (typeReferences.length) {109095 if (typeReferences.length) {
109090 (_j = tracing) == null ? void 0 : _j.push(tracing.Phase.Program, "processTypeReferences", { count: typeReferences.length });109096 (_j = tracing) == null ? void 0 : _j.push(tracing.Phase.Program, "processTypeReferences", { count: typeReferences.length });
109091 PerformanceDotting.start("processTypeReferences");109097 PerformanceDotting.start("processTypeReferences");
109098+ PerformanceDotting.startAdvanced("processTypeReferences", `count=${typeReferences.length}`);
109092 const containingDirectory = options.configFilePath ? getDirectoryPath(options.configFilePath) : host.getCurrentDirectory();109099 const containingDirectory = options.configFilePath ? getDirectoryPath(options.configFilePath) : host.getCurrentDirectory();
109093 const containingFilename = combinePaths(containingDirectory, inferredTypesContainingFile);109100 const containingFilename = combinePaths(containingDirectory, inferredTypesContainingFile);
109094 const resolutions = resolveTypeReferenceDirectiveNamesWorker(typeReferences, containingFilename);109101 const resolutions = resolveTypeReferenceDirectiveNamesWorker(typeReferences, containingFilename);
109095 for (let i = 0; i < typeReferences.length; i++) {109102 for (let i = 0; i < typeReferences.length; i++) {
109096 processTypeReferenceDirective(typeReferences[i], void 0, resolutions[i], { kind: 8 /* AutomaticTypeDirectiveFile */, typeReference: typeReferences[i], packageId: (_k = resolutions[i]) == null ? void 0 : _k.packageId });109103 processTypeReferenceDirective(typeReferences[i], void 0, resolutions[i], { kind: 8 /* AutomaticTypeDirectiveFile */, typeReference: typeReferences[i], packageId: (_k = resolutions[i]) == null ? void 0 : _k.packageId });
109097 }109104 }
109105+ PerformanceDotting.stopAdvanced("processTypeReferences");
109098 PerformanceDotting.stop("processTypeReferences");109106 PerformanceDotting.stop("processTypeReferences");
109099 (_l = tracing) == null ? void 0 : _l.pop();109107 (_l = tracing) == null ? void 0 : _l.pop();
109100 }109108 }
109101 PerformanceDotting.start("processDefaultLib");109109 PerformanceDotting.start("processDefaultLib");
109110+ PerformanceDotting.startAdvanced("processDefaultLib");
109102 if (rootNames.length && !skipDefaultLib) {109111 if (rootNames.length && !skipDefaultLib) {
109103 const defaultLibraryFileName = getDefaultLibraryFileName();109112 const defaultLibraryFileName = getDefaultLibraryFileName();
109104 if (!options.lib && defaultLibraryFileName) {109113 if (!options.lib && defaultLibraryFileName) {
@@ -109115,6 +109124,7 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109115 }109124 }
109116 }109125 }
109117 }109126 }
109127+ PerformanceDotting.stopAdvanced("processDefaultLib");
109118 PerformanceDotting.stop("processDefaultLib");109128 PerformanceDotting.stop("processDefaultLib");
109119 missingFilePaths = arrayFrom(mapDefinedIterator(filesByName.entries(), ([path, file]) => file === void 0 ? path : void 0));109129 missingFilePaths = arrayFrom(mapDefinedIterator(filesByName.entries(), ([path, file]) => file === void 0 ? path : void 0));
109120 files = stableSort(processingDefaultLibFiles, compareDefaultLibFiles).concat(processingOtherFiles);109130 files = stableSort(processingDefaultLibFiles, compareDefaultLibFiles).concat(processingOtherFiles);
@@ -109253,6 +109263,7 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109253 MemoryDotting.stopRecordStage(recordInfo);109263 MemoryDotting.stopRecordStage(recordInfo);
109254 measure("Program", "beforeProgram", "afterProgram");109264 measure("Program", "beforeProgram", "afterProgram");
109255 (_p = tracing) == null ? void 0 : _p.pop();109265 (_p = tracing) == null ? void 0 : _p.pop();
109266+ PerformanceDotting.stopAdvanced("createProgram");
109256 PerformanceDotting.stop("createProgram");109267 PerformanceDotting.stop("createProgram");
109257 return program;109268 return program;
109258 function addResolutionDiagnostics(list) {109269 function addResolutionDiagnostics(list) {
@@ -109476,39 +109487,71 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109476 return true;109487 return true;
109477 }109488 }
109478 }109489 }
109479- function canReuseProjectReferences() {109490+ function tryReuseProjectReferences() {
109480- return !forEachProjectReference(109491+ return forEachProjectReference(
109481 oldProgram.getProjectReferences(),109492 oldProgram.getProjectReferences(),
109482 oldProgram.getResolvedProjectReferences(),109493 oldProgram.getResolvedProjectReferences(),
109483 (oldResolvedRef, parent2, index) => {109494 (oldResolvedRef, parent2, index) => {
109495+ var _a3, _b2, _c2, _d2;
109484 const newRef = (parent2 ? parent2.commandLine.projectReferences : projectReferences)[index];109496 const newRef = (parent2 ? parent2.commandLine.projectReferences : projectReferences)[index];
109485 const newResolvedRef = parseProjectReferenceConfigFile(newRef);109497 const newResolvedRef = parseProjectReferenceConfigFile(newRef);
109498+ const refPath = (_d2 = (_c2 = (_a3 = newRef == null ? void 0 : newRef.originalPath) != null ? _a3 : newRef == null ? void 0 : newRef.path) != null ? _c2 : (_b2 = oldResolvedRef == null ? void 0 : oldResolvedRef.sourceFile) == null ? void 0 : _b2.fileName) != null ? _d2 : "(unknown project reference)";
109486 if (oldResolvedRef) {109499 if (oldResolvedRef) {
109487- return !newResolvedRef || newResolvedRef.sourceFile !== oldResolvedRef.sourceFile || !arrayIsEqualTo(oldResolvedRef.commandLine.fileNames, newResolvedRef.commandLine.fileNames);109500+ if (!newResolvedRef) {
109501+ return `resolved project reference no longer resolvable: ${refPath}`;
109502+ }
109503+ if (newResolvedRef.sourceFile !== oldResolvedRef.sourceFile) {
109504+ return `project reference sourceFile changed: ${refPath}`;
109505+ }
109506+ if (!arrayIsEqualTo(oldResolvedRef.commandLine.fileNames, newResolvedRef.commandLine.fileNames)) {
109507+ return `project reference fileNames changed: ${refPath}`;
109508+ }
109509+ return void 0;
109488 } else {109510 } else {
109489- return newResolvedRef !== void 0;109511+ if (newResolvedRef !== void 0) {
109512+ return `previously-unresolved project reference now resolved: ${refPath}`;
109513+ }
109514+ return void 0;
109490 }109515 }
109491 },109516 },
109492 (oldProjectReferences, parent2) => {109517 (oldProjectReferences, parent2) => {
109493 const newReferences = parent2 ? getResolvedProjectReferenceByPath(parent2.sourceFile.path).commandLine.projectReferences : projectReferences;109518 const newReferences = parent2 ? getResolvedProjectReferenceByPath(parent2.sourceFile.path).commandLine.projectReferences : projectReferences;
109494- return !arrayIsEqualTo(oldProjectReferences, newReferences, projectReferenceIsEqualTo);109519+ if (!arrayIsEqualTo(oldProjectReferences, newReferences, projectReferenceIsEqualTo)) {
109520+ const owner = parent2 ? parent2.sourceFile.fileName : "(root)";
109521+ return `project references array changed in: ${owner}`;
109522+ }
109523+ return void 0;
109495 }109524 }
109496 );109525 );
109497 }109526 }
109498 function tryReuseStructureFromOldProgram() {109527 function tryReuseStructureFromOldProgram() {
109499- var _a3, _b2;109528+ var _a3, _b2, _c2;
109500 if (!oldProgram) {109529 if (!oldProgram) {
109530+ PerformanceDotting.startAdvanced("structureIsReused: Not", "#1 oldProgram is undefined (first build or .tsbuildinfo missing/deleted/corrupt)");
109531+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
109501 return 0 /* Not */;109532 return 0 /* Not */;
109502 }109533 }
109503 const oldOptions = oldProgram.getCompilerOptions();109534 const oldOptions = oldProgram.getCompilerOptions();
109504 if (changesAffectModuleResolution(oldOptions, options)) {109535 if (changesAffectModuleResolution(oldOptions, options)) {
109536+ const changedOptions = moduleResolutionOptionDeclarations.filter((o) => !isJsonEqual(getCompilerOptionValue(oldOptions, o), getCompilerOptionValue(options, o))).map((o) => o.name);
109537+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#2 changesAffectModuleResolution - changedOptions: [${changedOptions.join(", ")}], configFilePath: ${oldOptions.configFilePath} -> ${options.configFilePath}`);
109538+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
109505 return 0 /* Not */;109539 return 0 /* Not */;
109506 }109540 }
109507 const oldRootNames = oldProgram.getRootFileNames();109541 const oldRootNames = oldProgram.getRootFileNames();
109508 if (!arrayIsEqualTo(oldRootNames, rootNames)) {109542 if (!arrayIsEqualTo(oldRootNames, rootNames)) {
109543+ const addedFiles = rootNames.filter((f) => !oldRootNames.includes(f));
109544+ const removedFiles = oldRootNames.filter((f) => !rootNames.includes(f));
109545+ const addedList = addedFiles.length > 10 ? addedFiles.slice(0, 10).join(", ") + `, ... and ${addedFiles.length - 10} more` : addedFiles.join(", ");
109546+ const removedList = removedFiles.length > 10 ? removedFiles.slice(0, 10).join(", ") + `, ... and ${removedFiles.length - 10} more` : removedFiles.join(", ");
109547+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#3 rootNames changed - oldCount=${oldRootNames.length}, newCount=${rootNames.length}, added=[${addedList}], removed=[${removedList}]`);
109548+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
109509 return 0 /* Not */;109549 return 0 /* Not */;
109510 }109550 }
109511- if (!canReuseProjectReferences()) {109551+ const projectReferenceReuseFailReason = tryReuseProjectReferences();
109552+ if (projectReferenceReuseFailReason !== void 0) {
109553+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#4 tryReuseProjectReferences failed: ${projectReferenceReuseFailReason}`);
109554+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
109512 return 0 /* Not */;109555 return 0 /* Not */;
109513 }109556 }
109514 if (projectReferences) {109557 if (projectReferences) {
@@ -109517,7 +109560,10 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109517 const newSourceFiles = [];109560 const newSourceFiles = [];
109518 const modifiedSourceFiles = [];109561 const modifiedSourceFiles = [];
109519 structureIsReused = 2 /* Completely */;109562 structureIsReused = 2 /* Completely */;
109520- if (oldProgram.getMissingFilePaths().some((missingFilePath) => host.fileExists(missingFilePath))) {109563+ const nowExistingMissingFilePath = oldProgram.getMissingFilePaths().find((missingFilePath) => host.fileExists(missingFilePath));
109564+ if (nowExistingMissingFilePath !== void 0) {
109565+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#5 a previously missing file now exists: ${nowExistingMissingFilePath}`);
109566+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
109521 return 0 /* Not */;109567 return 0 /* Not */;
109522 }109568 }
109523 const oldSourceFiles = oldProgram.getSourceFiles();109569 const oldSourceFiles = oldProgram.getSourceFiles();
@@ -109531,6 +109577,8 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109531 const sourceFileOptions = getCreateSourceFileOptions(oldSourceFile.fileName, moduleResolutionCache, host, options);109577 const sourceFileOptions = getCreateSourceFileOptions(oldSourceFile.fileName, moduleResolutionCache, host, options);
109532 let newSourceFile = host.getSourceFileByPath ? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.resolvedPath, sourceFileOptions, void 0, shouldCreateNewSourceFile || sourceFileOptions.impliedNodeFormat !== oldSourceFile.impliedNodeFormat) : host.getSourceFile(oldSourceFile.fileName, sourceFileOptions, void 0, shouldCreateNewSourceFile || sourceFileOptions.impliedNodeFormat !== oldSourceFile.impliedNodeFormat);109578 let newSourceFile = host.getSourceFileByPath ? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.resolvedPath, sourceFileOptions, void 0, shouldCreateNewSourceFile || sourceFileOptions.impliedNodeFormat !== oldSourceFile.impliedNodeFormat) : host.getSourceFile(oldSourceFile.fileName, sourceFileOptions, void 0, shouldCreateNewSourceFile || sourceFileOptions.impliedNodeFormat !== oldSourceFile.impliedNodeFormat);
109533 if (!newSourceFile) {109579 if (!newSourceFile) {
109580+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#6 source file no longer exists: ${oldSourceFile.fileName}`);
109581+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
109534 return 0 /* Not */;109582 return 0 /* Not */;
109535 }109583 }
109536 newSourceFile.packageJsonLocations = ((_a3 = sourceFileOptions.packageJsonLocations) == null ? void 0 : _a3.length) ? sourceFileOptions.packageJsonLocations : void 0;109584 newSourceFile.packageJsonLocations = ((_a3 = sourceFileOptions.packageJsonLocations) == null ? void 0 : _a3.length) ? sourceFileOptions.packageJsonLocations : void 0;
@@ -109539,12 +109587,16 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109539 let fileChanged;109587 let fileChanged;
109540 if (oldSourceFile.redirectInfo) {109588 if (oldSourceFile.redirectInfo) {
109541 if (newSourceFile !== oldSourceFile.redirectInfo.unredirected) {109589 if (newSourceFile !== oldSourceFile.redirectInfo.unredirected) {
109590+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#7 redirect underlying file changed: ${oldSourceFile.fileName}`);
109591+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
109542 return 0 /* Not */;109592 return 0 /* Not */;
109543 }109593 }
109544 fileChanged = false;109594 fileChanged = false;
109545 newSourceFile = oldSourceFile;109595 newSourceFile = oldSourceFile;
109546 } else if (oldProgram.redirectTargetsMap.has(oldSourceFile.path)) {109596 } else if (oldProgram.redirectTargetsMap.has(oldSourceFile.path)) {
109547 if (newSourceFile !== oldSourceFile) {109597 if (newSourceFile !== oldSourceFile) {
109598+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#8 redirected-to file changed: ${oldSourceFile.fileName}`);
109599+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
109548 return 0 /* Not */;109600 return 0 /* Not */;
109549 }109601 }
109550 fileChanged = false;109602 fileChanged = false;
@@ -109560,39 +109612,61 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109560 const prevKind = seenPackageNames.get(packageName);109612 const prevKind = seenPackageNames.get(packageName);
109561 const newKind = fileChanged ? 1 /* Modified */ : 0 /* Exists */;109613 const newKind = fileChanged ? 1 /* Modified */ : 0 /* Exists */;
109562 if (prevKind !== void 0 && newKind === 1 /* Modified */ || prevKind === 1 /* Modified */) {109614 if (prevKind !== void 0 && newKind === 1 /* Modified */ || prevKind === 1 /* Modified */) {
109615+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#9 package name conflict (two files for package "${packageName}", at least one changed): ${oldSourceFile.fileName}`);
109616+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
109563 return 0 /* Not */;109617 return 0 /* Not */;
109564 }109618 }
109565 seenPackageNames.set(packageName, newKind);109619 seenPackageNames.set(packageName, newKind);
109566 }109620 }
109567 if (fileChanged) {109621 if (fileChanged) {
109568 if (oldSourceFile.impliedNodeFormat !== newSourceFile.impliedNodeFormat) {109622 if (oldSourceFile.impliedNodeFormat !== newSourceFile.impliedNodeFormat) {
109623+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `impliedNodeFormat changed: ${oldSourceFile.fileName}`);
109624+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109569 structureIsReused = 1 /* SafeModules */;109625 structureIsReused = 1 /* SafeModules */;
109570 } else if (!arrayIsEqualTo(oldSourceFile.libReferenceDirectives, newSourceFile.libReferenceDirectives, fileReferenceIsEqualTo)) {109626 } else if (!arrayIsEqualTo(oldSourceFile.libReferenceDirectives, newSourceFile.libReferenceDirectives, fileReferenceIsEqualTo)) {
109627+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `libReferenceDirectives changed: ${oldSourceFile.fileName}`);
109628+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109571 structureIsReused = 1 /* SafeModules */;109629 structureIsReused = 1 /* SafeModules */;
109572 } else if (oldSourceFile.hasNoDefaultLib !== newSourceFile.hasNoDefaultLib) {109630 } else if (oldSourceFile.hasNoDefaultLib !== newSourceFile.hasNoDefaultLib) {
109631+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `hasNoDefaultLib changed: ${oldSourceFile.fileName}`);
109632+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109573 structureIsReused = 1 /* SafeModules */;109633 structureIsReused = 1 /* SafeModules */;
109574 } else if (!arrayIsEqualTo(oldSourceFile.referencedFiles, newSourceFile.referencedFiles, fileReferenceIsEqualTo)) {109634 } else if (!arrayIsEqualTo(oldSourceFile.referencedFiles, newSourceFile.referencedFiles, fileReferenceIsEqualTo)) {
109635+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `referencedFiles changed: ${oldSourceFile.fileName}`);
109636+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109575 structureIsReused = 1 /* SafeModules */;109637 structureIsReused = 1 /* SafeModules */;
109576 } else {109638 } else {
109577 collectExternalModuleReferences(newSourceFile);109639 collectExternalModuleReferences(newSourceFile);
109578 if (!arrayIsEqualTo(oldSourceFile.imports, newSourceFile.imports, moduleNameIsEqualTo)) {109640 if (!arrayIsEqualTo(oldSourceFile.imports, newSourceFile.imports, moduleNameIsEqualTo)) {
109641+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `imports changed: ${oldSourceFile.fileName}`);
109642+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109579 structureIsReused = 1 /* SafeModules */;109643 structureIsReused = 1 /* SafeModules */;
109580 } else if (!arrayIsEqualTo(oldSourceFile.moduleAugmentations, newSourceFile.moduleAugmentations, moduleNameIsEqualTo)) {109644 } else if (!arrayIsEqualTo(oldSourceFile.moduleAugmentations, newSourceFile.moduleAugmentations, moduleNameIsEqualTo)) {
109645+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `moduleAugmentations changed: ${oldSourceFile.fileName}`);
109646+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109581 structureIsReused = 1 /* SafeModules */;109647 structureIsReused = 1 /* SafeModules */;
109582 } else if ((oldSourceFile.flags & 6291456 /* PermanentlySetIncrementalFlags */) !== (newSourceFile.flags & 6291456 /* PermanentlySetIncrementalFlags */)) {109648 } else if ((oldSourceFile.flags & 6291456 /* PermanentlySetIncrementalFlags */) !== (newSourceFile.flags & 6291456 /* PermanentlySetIncrementalFlags */)) {
109649+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `PermanentlySetIncrementalFlags changed: ${oldSourceFile.fileName}`);
109650+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109583 structureIsReused = 1 /* SafeModules */;109651 structureIsReused = 1 /* SafeModules */;
109584 } else if (!arrayIsEqualTo(oldSourceFile.typeReferenceDirectives, newSourceFile.typeReferenceDirectives, fileReferenceIsEqualTo)) {109652 } else if (!arrayIsEqualTo(oldSourceFile.typeReferenceDirectives, newSourceFile.typeReferenceDirectives, fileReferenceIsEqualTo)) {
109653+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `typeReferenceDirectives changed: ${oldSourceFile.fileName}`);
109654+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109585 structureIsReused = 1 /* SafeModules */;109655 structureIsReused = 1 /* SafeModules */;
109586 }109656 }
109587 }109657 }
109588 modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });109658 modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });
109589 } else if (hasInvalidatedResolutions(oldSourceFile.path)) {109659 } else if (hasInvalidatedResolutions(oldSourceFile.path)) {
109660+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `hasInvalidatedResolutions: ${oldSourceFile.fileName}`);
109661+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109590 structureIsReused = 1 /* SafeModules */;109662 structureIsReused = 1 /* SafeModules */;
109591 modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });109663 modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });
109592 }109664 }
109593 newSourceFiles.push(newSourceFile);109665 newSourceFiles.push(newSourceFile);
109594 }109666 }
109595 if (structureIsReused !== 2 /* Completely */) {109667 if (structureIsReused !== 2 /* Completely */) {
109668+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `file content changed but module resolution reusable, modifiedFiles=${modifiedSourceFiles.length}`);
109669+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109596 return structureIsReused;109670 return structureIsReused;
109597 }109671 }
109598 const modifiedFiles = modifiedSourceFiles.map((f) => f.oldFile);109672 const modifiedFiles = modifiedSourceFiles.map((f) => f.oldFile);
@@ -109603,11 +109677,14 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109603 }109677 }
109604 }109678 }
109605 }109679 }
109680+ PerformanceDotting.startAdvanced("resolveModuleNames", `modifiedFiles=${modifiedSourceFiles.length}`);
109606 for (const { oldFile: oldSourceFile, newFile: newSourceFile } of modifiedSourceFiles) {109681 for (const { oldFile: oldSourceFile, newFile: newSourceFile } of modifiedSourceFiles) {
109607 const moduleNames = getModuleNames(newSourceFile);109682 const moduleNames = getModuleNames(newSourceFile);
109608 const resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFile);109683 const resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFile);
109609 const resolutionsChanged = hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, oldSourceFile, moduleResolutionIsEqualTo);109684 const resolutionsChanged = hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, oldSourceFile, moduleResolutionIsEqualTo);
109610 if (resolutionsChanged) {109685 if (resolutionsChanged) {
109686+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `module resolution changed: ${newSourceFile.fileName}`);
109687+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109611 structureIsReused = 1 /* SafeModules */;109688 structureIsReused = 1 /* SafeModules */;
109612 newSourceFile.resolvedModules = zipToModeAwareCache(newSourceFile, moduleNames, resolutions);109689 newSourceFile.resolvedModules = zipToModeAwareCache(newSourceFile, moduleNames, resolutions);
109613 } else {109690 } else {
@@ -109617,16 +109694,31 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109617 const typeReferenceResolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFile);109694 const typeReferenceResolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFile);
109618 const typeReferenceResolutionsChanged = hasChangesInResolutions(typesReferenceDirectives, typeReferenceResolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, oldSourceFile, typeDirectiveIsEqualTo);109695 const typeReferenceResolutionsChanged = hasChangesInResolutions(typesReferenceDirectives, typeReferenceResolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, oldSourceFile, typeDirectiveIsEqualTo);
109619 if (typeReferenceResolutionsChanged) {109696 if (typeReferenceResolutionsChanged) {
109697+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `typeReference resolution changed: ${newSourceFile.fileName}`);
109698+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109620 structureIsReused = 1 /* SafeModules */;109699 structureIsReused = 1 /* SafeModules */;
109621 newSourceFile.resolvedTypeReferenceDirectiveNames = zipToModeAwareCache(newSourceFile, typesReferenceDirectives, typeReferenceResolutions);109700 newSourceFile.resolvedTypeReferenceDirectiveNames = zipToModeAwareCache(newSourceFile, typesReferenceDirectives, typeReferenceResolutions);
109622 } else {109701 } else {
109623 newSourceFile.resolvedTypeReferenceDirectiveNames = oldSourceFile.resolvedTypeReferenceDirectiveNames;109702 newSourceFile.resolvedTypeReferenceDirectiveNames = oldSourceFile.resolvedTypeReferenceDirectiveNames;
109624 }109703 }
109625 }109704 }
109705+ PerformanceDotting.stopAdvanced("resolveModuleNames");
109626 if (structureIsReused !== 2 /* Completely */) {109706 if (structureIsReused !== 2 /* Completely */) {
109707+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `module resolution changed for modified files, modifiedFiles=${modifiedSourceFiles.length}`);
109708+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109627 return structureIsReused;109709 return structureIsReused;
109628 }109710 }
109629 if (changesAffectingProgramStructure(oldOptions, options) || ((_b2 = host.hasChangedAutomaticTypeDirectiveNames) == null ? void 0 : _b2.call(host))) {109711 if (changesAffectingProgramStructure(oldOptions, options) || ((_b2 = host.hasChangedAutomaticTypeDirectiveNames) == null ? void 0 : _b2.call(host))) {
109712+ const reasons = [];
109713+ if (changesAffectingProgramStructure(oldOptions, options)) {
109714+ const changedOpts = optionsAffectingProgramStructure.filter((o) => !isJsonEqual(getCompilerOptionValue(oldOptions, o), getCompilerOptionValue(options, o))).map((o) => o.name);
109715+ reasons.push(`changesAffectingProgramStructure: [${changedOpts.join(", ")}]`);
109716+ }
109717+ if ((_c2 = host.hasChangedAutomaticTypeDirectiveNames) == null ? void 0 : _c2.call(host)) {
109718+ reasons.push("hasChangedAutomaticTypeDirectiveNames");
109719+ }
109720+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `#10 ${reasons.join("; ")}`);
109721+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
109630 return 1 /* SafeModules */;109722 return 1 /* SafeModules */;
109631 }109723 }
109632 missingFilePaths = oldProgram.getMissingFilePaths();109724 missingFilePaths = oldProgram.getMissingFilePaths();
@@ -109655,6 +109747,8 @@ function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _config
109655 sourceFileToPackageName = oldProgram.sourceFileToPackageName;109747 sourceFileToPackageName = oldProgram.sourceFileToPackageName;
109656 redirectTargetsMap = oldProgram.redirectTargetsMap;109748 redirectTargetsMap = oldProgram.redirectTargetsMap;
109657 usesUriStyleNodeCoreModules = oldProgram.usesUriStyleNodeCoreModules;109749 usesUriStyleNodeCoreModules = oldProgram.usesUriStyleNodeCoreModules;
109750+ PerformanceDotting.startAdvanced("structureIsReused: Completely", "structure fully reused from old program");
109751+ PerformanceDotting.stopAdvanced("structureIsReused: Completely");
109658 return 2 /* Completely */;109752 return 2 /* Completely */;
109659 }109753 }
109660 function getEmitHost(writeFileCallback) {109754 function getEmitHost(writeFileCallback) {
@@ -112866,13 +112960,21 @@ function getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldP
112866 oldProgram = configFileParsingDiagnosticsOrOldProgram;112960 oldProgram = configFileParsingDiagnosticsOrOldProgram;
112867 Debug.assert(!!oldProgram);112961 Debug.assert(!!oldProgram);
112868 newProgram = oldProgram.getProgram();112962 newProgram = oldProgram.getProgram();
112963+ PerformanceDotting.startAdvanced("getBuilderCreationParameters: reuseProgramFromOldProgram", "newProgramOrRootNames undefined, no createProgram call");
112964+ PerformanceDotting.stopAdvanced("getBuilderCreationParameters: reuseProgramFromOldProgram");
112869 } else if (isArray(newProgramOrRootNames)) {112965 } else if (isArray(newProgramOrRootNames)) {
112870 oldProgram = configFileParsingDiagnosticsOrOldProgram;112966 oldProgram = configFileParsingDiagnosticsOrOldProgram;
112967+ const oldProgramForCreate = oldProgram && oldProgram.getProgramOrUndefined();
112968+ PerformanceDotting.startAdvanced(
112969+ "getBuilderCreationParameters: createProgram",
112970+ `oldProgram=${!!oldProgram}, hasOldProgram=${!!oldProgramForCreate}, rootNames=${newProgramOrRootNames.length}`
112971+ );
112972+ PerformanceDotting.stopAdvanced("getBuilderCreationParameters: createProgram");
112871 newProgram = createProgram({112973 newProgram = createProgram({
112872 rootNames: newProgramOrRootNames,112974 rootNames: newProgramOrRootNames,
112873 options: hostOrOptions,112975 options: hostOrOptions,
112874 host: oldProgramOrHost,112976 host: oldProgramOrHost,
112875- oldProgram: oldProgram && oldProgram.getProgramOrUndefined(),112977+ oldProgram: oldProgramForCreate,
112876 configFileParsingDiagnostics,112978 configFileParsingDiagnostics,
112877 projectReferences112979 projectReferences
112878 });112980 });
@@ -112882,6 +112984,8 @@ function getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldP
112882 host = hostOrOptions;112984 host = hostOrOptions;
112883 oldProgram = oldProgramOrHost;112985 oldProgram = oldProgramOrHost;
112884 configFileParsingDiagnostics = configFileParsingDiagnosticsOrOldProgram;112986 configFileParsingDiagnostics = configFileParsingDiagnosticsOrOldProgram;
112987+ PerformanceDotting.startAdvanced("getBuilderCreationParameters: newProgramProvided", `newProgram=${!!newProgram}, host=${!!host}, oldProgram=${!!oldProgram}, configFileParsingDiagnostics=${!!configFileParsingDiagnostics}`);
112988+ PerformanceDotting.stopAdvanced("getBuilderCreationParameters: newProgramProvided");
112885 }112989 }
112886 return { host, newProgram, oldProgram, configFileParsingDiagnostics: configFileParsingDiagnostics || emptyArray };112990 return { host, newProgram, oldProgram, configFileParsingDiagnostics: configFileParsingDiagnostics || emptyArray };
112887}112991}
@@ -113371,6 +113475,7 @@ function createEmitAndSemanticDiagnosticsBuilderProgram(newProgramOrRootNames, h
113371}113475}
113372function createEmitAndSemanticDiagnosticsBuilderProgramForArkTs(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences) {113476function createEmitAndSemanticDiagnosticsBuilderProgramForArkTs(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences) {
113373 PerformanceDotting.start("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");113477 PerformanceDotting.start("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");
113478+ PerformanceDotting.startAdvanced("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");
113374 PerformanceDotting.start("getBuilderCreationParameters");113479 PerformanceDotting.start("getBuilderCreationParameters");
113375 let builderCreatetionParameters = getBuilderCreationParameters(113480 let builderCreatetionParameters = getBuilderCreationParameters(
113376 newProgramOrRootNames,113481 newProgramOrRootNames,
@@ -113383,22 +113488,27 @@ function createEmitAndSemanticDiagnosticsBuilderProgramForArkTs(newProgramOrRoot
113383 PerformanceDotting.stop("getBuilderCreationParameters");113488 PerformanceDotting.stop("getBuilderCreationParameters");
113384 let newProgram = builderCreatetionParameters.newProgram;113489 let newProgram = builderCreatetionParameters.newProgram;
113385 PerformanceDotting.start("createBuilderProgram");113490 PerformanceDotting.start("createBuilderProgram");
113491+ PerformanceDotting.startAdvanced("createBuilderProgram");
113386 let builderProgram = createBuilderProgram(113492 let builderProgram = createBuilderProgram(
113387 1 /* EmitAndSemanticDiagnosticsBuilderProgram */,113493 1 /* EmitAndSemanticDiagnosticsBuilderProgram */,
113388 builderCreatetionParameters113494 builderCreatetionParameters
113389 );113495 );
113496+ PerformanceDotting.stopAdvanced("createBuilderProgram");
113390 PerformanceDotting.stop("createBuilderProgram");113497 PerformanceDotting.stop("createBuilderProgram");
113391 let oldProgramForLinter = readBuilderProgram(hostOrOptions, oldProgramOrHost, true);113498 let oldProgramForLinter = readBuilderProgram(hostOrOptions, oldProgramOrHost, true);
113392 builderCreatetionParameters.oldProgram = oldProgramForLinter;113499 builderCreatetionParameters.oldProgram = oldProgramForLinter;
113393 builderCreatetionParameters.newProgram = newProgram;113500 builderCreatetionParameters.newProgram = newProgram;
113394 PerformanceDotting.start("createBuilderProgramForLinter");113501 PerformanceDotting.start("createBuilderProgramForLinter");
113502+ PerformanceDotting.startAdvanced("createBuilderProgramForLinter");
113395 let builderProgramForLinter = createBuilderProgram(113503 let builderProgramForLinter = createBuilderProgram(
113396 1 /* EmitAndSemanticDiagnosticsBuilderProgram */,113504 1 /* EmitAndSemanticDiagnosticsBuilderProgram */,
113397 builderCreatetionParameters,113505 builderCreatetionParameters,
113398 true113506 true
113399 );113507 );
113508+ PerformanceDotting.stopAdvanced("createBuilderProgramForLinter");
113400 PerformanceDotting.stop("createBuilderProgramForLinter");113509 PerformanceDotting.stop("createBuilderProgramForLinter");
113401 builderProgram.builderProgramForLinter = builderProgramForLinter;113510 builderProgram.builderProgramForLinter = builderProgramForLinter;
113511+ PerformanceDotting.stopAdvanced("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");
113402 PerformanceDotting.stop("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");113512 PerformanceDotting.stop("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");
113403 return builderProgram;113513 return builderProgram;
113404}113514}
@@ -114813,12 +114923,20 @@ function readBuilderProgram(compilerOptions, host, isForLinter) {
114813 buildInfo = host.getBuildInfo(buildInfoPath, compilerOptions.configFilePath);114923 buildInfo = host.getBuildInfo(buildInfoPath, compilerOptions.configFilePath);
114814 } else {114924 } else {
114815 const content = host.readFile(buildInfoPath);114925 const content = host.readFile(buildInfoPath);
114816- if (!content)114926+ if (!content) {
114927+ PerformanceDotting.startAdvanced("readBuilderProgram: buildInfoNotFound", `${buildInfoPath} not found`);
114928+ PerformanceDotting.stopAdvanced("readBuilderProgram: buildInfoNotFound");
114817 return void 0;114929 return void 0;
114930+ }
114818 buildInfo = getBuildInfo(buildInfoPath, content);114931 buildInfo = getBuildInfo(buildInfoPath, content);
114819 }114932 }
114820- if (!buildInfo || buildInfo.version !== version || !buildInfo.program)114933+ if (!buildInfo || buildInfo.version !== version || !buildInfo.program) {
114934+ PerformanceDotting.startAdvanced("readBuilderProgram: invalidBuildInfo", `path=${buildInfoPath}, version=${buildInfo == null ? void 0 : buildInfo.version}, hasProgram=${!!(buildInfo == null ? void 0 : buildInfo.program)}`);
114935+ PerformanceDotting.stopAdvanced("readBuilderProgram: invalidBuildInfo");
114821 return void 0;114936 return void 0;
114937+ }
114938+ PerformanceDotting.startAdvanced("readBuilderProgram: loaded");
114939+ PerformanceDotting.stopAdvanced("readBuilderProgram: loaded");
114822 return createBuilderProgramUsingProgramBuildInfo(buildInfo.program, buildInfoPath, host);114940 return createBuilderProgramUsingProgramBuildInfo(buildInfo.program, buildInfoPath, host);
114823}114941}
114824function createIncrementalCompilerHost(options, system = sys) {114942function createIncrementalCompilerHost(options, system = sys) {
@@ -116467,11 +116585,17 @@ function listEmittedFile({ write }, proj, file) {
116467 }116585 }
116468}116586}
116469function getOldProgram({ options, builderPrograms, compilerHost }, proj, parsed) {116587function getOldProgram({ options, builderPrograms, compilerHost }, proj, parsed) {
116470- if (options.force)116588+ if (options.force) {
116589+ PerformanceDotting.startAdvanced("getOldProgram: force", `--force flag set, returning undefined for ${proj}`);
116590+ PerformanceDotting.stopAdvanced("getOldProgram: force");
116471 return void 0;116591 return void 0;
116592+ }
116472 const value = builderPrograms.get(proj);116593 const value = builderPrograms.get(proj);
116473- if (value)116594+ if (value) {
116595+ PerformanceDotting.startAdvanced("getOldProgram: cachedBuilderProgram", `reused from builderPrograms map for ${proj}`);
116596+ PerformanceDotting.stopAdvanced("getOldProgram: cachedBuilderProgram");
116474 return value;116597 return value;
116598+ }
116475 return readBuilderProgram(parsed.options, compilerHost);116599 return readBuilderProgram(parsed.options, compilerHost);
116476}116600}
116477function afterProgramDone(state, program, config) {116601function afterProgramDone(state, program, config) {
@@ -125556,7 +125680,9 @@ function createLanguageService(host, documentRegistry = createDocumentRegistry(h
125556 };125680 };
125557 const documentRegistryBucketKey = documentRegistry.getKeyForCompilationSettings(newSettings);125681 const documentRegistryBucketKey = documentRegistry.getKeyForCompilationSettings(newSettings);
125558 PerformanceDotting.start("isProgramUptoDate");125682 PerformanceDotting.start("isProgramUptoDate");
125683+ PerformanceDotting.startAdvanced("isProgramUptoDate");
125559 if (isProgramUptoDate(program, rootFileNames, newSettings, (_path, fileName) => host.getScriptVersion(fileName), (fileName) => compilerHost.fileExists(fileName), hasInvalidatedResolutions, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) {125684 if (isProgramUptoDate(program, rootFileNames, newSettings, (_path, fileName) => host.getScriptVersion(fileName), (fileName) => compilerHost.fileExists(fileName), hasInvalidatedResolutions, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) {
125685+ PerformanceDotting.stopAdvanced("isProgramUptoDate");
125560 PerformanceDotting.stop("isProgramUptoDate");125686 PerformanceDotting.stop("isProgramUptoDate");
125561 host.clearFileCache && host.clearFileCache();125687 host.clearFileCache && host.clearFileCache();
125562 if (isCreateIncrementalProgramMode && (builderProgram == null ? void 0 : builderProgram.resetConstEnumRelateUpdateFlag)) {125688 if (isCreateIncrementalProgramMode && (builderProgram == null ? void 0 : builderProgram.resetConstEnumRelateUpdateFlag)) {
@@ -125564,6 +125690,7 @@ function createLanguageService(host, documentRegistry = createDocumentRegistry(h
125564 }125690 }
125565 return;125691 return;
125566 }125692 }
125693+ PerformanceDotting.stopAdvanced("isProgramUptoDate");
125567 PerformanceDotting.stop("isProgramUptoDate");125694 PerformanceDotting.stop("isProgramUptoDate");
125568 host.clearProps && host.clearProps();125695 host.clearProps && host.clearProps();
125569 compilerHost.getLastCompiledProgram = () => {125696 compilerHost.getLastCompiledProgram = () => {
@@ -125591,7 +125718,9 @@ function createLanguageService(host, documentRegistry = createDocumentRegistry(h
125591 compilerHost = void 0;125718 compilerHost = void 0;
125592 parsedCommandLines = void 0;125719 parsedCommandLines = void 0;
125593 sourceMapper.clearCache();125720 sourceMapper.clearCache();
125721+ PerformanceDotting.startAdvanced("getTypeChecker");
125594 program.getTypeChecker();125722 program.getTypeChecker();
125723+ PerformanceDotting.stopAdvanced("getTypeChecker");
125595 host.clearFileCache && host.clearFileCache();125724 host.clearFileCache && host.clearFileCache();
125596 return;125725 return;
125597 function getParsedCommandLine(fileName) {125726 function getParsedCommandLine(fileName) {
@@ -165479,7 +165608,7 @@ function runArkTSLinter2(tsBuilderProgram, srcFile, buildInfoWriteFile, arkTSVer
165479 const tscStrictDiagnostics = getTscDiagnostics2(tscDiagnosticsLinter, srcFiles.filter((file) => changedFiles.has(file.resolvedPath)));165608 const tscStrictDiagnostics = getTscDiagnostics2(tscDiagnosticsLinter, srcFiles.filter((file) => changedFiles.has(file.resolvedPath)));
165480 timePrinterInstance.appendTime("getTscDiagnostics" /* GET_TSC_DIAGNOSTICS */);165609 timePrinterInstance.appendTime("getTscDiagnostics" /* GET_TSC_DIAGNOSTICS */);
165481 PerformanceDotting.stopAdvanced("getTscDiagnostics" /* GET_TSC_DIAGNOSTICS */);165610 PerformanceDotting.stopAdvanced("getTscDiagnostics" /* GET_TSC_DIAGNOSTICS */);
165482- const lintRecordLog = "lint" /* LINT */ + "(checkedFilesNum: " + changedFiles.size + ")";165611+ const lintRecordLog = "lint" /* LINT */ + "(checkedFilesNum: " + changedFiles.size + ", totalFilesNum: " + srcFiles.length + ")";
165483 PerformanceDotting.startAdvanced(lintRecordLog);165612 PerformanceDotting.startAdvanced(lintRecordLog);
165484 TypeScriptLinter2.initGlobals(compilerOptions);165613 TypeScriptLinter2.initGlobals(compilerOptions);
165485 InteropTypescriptLinter.initGlobals();165614 InteropTypescriptLinter.initGlobals();
@@ -62,6 +62,7 @@ import {
62 notImplemented,62 notImplemented,
63 outFile,63 outFile,
64 Path,64 Path,
65+ PerformanceDotting,
65 Program,66 Program,
66 ProjectReference,67 ProjectReference,
67 ReadBuildProgramHost,68 ReadBuildProgramHost,
@@ -1339,14 +1340,20 @@ export function getBuilderCreationParameters(newProgramOrRootNames: Program | re
1339 oldProgram = configFileParsingDiagnosticsOrOldProgram as BuilderProgram;1340 oldProgram = configFileParsingDiagnosticsOrOldProgram as BuilderProgram;
1340 Debug.assert(!!oldProgram);1341 Debug.assert(!!oldProgram);
1341 newProgram = oldProgram.getProgram();1342 newProgram = oldProgram.getProgram();
1343+ PerformanceDotting.startAdvanced("getBuilderCreationParameters: reuseProgramFromOldProgram", "newProgramOrRootNames undefined, no createProgram call");
1344+ PerformanceDotting.stopAdvanced("getBuilderCreationParameters: reuseProgramFromOldProgram");
1342 }1345 }
1343 else if (isArray(newProgramOrRootNames)) {1346 else if (isArray(newProgramOrRootNames)) {
1344 oldProgram = configFileParsingDiagnosticsOrOldProgram as BuilderProgram;1347 oldProgram = configFileParsingDiagnosticsOrOldProgram as BuilderProgram;
1348+ const oldProgramForCreate = oldProgram && oldProgram.getProgramOrUndefined();
1349+ PerformanceDotting.startAdvanced("getBuilderCreationParameters: createProgram",
1350+ `oldProgram=${!!oldProgram}, hasOldProgram=${!!oldProgramForCreate}, rootNames=${(newProgramOrRootNames as readonly string[]).length}`);
1351+ PerformanceDotting.stopAdvanced("getBuilderCreationParameters: createProgram");
1345 newProgram = createProgram({1352 newProgram = createProgram({
1346 rootNames: newProgramOrRootNames,1353 rootNames: newProgramOrRootNames,
1347 options: hostOrOptions as CompilerOptions,1354 options: hostOrOptions as CompilerOptions,
1348 host: oldProgramOrHost as CompilerHost,1355 host: oldProgramOrHost as CompilerHost,
1349- oldProgram: oldProgram && oldProgram.getProgramOrUndefined(),1356+ oldProgram: oldProgramForCreate,
1350 configFileParsingDiagnostics,1357 configFileParsingDiagnostics,
1351 projectReferences1358 projectReferences
1352 });1359 });
@@ -1357,6 +1364,8 @@ export function getBuilderCreationParameters(newProgramOrRootNames: Program | re
1357 host = hostOrOptions as BuilderProgramHost;1364 host = hostOrOptions as BuilderProgramHost;
1358 oldProgram = oldProgramOrHost as BuilderProgram;1365 oldProgram = oldProgramOrHost as BuilderProgram;
1359 configFileParsingDiagnostics = configFileParsingDiagnosticsOrOldProgram as readonly Diagnostic[];1366 configFileParsingDiagnostics = configFileParsingDiagnosticsOrOldProgram as readonly Diagnostic[];
1367+ PerformanceDotting.startAdvanced("getBuilderCreationParameters: newProgramProvided", `newProgram=${!!newProgram}, host=${!!host}, oldProgram=${!!oldProgram}, configFileParsingDiagnostics=${!!configFileParsingDiagnostics}`);
1368+ PerformanceDotting.stopAdvanced("getBuilderCreationParameters: newProgramProvided");
1360 }1369 }
1361 return { host, newProgram, oldProgram, configFileParsingDiagnostics: configFileParsingDiagnostics || emptyArray };1370 return { host, newProgram, oldProgram, configFileParsingDiagnostics: configFileParsingDiagnostics || emptyArray };
1362}1371}
@@ -206,6 +206,7 @@ export function createEmitAndSemanticDiagnosticsBuilderProgramForArkTs(
206 configFileParsingDiagnostics?: readonly Diagnostic[],206 configFileParsingDiagnostics?: readonly Diagnostic[],
207 projectReferences?: readonly ProjectReference[]) : EmitAndSemanticDiagnosticsBuilderProgram {207 projectReferences?: readonly ProjectReference[]) : EmitAndSemanticDiagnosticsBuilderProgram {
208 PerformanceDotting.start("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");208 PerformanceDotting.start("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");
209+ PerformanceDotting.startAdvanced("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");
209 PerformanceDotting.start("getBuilderCreationParameters");210 PerformanceDotting.start("getBuilderCreationParameters");
210 let builderCreatetionParameters: BuilderCreationParameters =211 let builderCreatetionParameters: BuilderCreationParameters =
211 getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost,212 getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost,
@@ -213,8 +214,10 @@ export function createEmitAndSemanticDiagnosticsBuilderProgramForArkTs(
213 PerformanceDotting.stop("getBuilderCreationParameters");214 PerformanceDotting.stop("getBuilderCreationParameters");
214 let newProgram = builderCreatetionParameters.newProgram;215 let newProgram = builderCreatetionParameters.newProgram;
215 PerformanceDotting.start("createBuilderProgram");216 PerformanceDotting.start("createBuilderProgram");
217+ PerformanceDotting.startAdvanced("createBuilderProgram");
216 let builderProgram: EmitAndSemanticDiagnosticsBuilderProgram = createBuilderProgram(218 let builderProgram: EmitAndSemanticDiagnosticsBuilderProgram = createBuilderProgram(
217 BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram, builderCreatetionParameters);219 BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram, builderCreatetionParameters);
220+ PerformanceDotting.stopAdvanced("createBuilderProgram");
218 PerformanceDotting.stop("createBuilderProgram");221 PerformanceDotting.stop("createBuilderProgram");
219 222 
220 let oldProgramForLinter =223 let oldProgramForLinter =
@@ -222,11 +225,14 @@ export function createEmitAndSemanticDiagnosticsBuilderProgramForArkTs(
222 builderCreatetionParameters.oldProgram = oldProgramForLinter;225 builderCreatetionParameters.oldProgram = oldProgramForLinter;
223 builderCreatetionParameters.newProgram = newProgram;226 builderCreatetionParameters.newProgram = newProgram;
224 PerformanceDotting.start("createBuilderProgramForLinter");227 PerformanceDotting.start("createBuilderProgramForLinter");
228+ PerformanceDotting.startAdvanced("createBuilderProgramForLinter");
225 let builderProgramForLinter: EmitAndSemanticDiagnosticsBuilderProgram = createBuilderProgram(229 let builderProgramForLinter: EmitAndSemanticDiagnosticsBuilderProgram = createBuilderProgram(
226 BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram, builderCreatetionParameters, true);230 BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram, builderCreatetionParameters, true);
231+ PerformanceDotting.stopAdvanced("createBuilderProgramForLinter");
227 PerformanceDotting.stop("createBuilderProgramForLinter");232 PerformanceDotting.stop("createBuilderProgramForLinter");
228 233 
229 builderProgram.builderProgramForLinter = builderProgramForLinter;234 builderProgram.builderProgramForLinter = builderProgramForLinter;
235+ PerformanceDotting.stopAdvanced("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");
230 PerformanceDotting.stop("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");236 PerformanceDotting.stop("createEmitAndSemanticDiagnosticsBuilderProgramForArkTs");
231 return builderProgram;237 return builderProgram;
232}238}
@@ -107,6 +107,7 @@ import {
107 getBaseFileName,107 getBaseFileName,
108 GetCanonicalFileName,108 GetCanonicalFileName,
109 getCommonSourceDirectoryOfConfig,109 getCommonSourceDirectoryOfConfig,
110+ getCompilerOptionValue,
110 getDefaultLibFileName,111 getDefaultLibFileName,
111 getDirectoryPath,112 getDirectoryPath,
112 getEmitDeclarations,113 getEmitDeclarations,
@@ -186,6 +187,7 @@ import {
186 isImportTypeNode,187 isImportTypeNode,
187 isIncrementalCompilation,188 isIncrementalCompilation,
188 isInJSFile,189 isInJSFile,
190+ isJsonEqual,
189 isLiteralImportTypeNode,191 isLiteralImportTypeNode,
190 isModifier,192 isModifier,
191 isModuleDeclaration,193 isModuleDeclaration,
@@ -219,6 +221,7 @@ import {
219 ModuleResolutionCache,221 ModuleResolutionCache,
220 ModuleResolutionHost,222 ModuleResolutionHost,
221 moduleResolutionIsEqualTo,223 moduleResolutionIsEqualTo,
224+ moduleResolutionOptionDeclarations,
222 ModuleResolutionKind,225 ModuleResolutionKind,
223 Mutable,226 Mutable,
224 Node,227 Node,
@@ -233,6 +236,7 @@ import {
233 ObjectLiteralExpression,236 ObjectLiteralExpression,
234 ohModulesPathPart,237 ohModulesPathPart,
235 OperationCanceledException,238 OperationCanceledException,
239+ optionsAffectingProgramStructure,
236 optionsHaveChanges,240 optionsHaveChanges,
237 outFile,241 outFile,
238 PackageId,242 PackageId,
@@ -1345,6 +1349,7 @@ export function createProgram(createProgramOptions: CreateProgramOptions): Progr
1345export function createProgram(rootNames: readonly string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, configFileParsingDiagnostics?: readonly Diagnostic[]): Program;1349export function createProgram(rootNames: readonly string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, configFileParsingDiagnostics?: readonly Diagnostic[]): Program;
1346export function createProgram(rootNamesOrOptions: readonly string[] | CreateProgramOptions, _options?: CompilerOptions, _host?: CompilerHost, _oldProgram?: Program, _configFileParsingDiagnostics?: readonly Diagnostic[]): Program {1350export function createProgram(rootNamesOrOptions: readonly string[] | CreateProgramOptions, _options?: CompilerOptions, _host?: CompilerHost, _oldProgram?: Program, _configFileParsingDiagnostics?: readonly Diagnostic[]): Program {
1347 PerformanceDotting.start("createProgram");1351 PerformanceDotting.start("createProgram");
1352+ PerformanceDotting.startAdvanced("createProgram");
1348 const createProgramOptions = isArray(rootNamesOrOptions) ? createCreateProgramOptions(rootNamesOrOptions, _options!, _host, _oldProgram, _configFileParsingDiagnostics) : rootNamesOrOptions; // TODO: GH#182171353 const createProgramOptions = isArray(rootNamesOrOptions) ? createCreateProgramOptions(rootNamesOrOptions, _options!, _host, _oldProgram, _configFileParsingDiagnostics) : rootNamesOrOptions; // TODO: GH#18217
1349 const { rootNames, options, configFileParsingDiagnostics, projectReferences } = createProgramOptions;1354 const { rootNames, options, configFileParsingDiagnostics, projectReferences } = createProgramOptions;
1350 let { oldProgram } = createProgramOptions;1355 let { oldProgram } = createProgramOptions;
@@ -1494,9 +1499,13 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
1494 let structureIsReused: StructureIsReused;1499 let structureIsReused: StructureIsReused;
1495 tracing?.push(tracing.Phase.Program, "tryReuseStructureFromOldProgram", {});1500 tracing?.push(tracing.Phase.Program, "tryReuseStructureFromOldProgram", {});
1496 PerformanceDotting.start("tryReuseStructureFromOldProgram");1501 PerformanceDotting.start("tryReuseStructureFromOldProgram");
1502+ PerformanceDotting.startAdvanced("tryReuseStructureFromOldProgram");
1497 structureIsReused = tryReuseStructureFromOldProgram(); // eslint-disable-line prefer-const1503 structureIsReused = tryReuseStructureFromOldProgram(); // eslint-disable-line prefer-const
1498- PerformanceDotting.startAdvanced("structureIsReused" + ': ' + structureIsReused);1504+ const structureIsReusedName = structureIsReused === StructureIsReused.Completely ? "Completely" :
1499- PerformanceDotting.stopAdvanced("structureIsReused" + ': ' + structureIsReused);1505+ structureIsReused === StructureIsReused.SafeModules ? "SafeModules" : "Not";
1506+ PerformanceDotting.startAdvanced("structureIsReused: " + structureIsReusedName);
1507+ PerformanceDotting.stopAdvanced("structureIsReused: " + structureIsReusedName);
1508+ PerformanceDotting.stopAdvanced("tryReuseStructureFromOldProgram");
1500 PerformanceDotting.stop("tryReuseStructureFromOldProgram");1509 PerformanceDotting.stop("tryReuseStructureFromOldProgram");
1501 tracing?.pop();1510 tracing?.pop();
1502 if (structureIsReused !== StructureIsReused.Completely) {1511 if (structureIsReused !== StructureIsReused.Completely) {
@@ -1537,7 +1546,9 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
1537 1546 
1538 tracing?.push(tracing.Phase.Program, "processRootFiles", { count: rootNames.length });1547 tracing?.push(tracing.Phase.Program, "processRootFiles", { count: rootNames.length });
1539 PerformanceDotting.start("processRootFiles");1548 PerformanceDotting.start("processRootFiles");
1549+ PerformanceDotting.startAdvanced("processRootFiles", `rootNames=${rootNames.length}`);
1540 forEach(rootNames, (name, index) => processRootFile(name, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, { kind: FileIncludeKind.RootFile, index }));1550 forEach(rootNames, (name, index) => processRootFile(name, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, { kind: FileIncludeKind.RootFile, index }));
1551+ PerformanceDotting.stopAdvanced("processRootFiles");
1541 PerformanceDotting.stop("processRootFiles");1552 PerformanceDotting.stop("processRootFiles");
1542 tracing?.pop();1553 tracing?.pop();
1543 1554 
@@ -1547,6 +1558,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
1547 if (typeReferences.length) {1558 if (typeReferences.length) {
1548 tracing?.push(tracing.Phase.Program, "processTypeReferences", { count: typeReferences.length });1559 tracing?.push(tracing.Phase.Program, "processTypeReferences", { count: typeReferences.length });
1549 PerformanceDotting.start("processTypeReferences");1560 PerformanceDotting.start("processTypeReferences");
1561+ PerformanceDotting.startAdvanced("processTypeReferences", `count=${typeReferences.length}`);
1550 // This containingFilename needs to match with the one used in managed-side1562 // This containingFilename needs to match with the one used in managed-side
1551 const containingDirectory = options.configFilePath ? getDirectoryPath(options.configFilePath) : host.getCurrentDirectory();1563 const containingDirectory = options.configFilePath ? getDirectoryPath(options.configFilePath) : host.getCurrentDirectory();
1552 const containingFilename = combinePaths(containingDirectory, inferredTypesContainingFile);1564 const containingFilename = combinePaths(containingDirectory, inferredTypesContainingFile);
@@ -1555,6 +1567,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
1555 // under node16/nodenext module resolution, load `types`/ata include names as cjs resolution results by passing an `undefined` mode1567 // under node16/nodenext module resolution, load `types`/ata include names as cjs resolution results by passing an `undefined` mode
1556 processTypeReferenceDirective(typeReferences[i], /*mode*/ undefined, resolutions[i], { kind: FileIncludeKind.AutomaticTypeDirectiveFile, typeReference: typeReferences[i], packageId: resolutions[i]?.packageId });1568 processTypeReferenceDirective(typeReferences[i], /*mode*/ undefined, resolutions[i], { kind: FileIncludeKind.AutomaticTypeDirectiveFile, typeReference: typeReferences[i], packageId: resolutions[i]?.packageId });
1557 }1569 }
1570+ PerformanceDotting.stopAdvanced("processTypeReferences");
1558 PerformanceDotting.stop("processTypeReferences");1571 PerformanceDotting.stop("processTypeReferences");
1559 tracing?.pop();1572 tracing?.pop();
1560 }1573 }
@@ -1564,6 +1577,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
1564 // - A 'no-default-lib' reference comment is encountered in1577 // - A 'no-default-lib' reference comment is encountered in
1565 // processing the root files.1578 // processing the root files.
1566 PerformanceDotting.start("processDefaultLib");1579 PerformanceDotting.start("processDefaultLib");
1580+ PerformanceDotting.startAdvanced("processDefaultLib");
1567 if (rootNames.length && !skipDefaultLib) {1581 if (rootNames.length && !skipDefaultLib) {
1568 // If '--lib' is not specified, include default library file according to '--target'1582 // If '--lib' is not specified, include default library file according to '--target'
1569 // otherwise, using options specified in '--lib' instead of '--target' default library file1583 // otherwise, using options specified in '--lib' instead of '--target' default library file
@@ -1584,6 +1598,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
1584 }1598 }
1585 }1599 }
1586 }1600 }
1601+ PerformanceDotting.stopAdvanced("processDefaultLib");
1587 PerformanceDotting.stop("processDefaultLib");1602 PerformanceDotting.stop("processDefaultLib");
1588 1603 
1589 missingFilePaths = arrayFrom(mapDefinedIterator(filesByName.entries(), ([path, file]) => file === undefined ? path as Path : undefined));1604 missingFilePaths = arrayFrom(mapDefinedIterator(filesByName.entries(), ([path, file]) => file === undefined ? path as Path : undefined));
@@ -1614,8 +1629,6 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
1614 });1629 });
1615 }1630 }
1616 }1631 }
1617- 
1618- // Release commandlines that new program does not use
1619 if (oldProgram && host.onReleaseParsedCommandLine) {1632 if (oldProgram && host.onReleaseParsedCommandLine) {
1620 forEachProjectReference(1633 forEachProjectReference(
1621 oldProgram.getProjectReferences(),1634 oldProgram.getProjectReferences(),
@@ -1736,6 +1749,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
1736 MemoryDotting.stopRecordStage(recordInfo);1749 MemoryDotting.stopRecordStage(recordInfo);
1737 performance.measure("Program", "beforeProgram", "afterProgram");1750 performance.measure("Program", "beforeProgram", "afterProgram");
1738 tracing?.pop();1751 tracing?.pop();
1752+ PerformanceDotting.stopAdvanced("createProgram");
1739 PerformanceDotting.stop("createProgram");1753 PerformanceDotting.stop("createProgram");
1740 1754 
1741 return program;1755 return program;
@@ -2036,34 +2050,51 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2036 }2050 }
2037 }2051 }
2038 2052 
2039- function canReuseProjectReferences(): boolean {2053+ function tryReuseProjectReferences(): string | undefined {
2040- return !forEachProjectReference(2054+ return forEachProjectReference(
2041 oldProgram!.getProjectReferences(),2055 oldProgram!.getProjectReferences(),
2042 oldProgram!.getResolvedProjectReferences(),2056 oldProgram!.getResolvedProjectReferences(),
2043 (oldResolvedRef, parent, index) => {2057 (oldResolvedRef, parent, index) => {
2044 const newRef = (parent ? parent.commandLine.projectReferences : projectReferences)![index];2058 const newRef = (parent ? parent.commandLine.projectReferences : projectReferences)![index];
2045 const newResolvedRef = parseProjectReferenceConfigFile(newRef);2059 const newResolvedRef = parseProjectReferenceConfigFile(newRef);
2060+ const refPath = newRef?.originalPath ?? newRef?.path ?? oldResolvedRef?.sourceFile?.fileName ?? "(unknown project reference)";
2046 if (oldResolvedRef) {2061 if (oldResolvedRef) {
2047 // Resolved project reference has gone missing or changed2062 // Resolved project reference has gone missing or changed
2048- return !newResolvedRef ||2063+ if (!newResolvedRef) {
2049- newResolvedRef.sourceFile !== oldResolvedRef.sourceFile ||2064+ return `resolved project reference no longer resolvable: ${refPath}`;
2050- !arrayIsEqualTo(oldResolvedRef.commandLine.fileNames, newResolvedRef.commandLine.fileNames);2065+ }
2066+ if (newResolvedRef.sourceFile !== oldResolvedRef.sourceFile) {
2067+ return `project reference sourceFile changed: ${refPath}`;
2068+ }
2069+ if (!arrayIsEqualTo(oldResolvedRef.commandLine.fileNames, newResolvedRef.commandLine.fileNames)) {
2070+ return `project reference fileNames changed: ${refPath}`;
2071+ }
2072+ return undefined;
2051 }2073 }
2052 else {2074 else {
2053 // A previously-unresolved reference may be resolved now2075 // A previously-unresolved reference may be resolved now
2054- return newResolvedRef !== undefined;2076+ if (newResolvedRef !== undefined) {
2077+ return `previously-unresolved project reference now resolved: ${refPath}`;
2078+ }
2079+ return undefined;
2055 }2080 }
2056 },2081 },
2057 (oldProjectReferences, parent) => {2082 (oldProjectReferences, parent) => {
2058 // If array of references is changed, we cant resue old program2083 // If array of references is changed, we cant resue old program
2059 const newReferences = parent ? getResolvedProjectReferenceByPath(parent.sourceFile.path)!.commandLine.projectReferences : projectReferences;2084 const newReferences = parent ? getResolvedProjectReferenceByPath(parent.sourceFile.path)!.commandLine.projectReferences : projectReferences;
2060- return !arrayIsEqualTo(oldProjectReferences, newReferences, projectReferenceIsEqualTo);2085+ if (!arrayIsEqualTo(oldProjectReferences, newReferences, projectReferenceIsEqualTo)) {
2086+ const owner = parent ? parent.sourceFile.fileName : "(root)";
2087+ return `project references array changed in: ${owner}`;
2088+ }
2089+ return undefined;
2061 }2090 }
2062 );2091 );
2063 }2092 }
2064 2093 
2065 function tryReuseStructureFromOldProgram(): StructureIsReused {2094 function tryReuseStructureFromOldProgram(): StructureIsReused {
2066 if (!oldProgram) {2095 if (!oldProgram) {
2096+ PerformanceDotting.startAdvanced("structureIsReused: Not", "#1 oldProgram is undefined (first build or .tsbuildinfo missing/deleted/corrupt)");
2097+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
2067 return StructureIsReused.Not;2098 return StructureIsReused.Not;
2068 }2099 }
2069 2100 
@@ -2071,17 +2102,31 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2071 // if any of these properties has changed - structure cannot be reused2102 // if any of these properties has changed - structure cannot be reused
2072 const oldOptions = oldProgram.getCompilerOptions();2103 const oldOptions = oldProgram.getCompilerOptions();
2073 if (changesAffectModuleResolution(oldOptions, options)) {2104 if (changesAffectModuleResolution(oldOptions, options)) {
2105+ const changedOptions = moduleResolutionOptionDeclarations
2106+ .filter(o => !isJsonEqual(getCompilerOptionValue(oldOptions, o), getCompilerOptionValue(options, o)))
2107+ .map(o => o.name);
2108+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#2 changesAffectModuleResolution - changedOptions: [${changedOptions.join(", ")}], configFilePath: ${oldOptions.configFilePath} -> ${options.configFilePath}`);
2109+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
2074 return StructureIsReused.Not;2110 return StructureIsReused.Not;
2075 }2111 }
2076 2112 
2077 // there is an old program, check if we can reuse its structure2113 // there is an old program, check if we can reuse its structure
2078 const oldRootNames = oldProgram.getRootFileNames();2114 const oldRootNames = oldProgram.getRootFileNames();
2079 if (!arrayIsEqualTo(oldRootNames, rootNames)) {2115 if (!arrayIsEqualTo(oldRootNames, rootNames)) {
2116+ const addedFiles = rootNames.filter(f => !oldRootNames.includes(f));
2117+ const removedFiles = oldRootNames.filter(f => !rootNames.includes(f));
2118+ const addedList = addedFiles.length > 10 ? addedFiles.slice(0, 10).join(", ") + `, ... and ${addedFiles.length - 10} more` : addedFiles.join(", ");
2119+ const removedList = removedFiles.length > 10 ? removedFiles.slice(0, 10).join(", ") + `, ... and ${removedFiles.length - 10} more` : removedFiles.join(", ");
2120+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#3 rootNames changed - oldCount=${oldRootNames.length}, newCount=${rootNames.length}, added=[${addedList}], removed=[${removedList}]`);
2121+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
2080 return StructureIsReused.Not;2122 return StructureIsReused.Not;
2081 }2123 }
2082 2124 
2083 // Check if any referenced project tsconfig files are different2125 // Check if any referenced project tsconfig files are different
2084- if (!canReuseProjectReferences()) {2126+ const projectReferenceReuseFailReason = tryReuseProjectReferences();
2127+ if (projectReferenceReuseFailReason !== undefined) {
2128+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#4 tryReuseProjectReferences failed: ${projectReferenceReuseFailReason}`);
2129+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
2085 return StructureIsReused.Not;2130 return StructureIsReused.Not;
2086 }2131 }
2087 if (projectReferences) {2132 if (projectReferences) {
@@ -2096,7 +2141,10 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2096 // If the missing file paths are now present, it can change the progam structure,2141 // If the missing file paths are now present, it can change the progam structure,
2097 // and hence cant reuse the structure.2142 // and hence cant reuse the structure.
2098 // This is same as how we dont reuse the structure if one of the file from old program is now missing2143 // This is same as how we dont reuse the structure if one of the file from old program is now missing
2099- if (oldProgram.getMissingFilePaths().some(missingFilePath => host.fileExists(missingFilePath))) {2144+ const nowExistingMissingFilePath = oldProgram.getMissingFilePaths().find(missingFilePath => host.fileExists(missingFilePath));
2145+ if (nowExistingMissingFilePath !== undefined) {
2146+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#5 a previously missing file now exists: ${nowExistingMissingFilePath}`);
2147+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
2100 return StructureIsReused.Not;2148 return StructureIsReused.Not;
2101 }2149 }
2102 2150 
@@ -2111,6 +2159,8 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2111 : host.getSourceFile(oldSourceFile.fileName, sourceFileOptions, /*onError*/ undefined, shouldCreateNewSourceFile || sourceFileOptions.impliedNodeFormat !== oldSourceFile.impliedNodeFormat); // TODO: GH#182172159 : host.getSourceFile(oldSourceFile.fileName, sourceFileOptions, /*onError*/ undefined, shouldCreateNewSourceFile || sourceFileOptions.impliedNodeFormat !== oldSourceFile.impliedNodeFormat); // TODO: GH#18217
2112 2160 
2113 if (!newSourceFile) {2161 if (!newSourceFile) {
2162+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#6 source file no longer exists: ${oldSourceFile.fileName}`);
2163+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
2114 return StructureIsReused.Not;2164 return StructureIsReused.Not;
2115 }2165 }
2116 newSourceFile.packageJsonLocations = sourceFileOptions.packageJsonLocations?.length ? sourceFileOptions.packageJsonLocations : undefined;2166 newSourceFile.packageJsonLocations = sourceFileOptions.packageJsonLocations?.length ? sourceFileOptions.packageJsonLocations : undefined;
@@ -2124,6 +2174,8 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2124 // This lets us know if the unredirected file has changed. If it has we should break the redirect.2174 // This lets us know if the unredirected file has changed. If it has we should break the redirect.
2125 if (newSourceFile !== oldSourceFile.redirectInfo.unredirected) {2175 if (newSourceFile !== oldSourceFile.redirectInfo.unredirected) {
2126 // Underlying file has changed. Might not redirect anymore. Must rebuild program.2176 // Underlying file has changed. Might not redirect anymore. Must rebuild program.
2177+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#7 redirect underlying file changed: ${oldSourceFile.fileName}`);
2178+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
2127 return StructureIsReused.Not;2179 return StructureIsReused.Not;
2128 }2180 }
2129 fileChanged = false;2181 fileChanged = false;
@@ -2132,6 +2184,8 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2132 else if (oldProgram.redirectTargetsMap.has(oldSourceFile.path)) {2184 else if (oldProgram.redirectTargetsMap.has(oldSourceFile.path)) {
2133 // If a redirected-to source file changes, the redirect may be broken.2185 // If a redirected-to source file changes, the redirect may be broken.
2134 if (newSourceFile !== oldSourceFile) {2186 if (newSourceFile !== oldSourceFile) {
2187+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#8 redirected-to file changed: ${oldSourceFile.fileName}`);
2188+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
2135 return StructureIsReused.Not;2189 return StructureIsReused.Not;
2136 }2190 }
2137 fileChanged = false;2191 fileChanged = false;
@@ -2153,6 +2207,8 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2153 const prevKind = seenPackageNames.get(packageName);2207 const prevKind = seenPackageNames.get(packageName);
2154 const newKind = fileChanged ? SeenPackageName.Modified : SeenPackageName.Exists;2208 const newKind = fileChanged ? SeenPackageName.Modified : SeenPackageName.Exists;
2155 if ((prevKind !== undefined && newKind === SeenPackageName.Modified) || prevKind === SeenPackageName.Modified) {2209 if ((prevKind !== undefined && newKind === SeenPackageName.Modified) || prevKind === SeenPackageName.Modified) {
2210+ PerformanceDotting.startAdvanced("structureIsReused: Not", `#9 package name conflict (two files for package "${packageName}", at least one changed): ${oldSourceFile.fileName}`);
2211+ PerformanceDotting.stopAdvanced("structureIsReused: Not");
2156 return StructureIsReused.Not;2212 return StructureIsReused.Not;
2157 }2213 }
2158 seenPackageNames.set(packageName, newKind);2214 seenPackageNames.set(packageName, newKind);
@@ -2160,21 +2216,29 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2160 2216 
2161 if (fileChanged) {2217 if (fileChanged) {
2162 if (oldSourceFile.impliedNodeFormat !== newSourceFile.impliedNodeFormat) {2218 if (oldSourceFile.impliedNodeFormat !== newSourceFile.impliedNodeFormat) {
2219+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `impliedNodeFormat changed: ${oldSourceFile.fileName}`);
2220+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
2163 structureIsReused = StructureIsReused.SafeModules;2221 structureIsReused = StructureIsReused.SafeModules;
2164 }2222 }
2165 // The `newSourceFile` object was created for the new program.2223 // The `newSourceFile` object was created for the new program.
2166 else if (!arrayIsEqualTo(oldSourceFile.libReferenceDirectives, newSourceFile.libReferenceDirectives, fileReferenceIsEqualTo)) {2224 else if (!arrayIsEqualTo(oldSourceFile.libReferenceDirectives, newSourceFile.libReferenceDirectives, fileReferenceIsEqualTo)) {
2167 // 'lib' references has changed. Matches behavior in changesAffectModuleResolution2225 // 'lib' references has changed. Matches behavior in changesAffectModuleResolution
2226+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `libReferenceDirectives changed: ${oldSourceFile.fileName}`);
2227+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
2168 structureIsReused = StructureIsReused.SafeModules;2228 structureIsReused = StructureIsReused.SafeModules;
2169 }2229 }
2170 else if (oldSourceFile.hasNoDefaultLib !== newSourceFile.hasNoDefaultLib) {2230 else if (oldSourceFile.hasNoDefaultLib !== newSourceFile.hasNoDefaultLib) {
2171 // value of no-default-lib has changed2231 // value of no-default-lib has changed
2172 // this will affect if default library is injected into the list of files2232 // this will affect if default library is injected into the list of files
2233+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `hasNoDefaultLib changed: ${oldSourceFile.fileName}`);
2234+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
2173 structureIsReused = StructureIsReused.SafeModules;2235 structureIsReused = StructureIsReused.SafeModules;
2174 }2236 }
2175 // check tripleslash references2237 // check tripleslash references
2176 else if (!arrayIsEqualTo(oldSourceFile.referencedFiles, newSourceFile.referencedFiles, fileReferenceIsEqualTo)) {2238 else if (!arrayIsEqualTo(oldSourceFile.referencedFiles, newSourceFile.referencedFiles, fileReferenceIsEqualTo)) {
2177 // tripleslash references has changed2239 // tripleslash references has changed
2240+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `referencedFiles changed: ${oldSourceFile.fileName}`);
2241+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
2178 structureIsReused = StructureIsReused.SafeModules;2242 structureIsReused = StructureIsReused.SafeModules;
2179 }2243 }
2180 else {2244 else {
@@ -2182,18 +2246,26 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2182 collectExternalModuleReferences(newSourceFile);2246 collectExternalModuleReferences(newSourceFile);
2183 if (!arrayIsEqualTo(oldSourceFile.imports, newSourceFile.imports, moduleNameIsEqualTo)) {2247 if (!arrayIsEqualTo(oldSourceFile.imports, newSourceFile.imports, moduleNameIsEqualTo)) {
2184 // imports has changed2248 // imports has changed
2249+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `imports changed: ${oldSourceFile.fileName}`);
2250+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
2185 structureIsReused = StructureIsReused.SafeModules;2251 structureIsReused = StructureIsReused.SafeModules;
2186 }2252 }
2187 else if (!arrayIsEqualTo(oldSourceFile.moduleAugmentations, newSourceFile.moduleAugmentations, moduleNameIsEqualTo)) {2253 else if (!arrayIsEqualTo(oldSourceFile.moduleAugmentations, newSourceFile.moduleAugmentations, moduleNameIsEqualTo)) {
2188 // moduleAugmentations has changed2254 // moduleAugmentations has changed
2255+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `moduleAugmentations changed: ${oldSourceFile.fileName}`);
2256+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
2189 structureIsReused = StructureIsReused.SafeModules;2257 structureIsReused = StructureIsReused.SafeModules;
2190 }2258 }
2191 else if ((oldSourceFile.flags & NodeFlags.PermanentlySetIncrementalFlags) !== (newSourceFile.flags & NodeFlags.PermanentlySetIncrementalFlags)) {2259 else if ((oldSourceFile.flags & NodeFlags.PermanentlySetIncrementalFlags) !== (newSourceFile.flags & NodeFlags.PermanentlySetIncrementalFlags)) {
2192 // dynamicImport has changed2260 // dynamicImport has changed
2261+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `PermanentlySetIncrementalFlags changed: ${oldSourceFile.fileName}`);
2262+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
2193 structureIsReused = StructureIsReused.SafeModules;2263 structureIsReused = StructureIsReused.SafeModules;
2194 }2264 }
2195 else if (!arrayIsEqualTo(oldSourceFile.typeReferenceDirectives, newSourceFile.typeReferenceDirectives, fileReferenceIsEqualTo)) {2265 else if (!arrayIsEqualTo(oldSourceFile.typeReferenceDirectives, newSourceFile.typeReferenceDirectives, fileReferenceIsEqualTo)) {
2196 // 'types' references has changed2266 // 'types' references has changed
2267+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `typeReferenceDirectives changed: ${oldSourceFile.fileName}`);
2268+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
2197 structureIsReused = StructureIsReused.SafeModules;2269 structureIsReused = StructureIsReused.SafeModules;
2198 }2270 }
2199 }2271 }
@@ -2203,6 +2275,8 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2203 }2275 }
2204 else if (hasInvalidatedResolutions(oldSourceFile.path)) {2276 else if (hasInvalidatedResolutions(oldSourceFile.path)) {
2205 // 'module/types' references could have changed2277 // 'module/types' references could have changed
2278+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `hasInvalidatedResolutions: ${oldSourceFile.fileName}`);
2279+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
2206 structureIsReused = StructureIsReused.SafeModules;2280 structureIsReused = StructureIsReused.SafeModules;
2207 2281 
2208 // add file to the modified list so that we will resolve it later2282 // add file to the modified list so that we will resolve it later
@@ -2214,6 +2288,8 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2214 }2288 }
2215 2289 
2216 if (structureIsReused !== StructureIsReused.Completely) {2290 if (structureIsReused !== StructureIsReused.Completely) {
2291+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `file content changed but module resolution reusable, modifiedFiles=${modifiedSourceFiles.length}`);
2292+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
2217 return structureIsReused;2293 return structureIsReused;
2218 }2294 }
2219 2295 
@@ -2226,12 +2302,15 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2226 }2302 }
2227 }2303 }
2228 // try to verify results of module resolution2304 // try to verify results of module resolution
2305+ PerformanceDotting.startAdvanced("resolveModuleNames", `modifiedFiles=${modifiedSourceFiles.length}`);
2229 for (const { oldFile: oldSourceFile, newFile: newSourceFile } of modifiedSourceFiles) {2306 for (const { oldFile: oldSourceFile, newFile: newSourceFile } of modifiedSourceFiles) {
2230 const moduleNames = getModuleNames(newSourceFile);2307 const moduleNames = getModuleNames(newSourceFile);
2231 const resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFile);2308 const resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFile);
2232 // ensure that module resolution results are still correct2309 // ensure that module resolution results are still correct
2233 const resolutionsChanged = hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, oldSourceFile, moduleResolutionIsEqualTo);2310 const resolutionsChanged = hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, oldSourceFile, moduleResolutionIsEqualTo);
2234 if (resolutionsChanged) {2311 if (resolutionsChanged) {
2312+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `module resolution changed: ${newSourceFile.fileName}`);
2313+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
2235 structureIsReused = StructureIsReused.SafeModules;2314 structureIsReused = StructureIsReused.SafeModules;
2236 newSourceFile.resolvedModules = zipToModeAwareCache(newSourceFile, moduleNames, resolutions);2315 newSourceFile.resolvedModules = zipToModeAwareCache(newSourceFile, moduleNames, resolutions);
2237 }2316 }
@@ -2243,6 +2322,8 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2243 // ensure that types resolutions are still correct2322 // ensure that types resolutions are still correct
2244 const typeReferenceResolutionsChanged = hasChangesInResolutions(typesReferenceDirectives, typeReferenceResolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, oldSourceFile, typeDirectiveIsEqualTo);2323 const typeReferenceResolutionsChanged = hasChangesInResolutions(typesReferenceDirectives, typeReferenceResolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, oldSourceFile, typeDirectiveIsEqualTo);
2245 if (typeReferenceResolutionsChanged) {2324 if (typeReferenceResolutionsChanged) {
2325+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `typeReference resolution changed: ${newSourceFile.fileName}`);
2326+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
2246 structureIsReused = StructureIsReused.SafeModules;2327 structureIsReused = StructureIsReused.SafeModules;
2247 newSourceFile.resolvedTypeReferenceDirectiveNames = zipToModeAwareCache(newSourceFile, typesReferenceDirectives, typeReferenceResolutions);2328 newSourceFile.resolvedTypeReferenceDirectiveNames = zipToModeAwareCache(newSourceFile, typesReferenceDirectives, typeReferenceResolutions);
2248 }2329 }
@@ -2250,12 +2331,27 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2250 newSourceFile.resolvedTypeReferenceDirectiveNames = oldSourceFile.resolvedTypeReferenceDirectiveNames;2331 newSourceFile.resolvedTypeReferenceDirectiveNames = oldSourceFile.resolvedTypeReferenceDirectiveNames;
2251 }2332 }
2252 }2333 }
2334+ PerformanceDotting.stopAdvanced("resolveModuleNames");
2253 2335 
2254 if (structureIsReused !== StructureIsReused.Completely) {2336 if (structureIsReused !== StructureIsReused.Completely) {
2337+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `module resolution changed for modified files, modifiedFiles=${modifiedSourceFiles.length}`);
2338+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
2255 return structureIsReused;2339 return structureIsReused;
2256 }2340 }
2257 2341 
2258 if (changesAffectingProgramStructure(oldOptions, options) || host.hasChangedAutomaticTypeDirectiveNames?.()) {2342 if (changesAffectingProgramStructure(oldOptions, options) || host.hasChangedAutomaticTypeDirectiveNames?.()) {
2343+ const reasons: string[] = [];
2344+ if (changesAffectingProgramStructure(oldOptions, options)) {
2345+ const changedOpts = optionsAffectingProgramStructure
2346+ .filter(o => !isJsonEqual(getCompilerOptionValue(oldOptions, o), getCompilerOptionValue(options, o)))
2347+ .map(o => o.name);
2348+ reasons.push(`changesAffectingProgramStructure: [${changedOpts.join(", ")}]`);
2349+ }
2350+ if (host.hasChangedAutomaticTypeDirectiveNames?.()) {
2351+ reasons.push("hasChangedAutomaticTypeDirectiveNames");
2352+ }
2353+ PerformanceDotting.startAdvanced("structureIsReused: SafeModules", `#10 ${reasons.join("; ")}`);
2354+ PerformanceDotting.stopAdvanced("structureIsReused: SafeModules");
2259 return StructureIsReused.SafeModules;2355 return StructureIsReused.SafeModules;
2260 }2356 }
2261 2357 
@@ -2291,6 +2387,8 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2291 redirectTargetsMap = oldProgram.redirectTargetsMap;2387 redirectTargetsMap = oldProgram.redirectTargetsMap;
2292 usesUriStyleNodeCoreModules = oldProgram.usesUriStyleNodeCoreModules;2388 usesUriStyleNodeCoreModules = oldProgram.usesUriStyleNodeCoreModules;
2293 2389 
2390+ PerformanceDotting.startAdvanced("structureIsReused: Completely", "structure fully reused from old program");
2391+ PerformanceDotting.stopAdvanced("structureIsReused: Completely");
2294 return StructureIsReused.Completely;2392 return StructureIsReused.Completely;
2295 }2393 }
2296 2394 
@@ -91,6 +91,7 @@ import {
91 parseConfigHostFromCompilerHostLike,91 parseConfigHostFromCompilerHostLike,
92 ParsedCommandLine,92 ParsedCommandLine,
93 Path,93 Path,
94+ PerformanceDotting,
94 PollingInterval,95 PollingInterval,
95 Program,96 Program,
96 ProgramBuildInfo,97 ProgramBuildInfo,
@@ -1494,9 +1495,17 @@ function listEmittedFile({ write }: SolutionBuilderState, proj: ParsedCommandLin
1494}1495}
1495 1496 
1496function getOldProgram<T extends BuilderProgram>({ options, builderPrograms, compilerHost }: SolutionBuilderState<T>, proj: ResolvedConfigFilePath, parsed: ParsedCommandLine) {1497function getOldProgram<T extends BuilderProgram>({ options, builderPrograms, compilerHost }: SolutionBuilderState<T>, proj: ResolvedConfigFilePath, parsed: ParsedCommandLine) {
1497- if (options.force) return undefined;1498+ if (options.force) {
1499+ PerformanceDotting.startAdvanced("getOldProgram: force", `--force flag set, returning undefined for ${proj}`);
1500+ PerformanceDotting.stopAdvanced("getOldProgram: force");
1501+ return undefined;
1502+ }
1498 const value = builderPrograms.get(proj);1503 const value = builderPrograms.get(proj);
1499- if (value) return value;1504+ if (value) {
1505+ PerformanceDotting.startAdvanced("getOldProgram: cachedBuilderProgram", `reused from builderPrograms map for ${proj}`);
1506+ PerformanceDotting.stopAdvanced("getOldProgram: cachedBuilderProgram");
1507+ return value;
1508+ }
1500 return readBuilderProgram(parsed.options, compilerHost) as any as T;1509 return readBuilderProgram(parsed.options, compilerHost) as any as T;
1501}1510}
1502 1511 
@@ -67,6 +67,7 @@ import {
67 ParsedCommandLine,67 ParsedCommandLine,
68 Path,68 Path,
69 perfLogger,69 perfLogger,
70+ PerformanceDotting,
70 PollingInterval,71 PollingInterval,
71 Program,72 Program,
72 ProjectReference,73 ProjectReference,
@@ -119,10 +120,20 @@ export function readBuilderProgram(compilerOptions: CompilerOptions, host: ReadB
119 }120 }
120 else {121 else {
121 const content = host.readFile(buildInfoPath);122 const content = host.readFile(buildInfoPath);
122- if (!content) return undefined;123+ if (!content) {
124+ PerformanceDotting.startAdvanced("readBuilderProgram: buildInfoNotFound", `${buildInfoPath} not found`);
125+ PerformanceDotting.stopAdvanced("readBuilderProgram: buildInfoNotFound");
126+ return undefined;
127+ }
123 buildInfo = getBuildInfo(buildInfoPath, content);128 buildInfo = getBuildInfo(buildInfoPath, content);
124 }129 }
125- if (!buildInfo || buildInfo.version !== version || !buildInfo.program) return undefined;130+ if (!buildInfo || buildInfo.version !== version || !buildInfo.program) {
131+ PerformanceDotting.startAdvanced("readBuilderProgram: invalidBuildInfo", `path=${buildInfoPath}, version=${buildInfo?.version}, hasProgram=${!!buildInfo?.program}`);
132+ PerformanceDotting.stopAdvanced("readBuilderProgram: invalidBuildInfo");
133+ return undefined;
134+ }
135+ PerformanceDotting.startAdvanced("readBuilderProgram: loaded");
136+ PerformanceDotting.stopAdvanced("readBuilderProgram: loaded");
126 return createBuilderProgramUsingProgramBuildInfo(buildInfo.program, buildInfoPath, host);137 return createBuilderProgramUsingProgramBuildInfo(buildInfo.program, buildInfoPath, host);
127}138}
128 139 
@@ -94,7 +94,7 @@ buildInfoWriteFile?: WriteFileCallback, arkTSVersion?: string): Diagnostic[] {
94 timePrinterInstance.appendTime(TimePhase.GET_TSC_DIAGNOSTICS);94 timePrinterInstance.appendTime(TimePhase.GET_TSC_DIAGNOSTICS);
95 PerformanceDotting.stopAdvanced(TimePhase.GET_TSC_DIAGNOSTICS);95 PerformanceDotting.stopAdvanced(TimePhase.GET_TSC_DIAGNOSTICS);
96 96 
97- const lintRecordLog: string = TimePhase.LINT + '(checkedFilesNum: ' + changedFiles.size + ')';97+ const lintRecordLog: string = TimePhase.LINT + '(checkedFilesNum: ' + changedFiles.size + ', totalFilesNum: ' + srcFiles.length + ')';
98 PerformanceDotting.startAdvanced(lintRecordLog);98 PerformanceDotting.startAdvanced(lintRecordLog);
99 TypeScriptLinter.initGlobals(compilerOptions);99 TypeScriptLinter.initGlobals(compilerOptions);
100 InteropTypescriptLinter.initGlobals();100 InteropTypescriptLinter.initGlobals();
@@ -1736,7 +1736,9 @@ export function createLanguageService(
1736 1736 
1737 // If the program is already up-to-date, we can reuse it1737 // If the program is already up-to-date, we can reuse it
1738 PerformanceDotting.start("isProgramUptoDate");1738 PerformanceDotting.start("isProgramUptoDate");
1739+ PerformanceDotting.startAdvanced("isProgramUptoDate");
1739 if (isProgramUptoDate(program, rootFileNames, newSettings, (_path, fileName) => host.getScriptVersion(fileName), fileName => compilerHost!.fileExists(fileName), hasInvalidatedResolutions, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) {1740 if (isProgramUptoDate(program, rootFileNames, newSettings, (_path, fileName) => host.getScriptVersion(fileName), fileName => compilerHost!.fileExists(fileName), hasInvalidatedResolutions, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) {
1741+ PerformanceDotting.stopAdvanced("isProgramUptoDate");
1740 PerformanceDotting.stop("isProgramUptoDate");1742 PerformanceDotting.stop("isProgramUptoDate");
1741 // During incremental compilation, executing isProgramUptoDate to check for program updates generates file caches;1743 // During incremental compilation, executing isProgramUptoDate to check for program updates generates file caches;
1742 // clear these caches to avoid affecting future compilations.1744 // clear these caches to avoid affecting future compilations.
@@ -1750,6 +1752,7 @@ export function createLanguageService(
1750 }1752 }
1751 return;1753 return;
1752 }1754 }
1755+ PerformanceDotting.stopAdvanced("isProgramUptoDate");
1753 PerformanceDotting.stop("isProgramUptoDate");1756 PerformanceDotting.stop("isProgramUptoDate");
1754 1757 
1755 // clear ArkUI collected properties1758 // clear ArkUI collected properties
@@ -1796,7 +1799,9 @@ export function createLanguageService(
1796 1799 
1797 // Make sure all the nodes in the program are both bound, and have their parent1800 // Make sure all the nodes in the program are both bound, and have their parent
1798 // pointers set property.1801 // pointers set property.
1802+ PerformanceDotting.startAdvanced("getTypeChecker");
1799 program.getTypeChecker();1803 program.getTypeChecker();
1804+ PerformanceDotting.stopAdvanced("getTypeChecker");
1800 host.clearFileCache && host.clearFileCache();1805 host.clearFileCache && host.clearFileCache();
1801 return;1806 return;
1802 1807 
@@ -729,6 +729,38 @@ describe("unittests:: Reuse program structure:: host is optional", () => {
729 });729 });
730});730});
731 731 
732+describe("unittests:: Reuse program structure:: PerformanceDotting VERBOSE balance", () => {
733+ // Verifies that `tryReuseStructureFromOldProgram` (program.ts) produces a balanced
734+ // `startAdvanced`/`stopAdvanced` call sequence under VERBOSE on an incremental reuse.
735+ it("does not throw and records tryReuse/processingDiagnostics on a Completely reuse under VERBOSE", () => {
736+ const PD = ts.PerformanceDotting;
737+ PD.setPerformanceSwitch(PD.AnalyzeMode.VERBOSE);
738+ try {
739+ const target = ts.ScriptTarget.Latest;
740+ const files: NamedSourceText[] = [
741+ { name: "a.ts", text: SourceText.New("", "", "var x = 1;") },
742+ ];
743+ const options: ts.CompilerOptions = { target, noLib: true };
744+ const program1 = newProgram(files, ["a.ts"], options);
745+ // Second build: only the function body changed -> structure fully reused (Completely).
746+ const program2 = updateProgram(program1, ["a.ts"], options, f => {
747+ f[0].text = f[0].text.updateProgram("var x = 100;");
748+ });
749+ assert.equal(program2.structureIsReused, ts.StructureIsReused.Completely);
750+ 
751+ const names = new Set(PD.getEventData().map(e => e.name));
752+ for (const want of ["structureIsReused: Completely", "tryReuseStructureFromOldProgram", "processingDiagnostics"]) {
753+ assert.isTrue(names.has(want), `expected PerformanceDotting event "${want}" to be recorded`);
754+ }
755+ }
756+ finally {
757+ // getEventData() already cleared internal state; reset the switch too so VERBOSE
758+ // cannot leak into neighbouring tests (clearEvent flips advancedSwitch/traceSwitch off).
759+ PD.clearEvent();
760+ }
761+ });
762+});
763+ 
732type File = ts.TestFSWithWatch.File;764type File = ts.TestFSWithWatch.File;
733import createTestSystem = ts.TestFSWithWatch.createWatchedSystem;765import createTestSystem = ts.TestFSWithWatch.createWatchedSystem;
734import libFile = ts.TestFSWithWatch.libFile;766import libFile = ts.TestFSWithWatch.libFile;