phantom-build 0.1.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.
- package/README.md +378 -0
- package/dist/analyzer.d.ts +11 -0
- package/dist/analyzer.d.ts.map +1 -0
- package/dist/analyzer.js +330 -0
- package/dist/analyzer.js.map +1 -0
- package/dist/ast-compat.d.ts +11 -0
- package/dist/ast-compat.d.ts.map +1 -0
- package/dist/ast-compat.js +84 -0
- package/dist/ast-compat.js.map +1 -0
- package/dist/classify/boundary.d.ts +30 -0
- package/dist/classify/boundary.d.ts.map +1 -0
- package/dist/classify/boundary.js +145 -0
- package/dist/classify/boundary.js.map +1 -0
- package/dist/classify/browser-globals.d.ts +29 -0
- package/dist/classify/browser-globals.d.ts.map +1 -0
- package/dist/classify/browser-globals.js +197 -0
- package/dist/classify/browser-globals.js.map +1 -0
- package/dist/classify/index.d.ts +14 -0
- package/dist/classify/index.d.ts.map +1 -0
- package/dist/classify/index.js +294 -0
- package/dist/classify/index.js.map +1 -0
- package/dist/classify/lazy-llm.d.ts +122 -0
- package/dist/classify/lazy-llm.d.ts.map +1 -0
- package/dist/classify/lazy-llm.js +142 -0
- package/dist/classify/lazy-llm.js.map +1 -0
- package/dist/classify/lazy.d.ts +23 -0
- package/dist/classify/lazy.d.ts.map +1 -0
- package/dist/classify/lazy.js +686 -0
- package/dist/classify/lazy.js.map +1 -0
- package/dist/classify/llm-client.d.ts +59 -0
- package/dist/classify/llm-client.d.ts.map +1 -0
- package/dist/classify/llm-client.js +193 -0
- package/dist/classify/llm-client.js.map +1 -0
- package/dist/classify/purity.d.ts +21 -0
- package/dist/classify/purity.d.ts.map +1 -0
- package/dist/classify/purity.js +47 -0
- package/dist/classify/purity.js.map +1 -0
- package/dist/classify/react-patterns.d.ts +15 -0
- package/dist/classify/react-patterns.d.ts.map +1 -0
- package/dist/classify/react-patterns.js +82 -0
- package/dist/classify/react-patterns.js.map +1 -0
- package/dist/classify/taint.d.ts +32 -0
- package/dist/classify/taint.d.ts.map +1 -0
- package/dist/classify/taint.js +68 -0
- package/dist/classify/taint.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +109 -0
- package/dist/cli.js.map +1 -0
- package/dist/extract/chunk-module.d.ts +20 -0
- package/dist/extract/chunk-module.d.ts.map +1 -0
- package/dist/extract/chunk-module.js +163 -0
- package/dist/extract/chunk-module.js.map +1 -0
- package/dist/extract/client-stub.d.ts +25 -0
- package/dist/extract/client-stub.d.ts.map +1 -0
- package/dist/extract/client-stub.js +233 -0
- package/dist/extract/client-stub.js.map +1 -0
- package/dist/extract/import-resolver.d.ts +20 -0
- package/dist/extract/import-resolver.d.ts.map +1 -0
- package/dist/extract/import-resolver.js +51 -0
- package/dist/extract/import-resolver.js.map +1 -0
- package/dist/extract/index.d.ts +20 -0
- package/dist/extract/index.d.ts.map +1 -0
- package/dist/extract/index.js +105 -0
- package/dist/extract/index.js.map +1 -0
- package/dist/extract/lazy-transform.d.ts +14 -0
- package/dist/extract/lazy-transform.d.ts.map +1 -0
- package/dist/extract/lazy-transform.js +473 -0
- package/dist/extract/lazy-transform.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin.d.ts +7 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +535 -0
- package/dist/plugin.js.map +1 -0
- package/dist/runtime/index.d.ts +28 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +73 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/types.d.ts +219 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/vite.d.ts +3 -0
- package/dist/vite.d.ts.map +1 -0
- package/dist/vite.js +3 -0
- package/dist/vite.js.map +1 -0
- package/dist/webpack.d.ts +3 -0
- package/dist/webpack.d.ts.map +1 -0
- package/dist/webpack.js +3 -0
- package/dist/webpack.js.map +1 -0
- package/package.json +79 -0
package/dist/analyzer.js
ADDED
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import { parseSync } from 'oxc-parser';
|
|
2
|
+
import { analyze as analyzeScope } from 'eslint-scope';
|
|
3
|
+
import { addASTMetadata } from './ast-compat.js';
|
|
4
|
+
import { classifyModule, detectLazyCandidates } from './classify/index.js';
|
|
5
|
+
import { extractModule } from './extract/index.js';
|
|
6
|
+
/**
|
|
7
|
+
* Determine the OXC parser `lang` option from a file path.
|
|
8
|
+
*/
|
|
9
|
+
function getLang(path) {
|
|
10
|
+
if (path.endsWith('.tsx'))
|
|
11
|
+
return 'tsx';
|
|
12
|
+
if (path.endsWith('.ts'))
|
|
13
|
+
return 'ts';
|
|
14
|
+
if (path.endsWith('.jsx'))
|
|
15
|
+
return 'jsx';
|
|
16
|
+
return 'js';
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Parse a module and perform scope analysis.
|
|
20
|
+
* Returns the AST, function dependency info, and import info.
|
|
21
|
+
*/
|
|
22
|
+
export function parseModule(code, path) {
|
|
23
|
+
// 1. Parse with OXC
|
|
24
|
+
const parseResult = parseSync(path, code, {
|
|
25
|
+
lang: getLang(path),
|
|
26
|
+
sourceType: 'module',
|
|
27
|
+
astType: 'js', // ESTree-compatible output (strips TS-specific nodes)
|
|
28
|
+
});
|
|
29
|
+
// Bail early on parse errors — partial ASTs cause cryptic downstream failures
|
|
30
|
+
if (parseResult.errors.length > 0) {
|
|
31
|
+
const errMsg = parseResult.errors.map((e) => e.message).join(', ');
|
|
32
|
+
throw new Error(`[phantom] Parse errors in ${path}: ${errMsg}`);
|
|
33
|
+
}
|
|
34
|
+
const ast = parseResult.program;
|
|
35
|
+
// 2. Patch AST for eslint-scope + esrap (add range + loc)
|
|
36
|
+
addASTMetadata(ast, code);
|
|
37
|
+
// 3. Run eslint-scope for scope/symbol resolution
|
|
38
|
+
// eslint-scope supports `jsx` but the type definitions don't declare it
|
|
39
|
+
const scopeManager = analyzeScope(ast, {
|
|
40
|
+
ecmaVersion: 2022,
|
|
41
|
+
sourceType: 'module',
|
|
42
|
+
jsx: true,
|
|
43
|
+
fallback: 'iteration',
|
|
44
|
+
});
|
|
45
|
+
// 4. Extract import information from OXC's module info
|
|
46
|
+
const imports = extractImports(parseResult);
|
|
47
|
+
// 5. Extract re-export mappings (for barrel file resolution)
|
|
48
|
+
const reExports = extractReExports(parseResult);
|
|
49
|
+
// 6. Build function dependency map from scope analysis
|
|
50
|
+
const functions = buildFunctionDependencies(scopeManager);
|
|
51
|
+
// 7. Resolve names for anonymous functions from assignment context
|
|
52
|
+
resolveAnonymousNames(ast, functions);
|
|
53
|
+
return { path, ast, functions, imports, reExports };
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Extract import information from OXC's parsed module info.
|
|
57
|
+
*/
|
|
58
|
+
function extractImports(parseResult) {
|
|
59
|
+
const moduleInfo = parseResult.module;
|
|
60
|
+
if (!moduleInfo)
|
|
61
|
+
return [];
|
|
62
|
+
return moduleInfo.staticImports.map((imp) => ({
|
|
63
|
+
source: imp.moduleRequest.value,
|
|
64
|
+
specifiers: imp.entries.map((entry) => ({
|
|
65
|
+
local: entry.localName.value,
|
|
66
|
+
imported: entry.importName.kind === 'Name'
|
|
67
|
+
? (entry.importName.name ?? null)
|
|
68
|
+
: null,
|
|
69
|
+
kind: entry.importName.kind === 'Default'
|
|
70
|
+
? 'default'
|
|
71
|
+
: entry.importName.kind === 'NamespaceObject'
|
|
72
|
+
? 'namespace'
|
|
73
|
+
: 'named',
|
|
74
|
+
})),
|
|
75
|
+
}));
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Extract re-export mappings from OXC's module info.
|
|
79
|
+
* Detects `export { X } from './X'` and `export { default as Y } from './Y'` patterns.
|
|
80
|
+
* These are pass-through re-exports with no local binding (barrel files).
|
|
81
|
+
*/
|
|
82
|
+
function extractReExports(parseResult) {
|
|
83
|
+
const moduleInfo = parseResult.module;
|
|
84
|
+
if (!moduleInfo)
|
|
85
|
+
return [];
|
|
86
|
+
const results = [];
|
|
87
|
+
for (const exp of moduleInfo.staticExports) {
|
|
88
|
+
for (const entry of exp.entries) {
|
|
89
|
+
// Skip type-only re-exports
|
|
90
|
+
if (entry.isType)
|
|
91
|
+
continue;
|
|
92
|
+
// Only re-exports have localName.kind === 'None' (no local binding)
|
|
93
|
+
if (entry.localName.kind !== 'None')
|
|
94
|
+
continue;
|
|
95
|
+
// Must have a module source (re-export from another module)
|
|
96
|
+
if (!entry.moduleRequest)
|
|
97
|
+
continue;
|
|
98
|
+
const exportedName = entry.exportName.kind === 'Name' ? entry.exportName.name : null;
|
|
99
|
+
const importedName = entry.importName.kind === 'Name' ? entry.importName.name : null;
|
|
100
|
+
if (!exportedName || !importedName)
|
|
101
|
+
continue;
|
|
102
|
+
results.push({
|
|
103
|
+
exportedName,
|
|
104
|
+
importedName,
|
|
105
|
+
source: entry.moduleRequest.value,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return results;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Build function dependency information from eslint-scope's analysis.
|
|
113
|
+
*
|
|
114
|
+
* For each function scope, we determine:
|
|
115
|
+
* - locals: variables declared in this function
|
|
116
|
+
* - captured: variables referenced from outer scopes
|
|
117
|
+
* - imported: variables that trace back to import declarations
|
|
118
|
+
* - globals: unresolved references (browser globals, etc.)
|
|
119
|
+
*/
|
|
120
|
+
function buildFunctionDependencies(scopeManager) {
|
|
121
|
+
const results = [];
|
|
122
|
+
// Collect all import-declared variable names at module scope
|
|
123
|
+
const importedNames = new Set();
|
|
124
|
+
const moduleScope = scopeManager.scopes.find((s) => s.type === 'module');
|
|
125
|
+
if (moduleScope) {
|
|
126
|
+
for (const variable of moduleScope.variables) {
|
|
127
|
+
// Variables with ImportBinding definitions are imports
|
|
128
|
+
const isImport = variable.defs.some((d) => d.type === 'ImportBinding');
|
|
129
|
+
if (isImport) {
|
|
130
|
+
importedNames.add(variable.name);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
for (const scope of scopeManager.scopes) {
|
|
135
|
+
// Only process function-like scopes
|
|
136
|
+
if (scope.type !== 'function')
|
|
137
|
+
continue;
|
|
138
|
+
const block = scope.block;
|
|
139
|
+
const name = getFunctionName(block);
|
|
140
|
+
const locals = [];
|
|
141
|
+
const captured = [];
|
|
142
|
+
const imported = [];
|
|
143
|
+
const globals = [];
|
|
144
|
+
// Local variables are those declared in this scope
|
|
145
|
+
for (const variable of scope.variables) {
|
|
146
|
+
if (variable.name === 'arguments')
|
|
147
|
+
continue; // skip implicit `arguments`
|
|
148
|
+
locals.push(variable.name);
|
|
149
|
+
}
|
|
150
|
+
// "through" references are those not resolved in this scope
|
|
151
|
+
// They might be captured from parent, imported, or truly global
|
|
152
|
+
for (const ref of scope.through) {
|
|
153
|
+
const refName = ref.identifier.name;
|
|
154
|
+
if (importedNames.has(refName)) {
|
|
155
|
+
if (!imported.includes(refName)) {
|
|
156
|
+
imported.push(refName);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
else if (ref.resolved) {
|
|
160
|
+
// Resolved to an outer scope variable → captured
|
|
161
|
+
if (!captured.includes(refName)) {
|
|
162
|
+
captured.push(refName);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
// Unresolved → global (browser API, etc.)
|
|
167
|
+
if (!globals.includes(refName)) {
|
|
168
|
+
globals.push(refName);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// Also check references that ARE resolved but point to outer scopes
|
|
173
|
+
for (const ref of scope.references) {
|
|
174
|
+
const refName = ref.identifier.name;
|
|
175
|
+
if (ref.resolved && !locals.includes(refName) && !importedNames.has(refName)) {
|
|
176
|
+
if (!captured.includes(refName)) {
|
|
177
|
+
captured.push(refName);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
results.push({
|
|
182
|
+
name,
|
|
183
|
+
locals,
|
|
184
|
+
captured,
|
|
185
|
+
imported,
|
|
186
|
+
globals,
|
|
187
|
+
span: {
|
|
188
|
+
start: block.start ?? 0,
|
|
189
|
+
end: block.end ?? 0,
|
|
190
|
+
},
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
return results;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Extract a human-readable name for a function AST node.
|
|
197
|
+
*/
|
|
198
|
+
function getFunctionName(node) {
|
|
199
|
+
// FunctionDeclaration with an id
|
|
200
|
+
if (node.type === 'FunctionDeclaration' && 'id' in node && node.id) {
|
|
201
|
+
return node.id.name;
|
|
202
|
+
}
|
|
203
|
+
// FunctionExpression with an id (e.g., const x = function foo() {})
|
|
204
|
+
if (node.type === 'FunctionExpression' && 'id' in node && node.id) {
|
|
205
|
+
return node.id.name;
|
|
206
|
+
}
|
|
207
|
+
return '<anonymous>';
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Resolve names for anonymous functions from their assignment context.
|
|
211
|
+
*
|
|
212
|
+
* After building FunctionDependency[], walk the AST to find:
|
|
213
|
+
* - `const foo = () => {}` → name is `foo` (VariableDeclarator parent)
|
|
214
|
+
* - `const foo = function() {}` → name is `foo` (VariableDeclarator parent)
|
|
215
|
+
* - `{ key: () => {} }` → name is the property key
|
|
216
|
+
*
|
|
217
|
+
* Matches functions to FunctionDependency entries by span (start/end).
|
|
218
|
+
*/
|
|
219
|
+
function resolveAnonymousNames(ast, functions) {
|
|
220
|
+
// Build a quick lookup from span → FunctionDependency for anonymous functions
|
|
221
|
+
const anonBySpan = new Map();
|
|
222
|
+
for (const fn of functions) {
|
|
223
|
+
if (fn.name === '<anonymous>') {
|
|
224
|
+
anonBySpan.set(`${fn.span.start}:${fn.span.end}`, fn);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
if (anonBySpan.size === 0)
|
|
228
|
+
return;
|
|
229
|
+
walkWithParent(ast, null, (node, parent) => {
|
|
230
|
+
if (!isFunctionNode(node))
|
|
231
|
+
return;
|
|
232
|
+
const nStart = node.start;
|
|
233
|
+
const nEnd = node.end;
|
|
234
|
+
if (nStart == null || nEnd == null)
|
|
235
|
+
return;
|
|
236
|
+
const key = `${nStart}:${nEnd}`;
|
|
237
|
+
const fn = anonBySpan.get(key);
|
|
238
|
+
if (!fn)
|
|
239
|
+
return;
|
|
240
|
+
// Case 1: VariableDeclarator — `const foo = () => {}`
|
|
241
|
+
if (parent && parent.type === 'VariableDeclarator' && 'id' in parent) {
|
|
242
|
+
const id = parent.id;
|
|
243
|
+
if (id.type === 'Identifier' && 'name' in id) {
|
|
244
|
+
fn.name = id.name;
|
|
245
|
+
anonBySpan.delete(key);
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
// Case 2: Property / ObjectProperty — `{ key: () => {} }`
|
|
250
|
+
if (parent && (parent.type === 'Property' || parent.type === 'ObjectProperty')) {
|
|
251
|
+
const propKey = parent.key;
|
|
252
|
+
if (propKey && propKey.type === 'Identifier' && 'name' in propKey) {
|
|
253
|
+
fn.name = propKey.name;
|
|
254
|
+
anonBySpan.delete(key);
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
function isFunctionNode(node) {
|
|
261
|
+
return (node.type === 'ArrowFunctionExpression' ||
|
|
262
|
+
node.type === 'FunctionExpression');
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Walk AST nodes, passing each node and its parent to the callback.
|
|
266
|
+
*/
|
|
267
|
+
function walkWithParent(node, parent, callback) {
|
|
268
|
+
if (!node || typeof node !== 'object')
|
|
269
|
+
return;
|
|
270
|
+
if (Array.isArray(node)) {
|
|
271
|
+
for (const child of node) {
|
|
272
|
+
walkWithParent(child, parent, callback);
|
|
273
|
+
}
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
const obj = node;
|
|
277
|
+
if (typeof obj.type !== 'string')
|
|
278
|
+
return;
|
|
279
|
+
const asNode = obj;
|
|
280
|
+
callback(asNode, parent);
|
|
281
|
+
for (const key of Object.keys(obj)) {
|
|
282
|
+
if (key === 'type')
|
|
283
|
+
continue;
|
|
284
|
+
walkWithParent(obj[key], asNode, callback);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Analyze a single module: parse → scope analysis → classify → extract.
|
|
289
|
+
*/
|
|
290
|
+
export function analyzeModule(code, path, _options) {
|
|
291
|
+
const parsed = parseModule(code, path);
|
|
292
|
+
// Phase 3: classification
|
|
293
|
+
const segments = classifyModule(parsed, code);
|
|
294
|
+
// Phase 3.5: lazy candidate detection
|
|
295
|
+
let lazyCandidates;
|
|
296
|
+
let lazyKeptStatic;
|
|
297
|
+
const enableLazy = _options?.enableLazy !== false; // default: true
|
|
298
|
+
if (enableLazy) {
|
|
299
|
+
const lazyResult = detectLazyCandidates(parsed, code, segments, _options?.componentProfiles);
|
|
300
|
+
if (lazyResult.lazy.length > 0) {
|
|
301
|
+
lazyCandidates = lazyResult.lazy;
|
|
302
|
+
}
|
|
303
|
+
if (lazyResult.keepStatic.length > 0) {
|
|
304
|
+
lazyKeptStatic = lazyResult.keepStatic;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
// Phase 4: extraction (handler chunks + lazy transforms)
|
|
308
|
+
const confidenceThreshold = _options?.confidenceThreshold ?? 0.8;
|
|
309
|
+
const extracted = extractModule(parsed, segments, code, confidenceThreshold, path, lazyCandidates);
|
|
310
|
+
if (extracted) {
|
|
311
|
+
return {
|
|
312
|
+
path,
|
|
313
|
+
segments,
|
|
314
|
+
hasExtractions: true,
|
|
315
|
+
clientCode: extracted.clientCode,
|
|
316
|
+
clientMap: extracted.clientMap,
|
|
317
|
+
chunkModules: extracted.chunkModules,
|
|
318
|
+
lazyCandidates,
|
|
319
|
+
lazyKeptStatic,
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
return {
|
|
323
|
+
path,
|
|
324
|
+
segments,
|
|
325
|
+
hasExtractions: false,
|
|
326
|
+
lazyCandidates,
|
|
327
|
+
lazyKeptStatic,
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
//# sourceMappingURL=analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Add `range` and `loc` properties to all AST nodes.
|
|
3
|
+
*
|
|
4
|
+
* OXC's parser outputs `start`/`end` byte offsets on nodes, but:
|
|
5
|
+
* - eslint-scope expects `range: [start, end]` (ESTree range convention)
|
|
6
|
+
* - esrap needs `loc: { start: { line, column }, end: { line, column } }` for source maps
|
|
7
|
+
*
|
|
8
|
+
* This function walks the AST and patches each node in-place.
|
|
9
|
+
*/
|
|
10
|
+
export declare function addASTMetadata(node: unknown, sourceCode: string): void;
|
|
11
|
+
//# sourceMappingURL=ast-compat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast-compat.d.ts","sourceRoot":"","sources":["../src/ast-compat.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAGtE"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Add `range` and `loc` properties to all AST nodes.
|
|
3
|
+
*
|
|
4
|
+
* OXC's parser outputs `start`/`end` byte offsets on nodes, but:
|
|
5
|
+
* - eslint-scope expects `range: [start, end]` (ESTree range convention)
|
|
6
|
+
* - esrap needs `loc: { start: { line, column }, end: { line, column } }` for source maps
|
|
7
|
+
*
|
|
8
|
+
* This function walks the AST and patches each node in-place.
|
|
9
|
+
*/
|
|
10
|
+
export function addASTMetadata(node, sourceCode) {
|
|
11
|
+
const lineStarts = buildLineStartTable(sourceCode);
|
|
12
|
+
addMetadataRecursive(node, lineStarts);
|
|
13
|
+
}
|
|
14
|
+
// ── Line/column computation ─────────────────────────────────────────────
|
|
15
|
+
/**
|
|
16
|
+
* Build a table of byte offsets where each line starts.
|
|
17
|
+
* lineStarts[i] = byte offset of the start of line i+1 (0-indexed internally).
|
|
18
|
+
*/
|
|
19
|
+
function buildLineStartTable(source) {
|
|
20
|
+
const lineStarts = [0]; // line 1 starts at offset 0
|
|
21
|
+
for (let i = 0; i < source.length; i++) {
|
|
22
|
+
if (source.charCodeAt(i) === 10) { // '\n'
|
|
23
|
+
lineStarts.push(i + 1);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return lineStarts;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Convert a byte offset to an ESTree position.
|
|
30
|
+
* ESTree uses 1-based lines and 0-based columns.
|
|
31
|
+
*/
|
|
32
|
+
function offsetToPosition(offset, lineStarts) {
|
|
33
|
+
// Binary search for the line containing this offset
|
|
34
|
+
let lo = 0;
|
|
35
|
+
let hi = lineStarts.length - 1;
|
|
36
|
+
while (lo < hi) {
|
|
37
|
+
const mid = (lo + hi + 1) >> 1;
|
|
38
|
+
if (lineStarts[mid] <= offset) {
|
|
39
|
+
lo = mid;
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
hi = mid - 1;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
line: lo + 1, // 1-based
|
|
47
|
+
column: offset - lineStarts[lo], // 0-based
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
// ── Recursive AST walker ────────────────────────────────────────────────
|
|
51
|
+
function addMetadataRecursive(node, lineStarts) {
|
|
52
|
+
if (!node || typeof node !== 'object') {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (Array.isArray(node)) {
|
|
56
|
+
for (const child of node) {
|
|
57
|
+
addMetadataRecursive(child, lineStarts);
|
|
58
|
+
}
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const obj = node;
|
|
62
|
+
// Only process AST nodes (objects with a `type` string property)
|
|
63
|
+
if (typeof obj.type !== 'string') {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
// Add range and loc if start/end byte offsets are present
|
|
67
|
+
if (typeof obj.start === 'number' && typeof obj.end === 'number') {
|
|
68
|
+
const start = obj.start;
|
|
69
|
+
const end = obj.end;
|
|
70
|
+
obj.range = [start, end];
|
|
71
|
+
obj.loc = {
|
|
72
|
+
start: offsetToPosition(start, lineStarts),
|
|
73
|
+
end: offsetToPosition(end, lineStarts),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
// Recurse into all properties
|
|
77
|
+
for (const key of Object.keys(obj)) {
|
|
78
|
+
if (key === 'type' || key === 'start' || key === 'end' || key === 'range' || key === 'loc') {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
addMetadataRecursive(obj[key], lineStarts);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=ast-compat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast-compat.js","sourceRoot":"","sources":["../src/ast-compat.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Node } from 'estree';
|
|
2
|
+
import type { ClassifiedSegment, FunctionDependency } from '../types.js';
|
|
3
|
+
import type { TaintResult } from './taint.js';
|
|
4
|
+
import type { PurityResult } from './purity.js';
|
|
5
|
+
interface ClassificationInput {
|
|
6
|
+
fn: FunctionDependency;
|
|
7
|
+
taint: TaintResult;
|
|
8
|
+
purity: PurityResult;
|
|
9
|
+
/** The parent call expression name, if this is a hook callback */
|
|
10
|
+
parentHook: string | null;
|
|
11
|
+
/** The JSX event prop name, if this function is used exclusively as an event handler */
|
|
12
|
+
parentEventProp: string | null;
|
|
13
|
+
/** Source code for content hashing */
|
|
14
|
+
sourceCode: string;
|
|
15
|
+
/** File path for naming */
|
|
16
|
+
filePath: string;
|
|
17
|
+
/** Index among siblings for disambiguation */
|
|
18
|
+
index: number;
|
|
19
|
+
/** The AST node for this function (for JSX detection) */
|
|
20
|
+
astNode: Node | null;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Pass 3: Boundary Detection
|
|
24
|
+
*
|
|
25
|
+
* Determines the final classification for each function and whether
|
|
26
|
+
* it's an extraction candidate.
|
|
27
|
+
*/
|
|
28
|
+
export declare function classifySegment(input: ClassificationInput): ClassifiedSegment;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=boundary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"boundary.d.ts","sourceRoot":"","sources":["../../src/classify/boundary.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAEnC,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAyB,MAAM,aAAa,CAAC;AAChG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,UAAU,mBAAmB;IAC3B,EAAE,EAAE,kBAAkB,CAAC;IACvB,KAAK,EAAE,WAAW,CAAC;IACnB,MAAM,EAAE,YAAY,CAAC;IACrB,kEAAkE;IAClE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,wFAAwF;IACxF,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,OAAO,EAAE,IAAI,GAAG,IAAI,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,mBAAmB,GAAG,iBAAiB,CAwF7E"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { EXTRACTABLE_HOOKS, CLIENT_ONLY_HOOKS } from './react-patterns.js';
|
|
3
|
+
/**
|
|
4
|
+
* Pass 3: Boundary Detection
|
|
5
|
+
*
|
|
6
|
+
* Determines the final classification for each function and whether
|
|
7
|
+
* it's an extraction candidate.
|
|
8
|
+
*/
|
|
9
|
+
export function classifySegment(input) {
|
|
10
|
+
const { fn, taint, purity, parentHook, parentEventProp, sourceCode, filePath, index, astNode } = input;
|
|
11
|
+
const codeSlice = sourceCode.slice(fn.span.start, fn.span.end);
|
|
12
|
+
const id = generateSegmentId(filePath, codeSlice);
|
|
13
|
+
const name = generateName(fn, filePath, index);
|
|
14
|
+
let classification;
|
|
15
|
+
let confidence;
|
|
16
|
+
const reasons = [];
|
|
17
|
+
// Rule 0: If used exclusively as a JSX event handler prop, it's an event handler
|
|
18
|
+
// This fires before taint analysis because event handlers are extracted regardless
|
|
19
|
+
// of whether they touch browser APIs (they all do — that's the point)
|
|
20
|
+
if (parentEventProp) {
|
|
21
|
+
classification = 'EventHandler';
|
|
22
|
+
confidence = 0.9;
|
|
23
|
+
reasons.push(`Event handler for ${parentEventProp}`);
|
|
24
|
+
}
|
|
25
|
+
// Rule 1: If inside a client-only hook (useEffect, useLayoutEffect), it's client
|
|
26
|
+
else if (parentHook && CLIENT_ONLY_HOOKS.has(parentHook)) {
|
|
27
|
+
classification = 'ClientInteractive';
|
|
28
|
+
confidence = 1.0;
|
|
29
|
+
reasons.push(`Inside ${parentHook} callback (client-side effect)`);
|
|
30
|
+
}
|
|
31
|
+
// Rule 2: If tainted by browser globals, it's client
|
|
32
|
+
else if (taint.tainted) {
|
|
33
|
+
classification = 'ClientInteractive';
|
|
34
|
+
confidence = 0.95;
|
|
35
|
+
reasons.push(`References browser APIs: ${taint.browserGlobals.join(', ')}`);
|
|
36
|
+
}
|
|
37
|
+
// Rule 3: If pure and inside an extractable hook (useMemo, useCallback), it's pure computation
|
|
38
|
+
else if (purity.pure && parentHook && EXTRACTABLE_HOOKS.has(parentHook)) {
|
|
39
|
+
classification = 'PureComputation';
|
|
40
|
+
confidence = 0.9;
|
|
41
|
+
reasons.push(`Pure computation inside ${parentHook}`);
|
|
42
|
+
reasons.push(...purity.reasons);
|
|
43
|
+
}
|
|
44
|
+
// Rule 3.5: If function contains JSX, it's a React component — not extractable
|
|
45
|
+
else if (astNode && containsJSX(astNode)) {
|
|
46
|
+
classification = 'Shared';
|
|
47
|
+
confidence = 0.0;
|
|
48
|
+
reasons.push('React component (contains JSX) — not extractable');
|
|
49
|
+
}
|
|
50
|
+
// Rule 4: If pure and a named helper function, it's pure computation
|
|
51
|
+
else if (purity.pure && fn.name !== '<anonymous>') {
|
|
52
|
+
classification = 'PureComputation';
|
|
53
|
+
confidence = 0.85;
|
|
54
|
+
reasons.push('Pure named helper function');
|
|
55
|
+
reasons.push(...purity.reasons);
|
|
56
|
+
}
|
|
57
|
+
// Rule 5: If pure but anonymous and not in a hook, it's shared
|
|
58
|
+
else if (purity.pure) {
|
|
59
|
+
classification = 'Shared';
|
|
60
|
+
confidence = 0.7;
|
|
61
|
+
reasons.push('Pure anonymous function — may be used in both contexts');
|
|
62
|
+
reasons.push(...purity.reasons);
|
|
63
|
+
}
|
|
64
|
+
// Rule 6a: Cross-environment globals (fetch, crypto, etc.) — ambiguous
|
|
65
|
+
else if (taint.ambiguousGlobals.length > 0) {
|
|
66
|
+
classification = 'Ambiguous';
|
|
67
|
+
confidence = 0.5;
|
|
68
|
+
reasons.push(`Cross-environment APIs: ${taint.ambiguousGlobals.join(', ')}`);
|
|
69
|
+
reasons.push('Available in both browser and Node.js — cannot determine intent');
|
|
70
|
+
}
|
|
71
|
+
// Rule 6b: Unknown globals — ambiguous
|
|
72
|
+
else if (taint.unknownGlobals.length > 0) {
|
|
73
|
+
classification = 'Ambiguous';
|
|
74
|
+
confidence = 0.5;
|
|
75
|
+
reasons.push(`Unknown globals: ${taint.unknownGlobals.join(', ')}`);
|
|
76
|
+
reasons.push('Cannot determine if these are browser-only APIs');
|
|
77
|
+
}
|
|
78
|
+
// Rule 7: Default — ambiguous, leave on client
|
|
79
|
+
else {
|
|
80
|
+
classification = 'Ambiguous';
|
|
81
|
+
confidence = 0.5;
|
|
82
|
+
reasons.push('Could not determine classification');
|
|
83
|
+
reasons.push(...purity.reasons);
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
id,
|
|
87
|
+
name,
|
|
88
|
+
classification,
|
|
89
|
+
confidence,
|
|
90
|
+
reasons,
|
|
91
|
+
dependencies: [...fn.captured, ...fn.imported],
|
|
92
|
+
span: fn.span,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function generateSegmentId(_filePath, code) {
|
|
96
|
+
// Content-addressable: hash only the code, not the file path.
|
|
97
|
+
// This ensures deterministic IDs across build environments (CI vs local)
|
|
98
|
+
// and enables deduplication of identical handler bodies across files.
|
|
99
|
+
const hash = createHash('sha256')
|
|
100
|
+
.update(code)
|
|
101
|
+
.digest('hex')
|
|
102
|
+
.slice(0, 12);
|
|
103
|
+
return `seg_${hash}`;
|
|
104
|
+
}
|
|
105
|
+
function generateName(fn, filePath, index) {
|
|
106
|
+
const base = filePath.replace(/\.[^.]+$/, '').replace(/[^a-zA-Z0-9]/g, '_');
|
|
107
|
+
if (fn.name !== '<anonymous>') {
|
|
108
|
+
return `${base}_${fn.name}`;
|
|
109
|
+
}
|
|
110
|
+
return `${base}_anon_${index}`;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Check if an AST node contains any JSX elements or fragments.
|
|
114
|
+
* Functions containing JSX are React components and should not be extracted.
|
|
115
|
+
*/
|
|
116
|
+
function containsJSX(node) {
|
|
117
|
+
let found = false;
|
|
118
|
+
walkNodeLocal(node, (n) => {
|
|
119
|
+
if (found)
|
|
120
|
+
return;
|
|
121
|
+
if (n.type.startsWith('JSX'))
|
|
122
|
+
found = true;
|
|
123
|
+
});
|
|
124
|
+
return found;
|
|
125
|
+
}
|
|
126
|
+
function walkNodeLocal(node, callback) {
|
|
127
|
+
if (!node || typeof node !== 'object')
|
|
128
|
+
return;
|
|
129
|
+
if (Array.isArray(node)) {
|
|
130
|
+
for (const child of node) {
|
|
131
|
+
walkNodeLocal(child, callback);
|
|
132
|
+
}
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const obj = node;
|
|
136
|
+
if (typeof obj.type !== 'string')
|
|
137
|
+
return;
|
|
138
|
+
callback(obj);
|
|
139
|
+
for (const key of Object.keys(obj)) {
|
|
140
|
+
if (key === 'type')
|
|
141
|
+
continue;
|
|
142
|
+
walkNodeLocal(obj[key], callback);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=boundary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"boundary.js","sourceRoot":"","sources":["../../src/classify/boundary.ts"],"names":[],"mappings":"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"}
|