mkc_c8_typescript_constructor_samefile and lrp_ts_s3_constructor name the declared
`constructor` as the target of `new Widget(name)`, and the edge went to the Class,
which the quality harness reports as WRONG_OCCURRENCE. A class that declares a
constructor now answers with it, in the same file and through an import. A class
without one stays the Class node, the materialized callable ts.same-file-constructor
requires.
Oracle changes, each because a rule is true now and a stricter entry replaces a gap:
- lsp_resolution_probe: implicit `new` targets the Class, required, not an
unmaterialized gap; s3 requires Widget.constructor. Its three TS annotation entries
pinned USAGE, which es_usage_crossfile_typescript forbids at the same occurrence;
they require USES_TYPE at that span, and the b/types.ts decoy is checked on USES_TYPE.
- matrix_known_classes, matrix_new_constructs, node_creation_probe: TS calls that are
now proved are required instead of counted gaps. Their forms and targets are unchanged.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
`accept(target); const target = () => {};` in one scope reads the const in its dead
zone, and `var` reads undefined, so no reference there names the function. The
binder treated a function value as visible everywhere, which published the edge
pipeline_cross_file_method_defines_method_venue_parity forbids. A closure still names
it, its own body included.
Tests: the CommonJS contract now counts the promoted case as found, and the JSX oracle
requires the USAGE that `<UI.Widget />` genuinely has: it reads that namespace member,
while the invocation stays a counted gap.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
`private opaque: unknown = new Tool()` then `this.opaque.fire()` was proved to
Tool.fire: an annotation that is not a plain type name fell through to the
initializer. tslsp_field_new_initializer_issue514 pins that it must abstain. The
initializer only decides a field with no annotation at all.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
`{ [K in Keys]: K }` and `T extends Array<infer U> ? U : never` bind K and U where
they are written. With USES_TYPE now walking every type name, both reached a
same-named module type, which is a wrong edge. They block that name the way a type
parameter does.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
`import { foo as bar }` then `bar()` kept an unresolved_calls row even with the exact
edge admitted. The per-file LSP reported the exported name, and the diagnostic joins
its call site by spelling, so it never found the occurrence that later cleared it.
It reports the spelling the file wrote now.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
es_usage_crossfile_typescript caught a wrong edge: with type positions resolving, a
parameter annotation also published USAGE to the interface. Its oracle forbids that,
because USAGE means a value. Every annotated name in TypeScript did this, so USAGE on
real code counted types as values.
A written type name, and the `Ns` root of `Ns.Type`, now abstains from USAGE with
reason usage_names_a_type. `typeof value` stays USAGE: it reads a value.
USES_TYPE had to take those names over, and it only looked at signatures and a few
body forms. It now walks every type name in the TS family, so class fields, heritage
clauses and alias bodies are not lost.
Also promotes two known gaps these rules satisfy: the TS parameter annotation and the
CommonJS `module.exports = async function`.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Two things the prior tests demanded and production did not do:
- declares_method read method_names, which exists only for classes swept from the
current file's AST. An imported base never answered, so an inherited method
across files abstained, and an imported subclass's own override could lose to a
same-file base. It now also asks the registry for that exact receiver.
- `x as T` and `x satisfies T` have no `type` field in the grammar, so the type
name was never extracted.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Three CommonJS facts the export table had wrong:
- `exports = x` without module.exports detaches the name, so a later `exports.y`
is not an export. It was published as one.
- `exports.y` or `module.exports.y` written before the last `module.exports =`
went to the replaced object.
- `exports = module.exports = createApp; exports.named = named` makes `named` a
name of the required value. `require(x).named` looked only for a member declared
under createApp, and `module.exports = require('./app')` did not forward names.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
An adversarial read of the member rule found eight wrong edges on one fixture:
- A function inside a nested scope named its `this` owner by spelling, so a
parameter or local `Owner` reached the module-level `Owner`'s members.
- `get m()` was taken for the callable; a call invokes what the getter returned.
- Object.assign, Object.defineProperty, mixin and `delete` replace members without
spelling an assignment.
- A class field initializer inside a member inherited the literal's `this`.
Owners now need a module-level function, mutator calls and `delete` make every
member of that owner unknown, and a class body clears `this`.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Preserves the js-ts lane's on-disk work after its tools were refused. Nothing here has been through a suite: no RED proof, no precision sample for the member rule. Not ready to integrate.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Checkpoint against a usage limit. Proved on express and kilocode subtrees; the
test suites have not run on this tree yet, so later commits may adjust it.
- Real lexical scopes replace the module-wide veto on any local name.
- CommonJS syntax, module extensions, package.json type and TypeScript prove a
module; a classic browser script stays unproved.
- require bindings and an exported-name table: aliases, default exports, barrels,
export *, export * as, module.exports and exports.x.
- Directory imports resolve through main and index.
- TS method proofs survive destructuring, catch, generics and decorators, take
own and inherited methods, this.field and new X() receivers, and have no budget.
- TS annotations give exact type-name occurrences.
- A registered route suppresses the unresolved diagnostic again.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Three pools hold a whole project's proofs under fixed caps, and running out of one
refuses the whole publication with no diagnostic:
shared resolver 4M nodes, 64M work cbm_shared_resolver_build
graph buffer 16M nodes, 4G work cbm_gbuf_new
infra adapters 65536 nodes, 4M work cbm_shared_resolver_adapter_init
proof_hash counts every hashed byte as work, so reaching a cap only means a large
enough repository. django reached the shared cap at 78580 proof nodes, and because
every proof hashes the project name, how soon a cap is reached also depends on the
length of the checkout path.
Measured, graph pool / shared pool work:
redis (967K occurrences) 524M / 1.2M
neovim (1.47M occurrences) 934M / 0.24M
django (672K occurrences) 1.36G / 133M over the shared cap
kubernetes (6.43M occurrences) 5.03G / 2.28G over both, and the adapter cap
These pools hold one node per distinct project fact and each operation is linear in
its own text, so the totals follow the input and are not guarding against a runaway.
cbm_resolve_proof_pool_init_project sets no cap, so only the memory core can refuse.
With this kubernetes publishes, 355464 nodes against main's 355619.
Per-file pools keep their limits: they degrade the file's outcomes to LIMITED rather
than stop publication.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
The strict resolver's syntax audit shared CBM_LSP_MAX_LOOKUP_DEPTH (16), a limit
meant for registry chains. It tripped on any node 17 levels down, even a clean
one under an error-bearing ancestor, and an #ifdef inside an else-if chain gets
there in ordinary C. That set binding_failed for the whole file.
c_proof_prepare then returned before allocating proof_includes, with include_count
already set, and processing carried on: c_proof_type_visible dereferenced NULL.
On redis the worker crashed 10 times; each crash quarantined files that happened to
be in flight on other threads (src/server.c, src/module.c, src/config.c), so the
failure status and the set of missing files changed from run to run.
Walk the audit with a tree cursor instead of recursing, so nesting depth is not a
property the answer can depend on. The result is what proof_syntax_limit already
documents: sites before the first error keep their proofs, sites at or after it
do not. The fail-closed behaviour is unchanged for every site past the error, and
the walk is linear in the error-bearing spine, so the depth and visit guards had
nothing left to bound.
c_proof_type_visible also refuses when binding_failed is set, because a failed
prepare can still leave the table unset on allocation failure.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Threads main's Go rel_path (#1910) through the proof-source and import-snapshot variants, keeps main's ADR sidecar so the rebuild no longer re-applies ADRs, and keeps the feature's removal of the import name fallback and JVM tail join, inside which main had added a generated-member filter. Main took semantic index version 12 for Markdown Section names, so the resolver generation becomes version 13.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Resolves the nine textual conflicts with the reviewed reconciliation: semantic index version 12 on top of main's migrations, digest stream v3 because both sides independently claimed v2, incremental metadata-current requires main completeness and the strict resolver generation receipt, and exact call joins by extraction index, full span and origin. Unresolved-call diagnostics reconcile only after final proof sealing and successful projection.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
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>
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>
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>