ucn 3.8.25 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/core/bridge.js CHANGED
@@ -86,11 +86,6 @@ function joinRoutePath(prefix, sub) {
86
86
  return p + '/' + s;
87
87
  }
88
88
 
89
- /** True if `s` ends with the wildcard sentinel from a template literal. */
90
- function endsWithWildcard(s) {
91
- return typeof s === 'string' && s.endsWith('*');
92
- }
93
-
94
89
  // ============================================================================
95
90
  // FRAMEWORK PATTERNS
96
91
  // ============================================================================
@@ -253,17 +248,6 @@ const PREFIX_ANNOTATIONS = new Set([
253
248
  'Path', // JAX-RS class-level @Path("/api")
254
249
  ]);
255
250
 
256
- // Python decorator name patterns (e.g., 'app.route' or 'app.get')
257
- // Returns { method, isPrefix } when matched.
258
- function parsePythonDecorator(name) {
259
- if (typeof name !== 'string') return null;
260
- const m = name.match(/^[A-Za-z_][A-Za-z0-9_]*\.(route|get|post|put|delete|patch|options|head)/i);
261
- if (!m) return null;
262
- const verb = m[1].toLowerCase();
263
- if (verb === 'route') return { method: 'ALL', isRoute: true };
264
- return { method: verb.toUpperCase() };
265
- }
266
-
267
251
  // ============================================================================
268
252
  // EXTRACT SERVER ROUTES
269
253
  // ============================================================================
@@ -34,6 +34,14 @@ function addSymbol(fileEntry, item, type) {
34
34
  docstring: item.docstring,
35
35
  bindingId: `${fileEntry.relativePath}:${type}:${item.startLine}`,
36
36
  };
37
+ // Field set MUST mirror project.js addSymbol exactly — a worker-side drop
38
+ // silently strips the field from every parallel-built index (>500 files).
39
+ // The cache.test.js / perf-optimizations.test.js indexSnapshot guards
40
+ // compare full symbol shapes, but only for shapes present in their
41
+ // fixtures — keep this list in sync by hand when addSymbol grows.
42
+ if (item.paramTypes) symbol.paramTypes = item.paramTypes;
43
+ if (item.isAsync) symbol.isAsync = true;
44
+ if (item.isGenerator) symbol.isGenerator = true;
37
45
  if (item.generics) symbol.generics = item.generics;
38
46
  if (item.extends) symbol.extends = item.extends;
39
47
  if (item.implements) symbol.implements = item.implements;
