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.
Files changed (93) hide show
  1. package/.claude/skills/ucn/SKILL.md +35 -9
  2. package/.claude/skills/ucn/references/commands.md +38 -16
  3. package/.claude/skills/ucn/references/resolution-rules.md +126 -20
  4. package/.claude/skills/ucn/references/trust-contract.md +5 -3
  5. package/README.md +30 -21
  6. package/cli/index.js +1 -1
  7. package/core/accessors.js +341 -54
  8. package/core/account.js +74 -20
  9. package/core/analysis.js +257 -125
  10. package/core/ast-analysis.js +12 -3
  11. package/core/brief.js +8 -4
  12. package/core/build-worker.js +2 -1
  13. package/core/cache.js +137 -6
  14. package/core/call-name-cache.js +134 -0
  15. package/core/callable-scope.js +21 -0
  16. package/core/callers.js +4726 -940
  17. package/core/check.js +22 -5
  18. package/core/class-identity.js +399 -12
  19. package/core/constructor-calls.js +831 -0
  20. package/core/constructor-hierarchy.js +147 -0
  21. package/core/constructor-protocol.js +196 -0
  22. package/core/contract-membership.js +346 -140
  23. package/core/cpp-conversion-constraints.js +123 -0
  24. package/core/cpp-conversion-syntax.js +216 -0
  25. package/core/cpp-conversions.js +414 -0
  26. package/core/cpp-scope.js +245 -44
  27. package/core/deadcode.js +35 -15
  28. package/core/decorator-binding.js +137 -3
  29. package/core/enum-reference-syntax.js +134 -0
  30. package/core/execute.js +17 -1
  31. package/core/external-macros.js +42 -10
  32. package/core/go-packages.js +171 -0
  33. package/core/graph-build.js +2 -0
  34. package/core/graph.js +75 -59
  35. package/core/ignore-rules.js +2 -1
  36. package/core/imports.js +145 -19
  37. package/core/index-ir.js +41 -4
  38. package/core/ir.js +27 -6
  39. package/core/macro-expansion.js +38 -2
  40. package/core/out-of-class-members.js +182 -0
  41. package/core/output/analysis-ext.js +4 -2
  42. package/core/output/analysis.js +89 -20
  43. package/core/output/graph.js +12 -3
  44. package/core/output/lines.js +4 -3
  45. package/core/output/public.js +1 -0
  46. package/core/output/reporting.js +6 -1
  47. package/core/output/shared.js +2 -0
  48. package/core/output/tracing.js +28 -22
  49. package/core/output-budget.js +2 -2
  50. package/core/parallel-build.js +52 -1
  51. package/core/project.js +217 -112
  52. package/core/provenance-constructor-base.js +161 -0
  53. package/core/provenance-facts.js +257 -27
  54. package/core/provenance-overload.js +458 -54
  55. package/core/provenance-type.js +487 -0
  56. package/core/provenance.js +234 -15
  57. package/core/public-command.js +17 -2
  58. package/core/query-bodies.js +159 -0
  59. package/core/reflection.js +255 -2
  60. package/core/rename-token-syntax.js +111 -0
  61. package/core/reporting.js +13 -7
  62. package/core/rust-macro-expansion.js +151 -19
  63. package/core/rust-modules.js +1 -1
  64. package/core/rust-names.js +607 -0
  65. package/core/search.js +70 -17
  66. package/core/shared.js +98 -1
  67. package/core/source-memo.js +201 -0
  68. package/core/text-usage-syntax.js +38 -0
  69. package/core/tracing.js +7 -1
  70. package/core/type-denotation.js +124 -37
  71. package/core/type-references.js +615 -246
  72. package/core/value-references.js +2777 -0
  73. package/core/verify.js +1097 -281
  74. package/languages/adapter.js +28 -4
  75. package/languages/c-family.js +1118 -164
  76. package/languages/constructor-bases.js +105 -0
  77. package/languages/cpp-platform.js +26 -0
  78. package/languages/cpp-site-syntax.js +83 -0
  79. package/languages/csharp-scope.js +439 -0
  80. package/languages/csharp.js +428 -68
  81. package/languages/go.js +385 -207
  82. package/languages/html.js +4 -2
  83. package/languages/index.js +397 -2
  84. package/languages/java-platform.js +226 -0
  85. package/languages/java-unicode.js +269 -0
  86. package/languages/java.js +461 -117
  87. package/languages/javascript.js +418 -66
  88. package/languages/lexical-scope.js +190 -23
  89. package/languages/python.js +404 -54
  90. package/languages/rust.js +510 -82
  91. package/languages/utils.js +67 -8
  92. package/mcp/server.js +8 -2
  93. package/package.json +2 -2
@@ -8,6 +8,11 @@ const path = require('path');
8
8
  const { UcnError } = require('../core/errors');
9
9
  const { createLanguageAdapter } = require('./adapter');
10
10
 
11
+ // Modules read lazily (load cycles), each resolved once: a require() per
12
+ // call in hot paths was measurable (fix #436).
13
+ let lazyJavaUnicodeModuleCache = null;
14
+ const lazyJavaUnicodeModule = () => lazyJavaUnicodeModuleCache || (lazyJavaUnicodeModuleCache = require('./java-unicode'));
15
+
11
16
  // Lazy-loaded tree-sitter
12
17
  let TreeSitter = null;
13
18
 
