Commit Graph
980 Commits
Author SHA1 Message Date
Martin Vogel f159b4c21d Merge pull request #1731 from henry-hz/upstream-pr/elixir-complexity
fix(elixir): functions carry no complexity, fingerprint or line count
2026-11-01 09:04:28 +01:00
Martin Vogel 6e0c59f5cf Merge pull request #2867 from DeusData/fix/cs-lsp-nested-types-global-ns
fix(cs-lsp): resolve nested types through type qualifiers, bind global-namespace types
2026-11-01 02:50:53 +01:00
Martin Vogel 21c253ff63 fix(cs-lsp): never pool global-namespace types as partial twins
cs_lookup_method searches the other declarations of a type (same simple
name, same declared namespace: `partial` pieces, reference-assembly
copies) before it walks the base classes. With global-namespace types now
carrying the namespace "", every same-name type declared without a
namespace anywhere in the repository became a twin of every other one.
Across a repository that is a different type per assembly (each test
project has its own Program or Helper), so a member missing on the
receiver bound to an unrelated type ahead of the receiver's own base.

cs_namespace_twins returns no twins for a type in the global namespace.

Test: cs_lsp::cslsp_global_namespace_types_are_not_partial_twins runs the
production Tier-2 C# registry builder over cross-file defs: two unrelated
global Helper types and a base class. RED without the guard:
stop_base=0 stop_unrelated_global_twin=1. GREEN with it.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-01 01:13:02 +01:00
Martin Vogel dad89184cb fix(cs-lsp): look up the global namespace in C# spec order
C# looks a simple type name up namespace by namespace, innermost outward.
At each namespace N it checks the members of N, then the usings of the
namespace declaration enclosing the reference. The global namespace is
the last N, and its declaration is the compilation unit. So a type
declared without a namespace hides a type that only a compilation-unit
`using` imports, while a `using` inside a namespace body still wins over
the global namespace. Step 8b used to rank every using before the global
namespace.

- CBMCSUsing records whether a directive sits inside a namespace body
  (in_namespace). cs_collect_imports tracks it per node, including the
  compilation-unit siblings after a file-scoped namespace; the cross-file
  entry pre-loads the pipeline import list without placement and the AST
  walk upgrades it.
- cs_visible_namespaces ranks a simple name as: enclosing namespaces
  innermost outward, namespace-body usings, the global namespace "", and
  last the compilation-unit usings.

Ranking the global namespace that high also requires that only a type
proven global claims it. The vendored grammar does not parse a
`ref partial struct` with members, and error recovery dissolves the
enclosing namespace, so every type after it in that namespace surfaced
with no namespace. Mapped to "" those types outranked the real, imported
declaration: on dotnet/runtime 5,313 CALLS moved from implementation
files into reference assemblies (System.Runtime.cs, which declares
DefaultInterpolatedStringHandler as a `ref partial struct`).
cs_type_decl_namespace now returns "" only when the compilation unit
parsed without errors and NULL (unknown, invisible to step 8b, as on
main) otherwise; cs_top_level_namespace passes that through.

Tests:
- parallel_csharp_nested_type_and_global_namespace_binding: the
  compilation-unit `using` probe now expects the global type (spec), and
  a new namespace-body `using` probe expects the imported one. RED with
  the previous order: cu_using=0/0.
- parallel_csharp_parse_damaged_namespace_is_not_global (sequential and
  parallel). RED without the clean-parse rule: real=0 no_damaged=0 on
  both paths.
- cs_lsp::cslsp_decl_namespace_global_needs_clean_parse: extractor
  contract ("" for a clean global type, the namespace when found, never
  "" after a parse error).

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-01 01:12:46 +01:00
Martin Vogel bc44de15d3 fix(cs-lsp): bound the nested-type qualifier walk
Resolving a qualified type name A.B that no namespace binds now resolves
the qualifier A as a type first (nested types). A using alias whose target
is qualified by the alias itself re-enters that walk through the alias
step without end: `using Loop = Loop.Inner;` resolves Loop to the target
Loop.Inner, whose qualifier is Loop again, and a mutual pair (`using
Ping = Pong.Inner; using Pong = Ping.Inner;`) cycles the same way. Both
are legal C# when namespaces of those names exist, and the walk overflowed
the stack on them.