@@ -44,9 +52,14 @@ function addSymbol(fileEntry, item, type) {
44
52
  if (item.className) symbol.className = item.className;
45
53
  if (item.memberType) symbol.memberType = item.memberType;
46
54
  if (item.fieldType) symbol.fieldType = item.fieldType;
55
+ if (item.aliasOf) symbol.aliasOf = item.aliasOf;
47
56
  if (item.decorators && item.decorators.length > 0) symbol.decorators = item.decorators;
57
+ if (item.decoratorsWithArgs && item.decoratorsWithArgs.length > 0) symbol.decoratorsWithArgs = item.decoratorsWithArgs;
58
+ if (item.annotationsWithArgs && item.annotationsWithArgs.length > 0) symbol.annotationsWithArgs = item.annotationsWithArgs;
59
+ if (item.attributesWithArgs && item.attributesWithArgs.length > 0) symbol.attributesWithArgs = item.attributesWithArgs;
48
60
  if (item.nameLine) symbol.nameLine = item.nameLine;
49
61
  if (item.traitImpl) symbol.traitImpl = true;
62
+ if (item.traitName) symbol.traitName = item.traitName;
50
63
  if (item.isSignature) symbol.isSignature = true;
51
64
 
52
65
  fileEntry.symbols.push(symbol);
@@ -130,6 +143,12 @@ function processFile(filePath) {
130
143
  size: stat.size,
131
144
  imports: imports.map(i => i.module),
132
145
  importNames: imports.flatMap(i => i.names || []),
146
+ // Paired name↔module bindings (fix #209) — mirrors indexFile; was
147
+ // missing here, so parallel-built indexes (>500 files) silently lost
148
+ // the name-level scope/ownership discipline (found during fix #217).
149
+ importBindings: imports.flatMap(i => (i.names || [])
150
+ .filter(n => n && n !== '*' && n !== '_' && n !== '.')
151
+ .map(n => ({ name: n, module: i.module }))),
133
152
  exports: exports.map(e => e.name),
134
153
  exportDetails: exports,
135
154
  symbols: [],
@@ -137,6 +156,7 @@ function processFile(filePath) {
137
156
  dynamicImports: dynamicCount || 0,
138
157
  };
139
158
  if (importAliases) fileEntry.importAliases = importAliases;
159
+ if (parsed.moduleAssignedNames) fileEntry.moduleAssignedNames = parsed.moduleAssignedNames;
140
160
  if (isBundled) fileEntry.isBundled = true;
141
161
  if (isGenerated) fileEntry.isGenerated = true;
142
162
 
@@ -152,7 +172,7 @@ function processFile(filePath) {
152
172
  addSymbol(fileEntry, cls, cls.type || 'class');
153
173
  if (cls.members) {
154
174
  for (const m of cls.members) {
155
- addSymbol(fileEntry, { ...m, className: cls.name, ...(cls.traitName && { traitImpl: true }) }, m.memberType || 'method');
175
+ addSymbol(fileEntry, { ...m, className: cls.name, ...(cls.traitName && { traitImpl: true, traitName: cls.traitName }) }, m.memberType || 'method');
156
176
  }
157
177
  }
158
178
  }
package/core/cache.js CHANGED
@@ -13,6 +13,46 @@ const { expandGlob, detectProjectPattern, parseGitignore, DEFAULT_IGNORES } = re
13
13
  // Read UCN version for cache invalidation
14
14
  const UCN_VERSION = require('../package.json').version;
15
15
 
16
+ // Index/calls cache format version — bump when the persisted call-record or
17
+ // symbol shape changes (saveCache writes it; loadCache rejects anything else).
18
+ // v14: Go qualified composite literals (pkg.Foo{...}) record the package
19
+ // qualifier as `receiver` (fix #206).
20
+ // v15: Go/Rust/Java calls record assignedTo (+assignedTuple/assignedUnwrap)
21
+ // for nominal return-type flow; Java declared-type locals feed receiverType
22
+ // (fix #207).
23
+ // v16: Rust/Go type-alias symbols record aliasOf (fix #208 — alias-qualified
24
+ // receivers are the aliased type); Go `type A = B` aliases now indexed.
25
+ // v17: TS type-alias symbols record aliasOf (fix #208 TS parity — alias-
26
+ // annotated receivers validate against the aliased type).
27
+ // v18: Go callback references carry localShadow (fix #203 Go parity —
28
+ // func-literal params and block locals shadow bare-identifier references).
29
+ // v19: Rust trait-impl member symbols carry traitName (fix #210 — external-
30
+ // contract attribution: `impl Iterator for X` members name their contract).
31
+ // v20: persisted extends/extendedBy graphs split parent lists on TOP-LEVEL
32
+ // commas and strip type-argument suffixes (fix #214 — `extends Base<string,
33
+ // object>` produced parents ["Base<string", "object>"], so every generically
34
+ // extended class had no usable ancestor edges).
35
+ // v21: fileEntry.moduleAssignedNames (fix #217)
36
+ // v22 (fix #219): JS/TS member fieldType; receiverRoot/receiverField/
37
+ // receiverRootType + receiverCall/receiverCallIsMethod/receiverCallAwaited on
38
+ // JS/TS/Python calls; build-worker symbol-field parity (paramTypes, isAsync,
39
+ // isGenerator, aliasOf, traitName, *WithArgs were silently dropped from
40
+ // parallel-built indexes).
41
+ // v23 (fix #220): receiverCall/receiverCallIsMethod on Go/Rust/Java calls
42
+ // (+receiverCallReceiver for Go package-qualified producers); Go receiverType
43
+ // from `var x T` declarations and new(T) allocations; Rust literal-receiver
44
+ // types ("...".parse() → str).
45
+ // v24 (fix #221): boundCall on JS/TS bind/call/apply call records (family B
46
+ // contract field — edges surface as calledAs:'bound').
47
+ // v25 (fix #222): turbofish path receivers — `Vec::<T>::new()` records
48
+ // receiver 'Vec' in BOTH the macro token-tree branch (was receiver-less) and
49
+ // the AST branch (was 'Vec::<T>').
50
+ // v26 (fix #223): Go selector-call line attribution moves to the FIELD
51
+ // node's line (the #201/RUST-2 name-node convention — multi-line receivers
52
+ // like `(&pkg.Name{...}).String()` reported the chain-start line; Go was the
53
+ // only parser still keying calls off the call node's start).
54
+ const CACHE_FORMAT_VERSION = 26;
55
+
16
56
  /**
17
57
  * Save index to cache file
18
58
  * @param {object} index - ProjectIndex instance
@@ -109,7 +149,16 @@ function saveCache(index, cachePath) {
109
149
 
110
150
  const cacheData = {
111
151
  // v10: persist _reachableSymbols set (computed by entrypoints.computeReachability)
112
- version: 10,
152
+ // v11: fix #202 — calls carry receiverRoot/receiverField/receiverRootType,
153
+ // Java classes emit field members with fieldType (stale shapes would
154
+ // silently disable declared-field receiver typing)
155
+ // v12: fix #203 — callback references carry localShadow (lexical-scope
156
+ // shadowing computed parser-side)
157
+ // v13: fix #205 — Python/Go/Rust/Java calls carry argCount (+argSpread
158
+ // where the language has call-site spread); Java calls carry
159
+ // argKinds for overload discipline (stale shapes would silently
160
+ // disable arity pruning)
161
+ version: CACHE_FORMAT_VERSION,
113
162
  ucnVersion: UCN_VERSION, // Invalidate cache when UCN is updated
114
163
  configHash,
115
164
  root,
@@ -215,7 +264,7 @@ function loadCache(index, cachePath) {
215
264
  // v7: symbols/bindings stripped from file entries (dedup)
216
265
  // v9: addSymbol propagates isAsync/isGenerator/paramTypes (force rebuild for old)
217
266
  // v10: persists _reachableSymbols set
218
- if (cacheData.version !== 10) {
267
+ if (cacheData.version !== CACHE_FORMAT_VERSION) {
219
268
  return false;
220
269
  }
221
270
 
@@ -566,5 +615,5 @@ function _computeReachabilityFingerprint(index) {
566
615
 
567
616
  module.exports = {
568
617
  saveCache, loadCache, loadCallsCache, isCacheStale, ensureCallsCacheLoaded,
569
- _computeReachabilityFingerprint,
618
+ _computeReachabilityFingerprint, CACHE_FORMAT_VERSION,
570
619
  };