ucn 5.5.1 → 5.5.2
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/.claude/skills/ucn/SKILL.md +35 -9
- package/.claude/skills/ucn/references/commands.md +38 -16
- package/.claude/skills/ucn/references/resolution-rules.md +126 -20
- package/.claude/skills/ucn/references/trust-contract.md +5 -3
- package/README.md +30 -21
- package/cli/index.js +1 -1
- package/core/accessors.js +341 -54
- package/core/account.js +74 -20
- package/core/analysis.js +257 -125
- package/core/ast-analysis.js +12 -3
- package/core/brief.js +8 -4
- package/core/build-worker.js +2 -1
- package/core/cache.js +137 -6
- package/core/call-name-cache.js +134 -0
- package/core/callable-scope.js +21 -0
- package/core/callers.js +4726 -940
- package/core/check.js +22 -5
- package/core/class-identity.js +399 -12
- package/core/constructor-calls.js +831 -0
- package/core/constructor-hierarchy.js +147 -0
- package/core/constructor-protocol.js +196 -0
- package/core/contract-membership.js +346 -140
- package/core/cpp-conversion-constraints.js +123 -0
- package/core/cpp-conversion-syntax.js +216 -0
- package/core/cpp-conversions.js +414 -0
- package/core/cpp-scope.js +245 -44
- package/core/deadcode.js +35 -15
- package/core/decorator-binding.js +137 -3
- package/core/enum-reference-syntax.js +134 -0
- package/core/execute.js +17 -1
- package/core/external-macros.js +42 -10
- package/core/go-packages.js +171 -0
- package/core/graph-build.js +2 -0
- package/core/graph.js +75 -59
- package/core/ignore-rules.js +2 -1
- package/core/imports.js +145 -19
- package/core/index-ir.js +41 -4
- package/core/ir.js +27 -6
- package/core/macro-expansion.js +38 -2
- package/core/out-of-class-members.js +182 -0
- package/core/output/analysis-ext.js +4 -2
- package/core/output/analysis.js +89 -20
- package/core/output/graph.js +12 -3
- package/core/output/lines.js +4 -3
- package/core/output/public.js +1 -0
- package/core/output/reporting.js +6 -1
- package/core/output/shared.js +2 -0
- package/core/output/tracing.js +28 -22
- package/core/output-budget.js +2 -2
- package/core/parallel-build.js +52 -1
- package/core/project.js +217 -112
- package/core/provenance-constructor-base.js +161 -0
- package/core/provenance-facts.js +257 -27
- package/core/provenance-overload.js +458 -54
- package/core/provenance-type.js +487 -0
- package/core/provenance.js +234 -15
- package/core/public-command.js +17 -2
- package/core/query-bodies.js +159 -0
- package/core/reflection.js +255 -2
- package/core/rename-token-syntax.js +111 -0
- package/core/reporting.js +13 -7
- package/core/rust-macro-expansion.js +151 -19
- package/core/rust-modules.js +1 -1
- package/core/rust-names.js +607 -0
- package/core/search.js +70 -17
- package/core/shared.js +98 -1
- package/core/source-memo.js +201 -0
- package/core/text-usage-syntax.js +38 -0
- package/core/tracing.js +7 -1
- package/core/type-denotation.js +124 -37
- package/core/type-references.js +615 -246
- package/core/value-references.js +2777 -0
- package/core/verify.js +1097 -281
- package/languages/adapter.js +28 -4
- package/languages/c-family.js +1118 -164
- package/languages/constructor-bases.js +105 -0
- package/languages/cpp-platform.js +26 -0
- package/languages/cpp-site-syntax.js +83 -0
- package/languages/csharp-scope.js +439 -0
- package/languages/csharp.js +428 -68
- package/languages/go.js +385 -207
- package/languages/html.js +4 -2
- package/languages/index.js +397 -2
- package/languages/java-platform.js +226 -0
- package/languages/java-unicode.js +269 -0
- package/languages/java.js +461 -117
- package/languages/javascript.js +418 -66
- package/languages/lexical-scope.js +190 -23
- package/languages/python.js +404 -54
- package/languages/rust.js +510 -82
- package/languages/utils.js +67 -8
- package/mcp/server.js +8 -2
- package/package.json +2 -2
package/core/output/tracing.js
CHANGED
|
@@ -39,18 +39,31 @@ function renderFrontier(lines, frontier, options = {}, expanded = false) {
|
|
|
39
39
|
return true;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
/**
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
42
|
+
/**
|
|
43
|
+
* A node's unresolved callee calls as [unverified] leaves, then the
|
|
44
|
+
* constructions whose constructor body is undecided (fix #421; their class
|
|
45
|
+
* edge is a child of the node).
|
|
46
|
+
*/
|
|
47
|
+
function undecidedLeafLines(node) {
|
|
48
|
+
const out = [];
|
|
49
|
+
for (const u of node.unverifiedCallees || []) {
|
|
50
50
|
const owners = u.ownerCount > 1 ? ` (${u.ownerCount} owners)` : '';
|
|
51
51
|
const linesPart = u.sites && u.sites.length > 0 ? ` L${u.sites.join(',L')}` : '';
|
|
52
|
-
|
|
52
|
+
out.push(`[unverified] ${u.name} — ${u.reason}${owners}${linesPart}`);
|
|
53
|
+
}
|
|
54
|
+
for (const r of node.initializerReviews || []) {
|
|
55
|
+
const candidates = r.candidates > 1 ? ` (${r.candidates} candidates)` : '';
|
|
56
|
+
const linesPart = r.sites && r.sites.length > 0 ? ` L${r.sites.join(',L')}` : '';
|
|
57
|
+
const label = r.name === r.initializerOf ? r.name : `${r.initializerOf}.${r.name}`;
|
|
58
|
+
out.push(`[constructor undecided] ${label} — ${r.reason}${candidates}${linesPart}`);
|
|
53
59
|
}
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function renderUnverifiedCallees(lines, node, prefix, isParentLast) {
|
|
64
|
+
const leaves = undecidedLeafLines(node);
|
|
65
|
+
const extension = isParentLast ? ' ' : '│ ';
|
|
66
|
+
leaves.forEach((text, i) => lines.push(`${prefix}${extension}${i === leaves.length - 1 ? '└── ' : '├── '}${text}`));
|
|
54
67
|
}
|
|
55
68
|
|
|
56
69
|
/** TREE ACCOUNT line for caller-direction trees. */
|
|
@@ -129,6 +142,7 @@ function formatTrace(trace, options = {}) {
|
|
|
129
142
|
} else if (node.file) {
|
|
130
143
|
label += ` (${node.file}:${node.line})`;
|
|
131
144
|
}
|
|
145
|
+
if (node.constructs) label += ` (constructs ${node.constructs})`;
|
|
132
146
|
if (node.weight && node.weight !== 'normal') {
|
|
133
147
|
label += ` [${node.weight}]`;
|
|
134
148
|
}
|
|
@@ -143,7 +157,7 @@ function formatTrace(trace, options = {}) {
|
|
|
143
157
|
|
|
144
158
|
if (node.children && !node.alreadyShown) {
|
|
145
159
|
const hasMore = node.truncatedChildren > 0;
|
|
146
|
-
const hasUnverified = node.unverifiedCallees
|
|
160
|
+
const hasUnverified = node.unverifiedCallees?.length > 0 || node.initializerReviews?.length > 0;
|
|
147
161
|
for (let i = 0; i < node.children.length; i++) {
|
|
148
162
|
const isChildLast = !hasMore && !hasUnverified && i === node.children.length - 1;
|
|
149
163
|
renderNode(node.children[i], prefix + extension, isChildLast);
|
|
@@ -160,7 +174,8 @@ function formatTrace(trace, options = {}) {
|
|
|
160
174
|
lines.push(trace.root);
|
|
161
175
|
if (trace.tree && trace.tree.children) {
|
|
162
176
|
const rootHasMore = trace.tree.truncatedChildren > 0;
|
|
163
|
-
const
|
|
177
|
+
const rootLeaves = undecidedLeafLines(trace.tree);
|
|
178
|
+
const rootHasUnverified = rootLeaves.length > 0;
|
|
164
179
|
for (let i = 0; i < trace.tree.children.length; i++) {
|
|
165
180
|
const isLast = !rootHasMore && !rootHasUnverified && i === trace.tree.children.length - 1;
|
|
166
181
|
renderNode(trace.tree.children[i], '', isLast);
|
|
@@ -169,17 +184,8 @@ function formatTrace(trace, options = {}) {
|
|
|
169
184
|
hasTruncation = true;
|
|
170
185
|
lines.push((rootHasUnverified ? '├── ' : '└── ') + `... and ${trace.tree.truncatedChildren} more callees`);
|
|
171
186
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
for (let i = 0; i < trace.tree.unverifiedCallees.length; i++) {
|
|
175
|
-
const u = trace.tree.unverifiedCallees[i];
|
|
176
|
-
const isLast = i === trace.tree.unverifiedCallees.length - 1;
|
|
177
|
-
const connector = isLast ? '└── ' : '├── ';
|
|
178
|
-
const owners = u.ownerCount > 1 ? ` (${u.ownerCount} owners)` : '';
|
|
179
|
-
const linesPart = u.sites && u.sites.length > 0 ? ` L${u.sites.join(',L')}` : '';
|
|
180
|
-
lines.push(`${connector}[unverified] ${u.name} — ${u.reason}${owners}${linesPart}`);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
187
|
+
// Root-level unverified callees: render with no prefix
|
|
188
|
+
rootLeaves.forEach((text, i) => lines.push(`${i === rootLeaves.length - 1 ? '└── ' : '├── '}${text}`));
|
|
183
189
|
}
|
|
184
190
|
|
|
185
191
|
// Callers section
|
package/core/output-budget.js
CHANGED
|
@@ -15,10 +15,10 @@ const BROAD_COMMANDS = new Set([
|
|
|
15
15
|
...[...BROAD_CANONICAL].map(toMcpName),
|
|
16
16
|
]);
|
|
17
17
|
|
|
18
|
-
const CONTRACT_LINE_RE = /^\s*(?:(?:Summary|ACCOUNT|CONTRACT|WARNING|FILTERED|CALLEE ACCOUNT|TREE ACCOUNT|Note):|\d+ test-file usage\(s\) hidden\b|Found \d+ (?:definitions|fuzzy matches)\b)/;
|
|
18
|
+
const CONTRACT_LINE_RE = /^\s*(?:(?:Summary|ACCOUNT|CONTRACT|WARNING|FILTERED|CALLEE ACCOUNT|TREE ACCOUNT|VALUE ACCOUNT|TYPE ACCOUNT|Note):|\d+ test-file usage\(s\) hidden\b|Found \d+ (?:definitions|fuzzy matches)\b)/;
|
|
19
19
|
// Trust lines: the accounting and contract lines that qualify a caller
|
|
20
20
|
// answer. A truncated answer carries every one of them or none of its body.
|
|
21
|
-
const TRUST_LINE_RE = /^(?:ACCOUNT|CONTRACT|WARNING|FILTERED|CALLEE ACCOUNT|TREE ACCOUNT):/;
|
|
21
|
+
const TRUST_LINE_RE = /^(?:ACCOUNT|CONTRACT|WARNING|FILTERED|CALLEE ACCOUNT|TREE ACCOUNT|VALUE ACCOUNT|TYPE ACCOUNT):/;
|
|
22
22
|
const MAX_PRESERVED_CONTRACT_LINES = 24;
|
|
23
23
|
const MAX_PRESERVED_CONTRACT_CHARS = 8000;
|
|
24
24
|
|
package/core/parallel-build.js
CHANGED
|
@@ -275,4 +275,55 @@ function parallelBuild(index, files, options = {}) {
|
|
|
275
275
|
return changed;
|
|
276
276
|
}
|
|
277
277
|
|
|
278
|
-
|
|
278
|
+
/**
|
|
279
|
+
* Worker threads for a sequential build's Rust macro expansion (fix #422): a
|
|
280
|
+
* pool shaped like the one a parallel build keeps (`options.onParsed`), whose
|
|
281
|
+
* workers have no file to parse and wait for their expansion job. A crate
|
|
282
|
+
* whose API macros generate most of its code has little source to parse and
|
|
283
|
+
* much expansion work.
|
|
284
|
+
*/
|
|
285
|
+
function spawnExpansionPool(index, count) {
|
|
286
|
+
if (!(count >= 1)) return null;
|
|
287
|
+
const sab = new SharedArrayBuffer(4 * (count + 1));
|
|
288
|
+
const control = new SharedArrayBuffer(4 * count);
|
|
289
|
+
const controlArray = new Int32Array(control);
|
|
290
|
+
const ports = [];
|
|
291
|
+
const workers = [];
|
|
292
|
+
for (let i = 0; i < count; i++) {
|
|
293
|
+
const { port1, port2 } = new MessageChannel();
|
|
294
|
+
ports.push(port1);
|
|
295
|
+
const worker = new Worker(path.join(__dirname, 'build-worker.js'), {
|
|
296
|
+
workerData: {
|
|
297
|
+
files: [], rootDir: index.root, existingHashes: {}, signal: sab, workerIndex: i,
|
|
298
|
+
queueIndex: count, port: port2, control, macroDictionary: null, dictionarySignal: null,
|
|
299
|
+
},
|
|
300
|
+
transferList: [port2],
|
|
301
|
+
resourceLimits: { maxYoungGenerationSizeMb: WORKER_YOUNG_GENERATION_MB },
|
|
302
|
+
});
|
|
303
|
+
worker.unref();
|
|
304
|
+
workers.push(worker);
|
|
305
|
+
}
|
|
306
|
+
const live = new Set(workers.map((_, i) => i));
|
|
307
|
+
const retire = i => {
|
|
308
|
+
if (!live.delete(i)) return;
|
|
309
|
+
Atomics.store(controlArray, i, 1);
|
|
310
|
+
Atomics.notify(controlArray, i);
|
|
311
|
+
ports[i].close();
|
|
312
|
+
workers[i].terminate();
|
|
313
|
+
};
|
|
314
|
+
return {
|
|
315
|
+
available: [...live],
|
|
316
|
+
ports,
|
|
317
|
+
post(i, job) {
|
|
318
|
+
ports[i].postMessage(job);
|
|
319
|
+
Atomics.store(controlArray, i, 2);
|
|
320
|
+
Atomics.notify(controlArray, i);
|
|
321
|
+
},
|
|
322
|
+
retire,
|
|
323
|
+
dispose() {
|
|
324
|
+
for (const i of [...live]) retire(i);
|
|
325
|
+
},
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
module.exports = { parallelBuild, scheduleFiles, spawnExpansionPool };
|