draft-ole 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/LICENSE +21 -0
  2. package/README.ja.md +134 -0
  3. package/README.md +128 -0
  4. package/dist/chunk-5BNNDTRT.js +95 -0
  5. package/dist/chunk-5BNNDTRT.js.map +1 -0
  6. package/dist/chunk-STLTIBMA.js +7658 -0
  7. package/dist/chunk-STLTIBMA.js.map +1 -0
  8. package/dist/chunk-YK4Y4ENL.js +389 -0
  9. package/dist/chunk-YK4Y4ENL.js.map +1 -0
  10. package/dist/entries/app.cjs +7337 -0
  11. package/dist/entries/app.cjs.map +1 -0
  12. package/dist/entries/app.d.cts +115 -0
  13. package/dist/entries/app.d.ts +115 -0
  14. package/dist/entries/app.js +10 -0
  15. package/dist/entries/app.js.map +1 -0
  16. package/dist/entries/page.cjs +7558 -0
  17. package/dist/entries/page.cjs.map +1 -0
  18. package/dist/entries/page.d.cts +2 -0
  19. package/dist/entries/page.d.ts +2 -0
  20. package/dist/entries/page.js +30 -0
  21. package/dist/entries/page.js.map +1 -0
  22. package/dist/index.cjs +10524 -0
  23. package/dist/index.cjs.map +1 -0
  24. package/dist/index.d.cts +4700 -0
  25. package/dist/index.d.ts +4700 -0
  26. package/dist/index.js +2573 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/page-DylNkWXm.d.ts +366 -0
  29. package/dist/page-h3DPzs8l.d.cts +366 -0
  30. package/dist/transformer/call-detector.d.ts +38 -0
  31. package/dist/transformer/call-detector.d.ts.map +1 -0
  32. package/dist/transformer/call-detector.js +151 -0
  33. package/dist/transformer/call-detector.js.map +1 -0
  34. package/dist/transformer/command-injector.d.ts +27 -0
  35. package/dist/transformer/command-injector.d.ts.map +1 -0
  36. package/dist/transformer/command-injector.js +111 -0
  37. package/dist/transformer/command-injector.js.map +1 -0
  38. package/dist/transformer/diagnostic-reporter.d.ts +81 -0
  39. package/dist/transformer/diagnostic-reporter.d.ts.map +1 -0
  40. package/dist/transformer/diagnostic-reporter.js +330 -0
  41. package/dist/transformer/diagnostic-reporter.js.map +1 -0
  42. package/dist/transformer/each-scope-branch.d.ts +28 -0
  43. package/dist/transformer/each-scope-branch.d.ts.map +1 -0
  44. package/dist/transformer/each-scope-branch.js +95 -0
  45. package/dist/transformer/each-scope-branch.js.map +1 -0
  46. package/dist/transformer/each-state-rewriter.d.ts +117 -0
  47. package/dist/transformer/each-state-rewriter.d.ts.map +1 -0
  48. package/dist/transformer/each-state-rewriter.js +393 -0
  49. package/dist/transformer/each-state-rewriter.js.map +1 -0
  50. package/dist/transformer/format-diagnostics.d.ts +27 -0
  51. package/dist/transformer/format-diagnostics.d.ts.map +1 -0
  52. package/dist/transformer/format-diagnostics.js +50 -0
  53. package/dist/transformer/format-diagnostics.js.map +1 -0
  54. package/dist/transformer/handler-ir-extractor.d.ts +71 -0
  55. package/dist/transformer/handler-ir-extractor.d.ts.map +1 -0
  56. package/dist/transformer/handler-ir-extractor.js +171 -0
  57. package/dist/transformer/handler-ir-extractor.js.map +1 -0
  58. package/dist/transformer/handler-serializer.d.ts +56 -0
  59. package/dist/transformer/handler-serializer.d.ts.map +1 -0
  60. package/dist/transformer/handler-serializer.js +315 -0
  61. package/dist/transformer/handler-serializer.js.map +1 -0
  62. package/dist/transformer/helper-context-resolver.d.ts +180 -0
  63. package/dist/transformer/helper-context-resolver.d.ts.map +1 -0
  64. package/dist/transformer/helper-context-resolver.js +376 -0
  65. package/dist/transformer/helper-context-resolver.js.map +1 -0
  66. package/dist/transformer/helper-decl-utils.d.ts +28 -0
  67. package/dist/transformer/helper-decl-utils.d.ts.map +1 -0
  68. package/dist/transformer/helper-decl-utils.js +92 -0
  69. package/dist/transformer/helper-decl-utils.js.map +1 -0
  70. package/dist/transformer/identifier-collector.d.ts +28 -0
  71. package/dist/transformer/identifier-collector.d.ts.map +1 -0
  72. package/dist/transformer/identifier-collector.js +184 -0
  73. package/dist/transformer/identifier-collector.js.map +1 -0
  74. package/dist/transformer/index.d.ts +56 -0
  75. package/dist/transformer/index.d.ts.map +1 -0
  76. package/dist/transformer/index.js +333 -0
  77. package/dist/transformer/index.js.map +1 -0
  78. package/dist/transformer/inline-recovery.d.ts +109 -0
  79. package/dist/transformer/inline-recovery.d.ts.map +1 -0
  80. package/dist/transformer/inline-recovery.js +369 -0
  81. package/dist/transformer/inline-recovery.js.map +1 -0
  82. package/dist/transformer/label-injector.d.ts +105 -0
  83. package/dist/transformer/label-injector.d.ts.map +1 -0
  84. package/dist/transformer/label-injector.js +221 -0
  85. package/dist/transformer/label-injector.js.map +1 -0
  86. package/dist/transformer/package.json +3 -0
  87. package/dist/transformer/per-call-context.d.ts +95 -0
  88. package/dist/transformer/per-call-context.d.ts.map +1 -0
  89. package/dist/transformer/per-call-context.js +3 -0
  90. package/dist/transformer/per-call-context.js.map +1 -0
  91. package/dist/transformer/state-id-fallback.d.ts +85 -0
  92. package/dist/transformer/state-id-fallback.d.ts.map +1 -0
  93. package/dist/transformer/state-id-fallback.js +132 -0
  94. package/dist/transformer/state-id-fallback.js.map +1 -0
  95. package/dist/transformer/state-id-resolver.d.ts +104 -0
  96. package/dist/transformer/state-id-resolver.d.ts.map +1 -0
  97. package/dist/transformer/state-id-resolver.js +222 -0
  98. package/dist/transformer/state-id-resolver.js.map +1 -0
  99. package/dist/transformer/theme-class-detector.d.ts +47 -0
  100. package/dist/transformer/theme-class-detector.d.ts.map +1 -0
  101. package/dist/transformer/theme-class-detector.js +242 -0
  102. package/dist/transformer/theme-class-detector.js.map +1 -0
  103. package/dist/transformer/varname-resolver.d.ts +53 -0
  104. package/dist/transformer/varname-resolver.d.ts.map +1 -0
  105. package/dist/transformer/varname-resolver.js +231 -0
  106. package/dist/transformer/varname-resolver.js.map +1 -0
  107. package/dist/transformer/whitelist-registry.d.ts +68 -0
  108. package/dist/transformer/whitelist-registry.d.ts.map +1 -0
  109. package/dist/transformer/whitelist-registry.js +122 -0
  110. package/dist/transformer/whitelist-registry.js.map +1 -0
  111. package/dist/transformer/whitelist-validator.d.ts +59 -0
  112. package/dist/transformer/whitelist-validator.d.ts.map +1 -0
  113. package/dist/transformer/whitelist-validator.js +493 -0
  114. package/dist/transformer/whitelist-validator.js.map +1 -0
  115. package/dist/types-BXV3vhHS.d.cts +4590 -0
  116. package/dist/types-BXV3vhHS.d.ts +4590 -0
  117. package/package.json +121 -0
