A stranded static function lost its static flag and read as externally linked, so a call could bind across files: fixed with a decoy. Tag uses such as struct cfs_rq *cfs_rq now bind, kernel subtree USAGE 44,251 to 113,857, along with cast macros as receivers, C++ unions as classes, and two-headed function repair. Macro hand-off walks keep a seen set on macro and position: on doubling depth the work counter goes 35 to 47 where it was 155 to 8,225 without one.
Withdrawn as not provable: a rule binding a macro in one configuration branch and a function in another, because the call exists in only one, costing kernel subtree CALLS about 1,041; and a raw define beside a missing header, which that header may undefine, costing neovim about 5,500 edges that look true. Canonical lint passes.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Projection deleted every controlled edge the resolver had not recorded, including route registrations, Helm includes, Kubernetes references, SQL lineage and Ansible notifies. A narrow exemption now needs the producer's own via marker and the target's label together; a forged-looking CALLS still goes, by decoy test. Over 47 repositories CALLS into Route go from 4,315 at baseline and 0 before this to 1,146, without client calls and string methods: django 1,206 to 0. Helm includes return to 3,365 and Kubernetes references to 3,936.
One empty .tf or terragrunt.hcl no longer aborts the whole index. One templated Ansible handler no longer voids every notify in the project, nor one unfollowable .env value every $ image in a compose project. Go method-value and ASP.NET method-group handlers no longer bind by name.
For review: a receiver named router or app, with a literal path and a handler, counts as evidence for a Route, which is name-based and an exception to CALLS meaning a declaration, as is a Helm define. A dbt model target in SQL is kept without package namespace proof. The test audits skip the projection table's rows.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Kotlin USES_TYPE goes from 0 to 6,131 on Exposed: extraction records type refs, leaving out a supertype's or annotation's head that INHERITS or DECORATES already carries. Call type arguments such as Box<Argument>() now emit. A C# named argument lands on the parameter it names, and a name the declaration lacks rules it out, so overloads such as new Reader(byte[], isFinal: true, state) settle. The default literal fits any parameter. A one-line Kotlin object reads as a class through a same-length parse view.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
cbm_shared_resolver_build creates both and cbm_shared_resolver_free never released them, so every index leaked two hash tables. LeakSanitizer reported it on Linux across 77 suites; macOS does not run it.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
rust_macros kept pointers to its locals in the caller's scan after returning; it now runs on a copy and clears them. path_alias.c allocates through the memory core, 40 raw sites down to 1, with cbm_path_alias_resolve alone staying raw because its callers free its result. Four copies of one import-map cleanup become one helper, 63 raw sites down to 53 in pass_pkgmap.c. The rest reshapes code cppcheck could not follow, without changing behaviour.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
CALLS: redis 28,295 to 32,377, neovim 29,542 to 31,306, whole llvm-project 432,362 to 644,451; USAGE on redis 42,133 to 51,931. Macro replacements are read at the use when every visible definition agrees. Local arrays bind a type, unnamed aggregates get members, ns::Name binds outside its namespace, and out-of-line template members and member templates get nodes.
New graph content: Class nodes named Owner$member. QN changes: out-of-line template members and ns::Foo::bar are Methods. A write through a macro member path records USAGE, not WRITES. False functions such as one spanning 1,445 lines of jemalloc's ctl.c are gone.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
dotnet/runtime CALLS go from 392,440 to 773,575 and USAGE from 709,951 to 1,688,346; elasticsearch CALLS from 1,308,131 to 1,342,695 and Exposed from 20,357 to 23,603. The same type in ref/ and src/ now means the implementation stands for the contract. A reader means its own file's declaration or the only one in its build project, and .projitems counts as a project. A same-length parse view reads spellings the grammar loses: Vector128.cs goes from 0 to 172 methods. Lambdas take their parameters from the callee's single abstract method.
A CALLS edge can now start from a Field node, and calls in C# conversion operators, indexers and property bodies belong to those members. Five wrong edge kinds found while sampling are fixed.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
USAGE goes from none to thousands of SCIP-confirmed pairs on Ruby (rubocop 3,322, vagrant 4,488) and to 890 sites on Elixir's plug. dune CALLS sites rise from 6,891 to 43,659: .mli files are read inside sig, includes reach paths below them, and functor parameters are bindings. Elixir's use reads __using__, Haskell's T(..) matches, Zig reads a field's type with its own file's visibility, Scala class-body vals carry their class in the QN.
A Ruby block keeps self only under a core iterator or a project method whose declaration does not rebind it, followed through a forwarded &block, so blocks under unknown gem methods abstain. Several OCaml and Scala false edges from the earlier tree are gone. CBM_INDEX_FORMAT_VERSION moves to 5 because OCaml, Zig and Scala QNs changed.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
CALLS recall against SCIP: cli/cli 35.4% to 99.9%, cargo 20.4% to 98.6%, tokio 26.6% to 91.8%, meilisearch 97.1% to 98.4%, prometheus 97.1% to 97.8%, helm 98.2% to 98.6%. A test go.mod declaring the repository's own module path no longer voids every import of it, and replace directives decide. Grammar errors from Go new(expr) and Rust str![[...]] no longer void the file: cargo had lost 477 of 1,374 files. Rust macro_rules definitions are read per package, and calls in nested items belong to the enclosing function.
A Go conversion T(x) is USES_TYPE, not CALLS, though SCIP counts it as a call pair.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
CALLS recall against SCIP: vue 62.9% to 98.0%, vite 62.2% to 97.4%, nest 90.9% to 96.6%, precision 100% and no site contradicting SCIP. An identifier merely named Function or eval no longer voids a file. Workspace packages, tsconfig paths, baseUrl and exports conditions resolve from their manifests. Receivers come from what the file spells. Five false-edge classes found by decoys are closed, one of which predates this round: this in an object literal read as the enclosing class.
A package.json, pnpm-workspace.yaml, tsconfig or extends base edit now declines incremental repair.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
CALLS recall against SCIP on six repositories rises from 80.7% to 95.5%, precision holding at 99.5%. A manifest now states source roots, so a src layout reaches its own package. A write blocks only the name it spells, not a whole package. Decorators keep the declaration unless the source proves the function dropped. Three false edges the baseline also had are fixed: a conditional star's first arm, t.x = make() reading the declared x, and a descriptor read as the instance.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
C writes no binding list to alter now, so the authority test forges one: a property naming a wrong target must still carry no authority. The Python suite ran about 500 full indexes through both drivers and passed the 900 s per-suite cap on Windows, so it is three suites, and rows of one fixture share its index. No assertion changes.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Nothing reads it, and a generated header with tens of thousands of includes made one File node 9 MB and its database 13 times the baseline's. Under strict_string_checks that string also made the FTS backfill's LIKE quadratic, so the diagnostic CI lane timed out at 900 s. The test now pins the node's size.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
js_fixture returned its arena by value while the index kept a pointer to it, which only worked where the copy was elided. The parallel harness never freed the Rust project and ECMAScript surfaces. Templates sized exactly to their text overflow on Windows, where cbm_mkdtemp rewrites /tmp/ to the longer temp root in place.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
GCC treats the conditional compound literal inside the context's designated initializer as missing braces, and the Linux build fails on it. A zeroed node is already null, so only a repaired parse assigns one.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Over the memory budget each result is parked on disk and read back only for a moment. The Java, Kotlin and C# declaration index kept qualified names from the freed result, and a resolve worker read them. TypeScript's merged label did the same. Both are found by ASan with CBM_MEM_SPILL=1; every resolver suite now runs clean that way.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
The same three comparisons read as one helper, and cppcheck no longer infers a constant from the indent loop. Behaviour is unchanged.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Fetching a child by index walks from the first child, so the audit was quadratic in the statement count, and it runs serially for every ECMAScript file. TypeScript's baselines held indexing that repository for over 28 minutes; it now takes 182 s. The C# reference-assembly fixture binds neither type now that the parse view keeps both namespaces.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Only a direct argument, parenthesized value, standalone reference or initializer hands over one callable. Branches and pairs do not, which is what this test required before it was flipped and what a Java ternary does. A Go result annotation is USES_TYPE alone, like TypeScript, so its USAGE row goes.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
With the harness building the index production builds, the reference argument,
the same-package access and the constructor call all bind, and each is what the
rules select: Java and Kotlin share com.example, and no constructor is declared,
so the class stands for the implicit one, as test_resolver_oo.c pins.
The Kotlin alias gap is named after its real cause. The file parses completely, so
the parse-gap name and text were stale. The alias call stays unbound once the file
also declares a class with a member.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
The parse view keeps one branch of each #if, which is enough for the graph's nodes.
The scope read that same tree, so a namespace or a type another branch names
differently looked placed and complete. A reference valid in the other build was
then reported as doc rot, where it used to be a graph gap.
When the view hid a branch, keep the file's own parse for the scope. A view that
only blanked `ref` hides nothing and stays in use. RED:
doc_mentions_cs_scope_parse_errors, doc_mentions_resolver_parse_errors.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
An unnamed companion now has a node, but the scope looked a definition up only by
a name token, which it does not have. [Type.Companion] stayed a graph gap with the
node right there. RED: doc_mentions_jvm_kotlin_scope_blob,
doc_mentions_jvm_kotlin_companion_inherits.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Kotlin nested types are named under their outer class and an unnamed companion
has nodes, so the pins move to those names, each confirmed against a real index.
One of them, a zero count on gk.K4.Wrapped.m, passed vacuously under a stale
suffix.
A nested class and a member function of one name now share a qualified name, and
so do a member function and a property. The later declaration owns the node, so
[Holder.Part] and a doc on the earlier twin are graph gaps. No edge goes to the
wrong twin. Both are pinned as known gaps.
The C# parse view reads `ref partial struct`, so those fixtures write it with a
comment between the words, which the grammar still cannot read and the view does
not repair. The plain spelling gets its own positive.
RED until the two doc-link fixes that follow: the slot of an unnamed companion, and
the C# scope of a file whose parse view hid a branch of a conditional.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Kotlin records no USES_TYPE occurrence for a result type, so USAGE names the class there. A
parameter annotation emits neither, so ad60078d4's parameter rows required an edge production does
not make. Dropped those two rows.
Also corrects ad60078d4's message: the PHP reason string was renamed in b821d1506, not aeb5971dc.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
A matrix row on a class target brings that class's other roles into the harness
audit. `make(): Widget` and `anon(): User` name the class they also construct, so
the signature's USAGE, and USES_TYPE in Scala and Swift, become required rows at
that exact token.
mkc_c2_csharp_operator_overloads pins the operator scope for overloads stored as
variants, for a spaced `operator -` and for the word form `operator true`.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Each row was checked against its fixture source.
Promoted to required, the target is what the language selects: same-class C# await call, Kotlin
suspend call, Kotlin sealed `is` branches with their forbids kept, Java enum methods, the static
interface target with its forbid kept, Kotlin operator plus, the imported Celery instance's
send_task with the foreign decoy kept, RestTemplate literal routes.
Corrected:
- writes_go named a `cache.` package part that a Go root file does not have, so neither the row
nor its decoy forbid could match anything. Both now bind.
- Python and Kotlin constructor rows name the class node. A Kotlin primary constructor has no node
of its own and Python's class call selects the class, as test_pipeline requires.
- FunC and Meson import probes required 0/0 spans. The carrier now records the literal's exact
occurrence, and the probes require that occurrence.
- es_php_include_occurrence_spans_and_sealing_guards pinned a reason string renamed in aeb5971dc.
Reads are USAGE: Go, Java and C# rows list it as required. Their READS rows stay named gaps because
nothing emits READS. Java's count++ stays a gap: its assignment kinds omit update_expression.
Celery's ASYNC_CALLS rows stay gaps with an updated reason: CALLS is proved, the service
classifier does not see that proof.
Adds es_go_annotation_types_are_not_value_usage and es_go_index_assignment_reads_operand_and_index
for the Go role rules. No forbid was removed.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
`cache[key] = v` stores an element through the operand's map or slice and rebinds nothing, but it
published WRITES for cache and nothing at all for key. Both are reads now, so they are USAGE. An
array variable is written in place by this form as well; its element type is not known here, so
it reads as USAGE too, which is a missing write and not a false one.
A Go parameter, result, var or conversion type also published USAGE on the same token that
type_refs already carries as USES_TYPE, which es_usage_crossfile_go forbids and the TypeScript
adapter already refuses. One token now has one role. A composite literal builds a value of its
type, a receiver has no USES_TYPE occurrence, and USES_TYPE reads a qualified type's whole
spelling rather than its member token, so those three stay USAGE.
RED: cp_reads_writes_go_global (forbid Set WRITES cache) and es_usage_crossfile_go (forbid
annotation-is-not-value-usage).
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
The parallel route decides per file whether cross-file analysis runs, and a file with no call
left to resolve was skipped. For Java, Kotlin and C# that also skipped the strict walk, which is
the only source of their field and type rows, so a class that only reads and writes its own
fields lost every USAGE, WRITES and type row in the parallel route. The sequential route has no
such filter, so the two routes disagreed.
C and C++ already had this exception. Extend it to the strict-walk languages.
RED: writes_java, writes_csharp, cp_reads_writes_java_static_field and
cp_reads_writes_cs_static_field found the write in the sequential route and lost it in the
parallel one.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Each row was checked against the fixture source and the language's own rules.
Conditional variants (Go build tags, Swift, Erlang, Elixir, Haskell): one node
holds every branch's span, so a body call is that node's call under its authored
variant, and a caller reaches that one node in every configuration. Targets
anchor on the node's stored span. Haskell later branches stay a known gap: the
source adapter walks the raw parse, which holds only the first branch of a #if.
C# same-name classes: all seven member rows promote, the constructor call under
`using Contoso.Threading` gets its own required row, and the edge checks now pin
the bound target with the decoy still refused. `new Thing()` on a partial type is
a known gap: no one node is that type.
The parallel harness now builds the declaration index production builds, so Java,
Kotlin and C# static selection runs on that route too.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
operator_declaration was no function kind, so `operator+` had no node and every
call and usage in its body was attributed to the file. The resolver then published
`Vec CALLS Vec2.Vec2` from a body that belongs to a named member.
The operator is now a Method named by its token, spelled like C++'s `operator+`,
through the one resolver the def side and the call scope share. Overloads merge
into one node with variants, as other C# methods do.
RED: mkc_c2_csharp_operator_plus reported scope=Vec for the constructor call. The
binary operator site `a + b` still abstains, and conversion operators, property
accessors and indexers still have no node of their own.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Rows written before the language rules existed. Each was re-derived from its
fixture source:
- Java, Kotlin, C#, Scala, Swift: a constructor call with no constructor node
binds the class, marked as a class call. Rows expecting a Method or nothing are
now required rows on the class declaration.
- Field initializers run in no callable node. The file-level node is their scope,
so the LRP oracle accepts a 0/0 range for a row naming that node, as rq_target
already does.
- Go struct literal: the type name is both USAGE and USES_TYPE at both of its
sites, and a literal key names a field.
- Recovered receiver and fluent rows in those scenarios become required.
- probe_kotlin_data_class and probe_cs_class_methods pinned both rows missing,
though both are required and found.
mkc_c2_csharp_operator_plus and the new mkc_c2_csharp_operator_overloads stay red
here: a call inside a C# operator is attributed to the file. The next commit fixes
that in production.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Rows the integrated resolver now proves become required. Fixes: a Python class statement reads its bases where it stands, so a later sibling is no base; a Kotlin callable reference in an if branch stays a usage; cppcheck findings on the integrated tree, including the OO walkers keeping a stack address in the walk. Swift package entries now count the two membership facts.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
A configured define's body keeps its meaning in the expanded parse, so -DAPI=Junk does not read class Junk Foo as class Foo. An ambiguous TypeScript proof is two distinct functions extraction named flat, not one merged identity. The _Thread_local pointer form now parses, so its pin says so. The module index and filtered defs allocate through the memory core. Format production files the merges left unformatted.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
C-family takes the attribute-macro parse, everything else the C# repairing parse. The Rust project model already replaced the walker in this lane's pkgmap hunk, so only build_include_path_context survives. c_variants joins the identity rule; the read-as-value-reference lookup is guarded to C-family because other lanes were measured without it.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
The project model replaces the old import-context walker, keeping the JVM lane's scoping of a context failure to Rust and C-family. Rust's identity rule runs before the merged-variant rule for Rust targets. Call, usage, write and type dispatch each gain a Rust arm beside Go's.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Python and ECMAScript each own separate paths through the binding index, so conflicts are unions. BINDING_DECORATED moves to the next free bit; Python lookups pass JS_SPACE_ANY; too_early keeps the ECMAScript closure rule, and the Python-guarded deferred site may still excuse it. Commit 456bdbb30's message says about 16 wrong edges; the measured figure is 11.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
`Ops make_ops(void);` in main.c with the definition in ops.c. The goldens named the prototype, which
has no graph node, and recorded a gap, so the correct edge counted as a false positive. A prototype
declares the external name, and the one definition of that name is the target.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Union with the other lanes. Merged same-kind declarations are one graph identity in core-go's rule; JVM overloads and TypeScript merged value/type stay on their own paths, and the JavaScript span rule still applies only to a source in this file. Evidence writing keeps the perf-scale writer, proven edge-identical. The lane's commit d38554e3d is labelled WIP but its code is final; the label could not be amended.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Conflicts are unions: the JVM lane's overload_set covers Java, Kotlin and C#, and the merged-target and Class-callable rules here cover TypeScript, JavaScript, Vue and Svelte.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Each of these pinned an abstention as a known gap, and the 18:41 run reported the exact expected
target as found. 20 field rows in c_member_fields_quality, cpp.enum.green and the four C++ static
factory rows become required.
Nine rows are new: parameter types and reads the rules now bind, read against the fixture source
one by one. `int use_beta(Beta b)` uses Beta. `a->count` in a function inside a preprocessor branch
reads Alpha.count. `g_alpha.count` on a static of written type reads Alpha.count.
In the conditional variant tests the calls in both branches and the call to `pick` now bind. A
caller's target is the one node both branches share, whose stored span is the last branch, so the
golden names that declaration.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Two failures from the 18:41 test run.
clsp_issue1527_long_binary_chain_is_not_nesting overflowed the stack under ASan. The new member
and value rules added locals to c_resolve_calls_in_node_inner, which is in every frame of a walk up
to C_LSP_MAX_WALK_DEPTH deep. What one node does now sits in a separate function kept out of line,
and it returns before the walk goes into the children. No logic changed: redis, neovim and the LLVM
subset give the same edge counts before and after.
extract_cpp_export_macro_explicit_define_priority_issue1989 pins that a define the caller provided
wins. A word the caller defined is no longer left out of the raw parse.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
From the 18:41 run of resolver_c. `parse()` also spells a declaration, so the call is named by its
context. `bump_flags` has a closed USAGE domain, so its parameter's type is expected. The hiding
header drops its guard macro: with it, the preprocessed pass adds a row the oracle cannot map to
the file as written.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>