@@ -33,6 +38,9 @@ function protocolMembers(rules) {
33
38
  const named = rule.pattern ? rule.pattern.test(name) : rule.names.includes(name);
34
39
  if (!named) continue;
35
40
  if (rule.member && ctx.isMember === false) continue;
41
+ // A member type alias (fix #427: `typedef int& reference;`).
42
+ if (rule.typeMember && !ctx.isTypeMember) continue;
43
+ if (!rule.typeMember && ctx.isTypeMember) continue;
36
44
  // Owner kinds the runtime exempts from the protocol (fix #392:
37
45
  // Java enum constants serialize by name and ignore the callbacks).
38
46
  if (rule.exceptOwnerKinds && typeof ctx.ownerKinds === 'function' &&
@@ -96,6 +104,40 @@ const JAVA_LANG_NOT_SERIALIZABLE = ['Object', 'Runnable', 'AutoCloseable', 'Comp
96
104
 
97
105
  const STRUCTURAL_TRAITS = {
98
106
  typeSystem: 'structural',
107
+ // A write on the instance can replace an inherited method with a
108
+ // callable value, including a wrapper of the previous method.
109
+ instanceAttributesShadowMethods: true,
110
+ // An external type can supply an inherent method before a project
111
+ // trait implementation at the same receiver probe step.
112
+ inherentMethodsPrecedeTraitImpls: false,
113
+ // Field access follows proven dereference wrappers on a return value.
114
+ derefFieldAccess: false,
115
+ // Whether importing a module runs its top-level code when the importer
116
+ // loads (JS/TS/HTML scripts, Python): only then is an import cycle an
117
+ // import-time cycle (fix #433).
118
+ importsRunModules: true,
119
+ // The receiver keyword whose member lookup starts at the enclosing
120
+ // class's bases, skipping its own members (`super.m()`, Python
121
+ // `super().m()`, C# `base.M()`), or null (fix #428).
122
+ superReceiver: 'super',
123
+ // The methods whose own receiver constructs their class (fix #434):
124
+ // `new this(..)` in a static method, `new this.constructor(..)` in an
125
+ // instance method. `binding` is the parser's 'class' or 'instance'.
126
+ ownClassMethod: (method, binding) => binding === 'class' ? method.type === 'static' : method.type !== 'static',
127
+ // Whether files without module syntax share one global scope (classic
128
+ // scripts): their top-level declarations are globals (fix #434).
129
+ scriptsShareGlobalScope: true,
130
+ plainQueryTree: true,
131
+ physicalCallTokenSyntax: true,
132
+ scopeAlternativeBindings: false,
133
+ nameReferenceFamily: 'js',
134
+ staticValueImportSyntax: null,
135
+ implicitEnumCaseLabels: false,
136
+ valuePatternConstants: false,
137
+ moduleValueLookup: false,
138
+ typeArgumentValues: null,
139
+ separateStaticStorage: true,
140
+ valueScopes: null,
99
141
  // A type's identity is its declaring module (a source file or inline
100
142
  // module), not the directory (fix #384): two same-name types in two
101
143
  // modules of one directory are distinct (JS/TS, Python modules, Rust
@@ -112,6 +154,9 @@ const STRUCTURAL_TRAITS = {
112
154
  // 'namespace-usings' (C#: enclosing namespaces, then using directives,
113
155
  // global usings and project-file <Using> items), or null.
114
156
  typeNameScoping: null,
157
+ typeNameSourceCanonical: null,
158
+ typeNameOwnersAt: null,
159
+ implementationOwnerSyntax: null,
115
160
  // Types every file imports on demand without writing it (Java java.lang,
116
161
  // JLS 7.3): { module, names }. A project type of the same name in another
117
162
  // package is visible only through an import.
@@ -128,7 +173,23 @@ const STRUCTURAL_TRAITS = {
128
173
  // signature must not use `= value` syntax (Go/Java/Rust).
129
174
  hasDefaultParams: true,
130
175
  allMethodsVirtual: false,
176
+ // A class member fills the slot of every supertype declaring that member
177
+ // (an override of `A.m` in `D(A, B)` overrides `B.m` too), and a member a
178
+ // class inherits implements its own interfaces' members (TS `class Impl
179
+ // extends Base implements Bean`): plan's rename closure climbs from
180
+ // every slot holder (fix #426). memberHidingModifier: the modifier of a
181
+ // member that hides the inherited one instead (C# `new`).
182
+ memberFillsSupertypeSlots: true,
183
+ inheritedMemberFillsSlots: true,
184
+ memberHidingModifier: null,
185
+ virtualMemberModifiers: null,
131
186
  hasArityOverloads: false,
187
+ userDefinedConversions: null,
188
+ overloadPhases: null,
189
+ overloadFileSymbols: false,
190
+ inheritedOverloadSignatures: false,
191
+ // Interface instance members join lookup after the superclass chain.
192
+ interfaceMembersInMethodLookup: false,
132
193
  // Whether `from pkg import name` can bind a SUBMODULE file as a plain
133
194
  // name (fix #224). Python sets true: graph-build resolves the composed
134
195
  // dotted specifier and records it in moduleResolved, making the receiver
@@ -155,6 +216,31 @@ const STRUCTURAL_TRAITS = {
155
216
  // inside a class means this.execute(), and static imports bind foreign
156
217
  // class methods to bare names (fix #220).
157
218
  bareCallReachesMethods: false,
219
+ // A function declared in a function body is a binding of that body
220
+ // (JS/TS function scope, fix #423; Python defs, fix #402): a bare name
221
+ // outside the enclosing function never names it.
222
+ nestedItemsBlockScoped: true,
223
+ // Whether a declaration binds its name in its whole scope whatever its
224
+ // position (JS/TS: function declarations hoist, `let`/`const`/`class`
225
+ // names resolve statically; fix #423). Python binds names as statements
226
+ // run, so a module-level reference sees only earlier bindings.
227
+ staticModuleScope: true,
228
+ // Where a bare (receiver-less) name can denote a class or enum MEMBER
229
+ // value when bare names never reach methods (fix #420): 'declaration-body'
230
+ // (JS/TS: only inside the enum or namespace declaring it), 'class-body'
231
+ // (Python: directly in the class body, never in its methods), 'imports'
232
+ // (Rust: enum variants a `use` brings in), 'none' (Go struct fields, C).
233
+ // Imports in these languages never name a member either.
234
+ bareValueMemberScope: 'declaration-body',
235
+ // An enum member names a type of its own (TS literal enum member types:
236
+ // `kind: Kind.Text` in an annotation reads the member, fix #431).
237
+ enumMemberTypes: true,
238
+ // A type path can name a field (`T::f` for a static member): Rust sets
239
+ // false (fix #431).
240
+ typePathReachesFields: true,
241
+ // Classes whose synthesized initializer takes their fields as keyword
242
+ // parameters (Python dataclasses, NamedTuple, TypedDict), or null.
243
+ fieldInitializers: null,
158
244
  // A method-shaped call CAN reach a standalone function here: attribute
159
245
  // assignment rebinds functions onto objects (obj.print = print), so the
160
246
  // #218b gate routes such calls visible instead of excluding (fix #220).
@@ -165,6 +251,24 @@ const STRUCTURAL_TRAITS = {
165
251
  // Whether `Type(...)` constructs a class without a `new` token. Python
166
252
  // classes are ordinary callable objects; JS/TS classes require `new`.
167
253
  classesCallableWithoutNew: false,
254
+ hasConstructors: true,
255
+ fixedConstructorName: 'constructor',
256
+ constructorArgumentNodes: { delegation: { nodeType: 'call_expression', argsField: 'arguments' } },
257
+ functionalTypeConstruction: false,
258
+ constructorInheritance: { order: 'single', classNodes: ['class_declaration', 'class'], headerNode: 'class_heritage' },
259
+ implicitBaseConstruction: null,
260
+ // Whether a constructor delegation is spelled by a keyword (`this(..)`,
261
+ // `super(..)`, `base(..)`) rather than by the type's name (C++
262
+ // mem-initializers): such a site holds no token a type rename edits
263
+ // (fix #421).
264
+ keywordConstructorDelegation: false,
265
+ constructorUsesAreTypeReferences: false,
266
+ packExpansionArguments: false,
267
+ // Whether a call may pass more or fewer arguments than the callee
268
+ // declares without error (JavaScript): argument count then never decides
269
+ // which one callable runs. TypeScript reports the mismatch at compile time
270
+ // and Python raises at run time, so there it stays evidence (fix #421).
271
+ lenientCallArity: false,
168
272
  // Whether a decorator REPLACES the callable it decorates with its own
169
273
  // return value (Python/JS decorators, fix #364). What a decorated async
170
274
  // function's call returns is then decided by the decorator, not by the
@@ -212,6 +316,11 @@ const STRUCTURAL_TRAITS = {
212
316
  // `Func<int> f = Build`): plan renames it by the language's simple-name
213
317
  // lookup. Java spells method values apart (`Type::m`).
214
318
  methodGroupReferences: false,
319
+ methodGroupReceiver: null,
320
+ // AST terminal-name test for invocations wrapped in generic syntax.
321
+ isInvokedName: null,
322
+ accessorReferenceShape: null,
323
+ accessorTypeSyntax: null,
215
324
  // Whether a class may declare a field and a method of one name, so a
216
325
  // paren-less member access (`this.size`) names the field and a method
217
326
  // value is spelled apart (`obj::m`, `Type::m`) (fix #390: Java, Rust).
@@ -262,10 +371,42 @@ const STRUCTURAL_TRAITS = {
262
371
  };
263
372
  const NOMINAL_TRAITS = {
264
373
  typeSystem: 'nominal',
374
+ instanceAttributesShadowMethods: false,
375
+ inherentMethodsPrecedeTraitImpls: false,
376
+ derefFieldAccess: false,
377
+ importsRunModules: false,
378
+ superReceiver: null,
379
+ ownClassMethod: null,
380
+ scriptsShareGlobalScope: false,
381
+ hasConstructors: false,
382
+ fixedConstructorName: null,
383
+ constructorInheritance: null,
384
+ implicitBaseConstruction: null,
385
+ keywordConstructorDelegation: false,
386
+ constructorUsesAreTypeReferences: false,
387
+ packExpansionArguments: false,
388
+ // Whether a member may be defined outside its class body (C++
389
+ // `W::W(int) {}` in a source file, its class in a header): such a
390
+ // definition holds the body of one in-class declaration (fix #421).
391
+ outOfClassMemberDefinitions: false,
392
+ plainQueryTree: true,
393
+ physicalCallTokenSyntax: true,
394
+ scopeAlternativeBindings: false,
395
+ nameReferenceFamily: null,
396
+ staticValueImportSyntax: null,
397
+ implicitEnumCaseLabels: false,
398
+ valuePatternConstants: false,
399
+ moduleValueLookup: false,
400
+ typeArgumentValues: null,
401
+ separateStaticStorage: false,
402
+ valueScopes: null,
265
403
  moduleTypeIdentity: false,
266
404
  standardPathRoots: [],
267
405
  typeNameScoping: null,
406
+ typeNameSourceCanonical: null,
407
+ typeNameOwnersAt: null,
268
408
  implicitTypeImport: null,
409
+ implementationOwnerSyntax: null,
269
410
  methodCallInclusion: 'auto',
270
411
  packageScope: 'file',
271
412
  hasReceiverPackageCalls: false,
@@ -291,11 +432,25 @@ const NOMINAL_TRAITS = {
291
432
  // sets and Rust inherent methods bind statically — only interface/trait
292
433
  // receivers dispatch there, which is detected per-type, not per-language.
293
434
  allMethodsVirtual: false,
435
+ // See STRUCTURAL_TRAITS (fix #426): Go and Rust members never fill
436
+ // other supertypes' slots (structural satisfaction and trait impls have
437
+ // closures of their own); Java, C# and C++ override.
438
+ memberFillsSupertypeSlots: false,
439
+ inheritedMemberFillsSlots: false,
440
+ memberHidingModifier: null,
441
+ virtualMemberModifiers: null,
294
442
  // Whether one class can define several same-name methods differing only
295
443
  // in parameters (Java overloading). Drives the overload discipline in
296
444
  // the caller contract: a pinned overload is only confirmed when the call
297
445
  // site provably binds it.
298
446
  hasArityOverloads: false,
447
+ // User-defined conversions keep otherwise incompatible argument types
448
+ // possible; selecting an overload still needs a positive conversion proof.
449
+ userDefinedConversions: null,
450
+ overloadPhases: null,
451
+ overloadFileSymbols: false,
452
+ inheritedOverloadSignatures: false,
453
+ interfaceMembersInMethodLookup: false,
299
454
  // What a TYPE-QUALIFIED method call looks like, so a receiver that merely
300
455
  // shares the target type's NAME isn't mistaken for the type itself:
301
456
  // 'static' — Type.method() static form, any arity (Java).
@@ -324,6 +479,10 @@ const NOMINAL_TRAITS = {
324
479
  // cobra/grpc-go-measured). Java overrides true (implicit this-calls,
325
480
  // static imports).
326
481
  bareCallReachesMethods: false,
482
+ bareValueMemberScope: 'none',
483
+ enumMemberTypes: false,
484
+ typePathReachesFields: true,
485
+ fieldInitializers: null,
327
486
  // Whether a method-shaped call (x.f()) can reach a standalone FUNCTION:
328
487
  // Go func-typed fields are name-callable (s.Run() may invoke a stored
329
488
  // function), so exclusion needs !bindingId there; Rust requires (s.f)()
@@ -346,6 +505,8 @@ const NOMINAL_TRAITS = {
346
505
  // methods — false. Per-language override, not preset-wide.
347
506
  memberAccessNeverMethod: false,
348
507
  classesCallableWithoutNew: false,
508
+ constructorArgumentNodes: {},
509
+ functionalTypeConstruction: false,
349
510
  decoratorsWrapCallables: false,
350
511
  callableDecorators: null,
351
512
  knownAsyncGlobals: null,
@@ -361,6 +522,11 @@ const NOMINAL_TRAITS = {
361
522
  docCrefReferences: false,
362
523
  // Simple-name method groups (fix #395, C#).
363
524
  methodGroupReferences: false,
525
+ methodGroupReceiver: null,
526
+ // AST terminal-name test for invocations wrapped in generic syntax.
527
+ isInvokedName: null,
528
+ accessorReferenceShape: null,
529
+ accessorTypeSyntax: null,
364
530
  // A static import of a type brings only the members the type itself
365
531
  // declares, never inherited ones (fix #392, C# `using static`). Java's
366
532
  // static imports reach inherited static members.
@@ -438,6 +604,7 @@ const LANGUAGES = {
438
604
  languageProtocolMember: JS_PROTOCOL_MEMBERS,
439
605
  storedPromises: true,
440
606
  knownAsyncGlobals: ['fetch'],
607
+ lenientCallArity: true,
441
608
  testFileCandidates: (base, ext) => [`${base}.test${ext}`, `${base}.spec${ext}`, `${base}.test.ts`, `${base}.test.js`, `${base}.spec.ts`, `${base}.spec.js`],
442
609
  testDirs: ['__tests__'],
443
610
  },
@@ -485,6 +652,21 @@ const LANGUAGES = {
485
652
  traits: {
486
653
  ...STRUCTURAL_TRAITS,
487
654
  selfParam: ['self', 'cls'],
655
+ // `cls(..)` in a classmethod (or an implicit one), `type(self)(..)`
656
+ // and `self.__class__(..)` in an instance method construct the
657
+ // method's class through its first parameter (fix #434).
658
+ ownClassMethod: (method, binding, receiver) => method.paramsStructured?.[0]?.name === receiver &&
659
+ (binding === 'class'
660
+ ? method.type === 'classmethod' || ['__init_subclass__', '__class_getitem__'].includes(method.name)
661
+ : !['classmethod', 'staticmethod'].includes(method.type) && method.name !== '__new__'),
662
+ // An inherited member shadows other bases' members in the MRO,
663
+ // no interface contract: not modeled as slot evidence (fix #426).
664
+ inheritedMemberFillsSlots: false,
665
+ memberLookupOrder: 'c3',
666
+ fixedConstructorName: null,
667
+ nameReferenceFamily: 'python',
668
+ scriptsShareGlobalScope: false,
669
+ separateStaticStorage: false,
488
670
  // fix #224: `from pkg import name` may bind a SUBMODULE file, not
489
671
  // a symbol — graph-build resolves the composed dotted specifier
490
672
  // and query code treats such receivers as module receivers. JS
@@ -493,10 +675,24 @@ const LANGUAGES = {
493
675
  // `__x` (not a dunder) is name-mangled per class (fix #397).
494
676
  privateMemberName: name => /^__/.test(String(name)) && !/__$/.test(String(name)),
495
677
  classesCallableWithoutNew: true,
678
+ constructorInheritance: { order: 'c3', classNodes: ['class_definition'], headerField: 'superclasses', keywordNode: 'keyword_argument' },
679
+ constructorProtocol: { initializer: '__init__', allocator: '__new__', metaclass: 'metaclass', builtinRoot: 'object',
680
+ functionNode: 'function_definition', classNode: 'class_definition',
681
+ headerField: 'superclasses', keywordNode: 'keyword_argument' },
496
682
  // Call sites bind by parameter name (f(x=1)); signatures carry
497
683
  // keyword-only (`*`) and positional-only (`/`) markers (fix #281).
498
684
  keywordArguments: true,
499
685
  assignmentDeclaresLocal: true,
686
+ bareValueMemberScope: 'class-body',
687
+ enumMemberTypes: false,
688
+ // Classes whose initializer the standard library synthesizes from
689
+ // their own fields (fix #431): a keyword argument of their
690
+ // construction names a field. Resolved qualified names.
691
+ fieldInitializers: {
692
+ decorators: ['dataclasses.dataclass'],
693
+ bases: ['typing.NamedTuple', 'typing_extensions.NamedTuple',
694
+ 'typing.TypedDict', 'typing_extensions.TypedDict'],
695
+ },
500
696
  // Calling an async def creates a coroutine object in any scope:
501
697
  // audit-async checks such calls in sync functions too, and
502
698
  // follows a local assigned from the call to the uses that need
@@ -507,10 +703,12 @@ const LANGUAGES = {
507
703
  // f` / `except ImportError: def f`) is one item with an
508
704
  // alternative per runtime configuration (fix #398F).
509
705
  conditionalDefinitions: 'branch',
706
+ scopeAlternativeBindings: true,
510
707
  // A def inside a function body binds a local of that function: a
511
708
  // bare name outside it never names it (fix #402), unless the
512
709
  // function declares the name `global`.
513
710
  nestedItemsBlockScoped: true,
711
+ staticModuleScope: false,
514
712
  // Decorators with a known effect on what calling the decorated
515
713
  // function returns (fix #364), as resolved qualified names (a
516
714
  // trailing `()` marks a decorator factory call). Any other
@@ -568,6 +766,8 @@ const LANGUAGES = {
568
766
  ...NOMINAL_TRAITS,
569
767
  selfParam: null,
570
768
  packageScope: 'directory',
769
+ nameReferenceFamily: 'go',
770
+ closedQueryBodies: ['function_declaration', 'method_declaration', 'func_literal'],
571
771
  hasReceiverPackageCalls: true,
572
772
  exportVisibility: 'capitalization',
573
773
  hasDynamicImports: false,
@@ -581,6 +781,9 @@ const LANGUAGES = {
581
781
  },
582
782
  testFileCandidates: (base, ext) => [`${base}_test.go`],
583
783
  nameBoundTestFunctions: GO_EXAMPLE_NAMES,
784
+ // One package-level name declared in files of one package under
785
+ // different build constraints is one item (fix #425).
786
+ conditionalDefinitions: 'build-constraint',
584
787
  },
585
788
  },
586
789
  rust: {
@@ -592,18 +795,38 @@ const LANGUAGES = {
592
795
  traits: {
593
796
  ...NOMINAL_TRAITS,
594
797
  selfParam: ['self', '&self', '&mut self', 'mut self'],
798
+ inherentMethodsPrecedeTraitImpls: true,
799
+ derefFieldAccess: true,
800
+ nameReferenceFamily: 'rust',
801
+ // Members live in impl blocks, separate from the declaration
802
+ // of the type. Resolve the written self type in the impl scope.
803
+ implementationOwnerSyntax: { node: 'impl_item', field: 'type' },
804
+ staticEnumReferenceSyntax: true,
805
+ valuePatternConstants: true,
806
+ moduleValueLookup: true,
807
+ typeArgumentValues: 'generic-parameter',
808
+ // A struct's fields are reached through a value (`x.f`, struct
809
+ // expressions and patterns); a type path `T::f` names an
810
+ // associated item (fix #431).
811
+ typePathReachesFields: false,
595
812
  hasDynamicImports: false,
596
813
  moduleTypeIdentity: true,
597
814
  // Same-scope definitions of one name are configuration
598
815
  // alternatives selected by `#[cfg]` (fix #376).
599
816
  conditionalDefinitions: 'attribute',
600
817
  typeQualifiedCallStyle: 'path',
818
+ // A path segment's case tells a type from a module (CamelCase
819
+ // types, snake_case modules: the language's naming lints); C++
820
+ // namespaces are not case-coded, its qualifiers are resolved by
821
+ // name lookup (fix #427).
822
+ caseCodedPathQualifiers: true,
601
823
  standardPathRoots: ['std', 'core', 'alloc'],
602
824
  // Call records say whether their value is consumed where it is
603
825
  // produced (`valueConsumed`, `consumingMethod`; fix #371).
604
826
  callValueFacts: true,
605
827
  memberAccessNeverMethod: true,
606
828
  fieldsAndMethodsSeparate: true,
829
+ bareValueMemberScope: 'imports',
607
830
  genericBoundDispatchClosed: true,
608
831
  macroTemplateBodies: true,
609
832
  // Macro invocations are written `name!(...)` / `#[name]`: a
@@ -612,6 +835,12 @@ const LANGUAGES = {
612
835
  // A fn declared inside a fn body is an item of that block: a
613
836
  // bare path outside the block never names it (fix #377).
614
837
  nestedItemsBlockScoped: true,
838
+ // A name resolves through the scopes that bind it, innermost
839
+ // first: block items and `use` declarations, then the module's
840
+ // items and explicit `use` bindings, then its globs, with types,
841
+ // values and macros in separate namespaces (fix #422,
842
+ // core/rust-names.js).
843
+ itemScopeResolution: true,
615
844
  // Names every module sees without a `use` (the std prelude of
616
845
  // editions 2015-2024 and the primitive types): a name no `use`,
617
846
  // glob or item binds must be one of them, or come from a macro
@@ -636,11 +865,39 @@ const LANGUAGES = {
636
865
  treeSitterLang: 'java',
637
866
  module: () => require('./java'),
638
867
  treeSitterModule: () => require('tree-sitter-java'),
868
+ // tree-sitter-java misreads a type annotation before a variable
869
+ // arity parameter's `...` (`Object @Nullable ... args`, JLS 8.4.1).
870
+ parseRecovery: () => require('./java').recoverTypeAnnotatedVarargs,
639
871
  traits: {
640
872
  ...NOMINAL_TRAITS,
873
+ // A method overrides/implements every supertype's same-signature
874
+ // member, an inherited one included (JLS 8.4.8) (fix #426).
875
+ memberFillsSupertypeSlots: true,
876
+ inheritedMemberFillsSlots: true,
877
+ superReceiver: 'super',
878
+ hasConstructors: true,
879
+ implicitBaseConstruction: { classes: ['class_declaration'], headerField: 'superclass',
880
+ constructors: ['constructor_declaration'], delegationNodes: ['explicit_constructor_invocation'],
881
+ ownerScope: node => require('./java').implicitOwnerScope(node),
882
+ baseKinds: ['class'], separator: '.' },
883
+ keywordConstructorDelegation: true,
884
+ constructorArgumentNodes: {
885
+ delegation: { nodeType: 'explicit_constructor_invocation', argsField: 'arguments' },
886
+ enum: { nodeType: 'enum_constant', argsField: 'arguments' },
887
+ },
641
888
  fieldsAndMethodsSeparate: true,
889
+ nameReferenceFamily: 'java',
890
+ staticEnumReferenceSyntax: true,
891
+ closedQueryBodies: ['method_declaration', 'constructor_declaration',
892
+ 'compact_constructor_declaration', 'lambda_expression'],
893
+ staticValueImportSyntax: tree => require('./java').staticValueImportSyntax(tree),
894
+ // Pattern variables are scoped by the pattern's flow (fix #420).
895
+ patternBindingReach: (binding, reference) => require('./java').patternBindingReach(binding, reference),
896
+ implicitEnumCaseLabels: true,
642
897
  standardPathRoots: ['java', 'javax'],
643
898
  typeNameScoping: 'package-on-demand',
899
+ typeNameSourceCanonical: (source, parseError, lines) => lazyJavaUnicodeModule().typeNameSourceCanonical(source, parseError, lines),
900
+ typeNameOwnersAt: (source, site) => lazyJavaUnicodeModule().typeNameOwnersAt(source, site),
644
901
  typeNamedSourceFile: true,
645
902
  // The public top-level types of java.lang (JDK 8-21, preview
646
903
  // included): a spec-level list, not project knowledge.
@@ -677,6 +934,10 @@ const LANGUAGES = {
677
934
  selfParam: ['this'],
678
935
  allMethodsVirtual: true,
679
936
  hasArityOverloads: true,
937
+ overloadPhases: 'strict-loose-variable',
938
+ overloadFileSymbols: true,
939
+ inheritedOverloadSignatures: true,
940
+ interfaceMembersInMethodLookup: true,
680
941
  universalSupertype: 'Object',
681
942
  universalSupertypeMembers: { toString: 0, equals: 1, hashCode: 0, clone: 0, finalize: 0 },
682
943
  // Serialization callbacks and fields the JVM uses reflectively.
@@ -718,6 +979,7 @@ const LANGUAGES = {
718
979
  ...NOMINAL_TRAITS,
719
980
  selfParam: null,
720
981
  packageScope: 'file',
982
+ nameReferenceFamily: 'c',
721
983
  hasDynamicImports: false,
722
984
  exportVisibility: 'linkage',
723
985
  // Same-signature definitions in one file are `#if` alternatives.
@@ -727,6 +989,7 @@ const LANGUAGES = {
727
989
  // spelled NAME( where #define NAME( is in effect is the macro
728
990
  // (fix #377).
729
991
  macroInvocationSyntax: 'call',
992
+ usageKindsOnly: true,
730
993
  typeQualifiedCallStyle: 'static',
731
994
  bareCallReachesMethods: false,
732
995
  methodCallReachesFunctions: true,
@@ -744,6 +1007,27 @@ const LANGUAGES = {
744
1007
  treeSitterModule: () => require('tree-sitter-cpp'),
745
1008
  traits: {
746
1009
  ...NOMINAL_TRAITS,
1010
+ // An override overrides every base's virtual of its signature; an
1011
+ // inherited member never implements another base's pure virtual
1012
+ // (fix #426).
1013
+ memberFillsSupertypeSlots: true,
1014
+ virtualMemberModifiers: ['virtual', 'override'],
1015
+ hasConstructors: true,
1016
+ implicitBaseConstruction: { classes: ['class_specifier', 'struct_specifier'], headerNode: 'base_class_clause',
1017
+ constructors: ['function_definition', 'field_declaration', 'declaration'], defaultPotential: true,
1018
+ constructorInfo: (...args) => require('./c-family').implicitConstructorInfo(...args),
1019
+ ownerScope: node => require('./c-family').implicitOwnerScope(node),
1020
+ baseKinds: ['class', 'struct'], separator: '::' },
1021
+ functionalTypeConstruction: true,
1022
+ outOfClassMemberDefinitions: true,
1023
+ constructorArgumentNodes: { direct: { nodeType: 'init_declarator', argsField: 'value' },
1024
+ delegation: { nodeType: 'field_initializer', argsNodeType: 'argument_list' } },
1025
+ isInvokedName: (node, options) => require('./c-family').isInvokedName(node, options),
1026
+ nameReferenceFamily: 'c',
1027
+ typeArgumentValues: 'ordinary',
1028
+ // A call's arguments may expand a parameter pack (`f(params...)`):
1029
+ // the written count is not the argument count (fix #430).
1030
+ packExpansionArguments: true,
747
1031
  selfParam: ['this'],
748
1032
  packageScope: 'file',
749
1033
  hasDynamicImports: false,
@@ -754,12 +1038,22 @@ const LANGUAGES = {
754
1038
  // spelled NAME( where #define NAME( is in effect is the macro
755
1039
  // (fix #377).
756
1040
  macroInvocationSyntax: 'call',
1041
+ usageKindsOnly: true,
757
1042
  typeQualifiedCallStyle: 'path',
758
1043
  standardPathRoots: ['std'],
759
1044
  hasArityOverloads: true,
1045
+ userDefinedConversions: 'constructors-and-operators',
760
1046
  // Range-for lowers onto member begin()/end() with no name token.
1047
+ // The standard library's traits read member types by name
1048
+ // (fix #427): std::iterator_traits (value_type, difference_type,
1049
+ // pointer, reference, iterator_category, iterator_concept),
1050
+ // std::pointer_traits (element_type), container adaptors
1051
+ // (size_type, const_reference), transparent comparators.
761
1052
  languageProtocolMember: protocolMembers([
762
1053
  { names: ['begin', 'end'], member: true },
1054
+ { names: ['value_type', 'difference_type', 'pointer', 'reference', 'iterator_category',
1055
+ 'iterator_concept', 'element_type', 'size_type', 'const_reference', 'is_transparent'],
1056
+ member: true, typeMember: true },
763
1057
  ]),
764
1058
  // C++ instance dispatch is virtual only when the declaration
765
1059
  // explicitly says virtual/override (unlike Java's implicit rule).
@@ -782,21 +1076,61 @@ const LANGUAGES = {
782
1076
  treeSitterModule: () => require('tree-sitter-c-sharp'),
783
1077
  traits: {
784
1078
  ...NOMINAL_TRAITS,
1079
+ // Interface mapping takes inherited members (C# spec 18.6.5); a
1080
+ // `new` member hides the inherited one, starting a slot of its
1081
+ // own (fix #426).
1082
+ memberFillsSupertypeSlots: true,
1083
+ inheritedMemberFillsSlots: true,
1084
+ superReceiver: 'base',
1085
+ memberHidingModifier: 'new',
1086
+ virtualMemberModifiers: ['virtual', 'abstract', 'override'],
1087
+ hasConstructors: true,
1088
+ implicitBaseConstruction: { classes: ['class_declaration', 'record_declaration'], headerNode: 'base_list',
1089
+ constructors: ['constructor_declaration'], delegationNodes: ['constructor_initializer'],
1090
+ ownerScope: node => require('./csharp').implicitOwnerScope(node),
1091
+ firstBaseOnly: true, referenceTypesOnly: true, baseKinds: ['class', 'record'], separator: '.' },
1092
+ keywordConstructorDelegation: true,
1093
+ // A use of a constructor is a use of its type (fix #430): a
1094
+ // `: this(..)` initializer depends on the type as `: base(..)`
1095
+ // depends on the base.
1096
+ constructorUsesAreTypeReferences: true,
1097
+ plainQueryTree: false,
1098
+ isInvokedName: (node, options) => require('./csharp').isInvokedName(node, options),
1099
+ nameReferenceFamily: 'csharp',
1100
+ staticEnumReferenceSyntax: true,
1101
+ enumReferenceContext: node => ({
1102
+ scopes: require('./csharp-scope').usingScopesOf(node),
1103
+ directives: require('./csharp').queryUsingDirectives(node.tree),
1104
+ }),
1105
+ closedQueryBodies: ['method_declaration', 'constructor_declaration', 'destructor_declaration',
1106
+ 'operator_declaration', 'conversion_operator_declaration', 'local_function_statement',
1107
+ 'accessor_declaration', 'lambda_expression', 'anonymous_method_expression'],
1108
+ queryBodyViews: tree => require('./csharp').queryBodyViews(tree),
1109
+ queryBodyTree: (...args) => require('./csharp').queryBodyTree(...args),
785
1110
  standardPathRoots: ['System'],
786
1111
  conditionalDefinitions: 'preprocessor',
787
1112
  typeNameScoping: 'namespace-usings',
1113
+ constructorArgumentNodes: { delegation: { nodeType: 'constructor_initializer', argsNodeType: 'argument_list' } },
788
1114
  genericArityIsIdentity: true,
789
1115
  typeArgumentsFromArgumentsOnly: true,
790
1116
  selfParam: ['this', 'base'],
791
1117
  packageScope: 'namespace',
792
1118
  hasDynamicImports: false,
793
1119
  hasArityOverloads: true,
1120
+ userDefinedConversions: 'operators',
794
1121
  bareCallReachesMethods: true,
1122
+ // The type the compiler synthesizes for top-level statements: a
1123
+ // local function there has no other class in lexical scope.
1124
+ topLevelStatementsType: 'Program',
1125
+ inheritedOverloadSignatures: true,
795
1126
  typeQualifiedCallStyle: 'static',
796
1127
  universalSupertype: 'Object',
797
1128
  universalSupertypeMembers: { ToString: 0, Equals: 1, GetHashCode: 0, Finalize: 0 },
798
1129
  docCrefReferences: true,
799
1130
  methodGroupReferences: true,
1131
+ methodGroupReceiver: node => require('./csharp').methodGroupReceiver(node),
1132
+ accessorReferenceShape: (tree, usage) => require('./csharp').accessorReferenceShape(tree, usage),
1133
+ accessorTypeSyntax: text => require('./csharp').accessorTypeSyntax(text),
800
1134
  staticImportsDeclaredOnly: true,
801
1135
  // Pattern-bound members the compiler lowers syntax onto
802
1136
  // (foreach, await, deconstruction) - invoked with no name token.
@@ -844,6 +1178,22 @@ const LANGUAGES = {
844
1178
  treeSitterModule: () => require('tree-sitter-html'),
845
1179
  traits: {
846
1180
  ...STRUCTURAL_TRAITS,
1181
+ lenientCallArity: true,
1182
+ // Embedded scripts supply their own parse trees.
1183
+ physicalCallTokenSyntax: false,
1184
+ // The script source with its rows and columns kept, parsed in its
1185
+ // own language where an edit reads tokens (fix #419).
1186
+ embeddedSyntax: { language: 'javascript', source: (content, parser) => {
1187
+ const html = require('./html');
1188
+ return html.buildVirtualJSContent(content, html.extractScriptBlocks(content, parser));
1189
+ } },
1190
+ constructorInheritance: { ...STRUCTURAL_TRAITS.constructorInheritance, syntaxLanguage: 'javascript',
1191
+ source: (content, parser) => {
1192
+ const html = require('./html');
1193
+ return html.buildVirtualJSContent(content, html.extractScriptBlocks(content, parser));
1194
+ } },
1195
+ valueScopes: (content, parser) => require('./html')
1196
+ .extractScriptBlocks(content, parser, { includeScopes: true }),
847
1197
  selfParam: ['this'],
848
1198
  storedPromises: true,
849
1199
  knownAsyncGlobals: ['fetch'],
@@ -981,7 +1331,14 @@ function _installNodeFieldCaches(TS) {
981
1331
  Object.defineProperty(base, NAMED_CHILDREN_LIST, {
982
1332
  configurable: true,
983
1333
  writable: true,
984
- value() { return namedList(this); },
1334
+ value(parent) {
1335
+ const children = namedList(this);
1336
+ // The traversal already knows this native child edge.
1337
+ // Keep leaf facts lazy: an empty list alone needs none.
1338
+ const facts = this[NODE_FACTS];
1339
+ if (parent !== undefined && facts !== undefined) facts.parent = parent;
1340
+ return children;
1341
+ },
985
1342
  });
986
1343
  Object.defineProperty(base, 'namedChildren', {
987
1344
  configurable: true,
@@ -1145,9 +1502,13 @@ function getParser(language) {
1145
1502
  }
1146
1503
 
1147
1504
  parsers[language] = parser;
1505
+ parserLanguages.set(parser, language);
1148
1506
  return parser;
1149
1507
  }
1150
1508
 
1509
+ // The language each cached parser reads, for grammar-gap recovery (fix #428).
1510
+ const parserLanguages = new WeakMap();
1511
+
1151
1512
  /**
1152
1513
  * Detect language from file path
1153
1514
  * @param {string} filePath - File path
@@ -1241,10 +1602,32 @@ function getParseOptions(contentLength = 0) {
1241
1602
  let _lastParseParser = null;
1242
1603
  let _lastParseContent = null;
1243
1604
  let _lastParseTree = null;
1605
+ // The plain parse of the file an analysis reads (fix #436): a language may
1606
+ // parse other views of the source after it (recoveries, configurations),
1607
+ // and an index-time fact of the literal tree then needs no second parse.
1608
+ let _literalCapture = null;
1609
+
1610
+ /** Remember the tree of the next plain parse of exactly (parser, content). */
1611
+ function captureLiteralParse(parser, content) {
1612
+ _literalCapture = { parser, content, tree: null };
1613
+ }
1614
+
1615
+ /** The tree captureLiteralParse remembered (null if none), ending the capture. */
1616
+ function takeLiteralParse() {
1617
+ const capture = _literalCapture;
1618
+ _literalCapture = null;
1619
+ return capture?.tree || null;
1620
+ }
1621
+
1622
+ function noteLiteralParse(parser, content, tree) {
1623
+ if (_literalCapture && !_literalCapture.tree && tree && parser === _literalCapture.parser &&
1624
+ content === _literalCapture.content) _literalCapture.tree = tree;
1625
+ }
1244
1626
 
1245
1627
  function safeParse(parser, content, oldTree = undefined, options = {}) {
1246
1628
  // Fast path: return cached tree if same parser and content (no oldTree override)
1247
1629
  if (!oldTree && parser === _lastParseParser && content === _lastParseContent && _lastParseTree) {
1630
+ noteLiteralParse(parser, content, _lastParseTree);
1248
1631
  return _lastParseTree;
1249
1632
  }
1250
1633
 
@@ -1266,12 +1649,22 @@ function safeParse(parser, content, oldTree = undefined, options = {}) {
1266
1649
  let lastError;
1267
1650
  for (const bufferSize of bufferSizes) {
1268
1651
  try {
1269
- const tree = parser.parse(content, oldTree, { ...options, bufferSize });
1652
+ let tree = parser.parse(content, oldTree, { ...options, bufferSize });
1653
+ // A language whose grammar misses a construct of valid source
1654
+ // recovers that construct by a reparse with the construct's
1655
+ // inert tokens blanked (positions unchanged, fix #428).
1656
+ const recovery = oldTree ? null : LANGUAGES[parserLanguages.get(parser)]?.parseRecovery;
1657
+ if (recovery && tree?.rootNode?.hasError) {
1658
+ const recovered = recovery()(tree, content,
1659
+ text => parser.parse(text, undefined, { ...options, bufferSize }));
1660
+ if (recovered) tree = recovered;
1661
+ }
1270
1662
  // Cache the result for same-(parser, content) reuse
1271
1663
  if (!oldTree) {
1272
1664
  _lastParseParser = parser;
1273
1665
  _lastParseContent = content;
1274
1666
  _lastParseTree = tree;
1667
+ noteLiteralParse(parser, content, tree);
1275
1668
  }
1276
1669
  return tree;
1277
1670
  } catch (e) {
@@ -1313,6 +1706,8 @@ module.exports = {
1313
1706
  PARSE_OPTIONS,
1314
1707
  getParseOptions,
1315
1708
  safeParse,
1709
+ captureLiteralParse,
1710
+ takeLiteralParse,
1316
1711
  langTraits,
1317
1712
  DEFAULT_BUFFER_SIZE,
1318
1713
  MAX_BUFFER_SIZE