@untangle-code/complexity 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/NOTICE +90 -0
- package/README.md +235 -2
- package/THIRD_PARTY_LICENSES.md +24 -0
- package/dist/aggregator.d.ts +28 -0
- package/dist/aggregator.d.ts.map +1 -0
- package/dist/aggregator.js +77 -0
- package/dist/aggregator.js.map +1 -0
- package/dist/assemble.d.ts +50 -0
- package/dist/assemble.d.ts.map +1 -0
- package/dist/assemble.js +43 -0
- package/dist/assemble.js.map +1 -0
- package/dist/cognitive.d.ts +62 -0
- package/dist/cognitive.d.ts.map +1 -0
- package/dist/cognitive.js +62 -0
- package/dist/cognitive.js.map +1 -0
- package/dist/cyclomatic.d.ts +29 -0
- package/dist/cyclomatic.d.ts.map +1 -0
- package/dist/cyclomatic.js +52 -0
- package/dist/cyclomatic.js.map +1 -0
- package/dist/entropy.d.ts +5 -0
- package/dist/entropy.d.ts.map +1 -0
- package/dist/entropy.js +29 -0
- package/dist/entropy.js.map +1 -0
- package/dist/explain.d.ts +22 -0
- package/dist/explain.d.ts.map +1 -0
- package/dist/explain.js +35 -0
- package/dist/explain.js.map +1 -0
- package/dist/halstead.d.ts +23 -0
- package/dist/halstead.d.ts.map +1 -0
- package/dist/halstead.js +24 -0
- package/dist/halstead.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/ir/build-ir.d.ts +105 -0
- package/dist/ir/build-ir.d.ts.map +1 -0
- package/dist/ir/build-ir.js +267 -0
- package/dist/ir/build-ir.js.map +1 -0
- package/dist/maintainability.d.ts +15 -0
- package/dist/maintainability.d.ts.map +1 -0
- package/dist/maintainability.js +10 -0
- package/dist/maintainability.js.map +1 -0
- package/dist/node-kind-heuristics.d.ts +24 -0
- package/dist/node-kind-heuristics.d.ts.map +1 -0
- package/dist/node-kind-heuristics.js +37 -0
- package/dist/node-kind-heuristics.js.map +1 -0
- package/dist/prose/metrics.d.ts +81 -0
- package/dist/prose/metrics.d.ts.map +1 -0
- package/dist/prose/metrics.js +103 -0
- package/dist/prose/metrics.js.map +1 -0
- package/dist/scope-aggregate.d.ts +229 -0
- package/dist/scope-aggregate.d.ts.map +1 -0
- package/dist/scope-aggregate.js +588 -0
- package/dist/scope-aggregate.js.map +1 -0
- package/dist/scope-identity.d.ts +85 -0
- package/dist/scope-identity.d.ts.map +1 -0
- package/dist/scope-identity.js +144 -0
- package/dist/scope-identity.js.map +1 -0
- package/dist/scope.d.ts +36 -0
- package/dist/scope.d.ts.map +1 -0
- package/dist/scope.js +60 -0
- package/dist/scope.js.map +1 -0
- package/dist/structural.d.ts +30 -0
- package/dist/structural.d.ts.map +1 -0
- package/dist/structural.js +98 -0
- package/dist/structural.js.map +1 -0
- package/dist/syntactic.d.ts +35 -0
- package/dist/syntactic.d.ts.map +1 -0
- package/dist/syntactic.js +143 -0
- package/dist/syntactic.js.map +1 -0
- package/dist/text-lines.d.ts +34 -0
- package/dist/text-lines.d.ts.map +1 -0
- package/dist/text-lines.js +60 -0
- package/dist/text-lines.js.map +1 -0
- package/dist/textual.d.ts +28 -0
- package/dist/textual.d.ts.map +1 -0
- package/dist/textual.js +75 -0
- package/dist/textual.js.map +1 -0
- package/dist/types.d.ts +112 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +60 -3
- package/src/aggregator.ts +105 -0
- package/src/assemble.ts +109 -0
- package/src/cognitive.ts +127 -0
- package/src/cyclomatic.ts +78 -0
- package/src/entropy.ts +30 -0
- package/src/explain.ts +64 -0
- package/src/halstead.ts +54 -0
- package/src/index.ts +85 -0
- package/src/ir/build-ir.ts +411 -0
- package/src/maintainability.ts +29 -0
- package/src/node-kind-heuristics.ts +55 -0
- package/src/prose/metrics.ts +201 -0
- package/src/scope-aggregate.ts +775 -0
- package/src/scope-identity.ts +240 -0
- package/src/scope.ts +77 -0
- package/src/structural.ts +132 -0
- package/src/syntactic.ts +183 -0
- package/src/text-lines.ts +90 -0
- package/src/textual.ts +119 -0
- package/src/types.ts +121 -0
|
@@ -0,0 +1,588 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Aggregation ueber einen Scope-BAUM, ohne Doppelzaehlung (WP-82; spec.md
|
|
3
|
+
* §16.10, docs/BUILD_PLAN.md E4).
|
|
4
|
+
*
|
|
5
|
+
* ## Das Problem
|
|
6
|
+
*
|
|
7
|
+
* `aggregate()` in `aggregator.ts` dedupliziert ueber `metricsScopeId` und
|
|
8
|
+
* loest damit genau einen Fall: dasselbe Retrieval-Fragment zweimal in der
|
|
9
|
+
* Eingabe. Es loest NICHT den Fall, um den es hier geht — verschachtelte
|
|
10
|
+
* Scopes. `buildSymbolIR()` bezieht bewusst jeden Nachfahren-Scope in die IR
|
|
11
|
+
* des Zielscopes ein (siehe `ir/build-ir.ts`, "documented nesting context"
|
|
12
|
+
* nach spec.md §16.4): der `file`-Scope traegt also den Kontrollfluss ALLER
|
|
13
|
+
* Klassen, Methoden und Closures der Datei, die Methode den ihrer Closures.
|
|
14
|
+
* Jeder dieser Scopes hat eine eigene, gueltige `metricsScopeId` — die
|
|
15
|
+
* Deduplizierung greift nicht, und `sum` zaehlt denselben Quelltext einmal
|
|
16
|
+
* je umschliessendem Scope.
|
|
17
|
+
*
|
|
18
|
+
* Am eigenen Repo gemessen (siehe `scripts/complexity-report.mjs`): naiv
|
|
19
|
+
* summiert ergibt cognitive rund das Dreifache der Summe, die jeden Scope
|
|
20
|
+
* genau einmal zaehlt. Eine Hotspot-Liste auf dieser Basis steuert in die
|
|
21
|
+
* falsche Richtung.
|
|
22
|
+
*
|
|
23
|
+
* ## Die drei Lesarten
|
|
24
|
+
*
|
|
25
|
+
* "Summe ueber ein Paket" ist ohne Angabe der Lesart bedeutungslos. Dieses
|
|
26
|
+
* Modul kennt genau drei, alle drei zaehlen jeden Scope GENAU EINMAL, und
|
|
27
|
+
* sie unterscheiden sich ausschliesslich darin, wie viel Nesting-Kontext ein
|
|
28
|
+
* Konstrukt mitbekommt:
|
|
29
|
+
*
|
|
30
|
+
* - `"top_level"` (Datei-Lesart): Summe der `inclusiveValue` ueber die
|
|
31
|
+
* Wurzel-Scopes. Jedes Konstrukt zaehlt einmal, mit dem VOLLEN
|
|
32
|
+
* Nesting-Kontext bis zur Wurzel — jede umschliessende Funktion zaehlt als
|
|
33
|
+
* Nesting-Ebene. Beantwortet: "wie schwer ist diese Datei am Stueck zu
|
|
34
|
+
* lesen".
|
|
35
|
+
* - `"execution_unit"` (Funktions-Lesart, DEFAULT): Summe der
|
|
36
|
+
* `inclusiveValue` ueber die AEUSSERSTEN Ausfuehrungseinheiten (Funktion,
|
|
37
|
+
* Methode, Konstruktor) plus die `selfValue` aller Scopes, die selbst keine
|
|
38
|
+
* Ausfuehrungseinheit sind und auch keine ueber sich haben (Datei, Klasse,
|
|
39
|
+
* Interface, Namespace). Der Nesting-Zaehler startet bei jeder aeussersten
|
|
40
|
+
* Funktion neu; verschachtelte Closures bleiben — wie von spec.md §16.4
|
|
41
|
+
* verlangt — Teil ihrer umschliessenden Funktion. Das ist die Lesart, die
|
|
42
|
+
* der verbreiteten "cognitive complexity je Funktion, danach aufsummiert"
|
|
43
|
+
* Konvention entspricht und damit die einzige, die einer Gegenprobe gegen
|
|
44
|
+
* ein etabliertes Werkzeug (X8) standhaelt.
|
|
45
|
+
* - `"self"` (Eigenanteil-Lesart): Summe der `selfValue` ueber ALLE Scopes.
|
|
46
|
+
* Der Nesting-Zaehler startet in jedem Scope neu, auch in einer Closure.
|
|
47
|
+
* Untere Schranke; nuetzlich, um den Anteil sichtbar zu machen, den reines
|
|
48
|
+
* Nesting am Gesamtwert hat.
|
|
49
|
+
*
|
|
50
|
+
* Fuer eine Metrik OHNE Sockel je Scope (`perScopeBase === 0`, also cognitive)
|
|
51
|
+
* gilt strukturell `self <= execution_unit <= top_level`, und zwar als Folge
|
|
52
|
+
* der Kerninvariante: die Differenzen sind nicht Rauschen, sondern genau der
|
|
53
|
+
* Nesting-Aufschlag der jeweils zusaetzlich beruecksichtigten Ebenen (belegt
|
|
54
|
+
* in `scope-aggregate.test.ts`).
|
|
55
|
+
*
|
|
56
|
+
* ## Woraus die Doppelzaehlungsfreiheit tatsaechlich folgt
|
|
57
|
+
*
|
|
58
|
+
* Nicht aus `checkScopeTreeInvariants`. Deren Kernpruefung
|
|
59
|
+
* `children_exceed_parent` ist eine EINSEITIGE Schranke
|
|
60
|
+
* (`self + Summe Kinder <= inclusive`): sie faengt einen zu KLEINEN
|
|
61
|
+
* Elternwert, also fehlenden Inhalt. Ein zu GROSSER Elternwert — der Fall, in
|
|
62
|
+
* dem ein Kindbeitrag zweimal im Elternwert steckt — erfuellt sie erst recht
|
|
63
|
+
* und bleibt damit unentdeckt. Aus Werten allein ist er auch nicht
|
|
64
|
+
* entscheidbar: ein aufgeblaehter `inclusiveValue` sieht genauso aus wie ein
|
|
65
|
+
* Scope, der im eigenen Koerper einfach viel Kontrollfluss traegt.
|
|
66
|
+
*
|
|
67
|
+
* Was dieses Modul stattdessen ZUSICHERT und mit `checkScopeCoverage`
|
|
68
|
+
* NACHPRUEFT, ist die strukturelle Aussage: in jeder der drei Lesarten geht
|
|
69
|
+
* jeder Scope in GENAU EINEN Summanden ein — entweder als eigener Summand
|
|
70
|
+
* oder als Nachfahre genau eines Summanden, der mit `inclusiveValue` zaehlt.
|
|
71
|
+
* Damit kann keine Lesart denselben Quelltext zweimal aufaddieren. Das ist
|
|
72
|
+
* die Zusicherung, die die Summen tragen; die Werttreue der einzelnen
|
|
73
|
+
* `inclusiveValue`s liegt beim Aufrufer, der sie berechnet hat.
|
|
74
|
+
*
|
|
75
|
+
* Fuer eine Metrik MIT Sockel (`perScopeBase > 0`, also cyclomatic:
|
|
76
|
+
* `M = 1 + decision_points`) kehrt sich die Reihenfolge um, und das ist
|
|
77
|
+
* korrekt: die `self`-Lesart zaehlt den Sockel einmal JE SCOPE, die
|
|
78
|
+
* `top_level`-Lesart nur einmal je Datei. Die drei Zahlen bleiben
|
|
79
|
+
* doppelzaehlungsfrei — sie beantworten nur verschiedene Fragen. Wer sie
|
|
80
|
+
* nebeneinander zeigt, muss den Sockel dazusagen.
|
|
81
|
+
*
|
|
82
|
+
* ## Warum es KEINE Blatt-Lesart gibt
|
|
83
|
+
*
|
|
84
|
+
* "Summe der Blatt-Scopes" waere die naheliegende vierte Lesart und ist
|
|
85
|
+
* FALSCH: der Kontrollfluss, der direkt im Koerper eines Scopes MIT Kindern
|
|
86
|
+
* steht (eine `if`-Kette in einer Methode, die ausserdem eine Closure
|
|
87
|
+
* definiert), gehoert keinem Blatt und faellt ersatzlos weg. Das ist kein
|
|
88
|
+
* Deduplizieren, sondern stilles Verlieren von Inhalt — genau das, was E4
|
|
89
|
+
* verbietet. `ScopeTreeAggregateV1.leafOnlySum` weist die Zahl trotzdem aus,
|
|
90
|
+
* aber ausdruecklich als Diagnose zusammen mit `leafOnlyDroppedAmount`, dem
|
|
91
|
+
* Betrag, den sie verschluckt.
|
|
92
|
+
*
|
|
93
|
+
* ## Determinismus
|
|
94
|
+
*
|
|
95
|
+
* Kein `localeCompare`, kein `Date.now()`, kein `Math.random()`. Reihenfolgen
|
|
96
|
+
* werden ueber `compareCodepoints` aus `@untangle-code/domain` hergestellt.
|
|
97
|
+
*/
|
|
98
|
+
import { compareCodepoints, UntangleError } from "@untangle-code/domain";
|
|
99
|
+
/** Die drei definierten Lesarten einer Scope-Summe. */
|
|
100
|
+
export const SCOPE_SUM_READINGS = ["top_level", "execution_unit", "self"];
|
|
101
|
+
/** Geschlossene Menge der Invariantenverstoesse. Ein Verstoss ist ein Fehler, kein Hinweis. */
|
|
102
|
+
export const SCOPE_INVARIANT_CODES = [
|
|
103
|
+
"duplicate_scope_id",
|
|
104
|
+
"unknown_parent",
|
|
105
|
+
"parent_cycle",
|
|
106
|
+
"negative_value",
|
|
107
|
+
"self_exceeds_inclusive",
|
|
108
|
+
"children_exceed_parent",
|
|
109
|
+
"leaf_self_differs_from_inclusive",
|
|
110
|
+
"scope_counted_twice",
|
|
111
|
+
"scope_uncounted",
|
|
112
|
+
];
|
|
113
|
+
/**
|
|
114
|
+
* Die Felder, in denen sich zwei Eintraege mit derselben `metricsScopeId`
|
|
115
|
+
* unterscheiden — als LISTE, nicht als Ja/Nein.
|
|
116
|
+
*
|
|
117
|
+
* WP-186: Die Begruendung im Verstoss darf nicht behaupten, „die Werte
|
|
118
|
+
* weichen ab", und dann zweimal dieselbe Zahl drucken. Genau das geschah,
|
|
119
|
+
* sobald der Unterschied in `parentScopeId` oder `executionUnit` lag: der
|
|
120
|
+
* Text nannte `inclusive`/`self`, die dort identisch waren, und das
|
|
121
|
+
* tatsaechlich abweichende Feld kam nirgends vor. Wer so etwas liest, sucht
|
|
122
|
+
* einen Fehler in einer Zahl, die stimmt.
|
|
123
|
+
*
|
|
124
|
+
* WP-200: `sloc` gehoert dazu. Es blieb ausserhalb des Vergleichs, obwohl es
|
|
125
|
+
* das GEWICHT im SLOC-gewichteten Mittel von `aggregate()` stellt: zwei
|
|
126
|
+
* Eintraege mit derselben Id und verschiedenem `sloc` galten als identisch,
|
|
127
|
+
* der zweite wurde ohne Verstoss verworfen — und mit ihm sein Gewicht. Der
|
|
128
|
+
* Mittelwert verschob sich, und nichts sagte es.
|
|
129
|
+
*/
|
|
130
|
+
function differingFields(a, b) {
|
|
131
|
+
const differing = [];
|
|
132
|
+
if (a.inclusiveValue !== b.inclusiveValue) {
|
|
133
|
+
differing.push(`inclusive ${String(b.inclusiveValue)} vs. ${String(a.inclusiveValue)}`);
|
|
134
|
+
}
|
|
135
|
+
if (a.selfValue !== b.selfValue) {
|
|
136
|
+
differing.push(`self ${String(b.selfValue)} vs. ${String(a.selfValue)}`);
|
|
137
|
+
}
|
|
138
|
+
if (a.executionUnit !== b.executionUnit) {
|
|
139
|
+
differing.push(`executionUnit ${String(b.executionUnit)} vs. ${String(a.executionUnit)}`);
|
|
140
|
+
}
|
|
141
|
+
if (a.parentScopeId !== b.parentScopeId) {
|
|
142
|
+
differing.push(`parentScopeId ${b.parentScopeId ?? "(none)"} vs. ${a.parentScopeId ?? "(none)"}`);
|
|
143
|
+
}
|
|
144
|
+
if (a.sloc !== b.sloc) {
|
|
145
|
+
differing.push(`sloc ${String(b.sloc ?? "(none)")} vs. ${String(a.sloc ?? "(none)")}`);
|
|
146
|
+
}
|
|
147
|
+
return differing;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Dedupliziert nach `metricsScopeId` (erstes Vorkommen gewinnt, wie
|
|
151
|
+
* `aggregate()`, spec.md §16.10: doppelte Retrieval-Fragmente MUESSEN ueber
|
|
152
|
+
* `metrics_scope_id` dedupliziert werden) und meldet dabei jede
|
|
153
|
+
* WIDERSPRUECHLICHE Wiederholung als Verstoss: zwei gleiche Ids mit
|
|
154
|
+
* verschiedenen Werten sind keine harmlose Dublette, sondern ein Zeichen,
|
|
155
|
+
* dass die Ids nicht das identifizieren, was sie sollen.
|
|
156
|
+
*
|
|
157
|
+
* ACHTUNG FUER AUFRUFER — was `duplicatesDropped` bedeutet: eine
|
|
158
|
+
* Wiederholung mit ZUFAELLIG gleichen Werten ist von einer echten Dublette
|
|
159
|
+
* nicht zu unterscheiden und wird deshalb ohne Verstoss verworfen. Wer keine
|
|
160
|
+
* wiederholten Retrieval-Fragmente in der Eingabe hat — wer also einen ECHTEN
|
|
161
|
+
* Scope-Baum aggregiert, in dem jede Id genau einen Scope bezeichnen MUSS —
|
|
162
|
+
* fuer den ist jedes `duplicatesDropped > 0` verlorener Inhalt und muss als
|
|
163
|
+
* Fehler behandelt werden. Die Zahl steht deshalb in
|
|
164
|
+
* `ScopeTreeAggregateV1.duplicatesDropped`; sie zu ignorieren waere ein
|
|
165
|
+
* stilles Ueberspringen (E4). `scripts/complexity-report.mjs` bricht darauf
|
|
166
|
+
* ab.
|
|
167
|
+
*/
|
|
168
|
+
function resolveTree(nodes) {
|
|
169
|
+
const byId = new Map();
|
|
170
|
+
const deduped = [];
|
|
171
|
+
const duplicateConflicts = [];
|
|
172
|
+
let duplicatesDropped = 0;
|
|
173
|
+
for (const node of nodes) {
|
|
174
|
+
const existing = byId.get(node.metricsScopeId);
|
|
175
|
+
if (existing !== undefined) {
|
|
176
|
+
duplicatesDropped++;
|
|
177
|
+
const differing = differingFields(existing, node);
|
|
178
|
+
if (differing.length > 0) {
|
|
179
|
+
duplicateConflicts.push({
|
|
180
|
+
code: "duplicate_scope_id",
|
|
181
|
+
metricsScopeId: node.metricsScopeId,
|
|
182
|
+
observed: node.inclusiveValue,
|
|
183
|
+
limit: existing.inclusiveValue,
|
|
184
|
+
detail: `metricsScopeId "${node.metricsScopeId}" appears more than once with differing ` +
|
|
185
|
+
`${differing.length === 1 ? "field" : "fields"}: ` +
|
|
186
|
+
`${differing.join(", ")}. The ID therefore does not identify exactly one scope; ` +
|
|
187
|
+
`a total over this set would be meaningless.`,
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
byId.set(node.metricsScopeId, node);
|
|
193
|
+
deduped.push(node);
|
|
194
|
+
}
|
|
195
|
+
deduped.sort((a, b) => compareCodepoints(a.metricsScopeId, b.metricsScopeId));
|
|
196
|
+
const childrenByParent = new Map();
|
|
197
|
+
for (const node of deduped) {
|
|
198
|
+
if (node.parentScopeId === undefined)
|
|
199
|
+
continue;
|
|
200
|
+
const siblings = childrenByParent.get(node.parentScopeId) ?? [];
|
|
201
|
+
siblings.push(node);
|
|
202
|
+
childrenByParent.set(node.parentScopeId, siblings);
|
|
203
|
+
}
|
|
204
|
+
return { nodes: deduped, byId, childrenByParent, duplicatesDropped, duplicateConflicts };
|
|
205
|
+
}
|
|
206
|
+
/** True, wenn `node` in einer Elternkette liegt, die sich schliesst oder ins Leere laeuft. */
|
|
207
|
+
function ancestryProblem(node, byId) {
|
|
208
|
+
const seen = new Set([node.metricsScopeId]);
|
|
209
|
+
let current = node;
|
|
210
|
+
for (;;) {
|
|
211
|
+
const parentId = current.parentScopeId;
|
|
212
|
+
if (parentId === undefined)
|
|
213
|
+
return null;
|
|
214
|
+
if (seen.has(parentId))
|
|
215
|
+
return "cycle";
|
|
216
|
+
const parent = byId.get(parentId);
|
|
217
|
+
if (parent === undefined)
|
|
218
|
+
return "unknown_parent";
|
|
219
|
+
seen.add(parentId);
|
|
220
|
+
current = parent;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Prueft alle Invarianten des Scope-Baums und liefert JEDEN Verstoss mit
|
|
225
|
+
* Begruendung. Leere Liste heisst: der Baum traegt eine sinnvolle Summe.
|
|
226
|
+
*
|
|
227
|
+
* Geprueft wird:
|
|
228
|
+
* 1. `duplicate_scope_id` — dieselbe Id mit abweichenden Werten.
|
|
229
|
+
* 2. `unknown_parent` — `parentScopeId` zeigt auf einen Scope, der nicht in
|
|
230
|
+
* der Menge ist. Ihn stillschweigend als Wurzel zu behandeln waere ein
|
|
231
|
+
* E4-Verstoss: der Elternwert, gegen den geprueft werden muesste, fehlt.
|
|
232
|
+
* 3. `parent_cycle` — die Elternkette schliesst sich.
|
|
233
|
+
* 4. `negative_value` — negative Metrikwerte.
|
|
234
|
+
* 5. `self_exceeds_inclusive` — der Eigenanteil ist groesser als der Wert
|
|
235
|
+
* mit Nachfahren. Der Eigenanteil ist per Definition ein Teil davon.
|
|
236
|
+
* 6. `children_exceed_parent` — der Eigenanteil eines Scopes plus die Summe
|
|
237
|
+
* seiner direkten Kinder darf seinen eigenen Wert nicht ueberschreiten.
|
|
238
|
+
*
|
|
239
|
+
* WAS DIESE PRUEFUNG LEISTET UND WAS NICHT — sie ist eine EINSEITIGE
|
|
240
|
+
* Schranke (`self + Summe Kinder <= inclusive`) und darf deshalb nicht als
|
|
241
|
+
* Doppelzaehlungspruefung gelesen werden:
|
|
242
|
+
* - Sie schlaegt an, wenn der Elternwert ZU KLEIN ist, dem Elternwert
|
|
243
|
+
* also Inhalt seiner Kinder FEHLT (oder ein Kindwert zu gross ist).
|
|
244
|
+
* Ein Verstoss heisst: der Baum verliert Inhalt, nicht: er zaehlt
|
|
245
|
+
* doppelt.
|
|
246
|
+
* - Sie schlaegt NICHT an, wenn der Elternwert ZU GROSS ist — genau der
|
|
247
|
+
* Fall, in dem ein Kindbeitrag zweimal im Elternwert steckt. Ein
|
|
248
|
+
* aufgeblaehter `inclusiveValue` ist aus Werten allein nicht von einem
|
|
249
|
+
* Scope zu unterscheiden, der im eigenen Koerper viel Kontrollfluss
|
|
250
|
+
* traegt.
|
|
251
|
+
*
|
|
252
|
+
* Die Zusicherung "jeder Beitrag zaehlt genau einmal" leistet
|
|
253
|
+
* `checkScopeCoverage` auf der Struktur der jeweiligen Lesart, nicht
|
|
254
|
+
* diese Wertschranke.
|
|
255
|
+
* 7. `leaf_self_differs_from_inclusive` — ein Scope ohne Kinder hat keine
|
|
256
|
+
* Nachfahren, sein Eigenanteil MUSS also sein Gesamtwert sein. Weicht er
|
|
257
|
+
* ab, hat der Aufrufer die beiden Werte nicht aus demselben Scope
|
|
258
|
+
* berechnet.
|
|
259
|
+
*
|
|
260
|
+
* NICHT geprueft (und mit Absicht hier benannt statt verschwiegen): ein zu
|
|
261
|
+
* grosser `inclusiveValue` eines Scopes MIT Kindern. Siehe Punkt 6 und die
|
|
262
|
+
* Modul-Doku, Abschnitt "Woraus die Doppelzaehlungsfreiheit tatsaechlich
|
|
263
|
+
* folgt".
|
|
264
|
+
*
|
|
265
|
+
* Alle Wertvergleiche laufen auf `wert - perScopeBase` (siehe
|
|
266
|
+
* `ScopeTreeOptions.perScopeBase`).
|
|
267
|
+
*/
|
|
268
|
+
export function checkScopeTreeInvariants(nodes, options = {}) {
|
|
269
|
+
const perScopeBase = options.perScopeBase ?? 0;
|
|
270
|
+
const epsilon = options.epsilon ?? 1e-9;
|
|
271
|
+
const tree = resolveTree(nodes);
|
|
272
|
+
const violations = [...tree.duplicateConflicts];
|
|
273
|
+
for (const node of tree.nodes) {
|
|
274
|
+
if (node.inclusiveValue < 0 || node.selfValue < 0) {
|
|
275
|
+
violations.push({
|
|
276
|
+
code: "negative_value",
|
|
277
|
+
metricsScopeId: node.metricsScopeId,
|
|
278
|
+
observed: Math.min(node.inclusiveValue, node.selfValue),
|
|
279
|
+
limit: 0,
|
|
280
|
+
detail: `Scope "${node.metricsScopeId}" has a negative metric value ` +
|
|
281
|
+
`(inclusive ${String(node.inclusiveValue)}, self ${String(node.selfValue)}). ` +
|
|
282
|
+
`Complexity metrics are non-negative.`,
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
const problem = ancestryProblem(node, tree.byId);
|
|
286
|
+
if (problem === "unknown_parent") {
|
|
287
|
+
violations.push({
|
|
288
|
+
code: "unknown_parent",
|
|
289
|
+
metricsScopeId: node.metricsScopeId,
|
|
290
|
+
observed: 0,
|
|
291
|
+
limit: 0,
|
|
292
|
+
detail: `Scope "${node.metricsScopeId}" references a scope through its parent chain ` +
|
|
293
|
+
`that is absent from the set. It is not treated as a root: without the parent value, ` +
|
|
294
|
+
`we cannot determine whether its contribution is already included there (E4).`,
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
else if (problem === "cycle") {
|
|
298
|
+
violations.push({
|
|
299
|
+
code: "parent_cycle",
|
|
300
|
+
metricsScopeId: node.metricsScopeId,
|
|
301
|
+
observed: 0,
|
|
302
|
+
limit: 0,
|
|
303
|
+
detail: `The parent chain of scope "${node.metricsScopeId}" closes a cycle. ` +
|
|
304
|
+
`A scope tree with a cycle has no root or well-defined total.`,
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
const inclusive = node.inclusiveValue - perScopeBase;
|
|
308
|
+
const own = node.selfValue - perScopeBase;
|
|
309
|
+
if (own > inclusive + epsilon) {
|
|
310
|
+
violations.push({
|
|
311
|
+
code: "self_exceeds_inclusive",
|
|
312
|
+
metricsScopeId: node.metricsScopeId,
|
|
313
|
+
observed: own,
|
|
314
|
+
limit: inclusive,
|
|
315
|
+
detail: `Scope "${node.metricsScopeId}": self contribution ${String(node.selfValue)} exceeds ` +
|
|
316
|
+
`the inclusive value ${String(node.inclusiveValue)}. The self contribution is part ` +
|
|
317
|
+
`of the total and cannot exceed it.`,
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
const children = tree.childrenByParent.get(node.metricsScopeId) ?? [];
|
|
321
|
+
if (children.length === 0) {
|
|
322
|
+
if (Math.abs(node.inclusiveValue - node.selfValue) > epsilon) {
|
|
323
|
+
violations.push({
|
|
324
|
+
code: "leaf_self_differs_from_inclusive",
|
|
325
|
+
metricsScopeId: node.metricsScopeId,
|
|
326
|
+
observed: node.selfValue,
|
|
327
|
+
limit: node.inclusiveValue,
|
|
328
|
+
detail: `Scope "${node.metricsScopeId}" has no child scopes, but its self contribution ` +
|
|
329
|
+
`${String(node.selfValue)} differs from the inclusive value ${String(node.inclusiveValue)}. ` +
|
|
330
|
+
`Without descendants, both values must be identical.`,
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
continue;
|
|
334
|
+
}
|
|
335
|
+
const childrenSum = children.reduce((sum, child) => sum + (child.inclusiveValue - perScopeBase), 0);
|
|
336
|
+
if (own + childrenSum > inclusive + epsilon) {
|
|
337
|
+
const childList = children
|
|
338
|
+
.map((child) => `${child.metricsScopeId}=${String(child.inclusiveValue)}`)
|
|
339
|
+
.join(", ");
|
|
340
|
+
violations.push({
|
|
341
|
+
code: "children_exceed_parent",
|
|
342
|
+
metricsScopeId: node.metricsScopeId,
|
|
343
|
+
observed: own + childrenSum,
|
|
344
|
+
limit: inclusive,
|
|
345
|
+
detail: `Scope "${node.metricsScopeId}": self contribution ${String(own)} plus the sum of ` +
|
|
346
|
+
`${String(children.length)} direct children ${String(childrenSum)} equals ` +
|
|
347
|
+
`${String(own + childrenSum)} and exceeds the parent value ${String(inclusive)} ` +
|
|
348
|
+
`(values after subtracting perScopeBase=${String(perScopeBase)}). Children: ${childList}. ` +
|
|
349
|
+
`The parent value is missing child content, or a child value is too large; ` +
|
|
350
|
+
`a root total would be too small. This one-sided bound cannot detect ` +
|
|
351
|
+
`a parent value that is too large; checkScopeCoverage checks that separately.`,
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
violations.sort((a, b) => compareCodepoints(a.metricsScopeId, b.metricsScopeId) || compareCodepoints(a.code, b.code));
|
|
356
|
+
return violations;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Wirft bei jedem Invariantenverstoss. Die Meldung nennt Anzahl und die
|
|
360
|
+
* ersten Verstoesse im Klartext; `context.violations` traegt die volle Liste.
|
|
361
|
+
*
|
|
362
|
+
* Geprueft wird in ZWEI Stufen: erst die Wert- und Bauminvarianten
|
|
363
|
+
* (`checkScopeTreeInvariants`), danach — nur wenn der Baum ueberhaupt
|
|
364
|
+
* wohlgeformt ist — die strukturelle Zaehlpruefung ueber alle drei Lesarten
|
|
365
|
+
* (`checkAllScopeCoverage`). Erst beide zusammen tragen die Aussage, dass die
|
|
366
|
+
* ausgegebenen Summen jeden Scope genau einmal enthalten; die Wertschranke
|
|
367
|
+
* allein taete es nicht (siehe Punkt 6 oben).
|
|
368
|
+
*/
|
|
369
|
+
export function assertScopeTreeInvariants(nodes, options = {}) {
|
|
370
|
+
const treeViolations = checkScopeTreeInvariants(nodes, options);
|
|
371
|
+
const violations = treeViolations.length > 0 ? treeViolations : checkAllScopeCoverage(nodes);
|
|
372
|
+
if (violations.length === 0)
|
|
373
|
+
return;
|
|
374
|
+
const preview = violations
|
|
375
|
+
.slice(0, 3)
|
|
376
|
+
.map((violation) => `${violation.code}: ${violation.detail}`)
|
|
377
|
+
.join(" | ");
|
|
378
|
+
throw new UntangleError("ANALYSIS_INCOMPLETE", `scope tree invariants violated (${String(violations.length)} violation(s)): ${preview}`, { operation: "complexity.aggregateScopeTree", context: { violations } });
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Liefert genau die Eintraege, die eine Lesart zaehlt — jeder Scope hoechstens
|
|
382
|
+
* einmal, jeweils mit dem fuer die Lesart richtigen Wert. Das Ergebnis geht
|
|
383
|
+
* unveraendert in `aggregate()`; damit gelten count/mean/median/p90/p95/max/
|
|
384
|
+
* Schwellenzaehlung (spec.md §16.10) auf einer doppelzaehlungsfreien Basis.
|
|
385
|
+
*
|
|
386
|
+
* Prueft KEINE Invarianten — dafuer ist `checkScopeTreeInvariants` da. Ein
|
|
387
|
+
* `unknown_parent` wird hier zwangslaeufig wie eine Wurzel behandelt; genau
|
|
388
|
+
* deshalb meldet die Pruefung ihn als Fehler, statt ihn zu tolerieren.
|
|
389
|
+
*/
|
|
390
|
+
export function selectScopeEntries(nodes, reading) {
|
|
391
|
+
const tree = resolveTree(nodes);
|
|
392
|
+
const selection = selectionFor(tree, reading);
|
|
393
|
+
const entries = [];
|
|
394
|
+
for (const node of tree.nodes) {
|
|
395
|
+
const kind = selection.get(node.metricsScopeId);
|
|
396
|
+
if (kind === undefined)
|
|
397
|
+
continue;
|
|
398
|
+
const entry = {
|
|
399
|
+
metricsScopeId: node.metricsScopeId,
|
|
400
|
+
value: kind === "inclusive" ? node.inclusiveValue : node.selfValue,
|
|
401
|
+
};
|
|
402
|
+
if (node.sloc !== undefined)
|
|
403
|
+
entry.sloc = node.sloc;
|
|
404
|
+
entries.push(entry);
|
|
405
|
+
}
|
|
406
|
+
return entries;
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Die Auswahl einer Lesart. Einzige Quelle der Wahrheit fuer
|
|
410
|
+
* `selectScopeEntries` UND `checkScopeCoverage`: die Pruefung soll dieselbe
|
|
411
|
+
* Auswahl sehen, die auch summiert wird, sonst prueft sie etwas anderes als
|
|
412
|
+
* das, was ausgegeben wird.
|
|
413
|
+
*/
|
|
414
|
+
export function selectionForReading(nodes, reading) {
|
|
415
|
+
return selectionFor(resolveTree(nodes), reading);
|
|
416
|
+
}
|
|
417
|
+
function selectionFor(tree, reading) {
|
|
418
|
+
const selection = new Map();
|
|
419
|
+
for (const node of tree.nodes) {
|
|
420
|
+
switch (reading) {
|
|
421
|
+
case "self":
|
|
422
|
+
selection.set(node.metricsScopeId, "self");
|
|
423
|
+
break;
|
|
424
|
+
case "top_level":
|
|
425
|
+
if (node.parentScopeId === undefined || !tree.byId.has(node.parentScopeId)) {
|
|
426
|
+
selection.set(node.metricsScopeId, "inclusive");
|
|
427
|
+
}
|
|
428
|
+
break;
|
|
429
|
+
case "execution_unit":
|
|
430
|
+
// Ein Scope MIT umschliessender Ausfuehrungseinheit ist bereits in
|
|
431
|
+
// deren `inclusiveValue` enthalten und darf nicht erneut zaehlen.
|
|
432
|
+
if (enclosingExecutionUnit(node, tree.byId) === null) {
|
|
433
|
+
selection.set(node.metricsScopeId, node.executionUnit ? "inclusive" : "self");
|
|
434
|
+
}
|
|
435
|
+
break;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
return selection;
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Prueft STRUKTURELL, dass eine Lesart jeden Scope genau einmal zaehlt — die
|
|
442
|
+
* Zusicherung, die `children_exceed_parent` NICHT leisten kann (siehe die
|
|
443
|
+
* Modul-Doku, Abschnitt "Woraus die Doppelzaehlungsfreiheit tatsaechlich
|
|
444
|
+
* folgt", und Punkt 6 von `checkScopeTreeInvariants`).
|
|
445
|
+
*
|
|
446
|
+
* Fuer jeden Scope wird gezaehlt, wie viele Summanden der Lesart seinen
|
|
447
|
+
* Beitrag tragen: er selbst, falls er ausgewaehlt ist, plus jeder echte
|
|
448
|
+
* Vorfahre, der mit `inclusiveValue` ausgewaehlt ist (dessen Summand deckt
|
|
449
|
+
* den ganzen Teilbaum ab). Genau EINER muss es sein.
|
|
450
|
+
*
|
|
451
|
+
* Was die Pruefung NICHT leisten kann: sie sieht die Struktur, nicht die
|
|
452
|
+
* Werte. Ein `inclusiveValue`, der den Beitrag eines Kindes intern doppelt
|
|
453
|
+
* enthaelt, ist aus Zahlen allein nicht erkennbar — dafuer haftet der
|
|
454
|
+
* Aufrufer, der die Werte berechnet hat.
|
|
455
|
+
*/
|
|
456
|
+
export function checkScopeCoverage(nodes, reading) {
|
|
457
|
+
return checkSelectionCoverage(nodes, selectionForReading(nodes, reading), reading);
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Dieselbe Zaehlpruefung wie `checkScopeCoverage`, aber gegen eine BELIEBIGE
|
|
461
|
+
* Auswahl. Sie ist der eigentliche Kern; `checkScopeCoverage` ist nur die
|
|
462
|
+
* Anwendung auf die Auswahl, die eine der drei Lesarten trifft.
|
|
463
|
+
*
|
|
464
|
+
* Getrennt exportiert, weil die Zusicherung sonst nicht vorfuehrbar waere:
|
|
465
|
+
* die Auswahlen der drei Lesarten koennen `scope_counted_twice` per
|
|
466
|
+
* Konstruktion nicht ausloesen (dort ist ein Scope ausgewaehlt GENAU DANN,
|
|
467
|
+
* wenn er keinen ausgewaehlten `inclusive`-Vorfahren hat). Eine Pruefung,
|
|
468
|
+
* deren Alarmfall ueber die oeffentliche Schnittstelle nicht erreichbar ist,
|
|
469
|
+
* waere eine Behauptung statt einer Pruefung — mit dieser Funktion laesst er
|
|
470
|
+
* sich zeigen, und der Waechter greift, sobald jemand `selectionFor` aendert.
|
|
471
|
+
*
|
|
472
|
+
* @param label Erscheint im Detailtext an der Stelle der Lesart.
|
|
473
|
+
*/
|
|
474
|
+
export function checkSelectionCoverage(nodes, selection, label) {
|
|
475
|
+
const tree = resolveTree(nodes);
|
|
476
|
+
const violations = [];
|
|
477
|
+
for (const node of tree.nodes) {
|
|
478
|
+
const carriers = [];
|
|
479
|
+
if (selection.has(node.metricsScopeId))
|
|
480
|
+
carriers.push(node.metricsScopeId);
|
|
481
|
+
const seen = new Set([node.metricsScopeId]);
|
|
482
|
+
let parentId = node.parentScopeId;
|
|
483
|
+
while (parentId !== undefined && !seen.has(parentId)) {
|
|
484
|
+
seen.add(parentId);
|
|
485
|
+
const parent = tree.byId.get(parentId);
|
|
486
|
+
if (parent === undefined)
|
|
487
|
+
break;
|
|
488
|
+
if (selection.get(parentId) === "inclusive")
|
|
489
|
+
carriers.push(parentId);
|
|
490
|
+
parentId = parent.parentScopeId;
|
|
491
|
+
}
|
|
492
|
+
if (carriers.length === 1)
|
|
493
|
+
continue;
|
|
494
|
+
if (carriers.length > 1) {
|
|
495
|
+
violations.push({
|
|
496
|
+
code: "scope_counted_twice",
|
|
497
|
+
metricsScopeId: node.metricsScopeId,
|
|
498
|
+
observed: carriers.length,
|
|
499
|
+
limit: 1,
|
|
500
|
+
detail: `Selection "${label}": the contribution of scope "${node.metricsScopeId}" appears in ` +
|
|
501
|
+
`${String(carriers.length)} contributing terms simultaneously (${carriers.join(", ")}). ` +
|
|
502
|
+
`The total counts the same source text more than once.`,
|
|
503
|
+
});
|
|
504
|
+
continue;
|
|
505
|
+
}
|
|
506
|
+
violations.push({
|
|
507
|
+
code: "scope_uncounted",
|
|
508
|
+
metricsScopeId: node.metricsScopeId,
|
|
509
|
+
observed: 0,
|
|
510
|
+
limit: 1,
|
|
511
|
+
detail: `Selection "${label}": the contribution of scope "${node.metricsScopeId}" belongs to no ` +
|
|
512
|
+
`contributing term. Its content is lost from the total without a replacement; ` +
|
|
513
|
+
`silently losing content is forbidden by E4.`,
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
violations.sort((a, b) => compareCodepoints(a.metricsScopeId, b.metricsScopeId) || compareCodepoints(a.code, b.code));
|
|
517
|
+
return violations;
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* `checkScopeCoverage` fuer ALLE drei Lesarten, Verstoesse deterministisch
|
|
521
|
+
* nach Lesart und Scope sortiert.
|
|
522
|
+
*/
|
|
523
|
+
export function checkAllScopeCoverage(nodes) {
|
|
524
|
+
return SCOPE_SUM_READINGS.flatMap((reading) => checkScopeCoverage(nodes, reading));
|
|
525
|
+
}
|
|
526
|
+
/** Naechster Vorfahre, der Ausfuehrungseinheit ist; `null`, wenn es keinen gibt. */
|
|
527
|
+
function enclosingExecutionUnit(node, byId) {
|
|
528
|
+
const seen = new Set([node.metricsScopeId]);
|
|
529
|
+
let parentId = node.parentScopeId;
|
|
530
|
+
while (parentId !== undefined && !seen.has(parentId)) {
|
|
531
|
+
seen.add(parentId);
|
|
532
|
+
const parent = byId.get(parentId);
|
|
533
|
+
if (parent === undefined)
|
|
534
|
+
return null;
|
|
535
|
+
if (parent.executionUnit)
|
|
536
|
+
return parent;
|
|
537
|
+
parentId = parent.parentScopeId;
|
|
538
|
+
}
|
|
539
|
+
return null;
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Summiert einen Scope-Baum in allen drei Lesarten, ohne Doppelzaehlung.
|
|
543
|
+
*
|
|
544
|
+
* WIRFT bei jedem Invariantenverstoss (`UntangleError`, Code
|
|
545
|
+
* `ANALYSIS_INCOMPLETE`): eine Summe ueber einen widerspruechlichen Baum ist
|
|
546
|
+
* keine Zahl mit Bedeutung, und ein Hinweis waere hier zu wenig. Wer die
|
|
547
|
+
* Verstoesse anzeigen statt abbrechen will, ruft vorher
|
|
548
|
+
* `checkScopeTreeInvariants` auf.
|
|
549
|
+
*/
|
|
550
|
+
export function aggregateScopeTree(nodes, options = {}) {
|
|
551
|
+
assertScopeTreeInvariants(nodes, options);
|
|
552
|
+
const tree = resolveTree(nodes);
|
|
553
|
+
const sumOf = (reading) => selectScopeEntries(nodes, reading).reduce((sum, entry) => sum + entry.value, 0);
|
|
554
|
+
let rootCount = 0;
|
|
555
|
+
let executionUnitRootCount = 0;
|
|
556
|
+
let leafCount = 0;
|
|
557
|
+
let naiveSum = 0;
|
|
558
|
+
let leafOnlySum = 0;
|
|
559
|
+
for (const node of tree.nodes) {
|
|
560
|
+
naiveSum += node.inclusiveValue;
|
|
561
|
+
if (node.parentScopeId === undefined)
|
|
562
|
+
rootCount++;
|
|
563
|
+
if (node.executionUnit && enclosingExecutionUnit(node, tree.byId) === null) {
|
|
564
|
+
executionUnitRootCount++;
|
|
565
|
+
}
|
|
566
|
+
if ((tree.childrenByParent.get(node.metricsScopeId) ?? []).length === 0) {
|
|
567
|
+
leafCount++;
|
|
568
|
+
leafOnlySum += node.inclusiveValue;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
const topLevelSum = sumOf("top_level");
|
|
572
|
+
const selfSum = sumOf("self");
|
|
573
|
+
return {
|
|
574
|
+
scopeCount: tree.nodes.length,
|
|
575
|
+
duplicatesDropped: tree.duplicatesDropped,
|
|
576
|
+
rootCount,
|
|
577
|
+
executionUnitRootCount,
|
|
578
|
+
leafCount,
|
|
579
|
+
topLevelSum,
|
|
580
|
+
executionUnitSum: sumOf("execution_unit"),
|
|
581
|
+
selfSum,
|
|
582
|
+
naiveSum,
|
|
583
|
+
doubleCountedAmount: naiveSum - topLevelSum,
|
|
584
|
+
leafOnlySum,
|
|
585
|
+
leafOnlyDroppedAmount: selfSum - leafOnlySum,
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
//# sourceMappingURL=scope-aggregate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope-aggregate.js","sourceRoot":"","sources":["../src/scope-aggregate.ts"],"names":[],"mappings":"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"}
|