The walk now carries a depth counter in the per-file context and stops
after CS_QUALIFIER_MAX_DEPTH (8) levels. One level is one type-nesting
step: a namespace-qualified top-level type binds without recursing, so
real nesting stays far below the bound.

Test: cs_lsp::cslsp_cyclic_alias_qualifier_terminates (self and mutual
alias cycles; the file must still resolve Svc.Go). RED without the bound:
AddressSanitizer stack-overflow, exit 134. GREEN with it.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-01 01:07:37 +01:00
Martin VogelandErsin Tarhan c0a8ed8b93 fix(cs-lsp): resolve nested types through type qualifiers, bind global-ns types
Follow-up to #2347 (issue #2120). Step 8b binds same-name TOP-LEVEL types
by declared namespace, but two shapes still fell through to the short-name
fallback, where the prefix score against a path-derived QN is 0 for every
variant and registration order decided:

1. A qualified A.B whose qualifier A is a TYPE, not a namespace:
   new Command.Result(...) and new Grain.Handler(dep).Handle(...).
   cs_visible_namespaces only tried A as a namespace, and nested types
   carry no namespace_qn, so the scan never had a candidate. Resolution
   now falls back to resolving the qualifier as a type (recursively, one
   segment shorter) and binding the nested member through the registry.

2. A top-level type with no namespace declaration (global namespace):
   cs_top_level_namespace returned NULL for it, making it invisible to
   step 8b. Top-level C# types now register namespace_qn "" and
   cs_visible_namespaces appends the global namespace last.

Test: parallel_csharp_nested_type_and_global_namespace_binding covers a
nested-type constructor and the member call on its result, a chained
constructor receiver, and a same-name type split across the global
namespace and an imported namespace, in the sequential pipeline and in
the parallel pipeline with the production Tier-2 C# registry. Decoys are
registered first. Adapted to current main: the two constructor-edge
checks gate the parallel path only, because the sequential constructor
edge is still drawn by the textual constructor carrier, a layer this
change does not touch.

Distilled from #2401: the net change of commits d11be54f and 613060ea.
The temporary debug prints added in d11be54f and the stale copy of #2347
the branch carried (already on main as 50d19f85) are not taken.

