@m3hti/commit-genie 2.0.0 → 3.0.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/dist/services/analyzerService.d.ts.map +1 -1
- package/dist/services/analyzerService.js +32 -4
- package/dist/services/analyzerService.js.map +1 -1
- package/dist/services/astAnalyzer.d.ts +42 -0
- package/dist/services/astAnalyzer.d.ts.map +1 -0
- package/dist/services/astAnalyzer.js +613 -0
- package/dist/services/astAnalyzer.js.map +1 -0
- package/dist/services/astAnalyzer.test.d.ts +2 -0
- package/dist/services/astAnalyzer.test.d.ts.map +1 -0
- package/dist/services/astAnalyzer.test.js +319 -0
- package/dist/services/astAnalyzer.test.js.map +1 -0
- package/dist/services/astClassifier.d.ts +17 -0
- package/dist/services/astClassifier.d.ts.map +1 -0
- package/dist/services/astClassifier.js +390 -0
- package/dist/services/astClassifier.js.map +1 -0
- package/dist/services/astClassifier.test.d.ts +2 -0
- package/dist/services/astClassifier.test.d.ts.map +1 -0
- package/dist/services/astClassifier.test.js +141 -0
- package/dist/services/astClassifier.test.js.map +1 -0
- package/dist/services/astDiffEngine.d.ts +45 -0
- package/dist/services/astDiffEngine.d.ts.map +1 -0
- package/dist/services/astDiffEngine.js +261 -0
- package/dist/services/astDiffEngine.js.map +1 -0
- package/dist/services/astDiffEngine.test.d.ts +2 -0
- package/dist/services/astDiffEngine.test.d.ts.map +1 -0
- package/dist/services/astDiffEngine.test.js +234 -0
- package/dist/services/astDiffEngine.test.js.map +1 -0
- package/dist/services/astExportAnalyzer.d.ts.map +1 -1
- package/dist/services/astExportAnalyzer.js +122 -292
- package/dist/services/astExportAnalyzer.js.map +1 -1
- package/dist/types/index.d.ts +68 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +2 -4
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.analyzeFile = analyzeFile;
|
|
4
|
+
exports.classifyCommit = classifyCommit;
|
|
5
|
+
exports.analyzeChangesAST = analyzeChangesAST;
|
|
6
|
+
const astExportAnalyzer_1 = require("./astExportAnalyzer");
|
|
7
|
+
const astAnalyzer_1 = require("./astAnalyzer");
|
|
8
|
+
const astDiffEngine_1 = require("./astDiffEngine");
|
|
9
|
+
const gitService_1 = require("./gitService");
|
|
10
|
+
// ── Performance pattern detection ──────────────────────────────
|
|
11
|
+
const PERF_CALL_PATTERNS = new Set([
|
|
12
|
+
'memo', 'useMemo', 'useCallback', 'memoize', 'cache',
|
|
13
|
+
'lazy', 'lazyLoad', 'createSelector', 'reselect',
|
|
14
|
+
]);
|
|
15
|
+
function hasPerformancePatterns(calls) {
|
|
16
|
+
return calls.some(c => PERF_CALL_PATTERNS.has(c));
|
|
17
|
+
}
|
|
18
|
+
// ── Guard / validation detection ───────────────────────────────
|
|
19
|
+
/**
|
|
20
|
+
* Check if a declaration gained a guard pattern:
|
|
21
|
+
* a new `if` that throws or returns early.
|
|
22
|
+
*/
|
|
23
|
+
function hasNewGuardPattern(changes) {
|
|
24
|
+
return changes.changedControlFlow &&
|
|
25
|
+
changes.statementsAdded > 0 &&
|
|
26
|
+
changes.statementsRemoved === 0;
|
|
27
|
+
}
|
|
28
|
+
// ── Per-file analysis ──────────────────────────────────────────
|
|
29
|
+
/**
|
|
30
|
+
* Analyze a single staged file, producing a FileASTResult.
|
|
31
|
+
*/
|
|
32
|
+
function analyzeFile(filePath, oldSource, newSource) {
|
|
33
|
+
const result = {
|
|
34
|
+
filePath,
|
|
35
|
+
parseError: false,
|
|
36
|
+
oldDeclarations: [],
|
|
37
|
+
newDeclarations: [],
|
|
38
|
+
added: [],
|
|
39
|
+
removed: [],
|
|
40
|
+
renamed: [],
|
|
41
|
+
modified: [],
|
|
42
|
+
reExportAll: false,
|
|
43
|
+
};
|
|
44
|
+
// Parse old version
|
|
45
|
+
let oldProgram = null;
|
|
46
|
+
if (oldSource !== null) {
|
|
47
|
+
oldProgram = (0, astAnalyzer_1.parseFile)(oldSource, filePath);
|
|
48
|
+
if (oldProgram) {
|
|
49
|
+
const { declarations, reExportAll } = (0, astAnalyzer_1.extractDeclarations)(oldProgram);
|
|
50
|
+
(0, astAnalyzer_1.populateBodyHashes)(declarations, oldProgram);
|
|
51
|
+
result.oldDeclarations = declarations;
|
|
52
|
+
if (reExportAll)
|
|
53
|
+
result.reExportAll = true;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Parse new version
|
|
57
|
+
let newProgram = null;
|
|
58
|
+
if (newSource !== null) {
|
|
59
|
+
newProgram = (0, astAnalyzer_1.parseFile)(newSource, filePath);
|
|
60
|
+
if (newProgram) {
|
|
61
|
+
const { declarations, reExportAll } = (0, astAnalyzer_1.extractDeclarations)(newProgram);
|
|
62
|
+
(0, astAnalyzer_1.populateBodyHashes)(declarations, newProgram);
|
|
63
|
+
result.newDeclarations = declarations;
|
|
64
|
+
if (reExportAll)
|
|
65
|
+
result.reExportAll = true;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// If both sources exist but both failed to parse, mark parse error
|
|
69
|
+
if (oldSource !== null && newSource !== null && !oldProgram && !newProgram) {
|
|
70
|
+
result.parseError = true;
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
// If at least one is new/deleted, just set added/removed
|
|
74
|
+
if (oldSource === null && newProgram) {
|
|
75
|
+
// New file: all declarations are added
|
|
76
|
+
result.added = result.newDeclarations;
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
if (newSource === null && oldProgram) {
|
|
80
|
+
// Deleted file: all declarations are removed
|
|
81
|
+
result.removed = result.oldDeclarations;
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
// Diff declarations
|
|
85
|
+
const diff = (0, astDiffEngine_1.diffDeclarations)(result.oldDeclarations, result.newDeclarations, oldProgram, newProgram);
|
|
86
|
+
result.added = diff.added;
|
|
87
|
+
result.removed = diff.removed;
|
|
88
|
+
result.renamed = diff.renamed.map(r => ({ oldName: r.oldName, newName: r.newName }));
|
|
89
|
+
// Compute body changes for modified declarations
|
|
90
|
+
if (oldProgram && newProgram) {
|
|
91
|
+
result.modified = diff.modified.map(m => {
|
|
92
|
+
const { body: oldBody } = (0, astAnalyzer_1.findDeclarationBody)(oldProgram, m.name);
|
|
93
|
+
const { body: newBody } = (0, astAnalyzer_1.findDeclarationBody)(newProgram, m.name);
|
|
94
|
+
if (oldBody && newBody) {
|
|
95
|
+
return {
|
|
96
|
+
name: m.name,
|
|
97
|
+
changes: (0, astDiffEngine_1.computeBodyChanges)(oldBody, newBody, oldProgram, newProgram),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
name: m.name,
|
|
102
|
+
changes: {
|
|
103
|
+
statementsAdded: 0, statementsRemoved: 0,
|
|
104
|
+
addedFunctionCalls: [], removedFunctionCalls: [],
|
|
105
|
+
addedImports: [], removedImports: [],
|
|
106
|
+
changedControlFlow: false, changedErrorHandling: false,
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
// ── Commit classification ──────────────────────────────────────
|
|
114
|
+
/**
|
|
115
|
+
* Classify a commit from per-file AST analysis results.
|
|
116
|
+
* Applies the signal table with weighted signals and tie-breaking.
|
|
117
|
+
*/
|
|
118
|
+
function classifyCommit(fileResults) {
|
|
119
|
+
const signals = [];
|
|
120
|
+
const allAdded = [];
|
|
121
|
+
const allRemoved = [];
|
|
122
|
+
const allRenamed = [];
|
|
123
|
+
const allModified = [];
|
|
124
|
+
// Check if any file parsed successfully
|
|
125
|
+
const anyParsed = fileResults.some(f => !f.parseError && (f.oldDeclarations.length > 0 || f.newDeclarations.length > 0 || f.added.length > 0 || f.removed.length > 0));
|
|
126
|
+
if (!anyParsed && fileResults.length > 0) {
|
|
127
|
+
// All files failed to parse or had no declarations
|
|
128
|
+
return {
|
|
129
|
+
primaryType: null,
|
|
130
|
+
confidence: 0,
|
|
131
|
+
signals: [],
|
|
132
|
+
declarations: { added: [], removed: [], renamed: [], modified: [] },
|
|
133
|
+
affectedElements: [],
|
|
134
|
+
isBreaking: false,
|
|
135
|
+
breakingReasons: [],
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
for (const file of fileResults) {
|
|
139
|
+
if (file.parseError)
|
|
140
|
+
continue;
|
|
141
|
+
const fp = file.filePath;
|
|
142
|
+
// New exported declarations → feat (weight 3)
|
|
143
|
+
for (const decl of file.added) {
|
|
144
|
+
allAdded.push(decl);
|
|
145
|
+
if (decl.exported) {
|
|
146
|
+
signals.push({
|
|
147
|
+
signal: 'new-exported-decl',
|
|
148
|
+
type: 'feat',
|
|
149
|
+
weight: 3,
|
|
150
|
+
file: fp,
|
|
151
|
+
detail: `new exported ${decl.kind} '${decl.name}'`,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
// New non-exported → feat (weight 1)
|
|
156
|
+
signals.push({
|
|
157
|
+
signal: 'new-internal-decl',
|
|
158
|
+
type: 'feat',
|
|
159
|
+
weight: 1,
|
|
160
|
+
file: fp,
|
|
161
|
+
detail: `new ${decl.kind} '${decl.name}'`,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// Removed exported declarations → refactor! (weight 3, breaking)
|
|
166
|
+
for (const decl of file.removed) {
|
|
167
|
+
allRemoved.push(decl);
|
|
168
|
+
if (decl.exported) {
|
|
169
|
+
signals.push({
|
|
170
|
+
signal: 'removed-exported-decl',
|
|
171
|
+
type: 'refactor',
|
|
172
|
+
weight: 3,
|
|
173
|
+
file: fp,
|
|
174
|
+
detail: `removed exported ${decl.kind} '${decl.name}'`,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
// Renamed declarations → refactor (weight 2)
|
|
179
|
+
for (const rename of file.renamed) {
|
|
180
|
+
allRenamed.push({ ...rename, file: fp });
|
|
181
|
+
signals.push({
|
|
182
|
+
signal: 'renamed-decl',
|
|
183
|
+
type: 'refactor',
|
|
184
|
+
weight: 2,
|
|
185
|
+
file: fp,
|
|
186
|
+
detail: `renamed '${rename.oldName}' → '${rename.newName}'`,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
// Check for exported signature changes on same-name declarations
|
|
190
|
+
// (even if body hash matches, signature can differ)
|
|
191
|
+
for (const oldDecl of file.oldDeclarations) {
|
|
192
|
+
if (!oldDecl.exported || !oldDecl.params)
|
|
193
|
+
continue;
|
|
194
|
+
const newDecl = file.newDeclarations.find(d => d.name === oldDecl.name);
|
|
195
|
+
if (!newDecl?.exported || !newDecl.params)
|
|
196
|
+
continue;
|
|
197
|
+
if ((0, astExportAnalyzer_1.isSignatureBreakingAST)(oldDecl.params, newDecl.params)) {
|
|
198
|
+
signals.push({
|
|
199
|
+
signal: 'changed-exported-sig',
|
|
200
|
+
type: 'refactor',
|
|
201
|
+
weight: 3,
|
|
202
|
+
file: fp,
|
|
203
|
+
detail: `breaking signature change on '${oldDecl.name}'`,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// Modified declarations
|
|
208
|
+
for (const mod of file.modified) {
|
|
209
|
+
allModified.push({ ...mod, file: fp });
|
|
210
|
+
// Error handling changed → fix (weight 2)
|
|
211
|
+
if (mod.changes.changedErrorHandling) {
|
|
212
|
+
signals.push({
|
|
213
|
+
signal: 'error-handling-change',
|
|
214
|
+
type: 'fix',
|
|
215
|
+
weight: 2,
|
|
216
|
+
file: fp,
|
|
217
|
+
detail: `error handling changed in '${mod.name}'`,
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
// Guard / validation added → fix (weight 2)
|
|
221
|
+
if (hasNewGuardPattern(mod.changes)) {
|
|
222
|
+
signals.push({
|
|
223
|
+
signal: 'guard-added',
|
|
224
|
+
type: 'fix',
|
|
225
|
+
weight: 2,
|
|
226
|
+
file: fp,
|
|
227
|
+
detail: `guard/validation added in '${mod.name}'`,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
// Control flow restructured → refactor (weight 2)
|
|
231
|
+
if (mod.changes.changedControlFlow && !hasNewGuardPattern(mod.changes)) {
|
|
232
|
+
signals.push({
|
|
233
|
+
signal: 'control-flow-restructured',
|
|
234
|
+
type: 'refactor',
|
|
235
|
+
weight: 2,
|
|
236
|
+
file: fp,
|
|
237
|
+
detail: `control flow restructured in '${mod.name}'`,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
// Performance patterns → perf (weight 2)
|
|
241
|
+
if (hasPerformancePatterns(mod.changes.addedFunctionCalls)) {
|
|
242
|
+
signals.push({
|
|
243
|
+
signal: 'perf-pattern',
|
|
244
|
+
type: 'perf',
|
|
245
|
+
weight: 2,
|
|
246
|
+
file: fp,
|
|
247
|
+
detail: `performance pattern added in '${mod.name}'`,
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
// Only literal changes → fix or chore (weight 1)
|
|
251
|
+
if (!mod.changes.changedControlFlow &&
|
|
252
|
+
!mod.changes.changedErrorHandling &&
|
|
253
|
+
mod.changes.addedFunctionCalls.length === 0 &&
|
|
254
|
+
mod.changes.removedFunctionCalls.length === 0 &&
|
|
255
|
+
mod.changes.statementsAdded === 0 &&
|
|
256
|
+
mod.changes.statementsRemoved === 0) {
|
|
257
|
+
signals.push({
|
|
258
|
+
signal: 'literal-only-change',
|
|
259
|
+
type: 'fix',
|
|
260
|
+
weight: 1,
|
|
261
|
+
file: fp,
|
|
262
|
+
detail: `only literals changed in '${mod.name}'`,
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
// If no signals at all, return inconclusive
|
|
268
|
+
if (signals.length === 0) {
|
|
269
|
+
return {
|
|
270
|
+
primaryType: null,
|
|
271
|
+
confidence: 0,
|
|
272
|
+
signals: [],
|
|
273
|
+
declarations: { added: allAdded, removed: allRemoved, renamed: allRenamed, modified: allModified },
|
|
274
|
+
affectedElements: buildAffectedElements(allAdded, allRemoved, allRenamed, allModified),
|
|
275
|
+
isBreaking: false,
|
|
276
|
+
breakingReasons: [],
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
// Determine primary type by highest total weight per type
|
|
280
|
+
const typeWeights = new Map();
|
|
281
|
+
for (const s of signals) {
|
|
282
|
+
typeWeights.set(s.type, (typeWeights.get(s.type) || 0) + s.weight);
|
|
283
|
+
}
|
|
284
|
+
const maxWeight = Math.max(...typeWeights.values());
|
|
285
|
+
const tiedTypes = [...typeWeights.entries()]
|
|
286
|
+
.filter(([_, w]) => w === maxWeight)
|
|
287
|
+
.map(([t]) => t);
|
|
288
|
+
let primaryType;
|
|
289
|
+
if (tiedTypes.length === 1) {
|
|
290
|
+
primaryType = tiedTypes[0];
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
// Tie-breaking order
|
|
294
|
+
primaryType = tieBreak(tiedTypes, signals);
|
|
295
|
+
}
|
|
296
|
+
// Confidence
|
|
297
|
+
const totalWeight = [...typeWeights.values()].reduce((a, b) => a + b, 0);
|
|
298
|
+
const confidence = totalWeight > 0 ? maxWeight / totalWeight : 0;
|
|
299
|
+
// Breaking changes
|
|
300
|
+
const breakingSignals = signals.filter(s => s.signal === 'removed-exported-decl' || s.signal === 'changed-exported-sig');
|
|
301
|
+
const isBreaking = breakingSignals.length > 0;
|
|
302
|
+
const breakingReasons = breakingSignals.map(s => s.detail);
|
|
303
|
+
return {
|
|
304
|
+
primaryType,
|
|
305
|
+
confidence,
|
|
306
|
+
signals,
|
|
307
|
+
declarations: {
|
|
308
|
+
added: allAdded,
|
|
309
|
+
removed: allRemoved,
|
|
310
|
+
renamed: allRenamed,
|
|
311
|
+
modified: allModified,
|
|
312
|
+
},
|
|
313
|
+
affectedElements: buildAffectedElements(allAdded, allRemoved, allRenamed, allModified),
|
|
314
|
+
isBreaking,
|
|
315
|
+
breakingReasons,
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
/** Tie-breaking: feat > refactor (breaking) > fix > refactor */
|
|
319
|
+
function tieBreak(types, signals) {
|
|
320
|
+
const hasNewExport = signals.some(s => s.signal === 'new-exported-decl');
|
|
321
|
+
const hasRemovedExport = signals.some(s => s.signal === 'removed-exported-decl' || s.signal === 'changed-exported-sig');
|
|
322
|
+
const hasErrorHandling = signals.some(s => s.signal === 'error-handling-change');
|
|
323
|
+
if (types.includes('feat') && hasNewExport)
|
|
324
|
+
return 'feat';
|
|
325
|
+
if (types.includes('refactor') && hasRemovedExport)
|
|
326
|
+
return 'refactor';
|
|
327
|
+
if (types.includes('fix') && hasErrorHandling)
|
|
328
|
+
return 'fix';
|
|
329
|
+
if (types.includes('refactor'))
|
|
330
|
+
return 'refactor';
|
|
331
|
+
return types[0]; // fallback
|
|
332
|
+
}
|
|
333
|
+
/** Build human-readable affected element strings. */
|
|
334
|
+
function buildAffectedElements(added, removed, renamed, modified) {
|
|
335
|
+
const elements = [];
|
|
336
|
+
for (const d of added)
|
|
337
|
+
elements.push(`${d.kind} ${d.name}`);
|
|
338
|
+
for (const d of removed)
|
|
339
|
+
elements.push(`${d.kind} ${d.name}`);
|
|
340
|
+
for (const r of renamed)
|
|
341
|
+
elements.push(`${r.oldName} → ${r.newName}`);
|
|
342
|
+
for (const m of modified)
|
|
343
|
+
elements.push(`${m.name}`);
|
|
344
|
+
return [...new Set(elements)];
|
|
345
|
+
}
|
|
346
|
+
// ── Entry point: analyze all staged files ──────────────────────
|
|
347
|
+
/**
|
|
348
|
+
* Run the full AST analysis pipeline on all staged files.
|
|
349
|
+
* Returns the classifier result.
|
|
350
|
+
*/
|
|
351
|
+
function analyzeChangesAST(stagedFiles) {
|
|
352
|
+
const parseableFiles = stagedFiles.filter(f => (0, astAnalyzer_1.isParseableFile)(f.path));
|
|
353
|
+
if (parseableFiles.length === 0) {
|
|
354
|
+
return {
|
|
355
|
+
primaryType: null,
|
|
356
|
+
confidence: 0,
|
|
357
|
+
signals: [],
|
|
358
|
+
declarations: { added: [], removed: [], renamed: [], modified: [] },
|
|
359
|
+
affectedElements: [],
|
|
360
|
+
isBreaking: false,
|
|
361
|
+
breakingReasons: [],
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
const fileResults = [];
|
|
365
|
+
for (const file of parseableFiles) {
|
|
366
|
+
const isDeleted = file.status === 'D';
|
|
367
|
+
const isNew = file.status === 'A';
|
|
368
|
+
let oldSource = null;
|
|
369
|
+
let newSource = null;
|
|
370
|
+
try {
|
|
371
|
+
if (!isNew) {
|
|
372
|
+
oldSource = gitService_1.GitService.getFileAtHead(file.path);
|
|
373
|
+
}
|
|
374
|
+
if (!isDeleted) {
|
|
375
|
+
newSource = gitService_1.GitService.getStagedFileContent(file.path);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
catch {
|
|
379
|
+
// If git retrieval fails, skip this file
|
|
380
|
+
continue;
|
|
381
|
+
}
|
|
382
|
+
// Skip if both are null (shouldn't happen, but safety check)
|
|
383
|
+
if (oldSource === null && newSource === null)
|
|
384
|
+
continue;
|
|
385
|
+
const result = analyzeFile(file.path, oldSource, newSource);
|
|
386
|
+
fileResults.push(result);
|
|
387
|
+
}
|
|
388
|
+
return classifyCommit(fileResults);
|
|
389
|
+
}
|
|
390
|
+
//# sourceMappingURL=astClassifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"astClassifier.js","sourceRoot":"","sources":["../../src/services/astClassifier.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"astClassifier.test.d.ts","sourceRoot":"","sources":["../../src/services/astClassifier.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const astClassifier_1 = require("./astClassifier");
|
|
4
|
+
/** Helper to create a FileASTResult by analyzing old/new source pairs. */
|
|
5
|
+
function analyze(oldSrc, newSrc, filePath = 'test.ts') {
|
|
6
|
+
return (0, astClassifier_1.analyzeFile)(filePath, oldSrc, newSrc);
|
|
7
|
+
}
|
|
8
|
+
describe('astClassifier', () => {
|
|
9
|
+
describe('analyzeFile', () => {
|
|
10
|
+
it('detects new file (all added)', () => {
|
|
11
|
+
const result = analyze(null, 'export function foo() { return 1; }');
|
|
12
|
+
expect(result.added).toHaveLength(1);
|
|
13
|
+
expect(result.added[0].name).toBe('foo');
|
|
14
|
+
expect(result.removed).toHaveLength(0);
|
|
15
|
+
});
|
|
16
|
+
it('detects deleted file (all removed)', () => {
|
|
17
|
+
const result = analyze('export function foo() { return 1; }', null);
|
|
18
|
+
expect(result.removed).toHaveLength(1);
|
|
19
|
+
expect(result.removed[0].name).toBe('foo');
|
|
20
|
+
expect(result.added).toHaveLength(0);
|
|
21
|
+
});
|
|
22
|
+
it('detects modified declaration', () => {
|
|
23
|
+
const result = analyze('export function foo() { return 1; }', 'export function foo() { return 2; }');
|
|
24
|
+
expect(result.modified).toHaveLength(1);
|
|
25
|
+
expect(result.modified[0].name).toBe('foo');
|
|
26
|
+
});
|
|
27
|
+
it('detects added and removed declarations', () => {
|
|
28
|
+
const result = analyze('export function foo() { return 1; }', 'export function bar() { return 2; }');
|
|
29
|
+
// Could be a rename or add+remove depending on body similarity
|
|
30
|
+
const totalChanges = result.added.length + result.removed.length + result.renamed.length;
|
|
31
|
+
expect(totalChanges).toBeGreaterThan(0);
|
|
32
|
+
});
|
|
33
|
+
it('marks parse error when both fail', () => {
|
|
34
|
+
const result = analyze('}{invalid', '}{alsobad');
|
|
35
|
+
expect(result.parseError).toBe(true);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
describe('classifyCommit', () => {
|
|
39
|
+
it('classifies new exported function as feat (weight 3)', () => {
|
|
40
|
+
const file = analyze(null, 'export function newFeature() { return "hello"; }');
|
|
41
|
+
const result = (0, astClassifier_1.classifyCommit)([file]);
|
|
42
|
+
expect(result.primaryType).toBe('feat');
|
|
43
|
+
expect(result.signals.some(s => s.signal === 'new-exported-decl')).toBe(true);
|
|
44
|
+
expect(result.confidence).toBeGreaterThan(0);
|
|
45
|
+
});
|
|
46
|
+
it('classifies new non-exported function as feat (weight 1)', () => {
|
|
47
|
+
const file = analyze(null, 'function helper() { return 1; }');
|
|
48
|
+
const result = (0, astClassifier_1.classifyCommit)([file]);
|
|
49
|
+
expect(result.primaryType).toBe('feat');
|
|
50
|
+
expect(result.signals.some(s => s.signal === 'new-internal-decl')).toBe(true);
|
|
51
|
+
});
|
|
52
|
+
it('classifies removed exported function as refactor with breaking', () => {
|
|
53
|
+
const file = analyze('export function oldFn() { return 1; }', '');
|
|
54
|
+
const result = (0, astClassifier_1.classifyCommit)([file]);
|
|
55
|
+
expect(result.primaryType).toBe('refactor');
|
|
56
|
+
expect(result.isBreaking).toBe(true);
|
|
57
|
+
expect(result.breakingReasons.length).toBeGreaterThan(0);
|
|
58
|
+
});
|
|
59
|
+
it('classifies changed exported signature as refactor with breaking', () => {
|
|
60
|
+
const file = analyze('export function greet(name: string) { return name; }', 'export function greet(name: string, age: number) { return name; }');
|
|
61
|
+
const result = (0, astClassifier_1.classifyCommit)([file]);
|
|
62
|
+
// Should detect breaking signature change
|
|
63
|
+
expect(result.isBreaking).toBe(true);
|
|
64
|
+
expect(result.signals.some(s => s.signal === 'changed-exported-sig')).toBe(true);
|
|
65
|
+
});
|
|
66
|
+
it('classifies added try/catch as fix', () => {
|
|
67
|
+
const file = analyze('export function process(data) { return transform(data); }', 'export function process(data) { try { return transform(data); } catch(e) { log(e); throw e; } }');
|
|
68
|
+
const result = (0, astClassifier_1.classifyCommit)([file]);
|
|
69
|
+
expect(result.primaryType).toBe('fix');
|
|
70
|
+
expect(result.signals.some(s => s.signal === 'error-handling-change')).toBe(true);
|
|
71
|
+
});
|
|
72
|
+
it('classifies renamed function as refactor', () => {
|
|
73
|
+
const file = analyze('export function oldName(x) { return x + 1; }', 'export function newName(x) { return x + 1; }');
|
|
74
|
+
const result = (0, astClassifier_1.classifyCommit)([file]);
|
|
75
|
+
expect(result.primaryType).toBe('refactor');
|
|
76
|
+
expect(result.signals.some(s => s.signal === 'renamed-decl')).toBe(true);
|
|
77
|
+
});
|
|
78
|
+
it('classifies control flow restructuring as refactor', () => {
|
|
79
|
+
const file = analyze('export function check(x) { return x > 0; }', 'export function check(x) { if (x === null) { return false; } return x > 0; }');
|
|
80
|
+
const result = (0, astClassifier_1.classifyCommit)([file]);
|
|
81
|
+
// Could be fix (guard) or refactor (control flow)
|
|
82
|
+
expect(['fix', 'refactor']).toContain(result.primaryType);
|
|
83
|
+
});
|
|
84
|
+
it('classifies performance pattern as perf', () => {
|
|
85
|
+
const file = analyze('export function compute(data) { return process(data); }', 'export function compute(data) { return useMemo(() => process(data)); }');
|
|
86
|
+
const result = (0, astClassifier_1.classifyCommit)([file]);
|
|
87
|
+
expect(result.signals.some(s => s.signal === 'perf-pattern')).toBe(true);
|
|
88
|
+
});
|
|
89
|
+
it('returns null primaryType when all files fail to parse', () => {
|
|
90
|
+
const file = {
|
|
91
|
+
filePath: 'bad.ts',
|
|
92
|
+
parseError: true,
|
|
93
|
+
oldDeclarations: [],
|
|
94
|
+
newDeclarations: [],
|
|
95
|
+
added: [],
|
|
96
|
+
removed: [],
|
|
97
|
+
renamed: [],
|
|
98
|
+
modified: [],
|
|
99
|
+
reExportAll: false,
|
|
100
|
+
};
|
|
101
|
+
const result = (0, astClassifier_1.classifyCommit)([file]);
|
|
102
|
+
expect(result.primaryType).toBeNull();
|
|
103
|
+
});
|
|
104
|
+
it('returns null primaryType for empty file list', () => {
|
|
105
|
+
const result = (0, astClassifier_1.classifyCommit)([]);
|
|
106
|
+
expect(result.primaryType).toBeNull();
|
|
107
|
+
});
|
|
108
|
+
it('tie-break: new export + error handling → feat wins', () => {
|
|
109
|
+
// File 1: new exported function (weight 3)
|
|
110
|
+
const file1 = analyze(null, 'export function newFn() { return 1; }', 'a.ts');
|
|
111
|
+
// File 2: error handling change (weight 2)
|
|
112
|
+
const file2 = analyze('export function existing() { doWork(); }', 'export function existing() { try { doWork(); } catch(e) { log(e); } }', 'b.ts');
|
|
113
|
+
const result = (0, astClassifier_1.classifyCommit)([file1, file2]);
|
|
114
|
+
expect(result.primaryType).toBe('feat');
|
|
115
|
+
});
|
|
116
|
+
it('tie-break: equal weight feat vs fix → feat wins', () => {
|
|
117
|
+
// This tests that feat wins ties via tie-breaking rules
|
|
118
|
+
const file1 = analyze(null, 'function helper() { return 1; }', 'a.ts'); // feat weight 1
|
|
119
|
+
const file2 = analyze('function process() { return 1; }', 'function process() { return "fixed"; }', 'b.ts'); // literal-only → fix weight 1
|
|
120
|
+
const result = (0, astClassifier_1.classifyCommit)([file1, file2]);
|
|
121
|
+
// feat and fix both have weight 1, but feat doesn't have new-exported-decl
|
|
122
|
+
// so tie-break falls through: feat? no (no new export signal). refactor? no. fix? no (no error handling).
|
|
123
|
+
// Falls through to types[0] which is the first in tiedTypes
|
|
124
|
+
expect(result.primaryType).toBeDefined();
|
|
125
|
+
});
|
|
126
|
+
it('populates affectedElements', () => {
|
|
127
|
+
const file = analyze(null, 'export function myFunc() { return 1; }\nexport class MyClass {}');
|
|
128
|
+
const result = (0, astClassifier_1.classifyCommit)([file]);
|
|
129
|
+
expect(result.affectedElements).toContain('function myFunc');
|
|
130
|
+
expect(result.affectedElements).toContain('class MyClass');
|
|
131
|
+
});
|
|
132
|
+
it('merges signals from multiple files', () => {
|
|
133
|
+
const file1 = analyze(null, 'export function a() {}', 'x.ts');
|
|
134
|
+
const file2 = analyze(null, 'export function b() {}', 'y.ts');
|
|
135
|
+
const result = (0, astClassifier_1.classifyCommit)([file1, file2]);
|
|
136
|
+
expect(result.signals.length).toBeGreaterThanOrEqual(2);
|
|
137
|
+
expect(result.declarations.added.length).toBe(2);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
//# sourceMappingURL=astClassifier.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"astClassifier.test.js","sourceRoot":"","sources":["../../src/services/astClassifier.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { TSESTree } from '@typescript-eslint/typescript-estree';
|
|
2
|
+
import { ASTDeclaration, BodyChanges } from '../types';
|
|
3
|
+
export interface RenameResult {
|
|
4
|
+
oldName: string;
|
|
5
|
+
newName: string;
|
|
6
|
+
exact: boolean;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Extract function call names from a body subtree.
|
|
10
|
+
* - Identifier callee → name
|
|
11
|
+
* - MemberExpression callee → property name
|
|
12
|
+
* - Otherwise ignored
|
|
13
|
+
*/
|
|
14
|
+
export declare function extractFunctionCalls(node: TSESTree.Node): string[];
|
|
15
|
+
/**
|
|
16
|
+
* Detect renames between old and new declarations.
|
|
17
|
+
* Uses exact hash match and near-match heuristics.
|
|
18
|
+
*/
|
|
19
|
+
export declare function detectRenames(oldDecls: ASTDeclaration[], newDecls: ASTDeclaration[], oldProgram: TSESTree.Program | null, newProgram: TSESTree.Program | null): RenameResult[];
|
|
20
|
+
export interface DeclarationDiff {
|
|
21
|
+
added: ASTDeclaration[];
|
|
22
|
+
removed: ASTDeclaration[];
|
|
23
|
+
renamed: RenameResult[];
|
|
24
|
+
modified: Array<{
|
|
25
|
+
name: string;
|
|
26
|
+
oldDecl: ASTDeclaration;
|
|
27
|
+
newDecl: ASTDeclaration;
|
|
28
|
+
}>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Diff two sets of declarations.
|
|
32
|
+
* Returns added, removed, renamed, and modified declarations.
|
|
33
|
+
*/
|
|
34
|
+
export declare function diffDeclarations(oldDecls: ASTDeclaration[], newDecls: ASTDeclaration[], oldProgram: TSESTree.Program | null, newProgram: TSESTree.Program | null): DeclarationDiff;
|
|
35
|
+
/** Count statement-level AST nodes in a body. */
|
|
36
|
+
export declare function countStatements(node: TSESTree.Node): number;
|
|
37
|
+
/**
|
|
38
|
+
* Extract import specifier names from a program.
|
|
39
|
+
*/
|
|
40
|
+
export declare function extractImports(program: TSESTree.Program): string[];
|
|
41
|
+
/**
|
|
42
|
+
* Compute body changes between old and new versions of a declaration.
|
|
43
|
+
*/
|
|
44
|
+
export declare function computeBodyChanges(oldBody: TSESTree.Node, newBody: TSESTree.Node, oldProgram: TSESTree.Program, newProgram: TSESTree.Program): BodyChanges;
|
|
45
|
+
//# sourceMappingURL=astDiffEngine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"astDiffEngine.d.ts","sourceRoot":"","sources":["../../src/services/astDiffEngine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAKvD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;CAChB;AAWD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,GAAG,MAAM,EAAE,CAelE;AAgBD;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,cAAc,EAAE,EAC1B,QAAQ,EAAE,cAAc,EAAE,EAC1B,UAAU,EAAE,QAAQ,CAAC,OAAO,GAAG,IAAI,EACnC,UAAU,EAAE,QAAQ,CAAC,OAAO,GAAG,IAAI,GAClC,YAAY,EAAE,CAkEhB;AAID,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,cAAc,CAAC;QAAC,OAAO,EAAE,cAAc,CAAA;KAAE,CAAC,CAAC;CACrF;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,cAAc,EAAE,EAC1B,QAAQ,EAAE,cAAc,EAAE,EAC1B,UAAU,EAAE,QAAQ,CAAC,OAAO,GAAG,IAAI,EACnC,UAAU,EAAE,QAAQ,CAAC,OAAO,GAAG,IAAI,GAClC,eAAe,CA4BjB;AA0BD,iDAAiD;AACjD,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,GAAG,MAAM,CAQ3D;AAwBD;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,QAAQ,CAAC,OAAO,GAAG,MAAM,EAAE,CAQlE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,QAAQ,CAAC,IAAI,EACtB,OAAO,EAAE,QAAQ,CAAC,IAAI,EACtB,UAAU,EAAE,QAAQ,CAAC,OAAO,EAC5B,UAAU,EAAE,QAAQ,CAAC,OAAO,GAC3B,WAAW,CAyCb"}
|