ucn 5.5.1 → 5.5.3
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 +40 -18
- package/.claude/skills/ucn/references/resolution-rules.md +126 -20
- package/.claude/skills/ucn/references/trust-contract.md +5 -3
- package/README.md +32 -21
- package/cli/index.js +2 -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/bridge.js +15 -65
- 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/client-receivers.js +189 -0
- 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 +61 -16
- 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/inprocess-clients.js +41 -15
- 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 +2 -0
- package/core/output/reporting.js +12 -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 +270 -2
- package/core/rename-token-syntax.js +111 -0
- package/core/reporting.js +13 -7
- package/core/request-helpers.js +63 -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 +3 -3
|
@@ -6,20 +6,54 @@ This is portable AST analysis, not a compiler build; macros, templates, generate
|
|
|
6
6
|
|
|
7
7
|
## Every language
|
|
8
8
|
|
|
9
|
+
### Value references
|
|
10
|
+
|
|
11
|
+
Field, constant, enum-member and module-value renames use lexical bindings and declaring class identities. A local of the same name and a proven unrelated member stay unchanged. Typed parameters and explicit constructors can prove a receiver; a reassigned constructor binding stays unverified. Structural inheritance with same-named fields requires review. JS/TS static and instance fields occupy separate storage, so an instance-field rename leaves class-property reads unchanged.
|
|
12
|
+
|
|
13
|
+
Ordinary JS/TS and Python module assignments, Python class-body fields, unexported Go package values, Rust constants and statics inside modules, and C/C++ anonymous enumerators are indexed as values. Python type aliases keep their type identity. HTML module bindings stay in their own script; classic script bindings share the page scope. Unresolved imports and initialization or pattern keys stay review items rather than automatic substitutions.
|
|
14
|
+
|
|
15
|
+
Java annotation element names belong to annotation methods. C# named attribute fields and properties require review when their declaring type is unresolved.
|
|
16
|
+
|
|
17
|
+
Private fields keep their `#` namespace. A private name belongs to its lexical declaring class; a receiver's type and a base class do not transfer that name to another private field. Anonymous structural member declarations stay unverified when their contract relationship is unresolved.
|
|
18
|
+
|
|
19
|
+
C++ direct-initialization arguments follow their value bindings when the grammar reads them as parameter types. Conflicting or unresolved type/value lookup requires review. Qualified enum values retain the complete declaring path.
|
|
20
|
+
|
|
9
21
|
### Type names and type identity
|
|
10
22
|
|
|
11
23
|
A type name written at a call site (a constructor, `Type::f()` / `Type.f()`, an annotated or constructed receiver, a declared field type, a producer's return type) denotes what that file binds it to: when it names an external type that shares its name with a project type (`use std::fs::File`, `import java.io.File`, `from pathlib import Path`, `import { Server } from 'http'`, `using F = System.IO.File`, `std::mutex`), members of the project type are excluded (`external-receiver`), and a project impl on the external type itself stays unverified `possible-dispatch`.
|
|
12
24
|
|
|
13
25
|
A type declared in a function body (Python, Java, JS/TS, Rust, C++, Go) is visible only in its block: a same-name type outside never captures its references or members, and inside the block it shadows the outer one. A Python field assigned a function-local class (`self.channel = Channel()`) names that class, not a same-named module class.
|
|
14
26
|
|
|
27
|
+
In JS/TS and Python, a receiver whose class resolves to a definition reaches the target only through that definition's ancestry: a sibling class sharing an ancestor's name is excluded, not a possible dispatch.
|
|
28
|
+
|
|
15
29
|
In JS/TS, Python and Rust a type's identity is its module: `Shared::init()` / `Shared.init()` names the `Shared` its own module declares or imports, never a same-name type of a sibling module (excluded `path-type-mismatch`).
|
|
16
30
|
|
|
17
31
|
A module-level `Alias = Box` (Python: bound once, or on every module-level `if`/`try` path to the same class; JS/TS: `const`, or a `let`/`var` never assigned again) names Box in annotations and constructor calls, also when imported, and `Alias(..)` / `new Alias(..)` is a caller of the class; an alias whose paths name different classes stays `possible-dispatch`.
|
|
18
32
|
|
|
33
|
+
Value-owner lookup accepts a function-local class when lexical scope proves that exact declaration and no assignment or parameter can replace it. Python keywords of its synthesized initializer name its fields. A construction with an unresolved owner stays `construction-owner-unresolved`, including a class name shadowed by a parameter or rebound to another value.
|
|
34
|
+
|
|
19
35
|
Type aliases and import renames are the same type on both the caller and callee side: a receiver annotated with Go `type IntFlag = FlagBase[int]`, TS `import { Box as B }`, Rust `use crate::Wrap as W` or C# `using IntBox = G.Box<int>` reaches the original type's methods; a Go alias of an external type (`type Ctx = context.Context`) is not a same-named project type.
|
|
20
36
|
|
|
37
|
+
### Constructors
|
|
38
|
+
|
|
39
|
+
A construction (`new C(..)`, `C(..)`, C++ `C c(..)`) is a confirmed dependency on its class whenever the class binding is proven. Its callee answer lists the class and, when the overload is proven, the constructor body it runs, marked `(constructs C)` (JSON `initializerOf`); an undecided body is listed under `CONSTRUCTOR BODIES — UNDECIDED` with its reason and never demotes the class edge. A constructor handle lists the constructions that select it, and signature checks compare their arguments, including calls bound to the declaration at the base revision. Java indexes each declared constructor, including compact record constructors. A C++ functional call `C(..)` also needs an ordinary name binding, since a function can hide the class name. A delegation (`this(..)`, `super(..)`, `base(..)`, a C++ mem-initializer) runs a constructor body only and never binds the constructor it runs in; in C#, where a constructor's uses are uses of its type, a `: this(..)` initializer is also a dependency on its own class. The parts of a C# partial type are one type: a constructor declared in any part is a member of its family. A C# primary constructor and a Java record's implicit canonical constructor take part in overload selection; what they receive is a dependency on the type. A JS/TS/HTML class with a default derived constructor forwards its arguments to the ancestor body, Python picks an inherited initializer by C3 order, and a class whose whole order declares no constructor needs no constructor review. In JavaScript (and HTML scripts) a call may pass any argument count, so a class's only constructor receives every construction and `check` reports the mismatch; in TypeScript and Python an arity mismatch is a compile or runtime error, so that construction is an unverified `constructor-overload-no-fit` caller. Python allocation, metaclass or replacing-decorator protocols and unresolved bases leave the body undecided.
|
|
40
|
+
|
|
41
|
+
Java, C# and C++ constructors that omit a base initializer supply zero arguments to a proven base constructor. A C++ constructor defined outside its class (`D::D() : B(1) {}` in a source file, the class in a header) binds its delegation and base initializers like an in-class one, and a mem-initializer of a data member is no call; a base it leaves uninitialized is an unverified `constructor-implicit-base-unproven` candidate on both sides, since the base list is read from the class declaration elsewhere. A generated C++ default constructor remains a potential dependency requiring review. A parameter plan requires review at an implicit initialization site because there is no argument list to edit.
|
|
42
|
+
|
|
43
|
+
C++ default initialization (`T v;`, `static T v;`, `T a[2];`, `new T`) runs the default constructor of a class type; a typedef, enum or `extern` declaration constructs nothing. An empty list (`T v{}`) runs the default constructor when the class has one. A list with elements (`T v{..}`, `new T{..}`, `T{..}`) has its own overload phase, so its constructor body stays undecided.
|
|
44
|
+
|
|
45
|
+
A construction through a method's own receiver, Python `cls(..)` in a classmethod, `type(self)(..)` and `self.__class__(..)`, and JS/TS `new this(..)` in a static method or `new this.constructor(..)`, constructs the method's class: a confirmed caller of that class and of its constructor (signature checks include it), never an edit in a class rename, and an unverified `possible-dispatch` candidate of a subclass's constructor. Constructor identity never crosses languages: a TypeScript class's constructor never lists a construction of a Python subclass of a same-named class.
|
|
46
|
+
|
|
47
|
+
JavaScript constructor identity uses the value of a non-computed method key, including string literals and escapes. Static methods and computed keys do not define an instance constructor. Renaming a JavaScript constructor handle renames its proven owning class while preserving the fixed constructor key. C# static initializers are separate from instance constructor overloads.
|
|
48
|
+
|
|
49
|
+
A C# or C++ construction through a generic type parameter requires review, even when a project class has the same name. TypeScript construction uses the separate value binding of a class.
|
|
50
|
+
|
|
51
|
+
Java and C# producer calls used as arguments need the producer's owner proven in the source file and a closed overload family; overloads that all return one type decide the argument's type without choosing among them. An imported or aliased owner cannot borrow methods from a project namesake, a same-spelled class supplies no value type, and an unresolved type-parameter return keeps the site in review. A platform supertype outside the JDK contracts the engine models (core `java.lang` interfaces, `Object`) has unknown members, so an overload family through it stays `overload-ambiguous`.
|
|
52
|
+
|
|
21
53
|
### Aliases, qualifiers and imports
|
|
22
54
|
|
|
55
|
+
Calls on a shared declaration line are attributed by each declaration's AST extent. Nested closures contribute to the enclosing callable; nested class methods keep their own scope. Constructor overloads on the same line retain separate callee entries and call sites.
|
|
56
|
+
|
|
23
57
|
Aliased and qualified calls resolve in every language: Rust `use m::f as g; g()` is a caller of `f` (listed as a beyond-text caller, since the line holds no target token); Java `pkg.Type.method()` and C# `Ns.Type.Method()` / `using T = Ns.Type; T.Method()` pick the type the qualifier names when several same-name types exist. A qualifier the resolver cannot place stays visible as `method-ambiguous`, never confirmed by first-definition order.
|
|
24
58
|
|
|
25
59
|
A bare name bound by an import resolves through that import only, never through another import whose package re-exports a same-named symbol. An import chain that reaches the target through any number of re-exports and renames (`export { a as b }`, then `import { b as c }`) is import evidence.
|
|
@@ -34,7 +68,7 @@ Inherited calls keep their declaring class; a shadowed or rebound module stays u
|
|
|
34
68
|
|
|
35
69
|
### Configuration alternatives
|
|
36
70
|
|
|
37
|
-
Definitions of one name, owner and
|
|
71
|
+
Definitions of one name, owner, signature and generic arity in one file under different `#if` branches (C/C++/C#) or `#[cfg]` attributes (Rust) are one item (two such definitions on one conditional path are separate members): a call bound to any of them reaches every variant alike, a type declared once per configuration is one type (receivers typed by either declaration reach its impls), members inside a class body's `#if` blocks are indexed in each branch, and a C++ implicit-this call reaches its own class definition, never a same-named class defined in another file. Python exclusive branches and Go files of other build constraints are one item too (see Python and Go below). Java pattern variables (`x instanceof Sq s`, `case Sq s ->`, record components) and Python class patterns (`case Sq() as s:`, `case Sq():` on a name subject) type their receivers inside their scope.
|
|
38
72
|
|
|
39
73
|
### Callback references
|
|
40
74
|
|
|
@@ -48,23 +82,39 @@ A bare call of a global assigned in another file (`globalThis.f = ..` in a test
|
|
|
48
82
|
|
|
49
83
|
A JS/TS name destructured from an object (`const { run } = api`, `({ run }: Api) => run()`) reads that member: its calls are member calls on the source, confirmed when the source is typed and unverified otherwise, and a same-name free function is never their target.
|
|
50
84
|
|
|
51
|
-
A JS file's extensionless import resolves a TS source; a bare specifier naming a package of the repository (workspaces, `@scope/core
|
|
85
|
+
A JS file's extensionless import resolves a TS source; a bare specifier naming a package of the repository (workspaces, `@scope/core`, the package's own name inside it) resolves to that package's source (its `exports`/`source` entries, else `src/index`; a subpath export naming build output absent from the checkout, such as `./dist/infinite/index.mjs`, is its source under `src/`), and one that still does not resolve stays unverified `import-unresolved`, never external and never confirmed through another import of the file. `require('..')` and `require('../')` load the directory's package.json `main`.
|
|
86
|
+
|
|
87
|
+
JS/TS names are lexically scoped: a function declared in a function body is visible only in that function, a module's top-level declarations bind its name everywhere in the module whatever their position, and a bare name an import binds never reaches a same-file object or member function of that name. `this.m()` in a base class dispatches by the runtime class: it confirms the base's own `m` and is an unverified `possible-dispatch` candidate of each subclass override. An arrow-function class field (`reset = () => {..}`) is a method for its callers and callees.
|
|
88
|
+
|
|
89
|
+
A function wrapped in parentheses, a cast or `satisfies` (`export const f = ((next) => ..) as Middleware`) is the declaration's value. An import of an existing file the index does not read (`import FormGroup from './FormGroup.svelte'`) binds that file, never a renamed declaration. In a module file (any import, `require` binding or export) a bare call that no declaration or import of the file binds never names another module's function (callee excluded `name-not-in-scope`); a plain script's top-level functions stay globals. `require('./m').name` reads what module m binds and is renamed with it (a CommonJS export key stays a property). An enum member is renamed through an aliased or default import (`C.Red`), a module namespace chain (`ns.Color.Red`) and a TS namespace (`E.Shade.Red`).
|
|
90
|
+
|
|
91
|
+
`plan` renames a method overwritten on a typed receiver (`cmd.m = mock` with `cmd = new Command()`) and an object-pattern key that destructures the renamed export from a module object (`const time = require('./time'); const { epochTime } = time` becomes `{ renamed: epochTime }`, the local kept). Declarations inside `declare global { }` and `declare module 'x' { }` merge with declarations outside the project and are never reported dead.
|
|
52
92
|
|
|
53
|
-
A structural receiver
|
|
93
|
+
A structural producer's imported alias and field path retain their own identity. When a known receiver supplies no proven return contract, chained calls and later assignments stay untyped; a same-named method elsewhere supplies no replacement evidence. Builtin-name filtering applies to bare calls, while qualified members follow receiver resolution. In Python and JavaScript, a write that wraps an inherited method creates an instance attribute. Its initializer reads the previous value before the write; field and method rename plans retain unresolved reads as `instance-attribute-before-write` reviews. A later call through a field whose initializer reads the method remains unverified (`instance-attribute-wraps-method`), because the wrapper may retain that callable. Callee lookup also keeps an undecided field value unverified (`callable-value`) instead of selecting the hidden method.
|
|
54
94
|
|
|
55
95
|
## Python
|
|
56
96
|
|
|
57
|
-
|
|
97
|
+
Member lookup preserves written base order and uses C3 for a complete project hierarchy. An unknown base cannot be skipped to confirm a later member. A known prefix can still establish ownership; unresolved lookup or proof evidence stays unverified. Explicit `super(Class, value)` calls retain their producer expression and remain unverified when its result cannot be proved. Only zero-argument `super()` uses the lexical parent lookup.
|
|
98
|
+
|
|
99
|
+
A field receiver named `self` or `cls` must bind to the method's first parameter. A closure capturing that parameter retains its owner; lambda parameters, nested-function parameters, static-method parameters and rebound names do not inherit it by spelling. `tests` includes a bare class-body method reference when one preceding declaration binds it, keeping same-named methods in other classes separate.
|
|
100
|
+
|
|
101
|
+
Class and instance field annotations feed receiver typing. An instance write such as `self.compute = wrap(self.compute)` remains a field declaration even when its right side reads an inherited method; data-descriptor assignments still belong to their property. A qualified member value such as `selected = pkg.Type.method` enters the method-reference inventory and `tests`, with unresolved ownership shown as unverified.
|
|
102
|
+
|
|
103
|
+
A value imported through a conditional reexport remains an `import-chain` dependency for review. Renaming one alternative preserves the chooser's binding name; unresolved source imports are reviewed instead of automatically edited.
|
|
104
|
+
|
|
105
|
+
A Python name bound in one scope only in exclusive branches (`if`/`elif`/`else`, `try`/`except`, `match` cases: `if sys.platform == "win32": def getchar` / `else: def getchar`) is one item: a call inside one branch reaches that branch's definition, any other call reaches each definition alternative (confirmed for each, since it reaches it whenever that definition exists), and a definition reached only through one branch's import (`try: from ._speedups import f` / `except ImportError: def f`) is listed unverified `configuration-alternative`; `plan` renames every definition alternative and keeps the item's name on an import alternative (`from ._speedups import new as f`), and that module's `__all__` keeps the name too. A value alternative (`else: tqdm = asyncio_tqdm`) is followed to what it names, so a construction through the item never confirms another module's class.
|
|
58
106
|
|
|
59
107
|
A name a Python module binds only by assignment is that module's value, never a re-export of what its other imports reach: `name = other` and `name = submodule.other` aliases are followed, `loads = registry.loads` with `registry = Registry()` is Registry's bound method (a call of the imported `loads` is no caller of another `loads`; it is an unverified `alias-call` of `Registry.loads`, and `plan` renames the attribute read `registry.loads`, never the variable or its calls), and any other value routes unverified `ambiguous-binding`.
|
|
60
108
|
|
|
61
|
-
Python qualified bases and receiver annotations follow the imported module, including aliased submodules and nested package paths.
|
|
109
|
+
Python qualified bases and receiver annotations follow the imported module, including aliased submodules and nested package paths. `from pkg import sub as x` binds the submodule `sub` as a module receiver (`x.f()`, `x.f` values), unless `pkg` itself binds the name. A base class imported by name is the class its import chain reaches; a base the chain leaves to one configuration alternative or a module value is unresolved, so members inherited through it, `super()` calls and class-qualified calls (`Sub.m()`) stay unverified `inherited-unresolved` instead of confirming the first same-named class. A parameter annotation (`def f(env: Environment)`) types the receiver of a property access when the parameter is the only binding of the name.
|
|
62
110
|
|
|
63
111
|
An untyped `self.attr.m()` callee is unverified `single-owner` even when one class declares `m`. A `self` attribute a base class types is typed in its subclasses, by the declaring class's file, when no class on the way writes it, declares a member of its name or writes attributes dynamically and no outside base could set it; `def`s under `if`/`try`/`with`/loops in a class body are methods of the class, and `Union[X, None]` names X.
|
|
64
112
|
|
|
65
|
-
A `def` inside a function is visible only in that function (unless the function declares the name `global`), and a nested function's bare name binds what its enclosing functions bind before the module.
|
|
113
|
+
A `def` inside a function is visible only in that function (unless the function declares the name `global`), on the caller and callee side, and a nested function's bare name binds what its enclosing functions bind before the module.
|
|
114
|
+
|
|
115
|
+
A Python name is one variable per scope: when the scope that binds a renamed def or class binds the name by other statements too (`if null: class Sink` / `else: Sink = sys.stdout`), `plan` renames every binding and every reference that resolves to that scope. An import of another module's name keeps that name (`from threading import RLock as Renamed` beside `class RLock`), an importer that also declares the name keeps its local name (`from .dictutils import Renamed as OMD`), the name in `from m import name as alias` is renamed only when `m` binds the renamed definition, and module path segments (`from pkg.check_updates import x`) are never edited.
|
|
66
116
|
|
|
67
|
-
A
|
|
117
|
+
A module-level read that runs before the variable's first binding reads what a preceding star import binds (`from m import *`, then `X = LIMIT + 1` above `LIMIT = 5`): a rename of the variable leaves it. A base whose import binds one class per runtime configuration (`try: from .std import tqdm` / `else: from .nb import tqdm`, or `tqdm = tqdm_asyncio` in one branch) is each alternative: a member every alternative reaches through one definition is confirmed, any other stays `inherited-unresolved`. A project class decorator whose every reachable return gives back its class (`return cls`, `return do_replace(cls, ..)`, and in the factory form `@d(..)` the decorator it returns) keeps the class's synthesized initializer, so construction keywords name its fields; a module value naming a class (`Seg = Segment`) constructs that class.
|
|
68
118
|
|
|
69
119
|
A Python string annotation that spells a call (`def cmd(v: "Annotated[int, typer.Argument()]")`) is parsed as the expression the runtime evaluates: its calls are callers and `plan` edits them; an annotation string that does not parse stays a text review item.
|
|
70
120
|
|
|
@@ -72,30 +122,46 @@ A Python string annotation that spells a call (`def cmd(v: "Annotated[int, typer
|
|
|
72
122
|
|
|
73
123
|
A Go import that writes no name binds a project package by its package clause (`.../internal/helpers` declaring `package utils` is `utils.F()`); an outside package's name is only the one the Go tools suggest (`github.com/goccy/go-json` is `json`, `k8s.io/api/core/v1` is `v1`), so a qualifier the file neither declares nor imports by that name stays unverified `package-qualifier`, never a confirmed or renamed project call, and `plan` keeps a call it cannot type as a review item in a file of another build configuration (`//go:build`, `_linux.go`) than the renamed declaration's.
|
|
74
124
|
|
|
75
|
-
`pkg.F()` names the package's function (or function-valued variable), never a same-named method. A Go instantiated value (`id[int]`) or package-qualified value (`pkg.F` passed as an argument) is a reference to that function. A composite literal `T{...}` names the type, never a same-named method.
|
|
125
|
+
`pkg.F()` names the package's function (or function-valued variable), never a same-named method. A Go instantiated value (`id[int]`, `lo.Map[int, string]`), a converted value (`conv[T](F)` with `type conv[T any] func(..)`) or a package-qualified value (`pkg.F` passed as an argument) is a reference to that function, and `plan` renames every bare reference of the package (`[]func(){F}`, `return F`, `ch <- F`) and through a dot import. A method expression `(*T).M`, `(T).M` or `(*pkg.T).M` names type T's method like `T.M`: confirmed for T, excluded for another type, possible dispatch through an interface. A composite literal `T{...}` names the type, never a same-named method.
|
|
126
|
+
|
|
127
|
+
A Go package is a directory's files with one package clause: `package x` files and the external test package `package x_test` are two packages, and a non-test file never sees a `_test.go` declaration, so a bare call in one never binds the other's namesake; a bare name reaches another package only through a dot import (`import . "p"`), never because the file imports a package that imports it. Declarations of one package-level name in files of one package under different build constraints (`//go:build`, `_linux.go`) are one item: a call reaches every alternative, except a call in a file of one alternative's own constraint, which compiles with that alternative only; callees list each alternative and `plan` renames them all. In `switch v := x.(type)`, a clause of one type gives `v` that type; a clause of several types and `default` keep the type of `x`.
|
|
128
|
+
|
|
129
|
+
A keyed element of a Go composite literal (`Box{limit: 5}`, `&Box{..}`, the elided inner literals of slices, arrays and maps such as `[]Box{{limit: 3}}`) names the field of the literal's type, and `b := Box{..}` / `p := &Box{..}` give their locals that type, so a field rename edits those tokens; `h.funcs[i](n)`, which the grammar reads as a conversion to a generic type, reads the field `funcs` when `h` is a value.
|
|
76
130
|
|
|
77
131
|
A Go package-level variable has one static type across its package: `var CommandLine = NewFlagSet(..)` types `CommandLine.VarP(..)` in every file of the package, before or after the declaration, and `pkg.CommandLine.VarP(..)` in importers.
|
|
78
132
|
|
|
79
133
|
## Rust
|
|
80
134
|
|
|
135
|
+
A chain starting with `Self::make()` uses the producer's return type for later methods. Recorded field suffixes, including one field, use the field's declared type; an unresolved hop remains unverified. Field access through a returned standard deref wrapper such as `MutexGuard<State>` uses `State` only after proving the wrapper's binding and payload identity. A project namesake or generic payload supplies no such proof.
|
|
136
|
+
|
|
137
|
+
Calls to a trait impl on an external type stay `autoref-dispatch` when the type's unseen inherent methods could precede it, including `self.method()` or `Self::method(self)` inside the impl. This review applies per target, including pins containing several definitions; a proven project-owned receiver keeps its own method. Explicit trait paths retain their own lookup. Struct literals never bind an impl block.
|
|
138
|
+
|
|
139
|
+
A field access through `self` in an `impl` uses the type written on that implementation, including scoped imports and aliases. An external type never borrows a project namesake's fields; an unresolved owner stays `member-owner-unresolved`.
|
|
140
|
+
|
|
81
141
|
Rust receivers are typed from annotations, closure parameters of the called function's `Fn` bounds, `Self::Assoc` returns, tuple `let` patterns, trait-provided methods, and range, tuple, slice, `vec!`, and `Some`/`Ok` values; owned versus `&` impls are told apart by the receiver's reference layer, and at one probe step an inherent method precedes a trait method (`self.key_mut()` inside a trait impl's own `key_mut` calls the inherent `key_mut`), on the caller and callee side; where a bound-conditional impl, a trait not provably in scope or a private inherent method could intervene, the site stays unverified.
|
|
82
142
|
|
|
83
143
|
Method probing follows the receiver's reference layer: a `self` receiver that reaches the member only after an autoref or deref step (a `&self` trait method called in a `&mut self` method) may be taken by an earlier impl, such as std's `impl AsRef<U> for &mut T`, so the site stays unverified `autoref-dispatch` unless the trait is the project's own and no impl for a reference type can intervene. A local bound from a producer returning `Self` or a value is owned and `-> &T` a reference, which selects between owned and `&` impls. An untyped `let` hides an outer binding's type, and calls in the item bodies of an item-position macro (`quickcheck! { fn p(..) { .. } }`, also when a project macro emits it) are read from the items, with their functions' locals typed.
|
|
84
144
|
|
|
85
|
-
A receiver behind a std deref wrapper (`Box`, `Rc`, `Arc`, `ManuallyDrop`, `LazyLock`, `Ref`/`RefMut` and lock guards, `Pin`, `Cow`; annotated, constructed with `W::new(..)` or a `LazyLock` static) reaches its target type's methods (a guard
|
|
145
|
+
A receiver behind a std deref wrapper (`Box`, `Rc`, `Arc`, `ManuallyDrop`, `LazyLock`, `Ref`/`RefMut` and lock guards, `Pin`, `Cow`; annotated, constructed with `W::new(..)` or a `LazyLock` static) reaches its target type's methods (a returned guard needs a proven standard wrapper and payload type; an unresolved producer stays unverified); a name the wrapper itself may supply (`clone`, `as_ref`, std trait methods, project impls on the wrapper) stays unverified `autoref-dispatch`, and `rc.clone()` is the wrapper's.
|
|
86
146
|
|
|
87
147
|
Values of std containers, slices, arrays (`[a, b].iter()`), `str`, `Option`/`Result` and std iterator adaptors never reach a method owned by a project struct or enum. Raw pointers (`*const T`/`*mut T` parameters and locals, casts `(p as *const T)`, `as_ptr()` results and pointer arithmetic such as `p.add(n)`) reach `impl<T> Tr for *const T` members and never a struct's method.
|
|
88
148
|
|
|
149
|
+
Declared slice and raw-pointer returns retain their primitive identity through chains and stored values, including tuple bindings and unwrapped assignments. A concrete-element impl stays unverified when only the primitive shape is known; a generic impl for that shape stays eligible. Project types named `slice` keep their nominal identity.
|
|
150
|
+
|
|
89
151
|
A parameter typed `Self` is the enclosing impl's type. A receiver whose type is a generic parameter (including `self` in a trait's own methods) reaches only implementations of its bound traits (unverified `possible-dispatch` via the trait, external for std traits such as `Iterator`) and never an inherent method or another trait's impl. A Rust `const`/`static` item types its method receivers by its declared type (`FLAGS.iter()`; never a `static mut`), and a local destructured from `self` (`let Self { iter, .. } = self;`) is that field.
|
|
90
152
|
|
|
91
153
|
Crate aliases (`use x as y`, `extern crate x as y`), the package's own name in tests/examples, glob and `pub use` re-export chains, auto-deref wrappers, enum-variant values, unit-struct values (`S.m()`, also through `let w = S;`), tuple-struct and tuple-variant constructors (`T(1).m()`, `E::V(2).m()`, `Self(..)`), struct expressions, and in-scope blanket extension traits (`impl<T: Iterator> Ext for T`) are followed; a blanket-impl member confirms only when its where-clause holds through exactly one visible project impl. `Trait::f(..)` returned from a member of that trait's impl binds that impl; elsewhere it stays one trait family.
|
|
92
154
|
|
|
93
155
|
Impls of one generic trait for one type (`impl From<A> for Vec<u8>` beside `impl From<B> for Vec<u8>`) are selected by argument type (declared parameters and locals, struct literals, literals, range-indexed slices, locals bound from a `Type::ctor(..)` whose project definitions return the type): another argument type excludes the impl (`overload-mismatch`), an undecided argument stays `overload-ambiguous`, and an undecided argument never confirms the only project impl of an out-of-project trait such as `From`, whose other impls UCN cannot see.
|
|
94
156
|
|
|
157
|
+
A Rust name resolves through the scopes that bind it, innermost first: a block's items and `use` declarations (grouped, nested, `self`, renamed, globs), then its module's items and explicit `use` bindings, then the module's globs; a module never sees its parent's names except through a `use`, each integration test, example, bench and binary is its own crate, and crate names follow the manifest's dependencies (renamed path dependencies included). Types, values and macros are separate namespaces: a `mod x` never hides a function `x`. Calls resolved this way confirm as `item-scope`; a name no scope binds is excluded `name-not-in-scope`, and a module whose item macros or `include!` could declare the name keeps the other evidence rules. `Trait::m(x)` and `<T as Trait>::m(x)` name the trait's member, never an inherent member of a type spelled like the trait (excluded `path-type-mismatch`); `Type::m` passed as an argument (`map(T::parse)`) is a caller of the method its qualifier names, a type's path to a trait member it inherits included, and `plan` renames such path values wherever they are written (`let f = T::m;`); a Self-returning trait member with no `self` (`inner: Default::default()`, `let x: T = Default::default()`, a return value) is selected by the type the value is written into (a struct field, an annotated `let`, a return type, or a free function's declared parameter for an argument: `run(Default::default())`), and stays unverified `trait-self-unknown` where no written type decides (a generic parameter). A paren-less member access (`take(self.len)`) reads a field and is never a method callee.
|
|
158
|
+
|
|
95
159
|
Rust `crate::f()`, `super::f()`, `self::m::f()` and child-module paths resolve through the module tree (`mod` files in both layouts, `#[path]`, inline modules) and confirm as `module-owned`; a type path (`crate::tests::memchr::Runner::new()`) names the type that module declares, and a type a glob import (`use super::*`) brings in is that module's type; a bare call never resolves to a struct field.
|
|
96
160
|
|
|
97
161
|
### Rust macros
|
|
98
162
|
|
|
163
|
+
Primitive-spelled value names such as `width.char()` and `char()` are recorded inside macro token trees; a primitive type annotation alone is not a call.
|
|
164
|
+
|
|
99
165
|
Invocations of project `macro_rules!` macros are expanded (rules matched over token trees, nested and recursive project macros, hygiene for locals the macro introduces, `$crate`, every `cfg` alternative): functions, impls and calls the expansion generates are indexed at the invocation, marked `[via macro NAME]`. A call written in the invocation keeps its own line and is typed in its expanded context; an unresolved call from the macro's template joins the target's `macro template` family in the compile-time band, and `plan` edits a generated declaration only through the argument or template token that spells it. Macros that only pass their arguments along (logging, `try!`-style matches) keep the invocation's token-tree view. Macros from dependencies are never expanded; project invocations that cannot be expanded are listed in `repo --sections=health` and warned by `deadcode`.
|
|
100
166
|
|
|
101
167
|
Macro names are their own namespace: `name!(...)`, `#[name]` and `#[derive(Name)]` never count as calls or references of a same-named fn (excluded `macro-namespace`), and a fn declared inside another fn's body is visible only there.
|
|
@@ -104,13 +170,33 @@ Macro names are their own namespace: `name!(...)`, `#[name]` and `#[derive(Name)
|
|
|
104
170
|
|
|
105
171
|
Unimported Java and C# names follow the language's scoping: the same package or an enclosing namespace, then on-demand imports with the implicit `java.lang`, or `using` directives, global usings and project-file `<Using>` items (`Static="true"` items are `global using static`; `Directory.Build.props` above an indexed sub-project count up to the repository root). A `using` directive written inside a namespace resolves from that namespace outward (`namespace A.B; using Internal;` imports `A.Internal` when the project declares it), and nested `namespace` blocks name their members by the full path; a project type not in scope there is not the named type, and a project on-demand import beside a `java.lang` type of that name stays unverified.
|
|
106
172
|
|
|
107
|
-
Overload choice needs argument evidence (Java, C#)
|
|
173
|
+
Overload choice needs argument evidence (Java, C#). Where the applicable overloads differ in a parameter and the argument's type is unknown, the site stays unverified `overload-ambiguous` for each of them (a review item for `plan`), the fixed-arity versus varargs/`params` choice included. What decides it:
|
|
174
|
+
|
|
175
|
+
- explicit method type arguments (`M<int>(..)`), literals, typed locals, parameters and fields of the enclosing class;
|
|
176
|
+
- a lambda's parameter count against `Action`/`Func`/`java.util.function` shapes, project delegates and project functional interfaces (one abstract method); a lambda never converts to a project class, struct, enum or record, nor in C# to an interface;
|
|
177
|
+
- every C# argument converts to `dynamic`; a modeled JDK value (`Arrays.asList(..)`, `List.of(..)`, `Collections.emptyList()` return their collection interface) never converts to a project type, so it never fills a project varargs element.
|
|
178
|
+
|
|
179
|
+
A C# generic method whose type parameter no parameter type mentions applies only with explicit type arguments, and so does one whose type parameter only an implicitly typed lambda's parameters mention (`Map<T>(Expression<Func<T, object>>)` is never inferred from `Map(m => m.Id)`); a lambda's output type is inferred once its inputs are fixed (`Select(this IEnumerable<TSource>, Func<TSource, TResult>)`).
|
|
180
|
+
|
|
181
|
+
A C# target-typed `new(..)` constructs the type its position declares: a typed local or field, a property, the enclosing member's return type, a member it is assigned to, or the parameter of the overload a call, construction or `this(..)`/`base(..)` initializer binds (primary constructors and a platform collection field's element type included). A decided overload confirms it; an undecided one lists it unverified `overload-ambiguous` for each candidate type.
|
|
182
|
+
|
|
183
|
+
Arguments that fit none of the pinned class's overloads (a C# extension method of another class) leave the site unverified, never confirmed, unless another project definition of the name provably takes every argument (`bf.getBean(Bean.class)` binds a subclass's `getBean(Class<T>)`): then the site is excluded `overload-mismatch`.
|
|
184
|
+
|
|
185
|
+
Java overload checks compare types by identity: a literal has its platform type, and a project type named `String`, `Class`, `Type` or `Object` is a different type. A parameter type is looked up in its declaring class (own and inherited member types before imports; unrelated nested types and static members never supply a type), and an argument's written type names a platform type only when its file and lexical owners establish it. The overload stays in review when Unicode translation changes names or structure, identifier-ignorable characters appear, a superclass is unresolved or the relationship involves an external type, and for calls and declarations in a member holding a parse error (an error outside every member, such as in an import, reaches the whole file). Unicode escapes inside literals or comments keep the evidence usable, and a type annotation before a varargs `...` (`Object @Nullable ... args`) is read with the annotation set aside.
|
|
186
|
+
|
|
187
|
+
A Java producer argument keeps its written owner through imports and collection elements: a proven SDK interface (`Iterable`, `Comparable`) supplies its declared members, a single-type SDK import establishes the owner beside wildcard imports unless a lexical type shadows it, and an unindexed namesake keeps the lookup open.
|
|
188
|
+
|
|
189
|
+
Generic collection `get` results require a proven JDK `List` or `Map` contract and a resolved element type. Project getters use their declared return types. Java instance interface members join inherited overload lookup after superclass members; subinterfaces supply their more specific declarations, and private or static interface methods stay on their declaring interface.
|
|
190
|
+
|
|
191
|
+
Java `Comparable` conversions retain the invariant argument and wildcard bounds of the boxed value or string. Unresolved generic conversions keep competing overloads in review; matching erased class or interface names does not establish their type arguments.
|
|
192
|
+
|
|
193
|
+
Java variadic parameters retain their declared array type. Overload checks consider both the normal array argument and expanded element arguments; a possible normal invocation stays in the fixed-arity phase. Unproved reference-array covariance and external subtype relationships keep competing candidates in review.
|
|
108
194
|
|
|
109
195
|
In C# and Java a type name is no value: a bare argument spelled like a type (a property named like its type) is never the type's caller. In C# and Java a capitalized receiver that names a field or property of the enclosing class (declared in another `partial` part or inherited) is that member, typed in its declaring file's scope.
|
|
110
196
|
|
|
111
197
|
A bare Java/C# call binds a member of the enclosing classes (own or inherited, by class definition, never a same-name class of another package) before a static import (`import static`, `using static`); the import decides it, as caller and callee, only when every class in scope has a resolved project ancestry, and otherwise it stays unverified.
|
|
112
198
|
|
|
113
|
-
A Java/C# local's declared type is its static receiver type: `Shape s = new Circle(); s.area()` is a caller of `Shape.area` and a `possible-dispatch` candidate of each implementation, except those the constructed type cannot reach when the local is never reassigned. A field initializer types only its own class's field, and only a field that cannot be reassigned.
|
|
199
|
+
A Java/C# local's declared type is its static receiver type: `Shape s = new Circle(); s.area()` is a caller of `Shape.area` and a `possible-dispatch` candidate of each implementation, except those the constructed type cannot reach when the local is never reassigned. An implicitly typed C# `out var` or pattern variable writes no type: calls on it stay unverified. A record (`record class`, `record struct`, Java `record`) qualifies static calls like a class. The declaring and implementing parts of a C# partial method are one method; a Java method reference or C# method group to one of several overloads stays `overload-ambiguous`, its target type choosing the overload. A field initializer types only its own class's field, and only a field that cannot be reassigned.
|
|
114
200
|
|
|
115
201
|
## Java
|
|
116
202
|
|
|
@@ -124,11 +210,19 @@ A Java enum implements its interfaces like a class (renames reach the enum's mem
|
|
|
124
210
|
|
|
125
211
|
C# resolution uses declared property/field receiver types plus overload and hiding discipline. A C# `#if` that splits a declaration (a method body or expression body, a base-list entry, a parameter, alternative heads) is read one configuration at a time with every line number kept: the branch holding the most calls is primary, and the other alternatives' declarations and calls come from their own configuration.
|
|
126
212
|
|
|
213
|
+
A C# local function reads the typed locals of the method around it (names it declares itself hide them). A generic method is inapplicable when its argument's type satisfies none of a type parameter's constraints (`Send<TRequest>(TRequest) where TRequest : IRequest` never takes a `Ping : IRequest<Pong>`) or does not implement a generic parameter type at its arity (`IRequest<T>` never takes a `Notify : IRequest`), and a type parameter inferred from the argument is an identity conversion, so `Send(new Ping())` binds `Send<TResponse>(IRequest<TResponse>)` over `Send(object)`. `T.Parse(s)` with `where T : IParse<T>` calls the constraint's static member: confirmed for the interface member, `possible-dispatch` for each implementation. An extension call whose argument count or written type arguments only a sibling overload of the class takes (`c.Query<A, B, C>(.., map)` against `Query<T>(this Conn, string)`) is excluded `overload-mismatch`.
|
|
214
|
+
|
|
127
215
|
C# generic arity is part of a type's identity: `Outcome`, `Outcome<T>` and `Outcome<T1, T2>` are distinct types, so a constructor `new Outcome<T>(..)`, a static call `Outcome.X()` / `Outcome<int>.X()`, a written receiver type and a base list name only the type of that arity (other-arity sites are excluded `generic-arity-mismatch`), and `partial` parts merge only with the same arity.
|
|
128
216
|
|
|
129
|
-
|
|
217
|
+
Constructor delegation retains that arity too: `this(...)` takes its declaring type's parameters and `base(...)` takes the written base type's arguments. A construction such as `new Outer<int>.Inner<string>()` records `Inner` as the constructed type. Nested constructions and declared receivers under a generic containing type remain review items when that owner's identity is unproven. Type-reference reviews use reason `generic-containing-type`. Namespace receivers are looked up through the enclosing namespaces; a field or property with that name keeps its member binding. Parent-receiver keywords follow the source language, so a C#, C++ or Go local named `super` is an ordinary receiver.
|
|
218
|
+
|
|
219
|
+
A C# argument such as `Outer<A, B>.Inner<T>` names the nested type with its own generic arity. When the constructed enclosing type cannot be resolved, competing overloads remain `overload-ambiguous`; an arity check cannot treat that argument as the outer type.
|
|
220
|
+
|
|
221
|
+
Declared C# implicit conversion operators, including operators on generic owners and inherited source types, keep potentially reachable overloads in review. A conversion into a type does not establish a conversion out of it. Explicit operators do not participate in implicit argument conversion, and generic method inference still uses the argument types. Operator existence alone is not proof of applicability.
|
|
222
|
+
|
|
223
|
+
An extension-method call `x.Ext()` is a caller of the extension when the declaring static class is in scope and x's type fits the `this` parameter (directly, through project heritage, or through a type parameter's constraints); a receiver whose ancestry cannot decide it (an external type) stays unverified `extension-receiver-unresolved`, and an applicable instance method of the receiver type wins (also a platform collection's own member, `List<T>.Add(T)`, and `object` members). Type arguments must fit: a `List<string>` or `DbSet<Customer>` receiver never takes `this List<Transformer>`. Type arguments the receiver fixes type the other parameters (`TryAdd<T>(this List<T>, T)` never takes a `string[]`). An extension call on a project type that derives from an outside class (other than `object`, the modelled collections and the type the extension is declared for) stays unverified, since an inherited instance member may take it. A receiver typed by a type parameter converts only to its constraints. The System.Data.Common base classes (`DbConnection`, `DbCommand`, `DbDataReader`, `DbTransaction`, `DbParameter`) are modeled with the System.Data interfaces they implement and their own instance members, so `connection.Execute(..)` on a `DbConnection` binds `Execute(this IDbConnection ..)`; provider types (`SqlConnection`, `NpgsqlConnection`) stay unresolved. An unresolved receiver whose arguments select a sibling overload (`Execute(cnn, new CommandDefinition(..))` against `Execute(this IDbConnection, string, ..)`) is excluded `overload-mismatch` from the other one.
|
|
130
224
|
|
|
131
|
-
A C# explicit interface implementation (`IEnumerator IEnumerable.GetEnumerator()`) is never reached by a simple-name or `this.` call, and through an interface-typed receiver only by runtime dispatch. An explicit interface implementation never types a member access on the class.
|
|
225
|
+
A C# explicit interface implementation (`IEnumerator IEnumerable.GetEnumerator()`) is never reached by a simple-name or `this.` call, and through an interface-typed receiver only by runtime dispatch. An explicit interface implementation never types a member access on the class. Casting `this` to the interface does not prove which implementation runs: subclasses may reimplement it. Such a class lookup remains `provenance-incomplete` with diagnostic `receiver-this-cast-dispatch`.
|
|
132
226
|
|
|
133
227
|
A C# static method is never reached through a value (a chained call's result, `this`, a field or a typed local), and `new X(..)` names the type X even where the enclosing class has a member named X. A C# static member path from a type (`Pool.Shared.Get()`, where `Pool` is no member of the enclosing class) is typed from that type's declared member, and a chained call (`Get().Initialize<T>()`) is typed from its producer or stays unverified, never read as a type name.
|
|
134
228
|
|
|
@@ -140,23 +234,35 @@ A C# target-typed `new(..)` in a collection initializer or collection expression
|
|
|
140
234
|
|
|
141
235
|
C/C++ uses `compile_commands.json` when available to classify headers and resolve include paths; free-function visibility follows the transitive `#include` closure, and a quoted include found only by a unique project basename is weaker evidence (rule `include-basename`). C++ resolution uses namespace ownership, static overload shape (including arrays), and macro-parameter requalification.
|
|
142
236
|
|
|
237
|
+
C++ argument checks resolve standard string and string-view types through qualified names, imports and aliases, preserving character encoding. Project class checks inspect converting constructors, conversion operators, inheritance and source-backed template constraints. A failed substitution or a known standard type trait can rule out a candidate; unknown constraints, inherited constructors and incomplete declarations keep it possible. A call with one surviving overload can be confirmed. Several possible conversions remain `overload-ambiguous` unless positive evidence selects one. Argument types resolve where their declarations were written, including local aliases and template parameters. Familiar class names alone never establish a conversion.
|
|
238
|
+
|
|
239
|
+
Integer literals with value zero, including hexadecimal, octal and suffixed forms, are null pointer constants. Pointer overloads remain reachable beside arithmetic and user-defined conversions; boolean and character literals keep their own conversion rules. The `NULL` macro does not inherit `nullptr` conversion rules.
|
|
240
|
+
|
|
143
241
|
### Declarations, linkage and configurations
|
|
144
242
|
|
|
145
|
-
|
|
243
|
+
C/C++ declarations in the same scope and file share their class body, including a conditional body; alternative bodies remain indexed separately. A forward declaration (`class State;`) is the class the project defines once under its qualified name (`find` marks it `(forward declaration)`); several definitions (separate programs, a vendored copy) keep it apart. A C++17 deduction guide declares no function. A plain forward-declared field type completes across files only to one same-scope class or struct visible through the consuming file's include closure. The field's written type resolves in its declaring scope, including a type alias. Separate programs keep their own complete classes; conditional, generic, anonymous-namespace or ambiguous cross-file completions stay unverified.
|
|
244
|
+
|
|
245
|
+
Every non-static declaration of a free function (a header prototype or a local forward declaration in another file) is the same entity as its external definition, so its calls are the definition's callers and `plan` renames every declaration; a `static` declaration joins only its own file's definition, and gives the later declarations and the definition in that file internal linkage even when they omit `static`. Several external-linkage definitions of one function (platform variants), or definitions in complementary `#if` branches, stay `link-ambiguous` on the caller and callee side unless the caller's own file (in the same branch) or the compile database separates them. A call in a header to a `static` function the header declares binds each including file's own definition: unverified `translation-unit-binding`.
|
|
146
246
|
|
|
147
|
-
Recoverable preprocessor branches contribute AST-proven source facts, so a single selected configuration does not silently erase definitions or calls; disagreeing conditional macro identities stay visible as unverified. Members a class declares only in a conditional branch the selected configuration skips are indexed too. In a
|
|
247
|
+
Recoverable preprocessor branches contribute AST-proven source facts, so a single selected configuration does not silently erase definitions or calls; disagreeing conditional macro identities stay visible as unverified. Members a class declares only in a conditional branch the selected configuration skips are indexed too. In a very large file, a conditional the parser cannot place (in a member-initializer list, an expression, template arguments) or whose branches split a block's braces is read in one configuration only.
|
|
248
|
+
|
|
249
|
+
A C++ namespace-scope name declared in one arm of a preprocessor group and imported by a using-declaration in another arm depends on the build configuration. Calls outside those branches stay unverified `configuration-alternative`; calls inside the project's branch keep their proven binding, and calls inside the import branch do not belong to the project declaration. A file that cannot include the declaring file reaches the declaration by linkage only, so its calls keep their ordinary binding. A rename edits the sites in every alternative's branch, keeps the import branch's spelling (counted as another target), and lists outside calls, using-declarations and value or type references for review.
|
|
250
|
+
|
|
251
|
+
Alternative namespace aliases keep the qualifier's namespace category even when its identity is unresolved, so their calls cannot reach class members. An alternative that can name a type keeps the qualifier unverified outside its branch.
|
|
148
252
|
|
|
149
253
|
A same-named class in a header that is only ever included in another branch of the same `#if` chain (`#ifdef _WIN32 #include "client-windows.h" #else #include "client.h"`) is that class in another configuration: calls its own members make are listed unverified `configuration-alternative` for this class's member, and `plan` renames the member in both.
|
|
150
254
|
|
|
151
255
|
### Receivers, qualifiers and lookup
|
|
152
256
|
|
|
153
|
-
A C++ `v->m()` reaches what `->` yields: the pointee of a pointer, of a std smart pointer (also behind a project alias) or of a class's `operator->`; any other object stays unverified. A receiver typed by a template parameter of the enclosing function or class template stays unverified `possible-dispatch` via that parameter, and an alias whose target is a dependent type (`typename X<..>::type`) is not a class. A C++ receiver declared with an alias (`Value v;`) has the class the alias names where it is written: a same-name alias in a namespace the site cannot see does not count.
|
|
257
|
+
A C++ `v->m()` reaches what `->` yields: the pointee of a pointer, of a std smart pointer (also behind a project alias) or of a class's `operator->`; any other object stays unverified. The same holds for a field (`m_state->m()` with `std::unique_ptr<State> m_state`). A local declared `decltype(x) v` has x's declared type; `decltype(auto)` and other `decltype` forms leave it untyped. `auto x = b`, `auto &r = b` and `auto *p = &b` give the local b's type when b is an object; an `auto` initialized from a pointer or a call stays untyped. A receiver whose class template derives from its own template parameter (`template <class T> struct Holder : T`) may reach the members of the argument: unverified `template-parameter-base`. Member overloads that differ only in `const` (`T& at(int)` / `const T& at(int) const`) are chosen by the object's constness (a const or non-const local, reference, pointer-to-const, or the enclosing member function's `this`); an object of unknown constness and ref-qualified overloads stay `overload-ambiguous`. `(T)(x)` where T names a project type in scope is a cast, a reference to the type, never a call. A receiver typed by a template parameter of the enclosing function or class template stays unverified `possible-dispatch` via that parameter, and an alias whose target is a dependent type (`typename X<..>::type`) is not a class. A C++ receiver declared with an alias (`Value v;`) has the class the alias names where it is written: a same-name alias in a namespace the site cannot see does not count.
|
|
258
|
+
|
|
259
|
+
A C++ initializer such as `Box value(factory<T>());` retains the call to `factory`. When that name denotes a project type or an enclosing template-template parameter, the empty function-type parameter remains a declaration rather than a call.
|
|
154
260
|
|
|
155
|
-
`::f()` names the global namespace, so a namespace member is not its target unless a global-scope using brings it in (unverified `global-qualified-using`); `plan` edits a qualified reference (an explicit instantiation `template auto ns::f(float) -> R;`, `&ns::f`) when its qualifier names the renamed function's namespace or class, and lists it for review when the qualifier cannot be resolved. A C++ `Q::f()` qualifier is resolved through `using` aliases, using-declarations, and macro-opened namespaces (a namespace an object-like macro names, `namespace LIB_NS {`, is the namespace the macro expands to, also where a qualifier or using-directive spells the macro): it excludes only when Q provably names a namespace or an unrelated class, and routes `unresolved-qualifier` or `dependent-qualifier` (template parameter) otherwise. `plan` also renames each C++ using-declaration that names the renamed declaration (`using ns::f;`, `using ns::Type;`) when its qualifier resolves to the declaration's namespace or class, and lists it for review when only the qualifier's suffix matches.
|
|
261
|
+
`::f()` names the global namespace, so a namespace member is not its target unless a global-scope using brings it in (unverified `global-qualified-using`); `plan` edits a qualified reference (an explicit instantiation `template auto ns::f(float) -> R;`, `&ns::f`) when its qualifier names the renamed function's namespace or class, and lists it for review when the qualifier cannot be resolved. A C++ `Q::f()` qualifier (its case says nothing: `Exp::Break()` names namespace `Exp`) is resolved through `using` aliases, using-declarations, and macro-opened namespaces (a namespace an object-like macro names, `namespace LIB_NS {`, is the namespace the macro expands to, also where a qualifier or using-directive spells the macro): it excludes only when Q provably names a namespace or an unrelated class, and routes `unresolved-qualifier` or `dependent-qualifier` (template parameter) otherwise; a function the index places at file scope stays an unverified (`overload-ambiguous`) candidate of a namespace-qualified call (`app::count()` for a global `count`), since a namespace macro can hide where a definition lives; the callee of `N::f()` is namespace N's function of that name, chosen among its overloads by the call's shape. `plan` also renames each C++ using-declaration that names the renamed declaration (`using ns::f;`, `using ns::Type;`) when its qualifier resolves to the declaration's namespace or class, and lists it for review when only the qualifier's suffix matches.
|
|
156
262
|
|
|
157
263
|
A C++ class member hides every base member of its name unless a `using Base::name;` in the class brings them in (default arguments count in the arity); `v[k].m()` on a class object takes the class its `operator[]` returns when every `operator[]` it declares returns that one class; `T v(X());` in a block is an object initialized by the call `X()` unless `X` is a type. A C++ receiver whose class declares several overloads of the name is never a caller of an unrelated class's member, even when the arguments cannot choose among the overloads. A C++ implicit-this call names the member the enclosing class's lookup finds; an override of it in a subclass is reached only by runtime dispatch, as an unverified `possible-dispatch` candidate when the member is virtual and not at all otherwise.
|
|
158
264
|
|
|
159
|
-
A C++ `friend` function declared or defined in a class body is a function of the enclosing namespace, not a member (argument-dependent calls reach it, its body sees the class's static members, `plan` renames the friend declaration with the definition), and a member of a nested class reaches the enclosing class's members by bare name.
|
|
265
|
+
A conversion operator defined outside its class (`Text::operator bool_type() const { .. }`) is a member of that class, so its bare calls reach the class's members. A C++ `friend` function declared or defined in a class body is a function of the enclosing namespace, not a member (argument-dependent calls reach it, its body sees the class's static members, `plan` renames the friend declaration with the definition), and a member of a nested class reaches the enclosing class's members by bare name.
|
|
160
266
|
|
|
161
267
|
### Preprocessor macros
|
|
162
268
|
|
|
@@ -166,6 +272,6 @@ Invocations of project function-like macros that paste (`fs__##lc(req)`), call a
|
|
|
166
272
|
|
|
167
273
|
A call spelled in a macro's replacement list binds at each place the macro is invoked (through other macros too): confirmed when every invocation sits where the call reaches the target (a member of the invoking class), unverified `macro-body-context` when only some do. A receiver the replacement list declares with a macro parameter as its type (`T v; v.f();` in `#define M(T)`) takes the class every project invocation passes for that parameter (through other macros too); invocations that disagree, or one that cannot be read, leave its calls unverified.
|
|
168
274
|
|
|
169
|
-
A decoration macro before a return type (`API std::string Cls::m()`, `bool API ns::Cls::m()`, `MACRO std::size_t f()` in a class) or in a class head (`class API Name : public Base<Name>`) is blanked before parsing, only when the file proves it decoration (its own `#define`, or a position no type can hold) and never the type, scope or keyword beside it; members after a class-body macro invocation take the access its definition spells, and when that definition is not in the project their access is unknown and `deadcode` treats them as public. Macros another header of the include closure defines are read by the recovery like the file's own when every project definition of the name agrees: decoration (`SPDLOG_INLINE`), removable statement (`TRY` / `CATCH` defined as `try` / a `catch` handler or nothing) and attribute or return-type macros (`ATTR(3)` before a member); `LUA_API int (lua_gettop)(..)` declares `lua_gettop`. Members that escaped a class body the parser closed early are disclosed as recovery-region lines.
|
|
275
|
+
A decoration macro before a return type (`API std::string Cls::m()`, `bool API ns::Cls::m()`, `MACRO std::size_t f()` in a class) or in a class head (`class API Name : public Base<Name>`) is blanked before parsing, only when the file proves it decoration (its own `#define`, or a position no type can hold) and never the type, scope or keyword beside it; members after a class-body macro invocation take the access its definition spells, and when that definition is not in the project their access is unknown and `deadcode` treats them as public. Macros another header of the include closure defines are read by the recovery like the file's own when every project definition of the name agrees: decoration (`SPDLOG_INLINE`, also one whose definitions name another decoration macro: `#define API __declspec(dllexport) VISIBILITY`), removable statement (`TRY` / `CATCH` defined as `try` / a `catch` handler, `if(true)` / `if(false)` or nothing) and attribute or return-type macros (`ATTR(3)` before a member); an abstract pointer-to-member parameter (`Ret (Class::*)(Args...)`) keeps its written type; `LUA_API int (lua_gettop)(..)` declares `lua_gettop`. Members that escaped a class body the parser closed early are disclosed as recovery-region lines.
|
|
170
276
|
|
|
171
|
-
An invocation of the file's own function-like macro that the parser reads as a declaration (`ERROR_DEF(Base, Name)` in a class body, `LIST(X)` statement lists) is read as the invocation: members its replacement list declares join the class at the invocation line (`generatedByMacro`), and a C++ declaration with no type outside a class body (`TEST(suite, name) { }`) is an invocation, never a function named after the macro. A namespace-scope invocation followed by a body (`TEST(suite, name) { }`, `TEST_CASE("text") { }`) defines a callable named from its arguments (`suite_name`, `text`), marked `generatedByMacro`: calls in the body belong to it, it is an entry point, and `plan` blocks its rename (`macro-generated-name`), as it does for a member a class-body invocation builds by token pasting (`Get##name##String`). A bare call in such a body to a member of a class one of its arguments names (`TEST_F(Fixture, Name)`) is unverified `macro-generated-scope via Fixture`, never excluded. A declaration named like a function-like macro in effect where it is written (`int seed_ GUARDED_BY(mu_);` under a conditional macro definition) is that macro's invocation, so `plan` blocks renaming it as a function (`macro-invocation`).
|
|
277
|
+
An invocation of the file's own function-like macro that the parser reads as a declaration (`ERROR_DEF(Base, Name)` in a class body, `LIST(X)` statement lists) is read as the invocation: members its replacement list declares join the class at the invocation line (`generatedByMacro`), and a C++ declaration with no type outside a class body (`TEST(suite, name) { }`) is an invocation, never a function named after the macro. A namespace-scope invocation followed by a body (`TEST(suite, name) { }`, `TEST_CASE("text") { }`, C `DEF_PRIMITIVE(name) { }`) defines the function the expansion declares when the project defines the macro (`#define DEF_PRIMITIVE(n) static bool prim_##n(..)` defines `prim_name` with its parameters), else a callable named from its arguments (`suite_name`, `text`), marked `generatedByMacro`: calls in the body belong to it, it is an entry point, and `plan` blocks its rename (`macro-generated-name`), as it does for a member a class-body invocation builds by token pasting (`Get##name##String`). A bare call in such a body to a member of a class one of its arguments names (`TEST_F(Fixture, Name)`) is unverified `macro-generated-scope via Fixture`, never excluded. A declaration named like a function-like macro in effect where it is written (`int seed_ GUARDED_BY(mu_);` under a conditional macro definition) is that macro's invocation, so `plan` blocks renaming it as a function (`macro-invocation`).
|
|
@@ -16,7 +16,7 @@ Use this reference when an agent, CI job, or script will make decisions from UCN
|
|
|
16
16
|
|
|
17
17
|
## Trust lines
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
Caller, callee and trace views carry the applicable trust lines below, preserved through truncation. Source, definition and test-reference lists do not supply a caller account; request `show` or `impact` when one is needed.
|
|
20
20
|
|
|
21
21
|
- `ACCOUNT` partitions every line where the name occurs: confirmed, unverified, non-call (import, definition, reference, other text), other-target, unaccounted. In mixed-language repositories it also counts occurrences in unsupported-language source files.
|
|
22
22
|
- `CONTRACT` states the scope of that partition. When unsupported-language files contain the name, it says so and limits the partition-complete claim to supported languages. Semantic completeness is never claimed.
|
|
@@ -48,11 +48,13 @@ Even when all five hold, `account.contract.semanticComplete` remains false. Use
|
|
|
48
48
|
|
|
49
49
|
Caller and callee JSON carries compact `provenance`: `rule`, contributing `rules` when there is more than one, `validation`, and the receiver's source and origin line when recorded. Incomplete proofs include a `diagnostic`, also shown in text. Callees retain compact `siteProvenance` for each distinct occurrence; their summary uses the weakest confirmed site's rule. Exclusions expose counts by rule and validation under `account.excluded.evidenceSummary`.
|
|
50
50
|
|
|
51
|
-
A lone project owner of a method name does not identify an untyped receiver. Such candidates stay unverified with `single-owner`; importing the class does not change that. `provenance-incomplete` means the available facts cannot establish this declaration. Inspect the site and diagnostic before editing it. Neither reason is permission to discard a possible caller. `validation: unsupported` means the witness collector does not cover that path (for example a wildcard re-export or an external inherited member); the existing classification is kept in report-only mode and is not a validated proof. Missing or inconsistent facts on a supported lookup still route unverified.
|
|
51
|
+
A lone project owner of a method name does not identify an untyped receiver. Such candidates stay unverified with `single-owner`; importing the class does not change that. `provenance-incomplete` means the available facts cannot establish this declaration. Inspect the site and diagnostic before editing it. Neither reason is permission to discard a possible caller. `validation: unsupported` means the witness collector does not cover that path (for example a wildcard re-export or an external inherited member); the existing classification is kept in report-only mode and is not a validated proof. Missing or inconsistent facts on a supported lookup still route unverified. A confirmed edge's `validation` is always `establishes-target` or `unsupported`: an edge whose witness proves another declaration, or cannot finish the lookup, is listed unverified (`provenance-incomplete`) instead. Super calls (`super.m()`, `super().m()`, C# `base.M()`) are looked up from the enclosing class's bases. An unverified alias call (`f = obj.m; f()`) can carry `establishes-target`: the target is proven, the call goes through a local alias.
|
|
52
52
|
|
|
53
53
|
## Release evaluation
|
|
54
54
|
|
|
55
|
-
Releases are gated on pinned real repositories against independent oracles (ts-morph, Pyright, gopls, rust-analyzer, JDT LS, Roslyn, clangd): 100% in-scope caller and
|
|
55
|
+
Releases are gated on pinned real repositories against independent oracles (ts-morph, Pyright, gopls, rust-analyzer, JDT LS, Roslyn, clangd): 100% in-scope caller, callee and value-reference recall with zero unaccounted oracle edges, at least 98% confirmed-tier precision, full conservation, zero false-dead claims in the default `deadcode` audit, exactly agreeing cross-command claims for the same handle (`find`, `show`, `source`, `impact`, `tests`, `check`, caller `trace`), and bounded unverified review burden (at most 10% of exact true edges left unverified, at least 80% of targets with no actionable ambiguity, at most five actionable candidates at p95).
|
|
56
|
+
|
|
57
|
+
Performance gates cover throughput, memory and per-class query latency on the reference host. Existing capabilities compare against the previous release. A newly introduced reference band or declaration inventory compares the complete command against its first working revision, with the same 1.15x and +5 ms allowance. The original release comparison stays visible; extra proof work or changed confidence alone does not qualify for a new baseline. Passing these sampled gates is evidence for the measured static evidence classes, not complete runtime knowledge of dynamic dispatch, generated code, reflection or external dependencies.
|
|
56
58
|
|
|
57
59
|
## Truncation
|
|
58
60
|
|
package/README.md
CHANGED
|
@@ -73,9 +73,9 @@ when the task needs every occurrence, including those that are not calls.
|
|
|
73
73
|
|
|
74
74
|
## Code navigation and change analysis
|
|
75
75
|
|
|
76
|
-
`show`
|
|
77
|
-
|
|
78
|
-
answer focused. `trace` follows the call graph across files, down into callees
|
|
76
|
+
`show` gives a symbol's summary, callers, and callees by default. Select
|
|
77
|
+
`--sections` to request source, tests, or related context, or set an output
|
|
78
|
+
budget to keep the answer focused. `trace` follows the call graph across files, down into callees
|
|
79
79
|
or up through callers toward entry points. Unverified relationships remain
|
|
80
80
|
visible, and the tree's accounting reports where exploration stopped.
|
|
81
81
|
|
|
@@ -121,7 +121,8 @@ needs the compiler and tests.
|
|
|
121
121
|
|
|
122
122
|
Release gates compare UCN's answers with independent compilers and language
|
|
123
123
|
servers on a ten-repository board of pinned production codebases. The local
|
|
124
|
-
|
|
124
|
+
November 6, 2026 evaluation, using clangd 18.1.8 for C/C++ and .NET 10.0.403
|
|
125
|
+
for Roslyn, recorded these sampled caller results:
|
|
125
126
|
|
|
126
127
|
| Repository | Pinned commit | Oracle | Symbols sampled | Confirmed precision | In-scope recall |
|
|
127
128
|
|---|---|---|---:|---:|---:|
|
|
@@ -136,24 +137,29 @@ October 4, 2026 evaluation recorded these sampled caller results:
|
|
|
136
137
|
| cjson | `c859b25d` | clangd | 50 | 100% | 100% |
|
|
137
138
|
| fmt | `e424e3f2` | clangd | 50 | 100% | 100% |
|
|
138
139
|
|
|
139
|
-
That evaluation
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
That evaluation scored 9,677 confirmed caller edges, all correct;
|
|
141
|
+
41 further edges were unscored. It reported zero missing in-scope
|
|
142
|
+
oracle edges in both caller and callee answers. The separate value-reference
|
|
143
|
+
sample scored 1,241 confirmed sites, all correct, with 4 unscored and zero
|
|
144
|
+
missing in-scope sites.
|
|
145
|
+
All 8,000 cross-command comparisons agreed.
|
|
146
|
+
The default dead-code audit found zero false-dead results among 7 scored
|
|
142
147
|
claims; 4 additional claims could not be pinned by the oracle and were unscored.
|
|
143
|
-
All ten repositories passed the performance budgets, with steady-state query
|
|
144
|
-
p95 from 4.7 to 101.1 ms. Those timings exclude process startup and indexing;
|
|
145
|
-
cold builds and cache loading are measured separately.
|
|
146
148
|
|
|
147
149
|
The samples are deterministic and stratified by reference activity. Confirmed
|
|
148
150
|
precision applies to scored claims; recall counts in-scope oracle edges found
|
|
149
151
|
in either the confirmed or unverified band. Unverified candidates, oracle
|
|
150
152
|
abstentions, and unscored findings remain separate. These measurements do not
|
|
151
|
-
establish complete runtime knowledge
|
|
153
|
+
establish complete runtime knowledge.
|
|
152
154
|
|
|
153
|
-
The scheduled board covers
|
|
154
|
-
express, hono, zustand, fastify, rich, click, attrs, grpc-go, chi, cursive,
|
|
155
|
-
itertools, rayon, gson,
|
|
156
|
-
|
|
155
|
+
The scheduled board covers 43 pinned repositories: the ten above plus zod,
|
|
156
|
+
express, hono, zustand, fastify, dayjs, rich, click, attrs, grpc-go, chi, cursive,
|
|
157
|
+
itertools, rayon, rand, gson, jsoup, pino, tanstack-form, tqdm, zap, nom, guice,
|
|
158
|
+
dapper, lz4, pugixml, stateless, luxon, arrow, more-itertools, rust-url,
|
|
159
|
+
indicatif, and cachetools. A rotating fresh-repository arm checks 13 untuned codebases.
|
|
160
|
+
Repositories used to repair a finding move to the pinned board and receive
|
|
161
|
+
untuned replacements. A fresh failure fails the weekly run; independent
|
|
162
|
+
checks still run and upload their reports.
|
|
157
163
|
|
|
158
164
|
The [repository manifest](eval/lib/repos.js) records the full commits.
|
|
159
165
|
The [Publish workflow](https://github.com/mleoca/ucn/actions/workflows/publish.yml)
|
|
@@ -190,8 +196,10 @@ npm run trust:gate
|
|
|
190
196
|
| Likely missing awaits | `audit-async` |
|
|
191
197
|
| Stack-trace frame resolution | `stacktrace <text>` |
|
|
192
198
|
|
|
193
|
-
`
|
|
194
|
-
|
|
199
|
+
`--staged` selects the Git-diff form of `impact` or `check`, without a symbol.
|
|
200
|
+
|
|
201
|
+
`deps --cycles` groups circular dependencies and, in JS/TS and Python,
|
|
202
|
+
distinguishes eager imports from deferred or type-only edges. Enumeration limits are disclosed. `repo`
|
|
195
203
|
reports source coverage as well as project structure; its HOT ranking counts
|
|
196
204
|
confirmed production callers exactly (a refinement budget only binds on very
|
|
197
205
|
large repositories, and is disclosed), and `repo --sections=stats --hot` ranks
|
|
@@ -208,14 +216,16 @@ Run `ucn --help` for flags, or use the
|
|
|
208
216
|
## Shell output
|
|
209
217
|
|
|
210
218
|
Records and code go to stdout; accounting and notes go to stderr. Unverified
|
|
211
|
-
records carry a tab-separated reason. An empty listing exits 1, an
|
|
212
|
-
exits 2, and a successful listing exits 0. `--lines` supports `find`, `show`,
|
|
219
|
+
records carry a tab-separated reason. An empty `--lines` listing exits 1, an
|
|
220
|
+
error exits 2, and a successful listing exits 0. `--lines` supports `find`, `show`,
|
|
213
221
|
`usages`, `search`, and `impact`; `show --lines` lists callers by default.
|
|
214
222
|
Use `--json` when the script needs structured fields or a tree result.
|
|
223
|
+
CLI JSON is uncapped by `--max-chars`, even when explicitly supplied;
|
|
224
|
+
`meta.maxChars` reports `"not-applied"`. Use command limits to narrow the result.
|
|
215
225
|
|
|
216
226
|
Listings are deterministic for a given source tree: a fresh build, a cache
|
|
217
227
|
load, and an incremental rebuild return the same records in the same order.
|
|
218
|
-
|
|
228
|
+
`--lines` listings have no default row cap. Explicit limits disclose what they omit,
|
|
219
229
|
and a shell-mode character budget fails before writing partial output.
|
|
220
230
|
`source --raw` extracts complete functions and classes unless an explicit
|
|
221
231
|
line limit is requested; any resulting truncation is reported on stderr.
|
|
@@ -225,7 +235,8 @@ empty results and exit 1 for command errors (`meta.ok: false` plus `error`).
|
|
|
225
235
|
An exception inside UCN is reported as `Internal error: ...` (JSON adds
|
|
226
236
|
`meta.internalError: true`), never as an answer about the code.
|
|
227
237
|
Target-less `check` exits 1 when `TRUST` is `BLOCKED`, 0 for other completed
|
|
228
|
-
checks, and 2 if it could not run.
|
|
238
|
+
checks, and 2 if it could not run. `check <symbol>` exits 1 for a signature
|
|
239
|
+
mismatch or an unverified call site.
|
|
229
240
|
|
|
230
241
|
Outside `--lines`, `find`, text `search`, `deadcode`, `api`, and
|
|
231
242
|
`repo --sections=files` default to a maximum of 500 results. `find` text shows
|
package/cli/index.js
CHANGED
|
@@ -960,9 +960,10 @@ Commands:
|
|
|
960
960
|
Common flags:
|
|
961
961
|
--file=PATH --exclude=a,b --in=PATH --depth=N --top=N --limit=N
|
|
962
962
|
--all --compact --no-compact --json --include-tests --class-name=X --line=N
|
|
963
|
-
--range=N-M (source
|
|
963
|
+
--range=N-M (source <file> --range=N-M, or --file=PATH)
|
|
964
964
|
--base=REF --staged --no-cache --clear-cache [--all] --max-files=N --workers=N
|
|
965
965
|
--max-chars=N (text characters, not UTF-8 bytes; default 10K targeted / 3K broad, ceiling 100K)
|
|
966
|
+
JSON is uncapped; meta.maxChars is "not-applied", even with an explicit budget.
|
|
966
967
|
--lines find/usages/search/show/impact: grep -n shape, one path:line:text
|
|
967
968
|
record per output line; usages combines occurrences on each source line
|
|
968
969
|
(tags after a tab: # unverified: <reason>, # import,
|