Co-authored-by: Ersin Tarhan <ersintarhan@gmail.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-01 01:07:01 +01:00
Martin Vogel 812d0755c1 Merge pull request #2854 from divakantpandey/fix/2768-angular-http-client-method
fix(pipeline): infer HTTP method for Angular and verb-suffix client calls (#2768)
2026-10-31 23:47:50 +01:00
Martin Vogel 3b33babd7c style(elixir): put the definition comment back above extract_elixir_func_def
The complexity helpers were inserted between the comment that documents
extract_elixir_func_def and the function itself, so that comment read as
the description of elixir_node_text_is. Move it back above the function it
documents; the comment and signature are again byte-identical to main. No
code change.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-31 21:31:39 +01:00
Martin Vogel 2caf51a4c6 fix(elixir): a folded multi-clause function carries the metrics of every clause
Since #2371 the clauses of a multi-clause function fold into one Function
node whose span covers all of them, but only the first clause was measured:
the folded node kept the complexity, cognitive, loop and access metrics and
the line count of that clause while its span grew.

fold_elixir_clause now receives the metrics of each clause it folds and
adds them to the node: cyclomatic, cognitive and loop_count add up,
loop_depth and max_access_depth take the deepest clause, every clause past
the first adds one dispatch decision to cyclomatic, and lines is recomputed
from the folded span. A clause whose walk reports
CBM_WALK_METRIC_UNAVAILABLE makes the folded value unavailable rather than a
partial sum. This is the treatment proposed in the PR description and
agreed in the review thread.

Indexed elixir-lang/elixir (669f8481, 6703 Elixir Function nodes) against
the merge parent: the 2212 folded functions change, the 4491 single-clause
functions keep identical metrics, Functions with complexity above 0 go from
3412 to 4785, and every node now has lines equal to its span (4491 did
before).

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-31 21:31:23 +01:00
Martin Vogel aa3161fd81 fix(elixir): grow the complexity walk stack instead of capping it
elixir_compute_complexity kept its pending frames in one fixed 4096-entry
array (48 bytes each, 196,608 bytes in a single stack frame) and stopped
pushing children once it was full. Children are pushed last to first, so a
wider body lost its FIRST children and the function reported a lower
complexity with no signal, on exactly the largest functions. Worker threads
do not get the 8 MB main-thread stack, so the array was a risk of its own.

It now uses the walker pattern cbm_compute_complexity has used since #2375:
a 512-frame on-stack first chunk that spills to the heap through
cbm_walk_stack_reserve (memory core, class EXTRACT) and is released with
cbm_walk_stack_release. If the stack cannot grow, every metric reports
CBM_WALK_METRIC_UNAVAILABLE instead of an undercount. This answers items 2
and 3 of the 2026-08-20 review.

The new test builds a 5000-statement body of alternating if and for. The
fixed stack reports complexity 4095 for it instead of 5000.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-31 21:31:06 +01:00
Martin Vogel 22a7dff3ff fix(service-patterns): end the Angular receiver rows at a separator (#2768)
The new HttpClient receiver rows matched by prefix, and an uppercase
letter after an id counts as CamelCase glue, so "this.http" also matched
this.httpAdapter.get (a NestJS route registration) and this.httpServer.post,
and "$http" matched $httpBackend.expectGET (an AngularJS test double).

Each receiver row now ends in a dot, like "gin.", plus a line-break twin
(LF, and CR for CRLF files): a chain wrapped before the verb keeps the break
in its callee text ("this.http\n      .post"). On
gothinkster/angular-realworld-example-app 5 of the 18 client calls are
written that way; with dot-only rows they fell back to phantom route
registrations. "HttpClient" duplicated the Java/C# row and
"this.httpClient." is covered by "httpClient.".

Unit cases pin both directions, and the Angular pipeline test gains a
wrapped call on both resolver routes.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-31 20:59:40 +01:00
Martin Vogel 2e6ab84fd9 Merge origin/main into the Elixir complexity branch
Brings the branch up to f6fb3e0d, which carries #2371 (guarded def heads,
the multi-clause fold and typespec attributes) and #1730.

Two files conflicted, both at spots where main rewrote the Elixir
definition code. Each is rebuilt as the main version of the file plus the
lines this branch adds, at the same place; no conflict side is
concatenated:

- internal/cbm/extract_defs.c: the complexity helpers sit between the
  definition comment and extract_elixir_func_def as before, and the
  metrics plus fingerprint block follows def.is_exported in the unfolded
  path.
- tests/test_extraction.c: TEST(elixir_complexity_and_fingerprint) and
  its RUN_TEST go just before the Haskell block, after the Elixir tests
  main added.

Per-file patch-id (git diff -U0 | git patch-id --stable) of this merge
against origin/main equals the branch change against its old base:
extract_defs.c b591a7bc, test_extraction.c 7b507156. The merge removes no
line of either file.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-31 20:56:13 +01:00
Martin Vogel a5c5b42fea Merge origin/main into fix/elixir-extraction-defects
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-31 16:38:55 +01:00
Martin Vogel 747665d71f Merge pull request #2752 from gaurav0107/fix/2537-go-net-http-servemux-patterns-with-a-met
fix(routes): read Go 1.22 ServeMux method and host patterns
2026-10-31 13:53:35 +01:00
Divakant Pandey c548d8e46a fix(pipeline): infer HTTP method for Angular and verb-suffix client calls (#2768)
Signed-off-by: Divakant Pandey <divakant01@gmail.com>
2026-10-31 14:16:04 +05:30
Martin Vogel c0e929378a Merge origin/main into fix/elixir-extraction-defects
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-31 06:11:38 +01:00
Martin Vogel 3e075d59be Merge origin/main into fix/2537-go-net-http-servemux-patterns-with-a-met
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-31 06:11:15 +01:00
Martin Vogel 8c62cb3344 Merge origin/main into fix/go-init-qn
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-31 06:10:26 +01:00
Martin Vogel 9f0fdcb400 Merge pull request #2613 from bline/fix/doc-section-hierarchy
fix(markdown): qualify a repeated heading's Section by its parent headings (#2586)
2026-10-31 06:09:28 +01:00
Martin Vogel 76dda7e35b Merge pull request #2827 from nefayran/fix/2818-puml-edge-operand
fix(diagram): set an empty PlantUML operand id when there is none
2026-10-31 04:27:30 +01:00
Martin Vogel bdf204b2e5 Merge origin/main into fix/elixir-extraction-defects
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-30 22:48:50 +01:00
Martin Vogel 0bd442cd2f Merge origin/main into fix/doc-section-hierarchy
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-30 22:34:08 +01:00
Martin Vogel 7ee29d8841 Merge origin/main into fix/go-init-qn
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-30 22:33:54 +01:00
Martin Vogel 46c95bcddb Merge origin/main into fix/2537-go-net-http-servemux-patterns-with-a-met
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-30 22:29:48 +01:00
Martin Vogel a33878c039 Merge pull request #2420 from Fieldnote-Echo/perf/py-cross-registry-index
perf(py-lsp): O(1) type membership in the shared Python cross-registry build
2026-10-30 22:26:46 +01:00
Martin Vogel edb4a6e735 Merge pull request #2295 from MopicMP/fix/java-record-accessor-calls
fix(java): resolve record accessor calls, and never bind a call to data
2026-10-30 22:26:38 +01:00
Martin Vogel f925afaab7 Merge origin/main into fix/elixir-extraction-defects
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-29 06:32:58 +01:00
Martin Vogel d807b1eca7 Merge pull request #2419 from Fieldnote-Echo/perf/py-lexical-ancestor-kind
perf(python): climb the walk cursor for scope-directive and default checks
2026-10-29 06:32:06 +01:00
Rodion Kazennov d68cd2e2af fix(diagram): set an empty PlantUML operand id when there is none
dg_puml_operand set *label up front but *id only on its success paths, so an
opener without its closer (`Alice ->: x`, `[-> Alice: x`, `class [Unclosed`)
returned with *id unwritten. dg_puml_relation and dg_puml_decl then read an
uninitialized dg_str_t and passed it to dg_element, which crashed the index
worker on some stacks. The operand now starts with an empty id, so those lines
take the existing `!lid.n` / `!rid.n` exits and declarations make no element.

Fixes #2818

Signed-off-by: Rodion Kazennov <nefayran@gmail.com>
2026-10-29 05:01:23 +00:00
Martin Vogel d1a96df077 Merge origin/main into fix/java-record-accessor-calls
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-29 03:48:11 +01:00
Martin Vogel fec0b87b4c Merge origin/main into fix/2537-go-net-http-servemux-patterns-with-a-met
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-29 03:33:16 +01:00
Martin Vogel bd19732017 Merge origin/main into fix/elixir-extraction-defects
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-29 03:33:10 +01:00
Martin Vogel 006101ae4f Merge pull request #1710 from benrfairless/fix/ruby-namespaced-constructor-callee
fix(extraction): reduce A::B.new callee to the constant
2026-10-29 03:32:26 +01:00
Martin Vogel 7a9e6c628e Merge origin/main into fix/go-init-qn
test_pipeline.c: kept the main version and re-applied this branch diff; its three Go init RUN_TESTs precede the #2769 alias tests. test_go_lsp.c: the two #2769 alias tests pass NULL for the new rel_path parameter.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-29 02:51:35 +01:00
Martin Vogel 32bd1d3047 Merge origin/main into fix/java-record-accessor-calls
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-29 02:34:20 +01:00
Martin Vogel 1962c214b1 Merge origin/main into fix/doc-section-hierarchy
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-29 02:34:06 +01:00
Martin Vogel 1c97a4d8a6 Merge origin/main into fix/elixir-extraction-defects
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-29 02:33:59 +01:00
Martin Vogel 7b398de4e4 Merge pull request #2769 from gaurav0107/fix/2033-go-type-alias-alias-of-is-never-register
fix(go-lsp): follow a type alias declared in another file of the package
2026-10-29 02:32:34 +01:00
Martin Vogel 19b57f3e64 Merge origin/main into fix/go-init-qn
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-29 01:58:11 +01:00
Martin Vogel c4e37c1239 Merge pull request #2290 from knewstimek/pr/windows-setenv-utf8
fix(windows): set UTF-8 environment values through wide CRT
2026-10-29 01:56:52 +01:00
Martin Vogel f1efbf60d8 Merge pull request #2746 from gaurav0107/fix/2297-typescript-calls-through-a-renamed-named
fix(ts-lsp): resolve calls through renamed named imports
2026-10-29 01:33:12 +01:00
Martin Vogel d758fd6080 Merge origin/main into fix/2537-go-net-http-servemux-patterns-with-a-met
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-29 01:10:44 +01:00
Martin Vogel 7ee3124bca Merge origin/main into fix/java-record-accessor-calls
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-29 01:10:38 +01:00
Martin Vogel 72ab1cefe1 Merge origin/main into perf/py-lexical-ancestor-kind
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-29 00:19:09 +01:00
Martin Vogel 5985131d86 Merge origin/main into perf/py-cross-registry-index
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-28 23:51:03 +01:00
Martin Vogel 2aaef23111 Merge origin/main into fix/java-record-accessor-calls
Conflict in src/pipeline/pass_calls.c: #2305 moved the inline LSP-target
emission of resolve_single_call into calls_emit_lsp_target() and added
the unresolved-call evidence around emit_classified_edge. The Java
data-member veto of this branch is ported into that structure:

- calls_emit_lsp_target: the veto runs once the target node is known,
  before the resolution, the evidence and any spawn or edge. It returns
  true (handled), so as before no edge is emitted and no registry
  fallback runs after it.
- resolve_single_call: the veto stays in front of main's
  candidate_qn/calls_emitted bookkeeping, matching the parallel
  resolver, whose veto also precedes that bookkeeping.

pass_parallel.c and the remaining files merged cleanly.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-28 22:57:43 +01:00
Martin Vogel f33f976458 Merge origin/main into fix/2537-go-net-http-servemux-patterns-with-a-met
origin/main (#2305) moved the route-registration checks of the sequential
resolver into calls_emit_route_call and made emit_classified_edge return
whether it emitted. Keep the structure and bookkeeping of main and carry
the ServeMux pattern reading over: emit_classified_edge and
calls_emit_route_call now take the registration path from route_reg_path,
so "POST /v1/x" patterns register in both passes as before.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-28 22:43:04 +01:00
Martin Vogel 4680954620 Merge origin/main into fix/doc-section-hierarchy
#2305 (now on main) took semantic index version 11, so this branch's
Markdown Section change becomes version 12; its history entry is kept
after main's 10 and 11 entries.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-28 18:28:17 +01:00
Martin Vogel 6cc63d2c69 Merge origin/main into fix/elixir-extraction-defects
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-28 18:15:38 +01:00
Martin Vogel 3bd645efd5 Merge origin/main into pr/windows-setenv-utf8
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-28 18:15:29 +01:00