@specverse/engines 6.18.3 → 6.20.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/analyse-prepass/adapters/typescript-decorators.d.ts +9 -0
- package/dist/analyse-prepass/adapters/typescript-decorators.d.ts.map +1 -1
- package/dist/analyse-prepass/adapters/typescript-decorators.js +55 -0
- package/dist/analyse-prepass/adapters/typescript-decorators.js.map +1 -1
- package/dist/analyse-prepass/behavior-step-classifier.d.ts +85 -0
- package/dist/analyse-prepass/behavior-step-classifier.d.ts.map +1 -0
- package/dist/analyse-prepass/behavior-step-classifier.js +266 -0
- package/dist/analyse-prepass/behavior-step-classifier.js.map +1 -0
- package/dist/analyse-prepass/index.d.ts +17 -0
- package/dist/analyse-prepass/index.d.ts.map +1 -1
- package/dist/analyse-prepass/index.js +9 -0
- package/dist/analyse-prepass/index.js.map +1 -1
- package/dist/analyse-prepass/method-body-walker.d.ts +113 -0
- package/dist/analyse-prepass/method-body-walker.d.ts.map +1 -0
- package/dist/analyse-prepass/method-body-walker.js +411 -0
- package/dist/analyse-prepass/method-body-walker.js.map +1 -0
- package/package.json +1 -1
|
@@ -56,11 +56,20 @@ export interface DecoratorRelationship {
|
|
|
56
56
|
* the entity's file for `export enum X { ... }` declarations and
|
|
57
57
|
* matching attribute `declaredType` against them. Only same-file
|
|
58
58
|
* enums today (cross-file lookup deferred until a fixture demands it).
|
|
59
|
+
*
|
|
60
|
+
* `transitions` are populated by the method-body walker (#27-A) — each
|
|
61
|
+
* entry is one instance method that mutates `this.<field>` to a new
|
|
62
|
+
* state, optionally guarded by a precondition `if (this.<field> op X)`.
|
|
59
63
|
*/
|
|
60
64
|
export interface DecoratorLifecycle {
|
|
61
65
|
model: string;
|
|
62
66
|
field: string;
|
|
63
67
|
states: string[];
|
|
68
|
+
transitions?: Array<{
|
|
69
|
+
action: string;
|
|
70
|
+
from: string[];
|
|
71
|
+
to: string;
|
|
72
|
+
}>;
|
|
64
73
|
}
|
|
65
74
|
export interface DecoratorFacts {
|
|
66
75
|
entities: DecoratorEntity[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typescript-decorators.d.ts","sourceRoot":"","sources":["../../../src/analyse-prepass/adapters/typescript-decorators.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"typescript-decorators.d.ts","sourceRoot":"","sources":["../../../src/analyse-prepass/adapters/typescript-decorators.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAGzD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,SAAS,EAAE,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,KAAK,GAAG,SAAS,CAAC;IAC/E,UAAU,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACpG,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,YAAY,CAAC;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,CAAC,EAAE,KAAK,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,aAAa,EAAE,qBAAqB,EAAE,CAAC;IACvC,UAAU,EAAE,kBAAkB,EAAE,CAAC;IACjC,mDAAmD;IACnD,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,cAAc,CAAC,CAwFzB"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { walkMethodBodies } from '../method-body-walker.js';
|
|
1
2
|
/**
|
|
2
3
|
* Run the generic decorator adapter against a structural backend.
|
|
3
4
|
* Caller is expected to have run `prepass.init(...)` and `prepass.index()`
|
|
@@ -81,16 +82,70 @@ export async function extractTypeScriptDecorators(prepass) {
|
|
|
81
82
|
const suffixMatch = exactMatch
|
|
82
83
|
?? enumTypedAttrs.find((e) => /(?:Status|State)$/.test(e.attr.name));
|
|
83
84
|
const chosen = suffixMatch ?? enumTypedAttrs[0];
|
|
85
|
+
const transitions = extractTransitions(classBody, chosen.attr.name, chosen.states);
|
|
84
86
|
facts.lifecycles.push({
|
|
85
87
|
model: cls.name,
|
|
86
88
|
field: chosen.attr.name,
|
|
87
89
|
states: chosen.states,
|
|
90
|
+
transitions: transitions.length > 0 ? transitions : undefined,
|
|
88
91
|
});
|
|
89
92
|
}
|
|
90
93
|
}
|
|
91
94
|
facts.frameworks = [...seenFrameworks];
|
|
92
95
|
return facts;
|
|
93
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Pair guards + assignments produced by `walkMethodBodies` into
|
|
99
|
+
* lifecycle transitions. Each method that mutates `this.<lifecycleField>`
|
|
100
|
+
* to an enum member yields one transition entry; the guard (if any)
|
|
101
|
+
* determines the source state(s).
|
|
102
|
+
*
|
|
103
|
+
* Two patterns recognised:
|
|
104
|
+
* 1. `if (this.<f> !== EnumName.X) throw; ... this.<f> = EnumName.Y;`
|
|
105
|
+
* → from: [X], to: Y
|
|
106
|
+
* 2. `if (this.<f> === EnumName.X) throw; ... this.<f> = EnumName.Y;`
|
|
107
|
+
* → from: allStates - [X], to: Y
|
|
108
|
+
*
|
|
109
|
+
* Methods without a guard but with the assignment yield a transition
|
|
110
|
+
* from `allStates` (any source). The action label is the method name.
|
|
111
|
+
*/
|
|
112
|
+
function extractTransitions(classBody, lifecycleField, allStates) {
|
|
113
|
+
const out = [];
|
|
114
|
+
const methods = walkMethodBodies(classBody);
|
|
115
|
+
for (const method of methods) {
|
|
116
|
+
// Filter to assignments touching the lifecycle field with an
|
|
117
|
+
// enum-member RHS (we only care about state mutations, not bare
|
|
118
|
+
// value writes like `this.status = someComputed`).
|
|
119
|
+
const assignments = method.thisAssignments.filter((a) => a.field === lifecycleField && a.enumMember);
|
|
120
|
+
if (assignments.length === 0)
|
|
121
|
+
continue;
|
|
122
|
+
// Take the FIRST assignment as the canonical transition target.
|
|
123
|
+
// Multi-assignment methods (rare; usually error-flow ternaries) fall
|
|
124
|
+
// through to the LLM with the first one wins.
|
|
125
|
+
const target = assignments[0].enumMember;
|
|
126
|
+
// Find guards on the same field. The first guard with `throws=true`
|
|
127
|
+
// is the precondition that defines source states.
|
|
128
|
+
const guard = method.guards.find((g) => g.field === lifecycleField && g.throws && g.enumMember);
|
|
129
|
+
let from;
|
|
130
|
+
if (!guard) {
|
|
131
|
+
from = [...allStates];
|
|
132
|
+
}
|
|
133
|
+
else if (guard.op === '!==' || guard.op === '!=') {
|
|
134
|
+
// `if (this.f !== X) throw` → must equal X to proceed.
|
|
135
|
+
from = [guard.enumMember];
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
// `if (this.f === X) throw` → must NOT be X to proceed; complement.
|
|
139
|
+
from = allStates.filter((s) => s !== guard.enumMember);
|
|
140
|
+
}
|
|
141
|
+
out.push({
|
|
142
|
+
action: method.methodName,
|
|
143
|
+
from,
|
|
144
|
+
to: target,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
return out;
|
|
148
|
+
}
|
|
94
149
|
/**
|
|
95
150
|
* Parse `export enum Foo { A = 'a', B, C = 3 }` declarations from a
|
|
96
151
|
* file. Returns a record of enum name → array of member NAMES (not
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typescript-decorators.js","sourceRoot":"","sources":["../../../src/analyse-prepass/adapters/typescript-decorators.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"typescript-decorators.js","sourceRoot":"","sources":["../../../src/analyse-prepass/adapters/typescript-decorators.ts"],"names":[],"mappings":"AA+BA,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAkD5D;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,OAA0B;IAE1B,MAAM,KAAK,GAAmB,EAAE,QAAQ,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;IAElG,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC;IAC5C,MAAM,cAAc,GAAG,IAAI,GAAG,EAAU,CAAC;IACzC,qEAAqE;IACrE,8BAA8B;IAC9B,MAAM,cAAc,GAAG,IAAI,GAAG,EAAoC,CAAC;IAEnE,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,IAAI,CAAC,GAAG,CAAC,QAAQ;YAAE,SAAS;QAC5B,IAAI,IAAY,CAAC;QACjB,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACpD,CAAC;QAAC,MAAM,CAAC;YAAC,SAAS;QAAC,CAAC;QACrB,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QAC3D,IAAI,CAAC,KAAK;YAAE,SAAS;QAErB,2EAA2E;QAC3E,2EAA2E;QAC3E,yEAAyE;QACzE,wEAAwE;QACxE,yDAAyD;QACzD,MAAM,SAAS,GAAG,eAAe,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACpD,IAAI,SAAS,KAAK,eAAe;YAAE,SAAS;QAC5C,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAE9B,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC;QAC7B,MAAM,UAAU,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAChD,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;YAClB,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,SAAS,EAAE,SAAyC;YACpD,UAAU;YACV,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU;SAC7B,CAAC,CAAC;QAEH,KAAK,MAAM,GAAG,IAAI,oBAAoB,CAAC,SAAS,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5D,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChC,CAAC;QAED,mEAAmE;QACnE,8DAA8D;QAC9D,6DAA6D;QAC7D,kEAAkE;QAClE,wDAAwD;QACxD,EAAE;QACF,4DAA4D;QAC5D,iEAAiE;QACjE,iEAAiE;QACjE,gEAAgE;QAChE,wDAAwD;QACxD,qEAAqE;QACrE,uCAAuC;QACvC,yDAAyD;QACzD,IAAI,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACjD,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YAC/B,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC9C,CAAC;QACD,MAAM,cAAc,GAA4D,EAAE,CAAC;QACnF,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;YAC9B,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YAClD,IAAI,CAAC,QAAQ;gBAAE,SAAS;YACxB,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,8BAA8B,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YAC7E,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;YACnC,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAChC,cAAc,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;QACD,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,MAAM,UAAU,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;YACnG,MAAM,WAAW,GAAG,UAAU;mBACzB,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YACvE,MAAM,MAAM,GAAG,WAAW,IAAI,cAAc,CAAC,CAAC,CAAE,CAAC;YACjD,MAAM,WAAW,GAAG,kBAAkB,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;YACnF,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC;gBACpB,KAAK,EAAE,GAAG,CAAC,IAAI;gBACf,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI;gBACvB,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,WAAW,EAAE,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS;aAC9D,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,KAAK,CAAC,UAAU,GAAG,CAAC,GAAG,cAAc,CAAC,CAAC;IACvC,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,SAAS,kBAAkB,CACzB,SAAiB,EACjB,cAAsB,EACtB,SAAmB;IAEnB,MAAM,GAAG,GAAmD,EAAE,CAAC;IAC/D,MAAM,OAAO,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAC5C,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,6DAA6D;QAC7D,gEAAgE;QAChE,mDAAmD;QACnD,MAAM,WAAW,GAAG,MAAM,CAAC,eAAe,CAAC,MAAM,CAC/C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,cAAc,IAAI,CAAC,CAAC,UAAU,CAClD,CAAC;QACF,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACvC,gEAAgE;QAChE,qEAAqE;QACrE,8CAA8C;QAC9C,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAE,CAAC,UAAW,CAAC;QAE3C,oEAAoE;QACpE,kDAAkD;QAClD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAC9B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,cAAc,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,UAAU,CAC9D,CAAC;QAEF,IAAI,IAAc,CAAC;QACnB,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC;QACxB,CAAC;aAAM,IAAI,KAAK,CAAC,EAAE,KAAK,KAAK,IAAI,KAAK,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;YACnD,uDAAuD;YACvD,IAAI,GAAG,CAAC,KAAK,CAAC,UAAW,CAAC,CAAC;QAC7B,CAAC;aAAM,CAAC;YACN,oEAAoE;YACpE,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,UAAU,CAAC,CAAC;QACzD,CAAC;QAED,GAAG,CAAC,IAAI,CAAC;YACP,MAAM,EAAE,MAAM,CAAC,UAAU;YACzB,IAAI;YACJ,EAAE,EAAE,MAAM;SACX,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAS,YAAY,CAAC,IAAY;IAChC,MAAM,GAAG,GAA6B,EAAE,CAAC;IACzC,mEAAmE;IACnE,mEAAmE;IACnE,MAAM,EAAE,GAAG,wCAAwC,CAAC;IACpD,IAAI,CAAyB,CAAC;IAC9B,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;QACnB,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;QACnB,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;YACvC,+CAA+C;YAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACxE,IAAI,CAAC,OAAO;gBAAE,SAAS;YACvB,+DAA+D;YAC/D,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;YACzD,IAAI,WAAW;gBAAE,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAE,CAAC,CAAC;QACjD,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;IACtB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,wEAAwE;AACxE,iCAAiC;AACjC,wEAAwE;AAExE;;;;;;;;GAQG;AACH,SAAS,eAAe,CAAC,cAAsB;IAC7C,4EAA4E;IAC5E,IAAI,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC;QAAE,OAAO,WAAW,CAAC;IAC3D,IAAI,qBAAqB,CAAC,IAAI,CAAC,cAAc,CAAC;QAAE,OAAO,WAAW,CAAC;IACnE,4BAA4B;IAC5B,IAAI,iBAAiB,CAAC,IAAI,CAAC,cAAc,CAAC;QAAE,OAAO,SAAS,CAAC;IAC7D,gCAAgC;IAChC,IAAI,iBAAiB,CAAC,IAAI,CAAC,cAAc,CAAC;QAAE,OAAO,UAAU,CAAC;IAC9D,8EAA8E;IAC9E,+DAA+D;IAC/D,OAAO,eAAe,CAAC;AACzB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAS,iBAAiB,CAAC,IAAY;IACrC,MAAM,GAAG,GAAkC,EAAE,CAAC;IAC9C,iEAAiE;IACjE,0EAA0E;IAC1E,MAAM,EAAE,GAAG,2PAA2P,CAAC;IACvQ,IAAI,CAAyB,CAAC;IAC9B,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACpC,MAAM,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAClB,MAAM,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACjC,GAAG,CAAC,IAAI,CAAC;YACP,IAAI;YACJ,YAAY;YACZ,SAAS,EAAE,6CAA6C,CAAC,IAAI,CAAC,cAAc,CAAC;YAC7E,QAAQ,EAAE,WAAW,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,oBAAoB,CAAC,IAAI,CAAC,cAAc,CAAC;SACxF,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,SAAS,oBAAoB,CAAC,IAAY,EAAE,QAAgB;IAC1D,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,sEAAsE;IACtE,gDAAgD;IAChD,qEAAqE;IACrE,4DAA4D;IAC5D,MAAM,EAAE,GAAG,mJAAmJ,CAAC;IAC/J,IAAI,CAAyB,CAAC;IAC9B,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAClB,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAClB,MAAM,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACvB,wEAAwE;QACxE,IAAI,EAAsB,CAAC;QAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAC1D,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;QACrE,IAAI,KAAK;YAAE,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;aACpB,IAAI,MAAM;YAAE,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;aAC3B,IAAI,SAAS;YAAE,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QACtC,IAAI,CAAC,EAAE;YAAE,SAAS;QAElB,IAAI,IAAmC,CAAC;QACxC,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,SAAS;YAAE,IAAI,GAAG,SAAS,CAAC;aAC5D,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,WAAW;YAAE,IAAI,GAAG,WAAW,CAAC;aACrE,IAAI,IAAI,KAAK,UAAU,IAAI,IAAI,KAAK,QAAQ;YAAE,IAAI,GAAG,QAAQ,CAAC;;YAC9D,IAAI,GAAG,YAAY,CAAC;QAEzB,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,SAAS,UAAU,CACjB,QAAgB,EAChB,SAAiB,EACjB,OAAe;IAEf,IAAI,CAAC,SAAS,IAAI,CAAC,OAAO,IAAI,OAAO,IAAI,SAAS;QAAE,OAAO,IAAI,CAAC;IAChE,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,SAAS,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAC/C,MAAM,YAAY,GAAG,SAAS,GAAG,CAAC,CAAC;IAEnC,MAAM,cAAc,GAAa,EAAE,CAAC;IACpC,iFAAiF;IACjF,iFAAiF;IACjF,gFAAgF;IAChF,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,KAAK,IAAI,CAAC,GAAG,YAAY,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,YAAY,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QACrE,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;QAC/C,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;QAChD,UAAU,IAAI,MAAM,GAAG,KAAK,CAAC;QAC7B,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACvB,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC7B,oFAAoF;YACpF,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,UAAU,GAAG,CAAC;gBAAE,SAAS;YACrF,oEAAoE;YACpE,SAAS;QACX,CAAC;QACD,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;YACnB,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC7B,SAAS;QACX,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAChC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC7B,SAAS;QACX,CAAC;QACD,gEAAgE;QAChE,MAAM;IACR,CAAC;IAED,+DAA+D;IAC/D,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvF,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Behavior step classifier — turns method-body walker output into a
|
|
3
|
+
* structured candidate-step timeline that the analyse LLM can refine
|
|
4
|
+
* into spec `behaviors[].steps[]` blocks. Implements Phase 2 of #27.
|
|
5
|
+
*
|
|
6
|
+
* The classifier is a "soft oracle" (per the
|
|
7
|
+
* 2026-04-26-BEHAVIOR-EXTRACTION-FOR-ANALYSE.md proposal): it labels
|
|
8
|
+
* what the patterns clearly say and falls through to `kind: 'call'` /
|
|
9
|
+
* `kind: 'compute'` for unclassifiable lines. The LLM filters / merges /
|
|
10
|
+
* refines the output into the final spec vocabulary.
|
|
11
|
+
*
|
|
12
|
+
* Why classification matters: pre-classifier the LLM sees raw method
|
|
13
|
+
* bodies (200 lines, lots of boilerplate). With it, the LLM sees
|
|
14
|
+
* "this method does {find, validate, create, emit, return}" — a
|
|
15
|
+
* structured anchor it can map to spec language without inventing.
|
|
16
|
+
*
|
|
17
|
+
* Step kinds (the categorical vocabulary):
|
|
18
|
+
* - `find` — read a record by key (`repo.findOne`, `findOneByField`)
|
|
19
|
+
* - `find-many` — read a collection (`repo.find()`, `findAll()`)
|
|
20
|
+
* - `create` — write a new record (`repo.save(create(...))`, `insertOne`)
|
|
21
|
+
* - `update` — mutate an existing record (`repo.update`, `updateOneById`)
|
|
22
|
+
* - `delete` — remove a record (`repo.delete`, `deleteOneById`)
|
|
23
|
+
* - `transition` — change a lifecycle state (assignment to enum-typed field)
|
|
24
|
+
* - `emit` — publish an event (`eventBus.emit/publish/dispatch`)
|
|
25
|
+
* - `validate` — precondition guard or throw outside a guard
|
|
26
|
+
* - `call` — invoke a service method (not repo, not eventBus)
|
|
27
|
+
* - `return` — explicit return (kept for completeness; the analyse
|
|
28
|
+
* layer usually folds this into the behavior's
|
|
29
|
+
* `returns:` declaration rather than a step)
|
|
30
|
+
*
|
|
31
|
+
* Open question (deferred to next phase): merging adjacent related
|
|
32
|
+
* steps (`repo.create + repo.save` = one `create`). For now the
|
|
33
|
+
* classifier emits both — the LLM can collapse.
|
|
34
|
+
*/
|
|
35
|
+
export type CandidateStepKind = 'find' | 'find-many' | 'create' | 'update' | 'delete' | 'transition' | 'emit' | 'validate' | 'call' | 'return';
|
|
36
|
+
export interface CandidateStep {
|
|
37
|
+
/** Categorical kind — see header for vocabulary. */
|
|
38
|
+
kind: CandidateStepKind;
|
|
39
|
+
/** Source position within the method body (for ordering across kinds). */
|
|
40
|
+
position: number;
|
|
41
|
+
/** Human-readable single-line summary of the step (fed to the LLM). */
|
|
42
|
+
summary: string;
|
|
43
|
+
/** For `find` / `find-many` / `create` / `update` / `delete`. */
|
|
44
|
+
entity?: string;
|
|
45
|
+
/** For `find` — the field used to look up. */
|
|
46
|
+
byField?: string;
|
|
47
|
+
/** For `transition`. */
|
|
48
|
+
transition?: {
|
|
49
|
+
field: string;
|
|
50
|
+
toState: string;
|
|
51
|
+
};
|
|
52
|
+
/** For `emit`. */
|
|
53
|
+
event?: string;
|
|
54
|
+
/** For `validate` — what the precondition asserts. */
|
|
55
|
+
precondition?: string;
|
|
56
|
+
/** For `call` — the receiver + method (`PaymentService.charge`). */
|
|
57
|
+
callTarget?: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Per-method classification result. The same shape `walkMethodBodies`
|
|
61
|
+
* returns, plus the `candidates` field — useful for IDE-like contexts
|
|
62
|
+
* that want both the raw facts AND the classified output.
|
|
63
|
+
*/
|
|
64
|
+
export interface MethodCandidates {
|
|
65
|
+
methodName: string;
|
|
66
|
+
isAsync: boolean;
|
|
67
|
+
/** Raw body source — passed through from the walker for downstream
|
|
68
|
+
* cross-validation. */
|
|
69
|
+
body: string;
|
|
70
|
+
candidates: CandidateStep[];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Walk a class body and return per-method candidate-step timelines.
|
|
74
|
+
* Each method's candidates are ordered by source position so the
|
|
75
|
+
* timeline reflects execution order.
|
|
76
|
+
*
|
|
77
|
+
* `lifecycleField` (optional) — when known, assignments to this field
|
|
78
|
+
* are classified as `transition` rather than generic `call`/`update`.
|
|
79
|
+
* Pass it from the lifecycle-detection pass (see
|
|
80
|
+
* typescript-decorators.ts).
|
|
81
|
+
*/
|
|
82
|
+
export declare function extractCandidateSteps(classBody: string, options?: {
|
|
83
|
+
lifecycleField?: string;
|
|
84
|
+
}): MethodCandidates[];
|
|
85
|
+
//# sourceMappingURL=behavior-step-classifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"behavior-step-classifier.d.ts","sourceRoot":"","sources":["../../src/analyse-prepass/behavior-step-classifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAIH,MAAM,MAAM,iBAAiB,GACzB,MAAM,GACN,WAAW,GACX,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,YAAY,GACZ,MAAM,GACN,UAAU,GACV,MAAM,GACN,QAAQ,CAAC;AAEb,MAAM,WAAW,aAAa;IAC5B,oDAAoD;IACpD,IAAI,EAAE,iBAAiB,CAAC;IACxB,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAC;IAKhB,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wBAAwB;IACxB,UAAU,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,kBAAkB;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB;4BACwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,aAAa,EAAE,CAAC;CAC7B;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IAAE,cAAc,CAAC,EAAE,MAAM,CAAA;CAAO,GACxC,gBAAgB,EAAE,CAkGpB"}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Behavior step classifier — turns method-body walker output into a
|
|
3
|
+
* structured candidate-step timeline that the analyse LLM can refine
|
|
4
|
+
* into spec `behaviors[].steps[]` blocks. Implements Phase 2 of #27.
|
|
5
|
+
*
|
|
6
|
+
* The classifier is a "soft oracle" (per the
|
|
7
|
+
* 2026-04-26-BEHAVIOR-EXTRACTION-FOR-ANALYSE.md proposal): it labels
|
|
8
|
+
* what the patterns clearly say and falls through to `kind: 'call'` /
|
|
9
|
+
* `kind: 'compute'` for unclassifiable lines. The LLM filters / merges /
|
|
10
|
+
* refines the output into the final spec vocabulary.
|
|
11
|
+
*
|
|
12
|
+
* Why classification matters: pre-classifier the LLM sees raw method
|
|
13
|
+
* bodies (200 lines, lots of boilerplate). With it, the LLM sees
|
|
14
|
+
* "this method does {find, validate, create, emit, return}" — a
|
|
15
|
+
* structured anchor it can map to spec language without inventing.
|
|
16
|
+
*
|
|
17
|
+
* Step kinds (the categorical vocabulary):
|
|
18
|
+
* - `find` — read a record by key (`repo.findOne`, `findOneByField`)
|
|
19
|
+
* - `find-many` — read a collection (`repo.find()`, `findAll()`)
|
|
20
|
+
* - `create` — write a new record (`repo.save(create(...))`, `insertOne`)
|
|
21
|
+
* - `update` — mutate an existing record (`repo.update`, `updateOneById`)
|
|
22
|
+
* - `delete` — remove a record (`repo.delete`, `deleteOneById`)
|
|
23
|
+
* - `transition` — change a lifecycle state (assignment to enum-typed field)
|
|
24
|
+
* - `emit` — publish an event (`eventBus.emit/publish/dispatch`)
|
|
25
|
+
* - `validate` — precondition guard or throw outside a guard
|
|
26
|
+
* - `call` — invoke a service method (not repo, not eventBus)
|
|
27
|
+
* - `return` — explicit return (kept for completeness; the analyse
|
|
28
|
+
* layer usually folds this into the behavior's
|
|
29
|
+
* `returns:` declaration rather than a step)
|
|
30
|
+
*
|
|
31
|
+
* Open question (deferred to next phase): merging adjacent related
|
|
32
|
+
* steps (`repo.create + repo.save` = one `create`). For now the
|
|
33
|
+
* classifier emits both — the LLM can collapse.
|
|
34
|
+
*/
|
|
35
|
+
import { walkMethodBodies } from './method-body-walker.js';
|
|
36
|
+
/**
|
|
37
|
+
* Walk a class body and return per-method candidate-step timelines.
|
|
38
|
+
* Each method's candidates are ordered by source position so the
|
|
39
|
+
* timeline reflects execution order.
|
|
40
|
+
*
|
|
41
|
+
* `lifecycleField` (optional) — when known, assignments to this field
|
|
42
|
+
* are classified as `transition` rather than generic `call`/`update`.
|
|
43
|
+
* Pass it from the lifecycle-detection pass (see
|
|
44
|
+
* typescript-decorators.ts).
|
|
45
|
+
*/
|
|
46
|
+
export function extractCandidateSteps(classBody, options = {}) {
|
|
47
|
+
const methods = walkMethodBodies(classBody);
|
|
48
|
+
const out = [];
|
|
49
|
+
for (const method of methods) {
|
|
50
|
+
const candidates = [];
|
|
51
|
+
// Each fact contributes 0 or 1 candidate steps. Push, then sort by
|
|
52
|
+
// position to merge across kinds.
|
|
53
|
+
for (const guard of method.guards) {
|
|
54
|
+
if (guard.throws) {
|
|
55
|
+
// Guard with throw = precondition.
|
|
56
|
+
candidates.push({
|
|
57
|
+
kind: 'validate',
|
|
58
|
+
position: guard.position,
|
|
59
|
+
summary: `Validate this.${guard.field} ${guard.op === '!==' || guard.op === '!=' ? '==' : '!='} ${guard.valueExpr}`,
|
|
60
|
+
precondition: `this.${guard.field} ${guard.op === '!==' || guard.op === '!=' ? '==' : '!='} ${guard.valueExpr}`,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
for (const throwStmt of method.throws) {
|
|
65
|
+
// Top-level throws (not inside an extracted guard) are also
|
|
66
|
+
// preconditions, but they may be reported alongside their guard's
|
|
67
|
+
// throw classification above. Deduplication-by-position would be
|
|
68
|
+
// more correct; for the soft-oracle stance, accept some redundancy
|
|
69
|
+
// and let downstream merge.
|
|
70
|
+
candidates.push({
|
|
71
|
+
kind: 'validate',
|
|
72
|
+
position: throwStmt.position,
|
|
73
|
+
summary: `Throw ${throwStmt.errorClass ?? 'Error'}${throwStmt.argsExpr ? ' (' + throwStmt.argsExpr + ')' : ''}`,
|
|
74
|
+
precondition: throwStmt.argsExpr,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
for (const assignment of method.thisAssignments) {
|
|
78
|
+
if (options.lifecycleField && assignment.field === options.lifecycleField && assignment.enumMember) {
|
|
79
|
+
candidates.push({
|
|
80
|
+
kind: 'transition',
|
|
81
|
+
position: assignment.position,
|
|
82
|
+
summary: `Transition this.${assignment.field} to ${assignment.enumMember}`,
|
|
83
|
+
transition: {
|
|
84
|
+
field: assignment.field,
|
|
85
|
+
toState: assignment.enumMember,
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
// Non-lifecycle assignments fall through (not a step on their own).
|
|
90
|
+
}
|
|
91
|
+
for (const call of method.calls) {
|
|
92
|
+
const classified = classifyCall(call);
|
|
93
|
+
if (classified) {
|
|
94
|
+
candidates.push({
|
|
95
|
+
...classified,
|
|
96
|
+
position: call.position,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
for (const ret of method.returns) {
|
|
101
|
+
// Skip the trivial implicit `return;` — only emit when there's a
|
|
102
|
+
// real value being returned (the analyse layer folds these into
|
|
103
|
+
// the behavior's `returns:` declaration usually).
|
|
104
|
+
if (ret.valueExpr) {
|
|
105
|
+
candidates.push({
|
|
106
|
+
kind: 'return',
|
|
107
|
+
position: ret.position,
|
|
108
|
+
summary: `Return ${truncate(ret.valueExpr, 80)}`,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
candidates.sort((a, b) => a.position - b.position);
|
|
113
|
+
// Deduplicate exact-position pairs (a `validate` from a guard often
|
|
114
|
+
// co-locates with its throw inside the guard body; the throw alone
|
|
115
|
+
// gets reported, the guard already covered the precondition).
|
|
116
|
+
const deduped = [];
|
|
117
|
+
for (const step of candidates) {
|
|
118
|
+
const last = deduped[deduped.length - 1];
|
|
119
|
+
if (last && last.kind === 'validate' && step.kind === 'validate'
|
|
120
|
+
&& Math.abs(last.position - step.position) < 5) {
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
deduped.push(step);
|
|
124
|
+
}
|
|
125
|
+
out.push({
|
|
126
|
+
methodName: method.methodName,
|
|
127
|
+
isAsync: method.isAsync,
|
|
128
|
+
body: method.body,
|
|
129
|
+
candidates: deduped,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
return out;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Classify a single method call into a CandidateStep (or null if the
|
|
136
|
+
* call shouldn't surface as a step — e.g. utility helpers like
|
|
137
|
+
* `Object.assign`, `Array.from`).
|
|
138
|
+
*
|
|
139
|
+
* Soft-oracle stance: when in doubt, classify as `call` rather than
|
|
140
|
+
* trying to be clever. The LLM has the call shape + receiver name and
|
|
141
|
+
* can collapse / refine.
|
|
142
|
+
*/
|
|
143
|
+
function classifyCall(call) {
|
|
144
|
+
const receiver = call.receiver;
|
|
145
|
+
const method = call.method;
|
|
146
|
+
const args = call.argsExpr;
|
|
147
|
+
// Skip JS stdlib utility invocations (no business value).
|
|
148
|
+
if (/^(Object|Array|JSON|Math|Date|Number|String|Boolean|RegExp)$/.test(receiver)) {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
// EventBus / Subject-style emissions.
|
|
152
|
+
if (/(?:^|\.)eventBus$/i.test(receiver) && /^(emit|publish|dispatch|fire)$/i.test(method)) {
|
|
153
|
+
const event = parseFirstStringArg(args);
|
|
154
|
+
return {
|
|
155
|
+
kind: 'emit',
|
|
156
|
+
summary: event ? `Emit ${event} event` : `Emit event (${truncate(args, 60)})`,
|
|
157
|
+
event: event ?? undefined,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
// RxJS-style: `subject.next('Foo', payload)` — heuristic, often used
|
|
161
|
+
// for events too. Receiver name often ends in `Subject` or contains
|
|
162
|
+
// `Bus` / `Stream` / `EventEmitter`.
|
|
163
|
+
if (/(?:Subject|Bus|Stream|Emitter)$/.test(receiver) && /^(next|emit|publish|fire|dispatch)$/i.test(method)) {
|
|
164
|
+
const event = parseFirstStringArg(args);
|
|
165
|
+
return {
|
|
166
|
+
kind: 'emit',
|
|
167
|
+
summary: event ? `Emit ${event} event` : `Emit event via ${receiver}.${method}`,
|
|
168
|
+
event: event ?? undefined,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
// Repository-pattern reads (TypeORM `repo.findOne`, Mongo
|
|
172
|
+
// `getCollection().findOne`, pg `findOneByField`).
|
|
173
|
+
if (/^(findOne|findOneBy|findOneByOrFail|findById|getById)$/i.test(method)) {
|
|
174
|
+
const entity = guessEntityFromReceiver(receiver);
|
|
175
|
+
return {
|
|
176
|
+
kind: 'find',
|
|
177
|
+
summary: `Find ${entity ?? '?'}${args ? ' by ' + truncate(args, 40) : ''}`,
|
|
178
|
+
entity,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
if (/^(findOneByField)$/.test(method)) {
|
|
182
|
+
return {
|
|
183
|
+
kind: 'find',
|
|
184
|
+
summary: `Find ${args ? truncate(args, 80) : 'record'}`,
|
|
185
|
+
entity: parseFirstStringArg(args) ?? undefined,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
if (/^(find|findAll|findMany|all|list|search)$/i.test(method)) {
|
|
189
|
+
const entity = guessEntityFromReceiver(receiver);
|
|
190
|
+
return {
|
|
191
|
+
kind: 'find-many',
|
|
192
|
+
summary: `Find ${entity ?? 'records'}${args ? ' (' + truncate(args, 40) + ')' : ''}`,
|
|
193
|
+
entity,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
// Repository-pattern writes.
|
|
197
|
+
if (/^(create|save|persist|insert|insertOne)$/i.test(method)) {
|
|
198
|
+
const entity = guessEntityFromReceiver(receiver) ?? parseFirstStringArg(args) ?? undefined;
|
|
199
|
+
return {
|
|
200
|
+
kind: 'create',
|
|
201
|
+
summary: `Create ${entity ?? 'record'}`,
|
|
202
|
+
entity,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
if (/^(insertMany)$/i.test(method)) {
|
|
206
|
+
return {
|
|
207
|
+
kind: 'create',
|
|
208
|
+
summary: `Bulk create records`,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
if (/^(update|updateOne|updateOneById|updateMany|patch)$/i.test(method)) {
|
|
212
|
+
const entity = guessEntityFromReceiver(receiver) ?? parseFirstStringArg(args) ?? undefined;
|
|
213
|
+
return {
|
|
214
|
+
kind: 'update',
|
|
215
|
+
summary: `Update ${entity ?? 'record'}`,
|
|
216
|
+
entity,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
if (/^(delete|deleteOne|deleteOneById|deleteMany|remove|destroy)$/i.test(method)) {
|
|
220
|
+
const entity = guessEntityFromReceiver(receiver) ?? parseFirstStringArg(args) ?? undefined;
|
|
221
|
+
return {
|
|
222
|
+
kind: 'delete',
|
|
223
|
+
summary: `Delete ${entity ?? 'record'}`,
|
|
224
|
+
entity,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
// Mongo native — `getCollection('name')` followed by `.findOne` etc.
|
|
228
|
+
// The walker reports these as separate calls; the find/create/update
|
|
229
|
+
// patterns above already cover the second leg.
|
|
230
|
+
// Anything else is a generic call (likely a service method).
|
|
231
|
+
return {
|
|
232
|
+
kind: 'call',
|
|
233
|
+
summary: `Call ${receiver}.${method}${args ? '(' + truncate(args, 40) + ')' : '()'}`,
|
|
234
|
+
callTarget: `${receiver}.${method}`,
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Best-effort entity name extraction from a receiver expression.
|
|
239
|
+
* `this.invoiceRepo` → `Invoice`. `this.payments` → `Payment`. Returns
|
|
240
|
+
* undefined when no clean inference is possible.
|
|
241
|
+
*/
|
|
242
|
+
function guessEntityFromReceiver(receiver) {
|
|
243
|
+
// Strip `this.` prefix.
|
|
244
|
+
const tail = receiver.replace(/^this\./, '');
|
|
245
|
+
// Last segment of dotted access.
|
|
246
|
+
const last = tail.split('.').pop() ?? tail;
|
|
247
|
+
// Common suffixes: Repo, Repository, Service, Bus, Manager. Strip them.
|
|
248
|
+
const trimmed = last.replace(/(?:Repo|Repository|Service|Bus|Manager|Store|Dao)$/i, '');
|
|
249
|
+
if (!trimmed)
|
|
250
|
+
return undefined;
|
|
251
|
+
// Pluralized — drop trailing s if Capitalised collection (e.g. `users` → `User`).
|
|
252
|
+
const singular = /^[a-z]+s$/.test(trimmed) ? trimmed.slice(0, -1) : trimmed;
|
|
253
|
+
// Capitalize first letter.
|
|
254
|
+
return singular.charAt(0).toUpperCase() + singular.slice(1);
|
|
255
|
+
}
|
|
256
|
+
/** Parse the first argument's string-literal value, if any. */
|
|
257
|
+
function parseFirstStringArg(args) {
|
|
258
|
+
const m = args.match(/^\s*['"]([^'"]+)['"]/);
|
|
259
|
+
return m ? m[1] : null;
|
|
260
|
+
}
|
|
261
|
+
function truncate(s, max) {
|
|
262
|
+
if (s.length <= max)
|
|
263
|
+
return s;
|
|
264
|
+
return s.slice(0, max - 1) + '…';
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=behavior-step-classifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"behavior-step-classifier.js","sourceRoot":"","sources":["../../src/analyse-prepass/behavior-step-classifier.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,6 +20,8 @@ import { type BackendName } from './backends/index.js';
|
|
|
20
20
|
import type { StructuralPrepass, MethodFactSheet } from './interface.js';
|
|
21
21
|
import type { ComponentSuggestion } from './community-detection.js';
|
|
22
22
|
export type { ComponentSuggestion } from './community-detection.js';
|
|
23
|
+
export { walkMethodBodies, type MethodBodyFacts, type ThisAssignment, type ThisGuard, type MethodCall, type ThrowStmt, type ReturnStmt, } from './method-body-walker.js';
|
|
24
|
+
export { extractCandidateSteps, type CandidateStep, type CandidateStepKind, type MethodCandidates, } from './behavior-step-classifier.js';
|
|
23
25
|
/**
|
|
24
26
|
* Normalised attribute shape — a per-adapter superset that consumers
|
|
25
27
|
* can rely on regardless of which framework the source code uses. Each
|
|
@@ -70,6 +72,21 @@ export interface SpecVerseFacts {
|
|
|
70
72
|
model: string;
|
|
71
73
|
field: string;
|
|
72
74
|
states: string[];
|
|
75
|
+
/**
|
|
76
|
+
* Inferred state-machine transitions — populated by the
|
|
77
|
+
* typescript-decorators adapter via `method-body-walker.ts` when
|
|
78
|
+
* instance methods follow the `if (this.field !== X) throw; this.field = Y;`
|
|
79
|
+
* pattern. Each transition's `from` is the array of source states the
|
|
80
|
+
* method allows (computed from the guard), `to` is the assignment
|
|
81
|
+
* target, `action` is the method name. Empty when no methods match
|
|
82
|
+
* the pattern. Cross-method composite transitions and complex flow
|
|
83
|
+
* control (ternaries, switch statements) fall through to the LLM.
|
|
84
|
+
*/
|
|
85
|
+
transitions?: Array<{
|
|
86
|
+
action: string;
|
|
87
|
+
from: string[];
|
|
88
|
+
to: string;
|
|
89
|
+
}>;
|
|
73
90
|
}>;
|
|
74
91
|
/** Provenance: which adapter(s) ran, what backend was used. */
|
|
75
92
|
meta: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analyse-prepass/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,YAAY,EACV,iBAAiB,EACjB,MAAM,EACN,MAAM,EACN,YAAY,EACZ,UAAU,EACV,WAAW,EACX,YAAY,EACZ,eAAe,EACf,WAAW,EACX,eAAe,GAChB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,KAAK,WAAW,GACjB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,uBAAuB,EACvB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,cAAc,GACpB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAiB,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEzE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAEpE,YAAY,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analyse-prepass/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,14 @@ export { extractTypeScriptPrisma, } from './adapters/index.js';
|
|
|
3
3
|
import { selectBackend } from './backends/index.js';
|
|
4
4
|
import { extractTypeScriptPrisma } from './adapters/index.js';
|
|
5
5
|
import { formatSuggestionsAsMarkdown } from './community-detection.js';
|
|
6
|
+
// #27-A: method-body walker — per-method facts (assignments, guards,
|
|
7
|
+
// calls, throws, returns) for entity classes. Foundation for behavior
|
|
8
|
+
// step extraction (#27-B) and lifecycle transition graphs (#28-lifecycle B).
|
|
9
|
+
export { walkMethodBodies, } from './method-body-walker.js';
|
|
10
|
+
// #27-B: behavior step classifier — turns walker output into ordered
|
|
11
|
+
// CandidateStep timeline that the analyse LLM refines into spec
|
|
12
|
+
// behaviors[].steps[] blocks.
|
|
13
|
+
export { extractCandidateSteps, } from './behavior-step-classifier.js';
|
|
6
14
|
/**
|
|
7
15
|
* Run the structural pre-pass on a source directory.
|
|
8
16
|
*
|
|
@@ -101,6 +109,7 @@ export async function runPrepass(sourceDir, options = {}) {
|
|
|
101
109
|
model: lc.model,
|
|
102
110
|
field: lc.field,
|
|
103
111
|
states: lc.states,
|
|
112
|
+
transitions: lc.transitions,
|
|
104
113
|
});
|
|
105
114
|
}
|
|
106
115
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analyse-prepass/index.ts"],"names":[],"mappings":"AA4BA,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,aAAa,GAEd,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,uBAAuB,GAKxB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,aAAa,EAAoB,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analyse-prepass/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Method-body walker — shared infrastructure for #27 (behavior step
|
|
3
|
+
* extraction) and #28-lifecycle Tier B (transition graph extraction).
|
|
4
|
+
*
|
|
5
|
+
* Given a class body string, produces per-method fact sheets: each
|
|
6
|
+
* method's `this.X = Y` assignments, `if (this.X op Y) throw` guards,
|
|
7
|
+
* external calls, throws, and explicit returns. The walker itself is
|
|
8
|
+
* pattern-matching only — interpretation (which call is a "step", how
|
|
9
|
+
* a guard pairs with an assignment to form a transition) is the
|
|
10
|
+
* caller's responsibility.
|
|
11
|
+
*
|
|
12
|
+
* Language assumption: TypeScript / JavaScript. Relies on regex-based
|
|
13
|
+
* parsing rather than a full AST walker — pragmatic for the patterns
|
|
14
|
+
* we care about (decorator-style classes with method bodies that
|
|
15
|
+
* follow the realize-stack discipline). When this stops being enough
|
|
16
|
+
* (genuinely complex flow control, ternary state mutations, etc.) we
|
|
17
|
+
* upgrade to tree-sitter via the CodeGraph backend.
|
|
18
|
+
*
|
|
19
|
+
* NOT intended to be exhaustive. The "soft oracle" stance from
|
|
20
|
+
* 2026-04-26-BEHAVIOR-EXTRACTION-FOR-ANALYSE.md applies: extract what
|
|
21
|
+
* the patterns clearly say, fall through to LLM for the rest.
|
|
22
|
+
*/
|
|
23
|
+
/** Per-method extracted facts. Empty arrays when no matches found. */
|
|
24
|
+
export interface MethodBodyFacts {
|
|
25
|
+
/** Method name as declared on the class. */
|
|
26
|
+
methodName: string;
|
|
27
|
+
/** Raw body source — for cross-validation against LLM extraction. */
|
|
28
|
+
body: string;
|
|
29
|
+
/** Async marker. */
|
|
30
|
+
isAsync: boolean;
|
|
31
|
+
/** `this.<field> = <expr>` assignments. */
|
|
32
|
+
thisAssignments: ThisAssignment[];
|
|
33
|
+
/** `if (this.<field> [!=|==|!==|===] <expr>)` style guards.
|
|
34
|
+
* `throws` is true when the guard's body is a throw statement
|
|
35
|
+
* (the common precondition pattern). */
|
|
36
|
+
guards: ThisGuard[];
|
|
37
|
+
/** `await foo.bar(...)` / `obj.method(...)` invocations.
|
|
38
|
+
* Excludes calls inside string literals or comments (cheap
|
|
39
|
+
* best-effort: a literal containing `foo.bar()` text won't be
|
|
40
|
+
* scanned thanks to the comment/string stripping pass). */
|
|
41
|
+
calls: MethodCall[];
|
|
42
|
+
/** `throw new Error('...')` / `throw new SomeError('...')`. */
|
|
43
|
+
throws: ThrowStmt[];
|
|
44
|
+
/** Explicit `return <expr>;` statements. */
|
|
45
|
+
returns: ReturnStmt[];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Positional metadata shared by all walker outputs. `position` is the
|
|
49
|
+
* byte offset of the match within the method body (NOT the class body),
|
|
50
|
+
* so consumers can order events across the per-kind arrays into a
|
|
51
|
+
* single timeline. Used by `behavior-step-classifier.ts` (#27-B).
|
|
52
|
+
*/
|
|
53
|
+
interface Positioned {
|
|
54
|
+
position: number;
|
|
55
|
+
}
|
|
56
|
+
export interface ThisAssignment extends Positioned {
|
|
57
|
+
/** Field being assigned (`status` in `this.status = X`). */
|
|
58
|
+
field: string;
|
|
59
|
+
/** Raw RHS expression as text. */
|
|
60
|
+
valueExpr: string;
|
|
61
|
+
/** When the RHS is `<EnumName>.<Member>`, the parsed parts. */
|
|
62
|
+
enumName?: string;
|
|
63
|
+
enumMember?: string;
|
|
64
|
+
}
|
|
65
|
+
export interface ThisGuard extends Positioned {
|
|
66
|
+
field: string;
|
|
67
|
+
/** Comparison operator as written in source. */
|
|
68
|
+
op: '!=' | '==' | '!==' | '===';
|
|
69
|
+
/** RHS of the comparison. */
|
|
70
|
+
valueExpr: string;
|
|
71
|
+
enumName?: string;
|
|
72
|
+
enumMember?: string;
|
|
73
|
+
/** True when the guard's body contains a `throw` statement
|
|
74
|
+
* (the load-bearing pattern for preconditions). */
|
|
75
|
+
throws: boolean;
|
|
76
|
+
}
|
|
77
|
+
export interface MethodCall extends Positioned {
|
|
78
|
+
/** Receiver expression — `this.repo` in `this.repo.save(...)`,
|
|
79
|
+
* `eventBus` in `eventBus.emit(...)`. */
|
|
80
|
+
receiver: string;
|
|
81
|
+
/** Method name being called. */
|
|
82
|
+
method: string;
|
|
83
|
+
/** Raw argument text (no parsing). */
|
|
84
|
+
argsExpr: string;
|
|
85
|
+
/** True when the call site is `await ...`. */
|
|
86
|
+
isAwait: boolean;
|
|
87
|
+
}
|
|
88
|
+
export interface ThrowStmt extends Positioned {
|
|
89
|
+
/** Constructor name, if `throw new X(...)`. */
|
|
90
|
+
errorClass?: string;
|
|
91
|
+
/** Argument text — useful as a precondition explanation. */
|
|
92
|
+
argsExpr?: string;
|
|
93
|
+
}
|
|
94
|
+
export interface ReturnStmt extends Positioned {
|
|
95
|
+
/** Raw return expression text (or empty for bare `return;`). */
|
|
96
|
+
valueExpr: string;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Walk all methods in a class body, returning per-method facts.
|
|
100
|
+
*
|
|
101
|
+
* Method extraction is pattern-based: we match either
|
|
102
|
+
* - explicit `<methodName>(<params>): <ret> {` declarations, or
|
|
103
|
+
* - shorthand `<methodName>(<params>) {` (no return type)
|
|
104
|
+
* - `async <methodName>` and `public/private/protected` modifiers
|
|
105
|
+
*
|
|
106
|
+
* Constructor + property initialisers are skipped — only "real"
|
|
107
|
+
* methods. Tightening the body extraction (matching the exact closing
|
|
108
|
+
* brace via brace counting) keeps multi-method classes from crossing
|
|
109
|
+
* boundaries.
|
|
110
|
+
*/
|
|
111
|
+
export declare function walkMethodBodies(classBody: string): MethodBodyFacts[];
|
|
112
|
+
export {};
|
|
113
|
+
//# sourceMappingURL=method-body-walker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"method-body-walker.d.ts","sourceRoot":"","sources":["../../src/analyse-prepass/method-body-walker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,sEAAsE;AACtE,MAAM,WAAW,eAAe;IAC9B,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB;IACpB,OAAO,EAAE,OAAO,CAAC;IAEjB,2CAA2C;IAC3C,eAAe,EAAE,cAAc,EAAE,CAAC;IAElC;;6CAEyC;IACzC,MAAM,EAAE,SAAS,EAAE,CAAC;IAEpB;;;gEAG4D;IAC5D,KAAK,EAAE,UAAU,EAAE,CAAC;IAEpB,+DAA+D;IAC/D,MAAM,EAAE,SAAS,EAAE,CAAC;IAEpB,4CAA4C;IAC5C,OAAO,EAAE,UAAU,EAAE,CAAC;CACvB;AAED;;;;;GAKG;AACH,UAAU,UAAU;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAe,SAAQ,UAAU;IAChD,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,SAAU,SAAQ,UAAU;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,EAAE,EAAE,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,CAAC;IAChC,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;wDACoD;IACpD,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,UAAW,SAAQ,UAAU;IAC5C;8CAC0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,SAAU,SAAQ,UAAU;IAC3C,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAW,SAAQ,UAAU;IAC5C,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,EAAE,CAiErE"}
|
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Method-body walker — shared infrastructure for #27 (behavior step
|
|
3
|
+
* extraction) and #28-lifecycle Tier B (transition graph extraction).
|
|
4
|
+
*
|
|
5
|
+
* Given a class body string, produces per-method fact sheets: each
|
|
6
|
+
* method's `this.X = Y` assignments, `if (this.X op Y) throw` guards,
|
|
7
|
+
* external calls, throws, and explicit returns. The walker itself is
|
|
8
|
+
* pattern-matching only — interpretation (which call is a "step", how
|
|
9
|
+
* a guard pairs with an assignment to form a transition) is the
|
|
10
|
+
* caller's responsibility.
|
|
11
|
+
*
|
|
12
|
+
* Language assumption: TypeScript / JavaScript. Relies on regex-based
|
|
13
|
+
* parsing rather than a full AST walker — pragmatic for the patterns
|
|
14
|
+
* we care about (decorator-style classes with method bodies that
|
|
15
|
+
* follow the realize-stack discipline). When this stops being enough
|
|
16
|
+
* (genuinely complex flow control, ternary state mutations, etc.) we
|
|
17
|
+
* upgrade to tree-sitter via the CodeGraph backend.
|
|
18
|
+
*
|
|
19
|
+
* NOT intended to be exhaustive. The "soft oracle" stance from
|
|
20
|
+
* 2026-04-26-BEHAVIOR-EXTRACTION-FOR-ANALYSE.md applies: extract what
|
|
21
|
+
* the patterns clearly say, fall through to LLM for the rest.
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Walk all methods in a class body, returning per-method facts.
|
|
25
|
+
*
|
|
26
|
+
* Method extraction is pattern-based: we match either
|
|
27
|
+
* - explicit `<methodName>(<params>): <ret> {` declarations, or
|
|
28
|
+
* - shorthand `<methodName>(<params>) {` (no return type)
|
|
29
|
+
* - `async <methodName>` and `public/private/protected` modifiers
|
|
30
|
+
*
|
|
31
|
+
* Constructor + property initialisers are skipped — only "real"
|
|
32
|
+
* methods. Tightening the body extraction (matching the exact closing
|
|
33
|
+
* brace via brace counting) keeps multi-method classes from crossing
|
|
34
|
+
* boundaries.
|
|
35
|
+
*/
|
|
36
|
+
export function walkMethodBodies(classBody) {
|
|
37
|
+
const out = [];
|
|
38
|
+
// Find candidate method-declaration lines. Decorator-style params
|
|
39
|
+
// like `@Param('id') id: string` carry nested parens, so a naive
|
|
40
|
+
// `\([^)]*\)` regex stops at the first `)` and misses the method.
|
|
41
|
+
// Walk the source: match the START of a declaration, then balance
|
|
42
|
+
// parens forward to find the param-list close, then scan to `{`.
|
|
43
|
+
const startRe = /^\s*(?:public\s+|private\s+|protected\s+)?(?:static\s+)?(async\s+)?([a-zA-Z_$][\w$]*)\s*\(/gm;
|
|
44
|
+
let m;
|
|
45
|
+
while ((m = startRe.exec(classBody)) !== null) {
|
|
46
|
+
const isAsync = !!m[1];
|
|
47
|
+
const methodName = m[2];
|
|
48
|
+
if (methodName === 'constructor')
|
|
49
|
+
continue;
|
|
50
|
+
if (/^(if|for|while|switch|catch|return|new|typeof|throw|await|async)$/.test(methodName))
|
|
51
|
+
continue;
|
|
52
|
+
// Find matching close-paren for the param list (nested-paren aware).
|
|
53
|
+
const paramOpenIdx = m.index + m[0].length - 1; // position of `(`
|
|
54
|
+
const paramCloseIdx = findMatchingParen(classBody, paramOpenIdx);
|
|
55
|
+
if (paramCloseIdx < 0)
|
|
56
|
+
continue;
|
|
57
|
+
// After the close-paren, an optional return type annotation `: <type>`
|
|
58
|
+
// and then the opening `{` of the body. Skip whitespace + comments.
|
|
59
|
+
let i = paramCloseIdx + 1;
|
|
60
|
+
// Skip whitespace.
|
|
61
|
+
while (i < classBody.length && /\s/.test(classBody[i]))
|
|
62
|
+
i++;
|
|
63
|
+
// Skip optional return annotation (everything from `:` up to but not
|
|
64
|
+
// including the opening `{` — we tolerate union types, generics, etc.)
|
|
65
|
+
if (classBody[i] === ':') {
|
|
66
|
+
// Walk until we hit the first `{` at the top level (not inside
|
|
67
|
+
// <generic> or [array] or another type expression).
|
|
68
|
+
i++;
|
|
69
|
+
let angleDepth = 0;
|
|
70
|
+
let bracketDepth = 0;
|
|
71
|
+
while (i < classBody.length) {
|
|
72
|
+
const c = classBody[i];
|
|
73
|
+
if (c === '<')
|
|
74
|
+
angleDepth++;
|
|
75
|
+
else if (c === '>')
|
|
76
|
+
angleDepth--;
|
|
77
|
+
else if (c === '[')
|
|
78
|
+
bracketDepth++;
|
|
79
|
+
else if (c === ']')
|
|
80
|
+
bracketDepth--;
|
|
81
|
+
else if (c === '{' && angleDepth <= 0 && bracketDepth <= 0)
|
|
82
|
+
break;
|
|
83
|
+
else if (c === ';')
|
|
84
|
+
break; // type alias-ish — definitely not a method
|
|
85
|
+
i++;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (classBody[i] !== '{')
|
|
89
|
+
continue;
|
|
90
|
+
const bodyOpenIdx = i;
|
|
91
|
+
const bodyEnd = findMatchingBrace(classBody, bodyOpenIdx);
|
|
92
|
+
if (bodyEnd < 0)
|
|
93
|
+
continue;
|
|
94
|
+
const body = classBody.slice(bodyOpenIdx + 1, bodyEnd);
|
|
95
|
+
out.push({
|
|
96
|
+
methodName,
|
|
97
|
+
body,
|
|
98
|
+
isAsync,
|
|
99
|
+
thisAssignments: extractThisAssignments(body),
|
|
100
|
+
guards: extractGuards(body),
|
|
101
|
+
calls: extractCalls(body),
|
|
102
|
+
throws: extractThrows(body),
|
|
103
|
+
returns: extractReturns(body),
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
return out;
|
|
107
|
+
}
|
|
108
|
+
/** Find the index of the `)` matching the `(` at `openIdx`. -1 if not found.
|
|
109
|
+
* Same string + comment awareness as `findMatchingBrace`. */
|
|
110
|
+
function findMatchingParen(src, openIdx) {
|
|
111
|
+
let depth = 0;
|
|
112
|
+
let i = openIdx;
|
|
113
|
+
let stringChar = null;
|
|
114
|
+
let inLineComment = false;
|
|
115
|
+
let inBlockComment = false;
|
|
116
|
+
while (i < src.length) {
|
|
117
|
+
const c = src[i];
|
|
118
|
+
const n = src[i + 1];
|
|
119
|
+
if (inLineComment) {
|
|
120
|
+
if (c === '\n')
|
|
121
|
+
inLineComment = false;
|
|
122
|
+
i++;
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (inBlockComment) {
|
|
126
|
+
if (c === '*' && n === '/') {
|
|
127
|
+
inBlockComment = false;
|
|
128
|
+
i += 2;
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
i++;
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
if (stringChar !== null) {
|
|
135
|
+
if (c === '\\' && i + 1 < src.length) {
|
|
136
|
+
i += 2;
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
if (c === stringChar)
|
|
140
|
+
stringChar = null;
|
|
141
|
+
i++;
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
if (c === '/' && n === '/') {
|
|
145
|
+
inLineComment = true;
|
|
146
|
+
i += 2;
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (c === '/' && n === '*') {
|
|
150
|
+
inBlockComment = true;
|
|
151
|
+
i += 2;
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
if (c === '"' || c === "'" || c === '`') {
|
|
155
|
+
stringChar = c;
|
|
156
|
+
i++;
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
if (c === '(') {
|
|
160
|
+
depth++;
|
|
161
|
+
i++;
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
if (c === ')') {
|
|
165
|
+
depth--;
|
|
166
|
+
if (depth === 0)
|
|
167
|
+
return i;
|
|
168
|
+
i++;
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
i++;
|
|
172
|
+
}
|
|
173
|
+
return -1;
|
|
174
|
+
}
|
|
175
|
+
/** Find the index of the `}` matching the `{` at `openIdx`. -1 if not found.
|
|
176
|
+
* Tracks string literals + comments so embedded braces don't fool the count. */
|
|
177
|
+
function findMatchingBrace(src, openIdx) {
|
|
178
|
+
let depth = 0;
|
|
179
|
+
let i = openIdx;
|
|
180
|
+
let stringChar = null;
|
|
181
|
+
let inLineComment = false;
|
|
182
|
+
let inBlockComment = false;
|
|
183
|
+
while (i < src.length) {
|
|
184
|
+
const c = src[i];
|
|
185
|
+
const n = src[i + 1];
|
|
186
|
+
if (inLineComment) {
|
|
187
|
+
if (c === '\n')
|
|
188
|
+
inLineComment = false;
|
|
189
|
+
i++;
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
if (inBlockComment) {
|
|
193
|
+
if (c === '*' && n === '/') {
|
|
194
|
+
inBlockComment = false;
|
|
195
|
+
i += 2;
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
i++;
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
if (stringChar !== null) {
|
|
202
|
+
if (c === '\\' && i + 1 < src.length) {
|
|
203
|
+
i += 2;
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
if (c === stringChar)
|
|
207
|
+
stringChar = null;
|
|
208
|
+
i++;
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
// Outside string/comment.
|
|
212
|
+
if (c === '/' && n === '/') {
|
|
213
|
+
inLineComment = true;
|
|
214
|
+
i += 2;
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
if (c === '/' && n === '*') {
|
|
218
|
+
inBlockComment = true;
|
|
219
|
+
i += 2;
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
if (c === '"' || c === "'" || c === '`') {
|
|
223
|
+
stringChar = c;
|
|
224
|
+
i++;
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
if (c === '{') {
|
|
228
|
+
depth++;
|
|
229
|
+
i++;
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
if (c === '}') {
|
|
233
|
+
depth--;
|
|
234
|
+
if (depth === 0)
|
|
235
|
+
return i;
|
|
236
|
+
i++;
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
i++;
|
|
240
|
+
}
|
|
241
|
+
return -1;
|
|
242
|
+
}
|
|
243
|
+
/** Strip comments only — string contents are LEFT INTACT so captured
|
|
244
|
+
* RHS values like `'Sent'` survive the regex pass. The brace-balanced
|
|
245
|
+
* scan in `findMatchingBrace` is what handles string-aware structural
|
|
246
|
+
* parsing; this helper just kills comment noise.
|
|
247
|
+
*
|
|
248
|
+
* Trade-off: a string literal containing JS-syntax-shaped text (e.g.
|
|
249
|
+
* `const x = "this.status = 'Open';"` inside a string) will be scanned
|
|
250
|
+
* by the regex extractors. Acceptable for the realize-stack-style code
|
|
251
|
+
* we target — disciplined entity classes don't carry shape-shifted
|
|
252
|
+
* literals, and the soft-oracle stance is that the LLM filters
|
|
253
|
+
* occasional false positives downstream. */
|
|
254
|
+
function stripComments(src) {
|
|
255
|
+
let out = '';
|
|
256
|
+
let i = 0;
|
|
257
|
+
let stringChar = null;
|
|
258
|
+
let inLineComment = false;
|
|
259
|
+
let inBlockComment = false;
|
|
260
|
+
while (i < src.length) {
|
|
261
|
+
const c = src[i];
|
|
262
|
+
const n = src[i + 1];
|
|
263
|
+
if (inLineComment) {
|
|
264
|
+
if (c === '\n') {
|
|
265
|
+
inLineComment = false;
|
|
266
|
+
out += '\n';
|
|
267
|
+
}
|
|
268
|
+
else
|
|
269
|
+
out += ' ';
|
|
270
|
+
i++;
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
if (inBlockComment) {
|
|
274
|
+
if (c === '*' && n === '/') {
|
|
275
|
+
inBlockComment = false;
|
|
276
|
+
out += ' ';
|
|
277
|
+
i += 2;
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
out += c === '\n' ? '\n' : ' ';
|
|
281
|
+
i++;
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
// Inside a string — pass through unchanged (this is the diff from
|
|
285
|
+
// the previous "strip strings too" approach). Track escape pairs
|
|
286
|
+
// so a `\"` doesn't close the string early.
|
|
287
|
+
if (stringChar !== null) {
|
|
288
|
+
if (c === '\\' && i + 1 < src.length) {
|
|
289
|
+
out += c + src[i + 1];
|
|
290
|
+
i += 2;
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
if (c === stringChar)
|
|
294
|
+
stringChar = null;
|
|
295
|
+
out += c;
|
|
296
|
+
i++;
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
if (c === '/' && n === '/') {
|
|
300
|
+
inLineComment = true;
|
|
301
|
+
out += ' ';
|
|
302
|
+
i += 2;
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
305
|
+
if (c === '/' && n === '*') {
|
|
306
|
+
inBlockComment = true;
|
|
307
|
+
out += ' ';
|
|
308
|
+
i += 2;
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
if (c === '"' || c === "'" || c === '`') {
|
|
312
|
+
stringChar = c;
|
|
313
|
+
out += c;
|
|
314
|
+
i++;
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
out += c;
|
|
318
|
+
i++;
|
|
319
|
+
}
|
|
320
|
+
return out;
|
|
321
|
+
}
|
|
322
|
+
function extractThisAssignments(body) {
|
|
323
|
+
const cleaned = stripComments(body);
|
|
324
|
+
const out = [];
|
|
325
|
+
const re = /\bthis\.([a-zA-Z_$][\w$]*)\s*=(?!=)\s*([^;]+);/g;
|
|
326
|
+
let m;
|
|
327
|
+
while ((m = re.exec(cleaned)) !== null) {
|
|
328
|
+
const field = m[1];
|
|
329
|
+
const valueExpr = m[2].trim();
|
|
330
|
+
const enumMatch = valueExpr.match(/^([A-Z][\w$]*)\.([A-Z][\w$]*)\b/);
|
|
331
|
+
out.push({
|
|
332
|
+
position: m.index,
|
|
333
|
+
field,
|
|
334
|
+
valueExpr,
|
|
335
|
+
enumName: enumMatch?.[1],
|
|
336
|
+
enumMember: enumMatch?.[2],
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
return out;
|
|
340
|
+
}
|
|
341
|
+
function extractGuards(body) {
|
|
342
|
+
const cleaned = stripComments(body);
|
|
343
|
+
const out = [];
|
|
344
|
+
const re = /\bif\s*\(\s*this\.([a-zA-Z_$][\w$]*)\s*(!==|===|!=|==)\s*([^)]+?)\s*\)\s*([{][^}]*[}]|[^;{}]+;)/g;
|
|
345
|
+
let m;
|
|
346
|
+
while ((m = re.exec(cleaned)) !== null) {
|
|
347
|
+
const field = m[1];
|
|
348
|
+
const op = m[2];
|
|
349
|
+
const valueExpr = m[3].trim();
|
|
350
|
+
const guardBody = m[4];
|
|
351
|
+
const throws = /\bthrow\b/.test(guardBody);
|
|
352
|
+
const enumMatch = valueExpr.match(/^([A-Z][\w$]*)\.([A-Z][\w$]*)\b/);
|
|
353
|
+
out.push({
|
|
354
|
+
position: m.index,
|
|
355
|
+
field,
|
|
356
|
+
op,
|
|
357
|
+
valueExpr,
|
|
358
|
+
enumName: enumMatch?.[1],
|
|
359
|
+
enumMember: enumMatch?.[2],
|
|
360
|
+
throws,
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
return out;
|
|
364
|
+
}
|
|
365
|
+
function extractCalls(body) {
|
|
366
|
+
const cleaned = stripComments(body);
|
|
367
|
+
const out = [];
|
|
368
|
+
const re = /(\bawait\s+)?((?:this|[a-zA-Z_$][\w$]*)(?:\.[a-zA-Z_$][\w$]*)*)\.([a-zA-Z_$][\w$]*)\s*\(([^()]*(?:\([^()]*\)[^()]*)*)\)/g;
|
|
369
|
+
let m;
|
|
370
|
+
while ((m = re.exec(cleaned)) !== null) {
|
|
371
|
+
const isAwait = !!m[1];
|
|
372
|
+
const receiver = m[2];
|
|
373
|
+
const method = m[3];
|
|
374
|
+
out.push({
|
|
375
|
+
position: m.index,
|
|
376
|
+
receiver,
|
|
377
|
+
method,
|
|
378
|
+
argsExpr: m[4].trim(),
|
|
379
|
+
isAwait,
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
return out;
|
|
383
|
+
}
|
|
384
|
+
function extractThrows(body) {
|
|
385
|
+
const cleaned = stripComments(body);
|
|
386
|
+
const out = [];
|
|
387
|
+
const reNew = /\bthrow\s+new\s+([A-Z][\w$]*)\s*\(([^)]*)\)/g;
|
|
388
|
+
let m;
|
|
389
|
+
while ((m = reNew.exec(cleaned)) !== null) {
|
|
390
|
+
out.push({
|
|
391
|
+
position: m.index,
|
|
392
|
+
errorClass: m[1],
|
|
393
|
+
argsExpr: m[2].trim() || undefined,
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
return out;
|
|
397
|
+
}
|
|
398
|
+
function extractReturns(body) {
|
|
399
|
+
const cleaned = stripComments(body);
|
|
400
|
+
const out = [];
|
|
401
|
+
const re = /\breturn\b\s*([^;]*);/g;
|
|
402
|
+
let m;
|
|
403
|
+
while ((m = re.exec(cleaned)) !== null) {
|
|
404
|
+
out.push({
|
|
405
|
+
position: m.index,
|
|
406
|
+
valueExpr: m[1].trim(),
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
return out;
|
|
410
|
+
}
|
|
411
|
+
//# sourceMappingURL=method-body-walker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"method-body-walker.js","sourceRoot":"","sources":["../../src/analyse-prepass/method-body-walker.ts"],"names":[],"mappings":"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"}
|