@@ -0,0 +1,109 @@
1
+ /**
2
+ * inline-recovery — ヘルパー関数インライン展開の採否判定
3
+ *
4
+ * 仕様: `.kiro/specs/transformer-inline-recovery-spec/`
5
+ * - design.md §6.1
6
+ * - requirements.md 1.1, 1.2, 3.2, 4.1, 4.2, 5.2
7
+ *
8
+ * 単一責任:
9
+ * 1. ハンドラ AST を再帰スキャンしてヘルパー呼び出し候補を列挙する
10
+ * 2. design §6.1 の優先順位(1. function-declaration → 2. not-module-level
11
+ * → 3. mutable-binding → 4. has-parameters → 5. has-arguments)に従い
12
+ * 採否を分類する
13
+ * 3. 採用候補から `Map<string, ts.ArrowFunction>` を構築する
14
+ * 4. 不採用候補から DT012 診断を生成する
15
+ *
16
+ * 副作用なしの純粋関数のみで構成し、`fileDiagnostics` への push は
17
+ * 呼び出し側(transformer/index.ts)の責任。
18
+ */
19
+ import * as ts from 'typescript';
20
+ import type { OnCallInfo } from './call-detector';
21
+ import { type HandlerIR, type IdentifierRef } from './handler-ir-extractor';
22
+ import type { RecoveryOutcome, TransformerBaseContext, ValidationOutcome } from './per-call-context';
23
+ import type { StateIdFallback } from './state-id-fallback';
24
+ /** 採用された helper 候補。`buildInlineMap` の戻り値要素に対応。 */
25
+ export interface AcceptedHelper {
26
+ readonly kind: 'accepted';
27
+ readonly name: string;
28
+ readonly arrow: ts.ArrowFunction;
29
+ readonly callSite: ts.CallExpression;
30
+ }
31
+ /** 不採用理由(discriminated union)。 */
32
+ export type HelperRejectionReason = {
33
+ readonly code: 'has-arguments';
34
+ readonly argCount: number;
35
+ } | {
36
+ readonly code: 'has-parameters';
37
+ readonly paramCount: number;
38
+ } | {
39
+ readonly code: 'function-declaration';
40
+ } | {
41
+ readonly code: 'not-module-level';
42
+ } | {
43
+ readonly code: 'mutable-binding';
44
+ };
45
+ export interface RejectedHelper {
46
+ readonly kind: 'rejected';
47
+ readonly name: string;
48
+ readonly callSite: ts.CallExpression;
49
+ readonly reason: HelperRejectionReason;
50
+ }
51
+ export type HelperClassification = AcceptedHelper | RejectedHelper;
52
+ /**
53
+ * ハンドラ本体を再帰スキャンし、ヘルパー呼び出し候補を分類して返す。
54
+ *
55
+ * 候補とは: ExpressionStatement 直下の CallExpression で、
56
+ * 呼び出し対象が単純 Identifier かつ宣言が解決可能なもの(引数の有無は問わない)。
57
+ * 同名 helper は最初の出現のみを返す(重複 push を防ぐ)。
58
+ */
59
+ export declare function classifyHelperCandidates(arrowFn: ts.ArrowFunction, sourceFile: ts.SourceFile, checker: ts.TypeChecker): readonly HelperClassification[];
60
+ /**
61
+ * 採用候補のみから inlineMap を構築する。
62
+ * 既存 `buildInlineMap` と互換の戻り値(Map<name, ArrowFunction>)。
63
+ */
64
+ export declare function buildInlineMap(classifications: readonly HelperClassification[]): Map<string, ts.ArrowFunction>;
65
+ /**
66
+ * 不採用候補から DT012 診断を生成する。
67
+ *
68
+ * - `category`: 呼び出し側が `options.strictHelpers ? Warning : Suggestion` を渡す
69
+ * - `relatedInformation`: reason.code を平文化したメッセージを 1 件付与
70
+ */
71
+ export declare function buildRejectionDiagnostics(classifications: readonly HelperClassification[], sourceFile: ts.SourceFile, category: ts.DiagnosticCategory): readonly ts.Diagnostic[];
72
+ /**
73
+ * `tryInlineRecovery` の戻り値 (成功時)。
74
+ *
75
+ * relocated from index.ts (transformer-index-pipeline-split task 2.4).
76
+ */
77
+ export interface InlineRecoveryResult {
78
+ stateIdMap: Map<ts.Symbol, string>;
79
+ inlineMap: Map<string, ts.ArrowFunction>;
80
+ rejectionDiagnostics: readonly ts.Diagnostic[];
81
+ }
82
+ /**
83
+ * バリデーションエラー時にモジュールレベル関数インライン展開による回復を試みる。
84
+ *
85
+ * 手順:
86
+ * 1. ハンドラ内のゼロ引数モジュールレベル関数呼び出しを検出して inlineMap を構築
87
+ * 2. 検出した関数名を extraWhitelist に追加して再バリデーション
88
+ * 3. 各インライン関数の本体を独立してバリデーション
89
+ * 4. すべてパスした場合 stateIdMap と inlineMap を返す
90
+ *
91
+ * @returns 回復成功時 { stateIdMap, inlineMap, rejectionDiagnostics }、
92
+ * 失敗時 { rejectionDiagnostics } または undefined
93
+ */
94
+ export declare function tryInlineRecovery(arrowFn: ts.ArrowFunction, ir: HandlerIR, refs: IdentifierRef[], checker: ts.TypeChecker, program: ts.Program, sourceFile: ts.SourceFile, extraWhitelist: readonly string[] | undefined, debugMode: boolean, fallback: StateIdFallback, rejectionCategory: ts.DiagnosticCategory): InlineRecoveryResult | {
95
+ rejectionDiagnostics: readonly ts.Diagnostic[];
96
+ } | undefined;
97
+ /**
98
+ * Phase 4a per-call delegate: validation エラーありの場合の inline recovery 分岐を実行する。
99
+ *
100
+ * 2 個の private sub-helper を順次呼んで `RecoveryOutcome` を組み立てる薄い
101
+ * オーケストレーター (本体 ≤ 12 行)。
102
+ *
103
+ * @param base - per-invocation base context (checker / program / fallback / debug など)
104
+ * @param callInfo - 対象 .on() 呼出情報
105
+ * @param ir - Phase 2a で抽出済の HandlerIR
106
+ * @param validation - Phase 3 outcome (元の validation 診断を保持)
107
+ */
108
+ export declare function runInlineRecoveryBranch(base: TransformerBaseContext, callInfo: OnCallInfo, ir: HandlerIR, validation: ValidationOutcome): RecoveryOutcome;
109
+ //# sourceMappingURL=inline-recovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inline-recovery.d.ts","sourceRoot":"","sources":["../../src/transformer/inline-recovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,369 @@
1
+ "use strict";
2
+ /**
3
+ * inline-recovery — ヘルパー関数インライン展開の採否判定
4
+ *
5
+ * 仕様: `.kiro/specs/transformer-inline-recovery-spec/`
6
+ * - design.md §6.1
7
+ * - requirements.md 1.1, 1.2, 3.2, 4.1, 4.2, 5.2
8
+ *
9
+ * 単一責任:
10
+ * 1. ハンドラ AST を再帰スキャンしてヘルパー呼び出し候補を列挙する
11
+ * 2. design §6.1 の優先順位(1. function-declaration → 2. not-module-level
12
+ * → 3. mutable-binding → 4. has-parameters → 5. has-arguments)に従い
13
+ * 採否を分類する
14
+ * 3. 採用候補から `Map<string, ts.ArrowFunction>` を構築する
15
+ * 4. 不採用候補から DT012 診断を生成する
16
+ *
17
+ * 副作用なしの純粋関数のみで構成し、`fileDiagnostics` への push は
18
+ * 呼び出し側(transformer/index.ts)の責任。
19
+ */
20
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ var desc = Object.getOwnPropertyDescriptor(m, k);
23
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
24
+ desc = { enumerable: true, get: function() { return m[k]; } };
25
+ }
26
+ Object.defineProperty(o, k2, desc);
27
+ }) : (function(o, m, k, k2) {
28
+ if (k2 === undefined) k2 = k;
29
+ o[k2] = m[k];
30
+ }));
31
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
32
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
33
+ }) : function(o, v) {
34
+ o["default"] = v;
35
+ });
36
+ var __importStar = (this && this.__importStar) || (function () {
37
+ var ownKeys = function(o) {
38
+ ownKeys = Object.getOwnPropertyNames || function (o) {
39
+ var ar = [];
40
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
41
+ return ar;
42
+ };
43
+ return ownKeys(o);
44
+ };
45
+ return function (mod) {
46
+ if (mod && mod.__esModule) return mod;
47
+ var result = {};
48
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
49
+ __setModuleDefault(result, mod);
50
+ return result;
51
+ };
52
+ })();
53
+ Object.defineProperty(exports, "__esModule", { value: true });
54
+ exports.classifyHelperCandidates = classifyHelperCandidates;
55
+ exports.buildInlineMap = buildInlineMap;
56
+ exports.buildRejectionDiagnostics = buildRejectionDiagnostics;
57
+ exports.tryInlineRecovery = tryInlineRecovery;
58
+ exports.runInlineRecoveryBranch = runInlineRecoveryBranch;
59
+ const ts = __importStar(require("typescript"));
60
+ const handler_ir_extractor_1 = require("./handler-ir-extractor");
61
+ const helper_decl_utils_1 = require("./helper-decl-utils");
62
+ const identifier_collector_1 = require("./identifier-collector");
63
+ const state_id_resolver_1 = require("./state-id-resolver");
64
+ const whitelist_validator_1 = require("./whitelist-validator");
65
+ // ---- ヘルパー: シンボル解決 -------------------------------------------------
66
+ // resolveValueDeclaration / isModuleLevelVariableDeclaration / isConstDeclaration は
67
+ // `./helper-decl-utils` に移管。本ファイルでは import して使用する。
68
+ // ---- 候補列挙 + 分類 --------------------------------------------------------
69
+ /**
70
+ * 1 つの候補 CallExpression に対して採否を確定する。
71
+ * design §6.1 の優先順位(先勝ち)に従う。
72
+ */
73
+ function classifyOne(callSite, identName, checker, sourceFile) {
74
+ if (!ts.isIdentifier(callSite.expression))
75
+ return undefined;
76
+ const decl = (0, helper_decl_utils_1.resolveValueDeclaration)(callSite.expression, checker);
77
+ if (decl === undefined) {
78
+ // 解決不能 Identifier → 候補列挙対象外(既存 DT001 路に委ねる)
79
+ return undefined;
80
+ }
81
+ // 1. function-declaration
82
+ if (ts.isFunctionDeclaration(decl)) {
83
+ return {
84
+ kind: 'rejected',
85
+ name: identName,
86
+ callSite,
87
+ reason: { code: 'function-declaration' },
88
+ };
89
+ }
90
+ // VariableDeclaration で arrow を初期化しているか確認
91
+ if (!ts.isVariableDeclaration(decl)) {
92
+ // 想定外形状(class、parameter 等)→ not-module-level 相当として扱う
93
+ return {
94
+ kind: 'rejected',
95
+ name: identName,
96
+ callSite,
97
+ reason: { code: 'not-module-level' },
98
+ };
99
+ }
100
+ // 2. not-module-level
101
+ // ブロック内 const、cross-file(別 sourceFile)含む
102
+ if (decl.getSourceFile() !== sourceFile || !(0, helper_decl_utils_1.isModuleLevelVariableDeclaration)(decl, sourceFile)) {
103
+ return {
104
+ kind: 'rejected',
105
+ name: identName,
106
+ callSite,
107
+ reason: { code: 'not-module-level' },
108
+ };
109
+ }
110
+ // 3. mutable-binding
111
+ if (!(0, helper_decl_utils_1.isConstDeclaration)(decl)) {
112
+ return {
113
+ kind: 'rejected',
114
+ name: identName,
115
+ callSite,
116
+ reason: { code: 'mutable-binding' },
117
+ };
118
+ }
119
+ // initializer が ArrowFunction でなければ採否対象外(function expression 等)
120
+ if (decl.initializer === undefined || !ts.isArrowFunction(decl.initializer)) {
121
+ return {
122
+ kind: 'rejected',
123
+ name: identName,
124
+ callSite,
125
+ reason: { code: 'not-module-level' },
126
+ };
127
+ }
128
+ const arrow = decl.initializer;
129
+ // 4. has-parameters(宣言側 param > 0)— 呼び出し側引数より優先
130
+ if (arrow.parameters.length > 0) {
131
+ return {
132
+ kind: 'rejected',
133
+ name: identName,
134
+ callSite,
135
+ reason: { code: 'has-parameters', paramCount: arrow.parameters.length },
136
+ };
137
+ }
138
+ // 5. has-arguments
139
+ if (callSite.arguments.length > 0) {
140
+ return {
141
+ kind: 'rejected',
142
+ name: identName,
143
+ callSite,
144
+ reason: { code: 'has-arguments', argCount: callSite.arguments.length },
145
+ };
146
+ }
147
+ // すべての条件をクリア → 採用
148
+ return {
149
+ kind: 'accepted',
150
+ name: identName,
151
+ arrow,
152
+ callSite,
153
+ };
154
+ }
155
+ /**
156
+ * ハンドラ本体を再帰スキャンし、ヘルパー呼び出し候補を分類して返す。
157
+ *
158
+ * 候補とは: ExpressionStatement 直下の CallExpression で、
159
+ * 呼び出し対象が単純 Identifier かつ宣言が解決可能なもの(引数の有無は問わない)。
160
+ * 同名 helper は最初の出現のみを返す(重複 push を防ぐ)。
161
+ */
162
+ function classifyHelperCandidates(arrowFn, sourceFile, checker) {
163
+ const seen = new Set();
164
+ const result = [];
165
+ function visit(node) {
166
+ if (ts.isExpressionStatement(node)) {
167
+ const expr = node.expression;
168
+ if (ts.isCallExpression(expr) && ts.isIdentifier(expr.expression)) {
169
+ const name = expr.expression.text;
170
+ if (!seen.has(name)) {
171
+ const cls = classifyOne(expr, name, checker, sourceFile);
172
+ if (cls !== undefined) {
173
+ seen.add(name);
174
+ result.push(cls);
175
+ }
176
+ }
177
+ }
178
+ }
179
+ ts.forEachChild(node, visit);
180
+ }
181
+ visit(arrowFn.body);
182
+ return result;
183
+ }
184
+ // ---- 採用マップ構築 ---------------------------------------------------------
185
+ /**
186
+ * 採用候補のみから inlineMap を構築する。
187
+ * 既存 `buildInlineMap` と互換の戻り値(Map<name, ArrowFunction>)。
188
+ */
189
+ function buildInlineMap(classifications) {
190
+ const map = new Map();
191
+ for (const c of classifications) {
192
+ if (c.kind === 'accepted' && !map.has(c.name)) {
193
+ map.set(c.name, c.arrow);
194
+ }
195
+ }
196
+ return map;
197
+ }
198
+ // ---- 診断生成 ---------------------------------------------------------------
199
+ /** reason.code を人読み形に整形する。 */
200
+ function describeReason(reason) {
201
+ switch (reason.code) {
202
+ case 'has-arguments':
203
+ return `has-arguments: call site passes ${reason.argCount} argument(s)`;
204
+ case 'has-parameters':
205
+ return `has-parameters: helper takes ${reason.paramCount} parameter(s)`;
206
+ case 'function-declaration':
207
+ return 'function-declaration: helper is a function declaration, not a const arrow';
208
+ case 'not-module-level':
209
+ return 'not-module-level: helper is not declared at module top-level';
210
+ case 'mutable-binding':
211
+ return 'mutable-binding: helper is declared with let (mutable binding)';
212
+ }
213
+ }
214
+ /**
215
+ * 不採用候補から DT012 診断を生成する。
216
+ *
217
+ * - `category`: 呼び出し側が `options.strictHelpers ? Warning : Suggestion` を渡す
218
+ * - `relatedInformation`: reason.code を平文化したメッセージを 1 件付与
219
+ */
220
+ function buildRejectionDiagnostics(classifications, sourceFile, category) {
221
+ const diags = [];
222
+ for (const c of classifications) {
223
+ if (c.kind !== 'rejected')
224
+ continue;
225
+ const reasonText = describeReason(c.reason);
226
+ const start = c.callSite.getStart(sourceFile);
227
+ const length = c.callSite.getWidth(sourceFile);
228
+ const messageText = `DT012: Helper '${c.name}' is not eligible for inline recovery (${reasonText}). ` +
229
+ 'Supported shape: zero-argument module-level const arrow function, single level.';
230
+ diags.push({
231
+ file: sourceFile,
232
+ start,
233
+ length,
234
+ messageText,
235
+ category,
236
+ code: 9012,
237
+ source: 'draftole-transformer',
238
+ relatedInformation: [
239
+ {
240
+ file: sourceFile,
241
+ start,
242
+ length,
243
+ messageText: `reason: ${c.reason.code}`,
244
+ category: ts.DiagnosticCategory.Message,
245
+ code: 9012,
246
+ },
247
+ ],
248
+ });
249
+ }
250
+ return diags;
251
+ }
252
+ /**
253
+ * バリデーションエラー時にモジュールレベル関数インライン展開による回復を試みる。
254
+ *
255
+ * 手順:
256
+ * 1. ハンドラ内のゼロ引数モジュールレベル関数呼び出しを検出して inlineMap を構築
257
+ * 2. 検出した関数名を extraWhitelist に追加して再バリデーション
258
+ * 3. 各インライン関数の本体を独立してバリデーション
259
+ * 4. すべてパスした場合 stateIdMap と inlineMap を返す
260
+ *
261
+ * @returns 回復成功時 { stateIdMap, inlineMap, rejectionDiagnostics }、
262
+ * 失敗時 { rejectionDiagnostics } または undefined
263
+ */
264
+ function tryInlineRecovery(arrowFn, ir, refs, checker, program, sourceFile, extraWhitelist, debugMode, fallback, rejectionCategory) {
265
+ // 採否判定: 候補ごとに accepted / rejected を確定
266
+ const classifications = classifyHelperCandidates(arrowFn, sourceFile, checker);
267
+ const rejectionDiagnostics = buildRejectionDiagnostics(classifications, sourceFile, rejectionCategory);
268
+ const inlineMap = buildInlineMap(classifications);
269
+ // 採用候補が無い場合: rejection 診断のみ呼び出し側に返却
270
+ if (inlineMap.size === 0) {
271
+ if (rejectionDiagnostics.length === 0)
272
+ return undefined;
273
+ return { rejectionDiagnostics };
274
+ }
275
+ // インライン関数名を whitelist に追加して再バリデーション
276
+ const extendedWhitelist = [...(extraWhitelist !== null && extraWhitelist !== void 0 ? extraWhitelist : []), ...inlineMap.keys()];
277
+ const revalidDiags = (0, whitelist_validator_1.validateHandler)(ir, refs, program, sourceFile, extendedWhitelist);
278
+ if (revalidDiags.some((d) => d.category === ts.DiagnosticCategory.Error)) {
279
+ return rejectionDiagnostics.length > 0 ? { rejectionDiagnostics } : undefined;
280
+ }
281
+ // 各インライン関数本体を個別にバリデーション
282
+ for (const [name, funcArrow] of inlineMap) {
283
+ const { ir: inlineIr } = (0, handler_ir_extractor_1.extractHandlerIR)(funcArrow, sourceFile);
284
+ if (inlineIr === undefined) {
285
+ return rejectionDiagnostics.length > 0 ? { rejectionDiagnostics } : undefined;
286
+ }
287
+ const inlineRefs = (0, identifier_collector_1.collectIdentifiers)(inlineIr);
288
+ const inlineDiags = (0, whitelist_validator_1.validateHandler)(inlineIr, inlineRefs, program, sourceFile, extraWhitelist);
289
+ if (inlineDiags.some((d) => d.category === ts.DiagnosticCategory.Error)) {
290
+ if (debugMode) {
291
+ console.log(`[draftole-transformer] inline recovery: '${name}' body has validation errors`);
292
+ }
293
+ return rejectionDiagnostics.length > 0 ? { rejectionDiagnostics } : undefined;
294
+ }
295
+ }
296
+ const resolution = (0, state_id_resolver_1.buildStateIdMapWithInlining)(arrowFn, checker, inlineMap, fallback);
297
+ // マージ後も未解決 Symbol が残る場合は recovery 不成立とする。
298
+ if (resolution.unresolved.size > 0) {
299
+ if (debugMode) {
300
+ const names = [...resolution.unresolved.values()].map((id) => id.text).join(', ');
301
+ console.log(`[draftole-transformer] inline recovery: unresolved states remain after merge: ${names}`);
302
+ }
303
+ return rejectionDiagnostics.length > 0 ? { rejectionDiagnostics } : undefined;
304
+ }
305
+ return { stateIdMap: resolution.stateIdMap, inlineMap, rejectionDiagnostics };
306
+ }
307
+ /**
308
+ * sub-helper 1: tryInlineRecovery を呼び、3 通りの戻り値を flat な `InlineRecoveryAttempt`
309
+ * に正規化する。base.strictHelpers に応じて rejectionCategory (Warning / Suggestion) を決定し、
310
+ * base.debug を debugMode として渡す。
311
+ */
312
+ function attemptInlineRecovery(base, callInfo, ir) {
313
+ const refs = (0, identifier_collector_1.collectIdentifiers)(ir);
314
+ const rejectionCategory = base.strictHelpers
315
+ ? ts.DiagnosticCategory.Warning
316
+ : ts.DiagnosticCategory.Suggestion;
317
+ const result = tryInlineRecovery(callInfo.handlerArg, ir, refs, base.checker, base.program, base.sourceFile, base.extraWhitelist, base.debug, base.fallback, rejectionCategory);
318
+ if (result === undefined) {
319
+ return { success: false, stateIdMap: new Map(), inlineMap: undefined, rejectionDiagnostics: [] };
320
+ }
321
+ if ('stateIdMap' in result) {
322
+ return {
323
+ success: true,
324
+ stateIdMap: result.stateIdMap,
325
+ inlineMap: result.inlineMap,
326
+ rejectionDiagnostics: result.rejectionDiagnostics,
327
+ };
328
+ }
329
+ return {
330
+ success: false,
331
+ stateIdMap: new Map(),
332
+ inlineMap: undefined,
333
+ rejectionDiagnostics: result.rejectionDiagnostics,
334
+ };
335
+ }
336
+ /**
337
+ * sub-helper 2: 元の validation エラーと DT012 rejection 診断を mix する中央管理箇所。
338
+ *
339
+ * - success: recovery 成功 → 元の validation エラーは superseded、rejection のみ発行
340
+ * - failure: 元の validation エラー + DT012 rejection を順に concat
341
+ *
342
+ * 既存テストが mix 順序を等価性 oracle とするため、本関数で順序を固定する。
343
+ */
344
+ function composeRecoveryDiagnostics(originalValidationDiags, rejectionDiagnostics, success) {
345
+ if (success)
346
+ return rejectionDiagnostics;
347
+ return [...originalValidationDiags, ...rejectionDiagnostics];
348
+ }
349
+ /**
350
+ * Phase 4a per-call delegate: validation エラーありの場合の inline recovery 分岐を実行する。
351
+ *
352
+ * 2 個の private sub-helper を順次呼んで `RecoveryOutcome` を組み立てる薄い
353
+ * オーケストレーター (本体 ≤ 12 行)。
354
+ *
355
+ * @param base - per-invocation base context (checker / program / fallback / debug など)
356
+ * @param callInfo - 対象 .on() 呼出情報
357
+ * @param ir - Phase 2a で抽出済の HandlerIR
358
+ * @param validation - Phase 3 outcome (元の validation 診断を保持)
359
+ */
360
+ function runInlineRecoveryBranch(base, callInfo, ir, validation) {
361
+ const attempt = attemptInlineRecovery(base, callInfo, ir);
362
+ return {
363
+ success: attempt.success,
364
+ stateIdMap: attempt.stateIdMap,
365
+ inlineMap: attempt.inlineMap,
366
+ diagnostics: composeRecoveryDiagnostics(validation.diagnostics, attempt.rejectionDiagnostics, attempt.success),
367
+ };
368
+ }
369
+ //# sourceMappingURL=inline-recovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inline-recovery.js","sourceRoot":"","sources":["../../src/transformer/inline-recovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * label-injector: 抽出済み varName を用いて、対象 CallExpression を
3
+ * `__draftole_label__(<origCall>, "<varName>")` の形にラップする AST プリミティブを提供する。
4
+ *
5
+ * # 役割
6
+ * - 本モジュールは **AST ノードを構築するだけ** で、SourceFile への変異は一切行わない。
7
+ * 呼び出し側(task 4.7 の transformer pipeline)が printer / replace で適用する。
8
+ *
9
+ * # `__draftole_label__` の import 戦略(reuse-existing-import)
10
+ * design §label-injector の方針:
11
+ * 1. 既に DraftOle が export している識別子(`KNOWN_DRAFTOLE_IDENTIFIERS`)のいずれかを
12
+ * named import で取り込んでいる ImportDeclaration をファイル先頭から探索する。
13
+ * 2. 見つかった ImportDeclaration の `moduleSpecifier` をそのまま再利用し、
14
+ * その named imports に `__draftole_label__` を **追加** する。
15
+ * 3. 見つからない場合は新規 import を生成せず、対象ファイルの書き換えをスキップし、
16
+ * pipeline 側で diagnostic コード `DT013`(Suggestion カテゴリ)を発行する。
17
+ *
18
+ * # DT013 フォールバック方針
19
+ * `findDraftOleImport` が `undefined` を返した場合、呼び出し側 pipeline は:
20
+ * - 新規 import を作らない
21
+ * - 当該ファイルの label 注入をスキップする
22
+ * - `fileDiagnostics` に Suggestion カテゴリ・コード `DT013` の `ts.Diagnostic` を push する
23
+ * 本モジュールはあくまでプリミティブを提供するのみで、上記オーケストレーションは行わない。
24
+ *
25
+ * 対応 requirements: 4.1, 4.2, 4.5
26
+ * 対応 design: §label-injector
27
+ */
28
+ import * as ts from 'typescript';
29
+ /**
30
+ * `__draftole_label__` をどこから import するかの方針を表す。
31
+ * `findDraftOleImport` の戻り値。
32
+ */
33
+ export interface DraftOleImportSite {
34
+ /** 拡張対象の既存 ImportDeclaration(named imports に `__draftole_label__` を追加する)。 */
35
+ readonly importDecl: ts.ImportDeclaration;
36
+ /** その import の moduleSpecifier 文字列(例: `'draft-ole'`, `'../../dist/index.js'`)。 */
37
+ readonly moduleSpecifier: string;
38
+ }
39
+ /**
40
+ * SourceFile を走査し、再利用可能な DraftOle named import を探す。
41
+ *
42
+ * 仕様:
43
+ * - `ts.ImportDeclaration` を順に検査する。
44
+ * - `importClause.namedBindings` が `ts.NamedImports` の場合のみ対象。
45
+ * (`NamespaceImport` の場合は本モジュールでは扱わない。)
46
+ * - いずれかの `ImportSpecifier.name.text` が `KNOWN_DRAFTOLE_IDENTIFIERS` に含まれていれば
47
+ * その import を採用する(**ファイル中で最初に一致したもの**)。
48
+ * - 該当が無ければ `undefined` を返す。
49
+ *
50
+ * # 呼び出し側への期待
51
+ * `undefined` が返った場合、pipeline は label 注入をスキップし、
52
+ * Suggestion カテゴリの diagnostic(コード `DT013`)を発行すること。
53
+ */
54
+ export declare function findDraftOleImport(sourceFile: ts.SourceFile): DraftOleImportSite | undefined;
55
+ /**
56
+ * `__draftole_label__` が既に SourceFile の named imports に存在するかを判定する。
57
+ * 存在する場合は pipeline 側で import 追加処理をスキップできる。
58
+ */
59
+ export declare function hasLabelImport(sourceFile: ts.SourceFile): boolean;
60
+ /**
61
+ * `__draftole_label__(<callExpr>, "<varName>")` の CallExpression を構築する。
62
+ *
63
+ * - 純粋な AST 構築のみ。SourceFile への変異は行わない。
64
+ * - 返り値の型は元の式と同じ(runtime helper の signature が identity 型透過のため)。
65
+ */
66
+ export declare function buildLabeledCall(callExpr: ts.CallExpression, varName: string): ts.CallExpression;
67
+ /**
68
+ * `__draftole_label__` を単独で named import する新規 ImportDeclaration を生成する。
69
+ *
70
+ * # 用途: emit-safe な import 注入
71
+ * 呼び出し側 pipeline は、本関数で生成した ImportDeclaration を
72
+ * SourceFile の statements 先頭に prepend することで `__draftole_label__` を
73
+ * 取り込む。`updateImportDeclaration` で既存 import を mutate する方式は
74
+ * TS→TS printing では問題なく動作するが、`program.emit()` 経由の TS→JS では
75
+ * binder が pre-transform 時点のシンボル表で識別子解決を行うため、後付けで
76
+ * 加えた named specifier が「bare identifier」として未解決化される。
77
+ *
78
+ * # 重要: emit substitution の限界
79
+ * TypeScript の ES→CJS modules transformer は、シンボル束縛済みの識別子のみ
80
+ * `draft_ole_N.__draftole_label__` 形に書き換える。transformer が新規追加した
81
+ * 識別子はシンボル束縛を持たないため、`import` 構文を新規追加するだけでは
82
+ * call site が bare identifier のまま emit され ReferenceError になる。
83
+ *
84
+ * このため、CommonJS ターゲット時は本関数ではなく
85
+ * {@link createLabelRequireStatement} を使い、`const { __draftole_label__ } = require(...)`
86
+ * を直接生成すること。本関数は ESM ターゲット / TS→TS printing 用途に残す。
87
+ *
88
+ * @param moduleSpecifier `findDraftOleImport` で取得した既存 draft-ole import の
89
+ * module path をそのまま渡す。新規 import は同一 module を参照する必要がある。
90
+ */
91
+ export declare function createLabelImportDeclaration(moduleSpecifier: string): ts.ImportDeclaration;
92
+ /**
93
+ * CommonJS 出力向けの `__draftole_label__` 取り込み文を生成する。
94
+ *
95
+ * 生成形:
96
+ * `const { __draftole_label__ } = require('<moduleSpecifier>');`
97
+ *
98
+ * TS の ES→CJS modules transformer による識別子置換に依存しないため、
99
+ * transformer が新規追加した識別子でも安全に解決される。
100
+ *
101
+ * 呼び出し側 pipeline は、`compilerOptions.module` が CommonJS 系の場合に
102
+ * 本関数の戻り値を SourceFile.statements の先頭に prepend する。
103
+ */
104
+ export declare function createLabelRequireStatement(moduleSpecifier: string): ts.VariableStatement;
105
+ //# sourceMappingURL=label-injector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"label-injector.d.ts","sourceRoot":"","sources":["../../src/transformer/label-injector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AA6BjC;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,6EAA6E;IAC7E,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,iBAAiB,CAAC;IAC1C,kFAAkF;IAClF,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CAClC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,kBAAkB,GAAG,SAAS,CAqB5F;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,OAAO,CAajE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,EAAE,CAAC,cAAc,EAC3B,OAAO,EAAE,MAAM,GACd,EAAE,CAAC,cAAc,CAMnB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,4BAA4B,CAC1C,eAAe,EAAE,MAAM,GACtB,EAAE,CAAC,iBAAiB,CAiBtB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,2BAA2B,CACzC,eAAe,EAAE,MAAM,GACtB,EAAE,CAAC,iBAAiB,CA4BtB"}