Commit graph

1676 commits

Author SHA1 Message Date
Mick Cooney
3d207378ec Merge upstream/main into feat/r-language-support 2026-10-16 18:04:10 +01:00
Mick Cooney
b9f30c23d8 test(r): size the argument-scaling guard so the small run is measurable
The ratio guard divided by a 15 ms floor on the small run, so shapes whose
small run took 1 to 2 ms (comments before the naming argument) could hide
a quadratic regression that cost less than 150 ms at 8,000 arguments. The
small size now doubles from 2,000 until its fastest run lasts 20 ms, and
the large run stays four times that size, so the ratio is taken between
runs long enough to measure. The largest shape runs for about 2.4 s.
2026-10-16 17:59:09 +01:00
Mick Cooney
8997970f2c test(r): pin the cross-file and R6 method rename refusals
The guide documents ambiguous_reference for an unqualified call into
another file and a refusal for R6 methods, but no fixture covered
either. Add both. The R6 method is refused by the provider as a class
member (unsupported_occurrence); the guide wrongly listed it among the
shared engine's stale_graph refusals, which now name only dotted
functions and S4 classes.
2026-10-16 17:56:12 +01:00
Mick Cooney
197af8fd16 test(r): count 23 hinted members in r-packages
Member ids carry their class since fc32e539, so the two greet methods of
Parent and Child in s4_and_r6.R are two nodes instead of one. The
owner-absence test sits outside the R test set script and kept the old
count of 22.
2026-10-16 17:53:26 +01:00
Mick Cooney
1adf8ca762 test(r): state the real CI behaviour of the worker owner-absence guard
The header said the suite hard-fails on CI like the other worker-backed
suites. Only object-literal-owner-resolution shares that tripwire; the
others skip silently when dist/ is missing. The header now says so, and
that the integration tier builds dist/ first.
2026-10-16 17:51:41 +01:00
Mick Cooney
d9095b973f fix: name the published grammar package in the parser-unavailable hint
The warning for a language whose grammar could not be loaded told the
user to run npm rebuild tree-sitter-<language>. R's grammar is published
as @eagleoutice/tree-sitter-r, so the hint named a package that does not
exist. The grammar loader now keeps a small map of grammars published
under another name, and every other language gets the same hint as
before.
2026-10-16 17:50:26 +01:00
Mick Cooney
755278a040 fix(r): rename a call that a non-function parameter of the same name does not shadow
R skips a binding that is not a function when it looks up the callee of
f(x), but the rename provider claimed every parameter, so a call under
function(x, helper = 2) was left unrenamed and failed after the rename.

A parameter whose default is a constant and which the body never assigns
is no longer claimed, so the call is renamed with the function it
reaches. A parameter that may hold a function (a function or computed
default, or an assignment to it in the body) is claimed as before, and
a call of the name under it is refused as ambiguous_reference, since it
may reach either. A parameter without a default that is called stays a
function-valued parameter and its call is left alone.
2026-10-16 17:48:25 +01:00
Mick Cooney
6355538947 fix(r): refuse renaming a function that is also assigned with <<-
A <<- inside a function is a global re-definition that the scope graph
keeps as a second declaration of the same name. A rename dropped the
selected function and its calls but left the superassignment, so after
the rename the function wrote a new global of the old name instead of
replacing the renamed one. The top-level form was already refused by
the engine; checkSafety now refuses any <<- or ->> to the name, in or
out of a function, with the same ambiguous_reference code.
2026-10-16 17:43:08 +01:00
Mick Cooney
85fb8aeb55 fix(r): refuse a rename target name that registers an S3 method at any dot
The guard looked only at the text before the first dot, so
to.json.foo (a method of the dotted generic to.json) passed, and base
generics such as print, format, summary and plot were never checked
unless the sources defined them. Every dot-separated prefix of the new
name is now tested against the functions the indexed sources define and
a small list of base generics.
2026-10-16 17:41:01 +01:00
Mick Cooney
154b7d4ebb fix(r): bind importFrom() of a backtick-quoted definition
A function written in backticks keeps them in its binding key and on its
node, while NAMESPACE entries and importFrom() carry the bare symbol, so
importFrom(pkg, `%||%`) found no defining file and the call degraded to
the name-based guess, which cannot tell two packages' `%||%` apart.

rFileTopLevel now keys the top-level names by symbol (rBareName) and
records the spellings it saw. resolveRNamedImport looks files up by
symbol, populateRNamespaceImports synthesises the import with the
definition's own spelling (one per spelling the provider uses) and lets
a backtick-defined function of the caller package mask its import. The
global-name-fallback veto and the pkg::name() lookups compare symbols.
The dotted-tail guard still compares the name as written, which is how
finalize indexes it. Names without backticks answer exactly as before,
pinned by a characterisation snapshot recorded before the change.
2026-10-16 17:36:39 +01:00
Mick Cooney
e218c52a59 fix(r): read RefClass methods of an unassigned setRefClass call
The method patterns required `A <- setRefClass(...)`, so a bare
`setRefClass("A", methods = list(...))` produced the Class and its fields
but no Method. The method extractor and the class owner lookup never needed
the assignment; match the call itself in both queries.
2026-10-16 17:19:51 +01:00
Mick Cooney
72af8166b7 fix(r): order merged bindings by code unit, not by locale
rMergeBindings sorted same-tier bindings with localeCompare, whose order
follows the machine's locale. Compare node ids by code unit, as the package
discovery does.
2026-10-16 17:18:44 +01:00
Mick Cooney
f78f7cbc2e perf(r): look up a wildcard import's target file in a per-pass index
expandRWildcardNames scanned every parsed file with find() for each
library() edge (450,000 edges over 3,000 files took 5.9 s). Build the
module-scope lookup once per pass, as the C, C++ and Python providers do.
2026-10-16 17:17:01 +01:00
Mick Cooney
c63dcc1278 fix(r): type R6 field defaults that are typed NA constants
The grammar parses NA, NA_integer_, NA_real_, NA_character_ and NA_complex_
as `na` nodes, not identifiers, so the identifier branch never ran and no
type was inferred. Type them as integer, numeric, character and complex, and
plain NA as logical.
2026-10-16 17:16:18 +01:00
Mick Cooney
76acfd2b59 fix(r): read the DESCRIPTION Package field past a byte-order mark
A UTF-8 byte-order mark before `Package:` hid the package, so its qualified
calls were dropped as external. And `\s*` crossed a newline, so an empty
`Package:` field captured the next line's `Version:` as the package name.
Strip the mark and keep the value on the field's own line.
2026-10-16 17:15:30 +01:00
Mick Cooney
2566751ba1 fix(r): reject POSIX class names that Object.prototype also has
[[:constructor:]], [[:toString:]] and [[:__proto__:]] resolved on the
prototype chain and spliced function source text into the pattern, so the
pattern compiled to garbage instead of being rejected as an unknown class
and reported as dropped. Look classes up as own properties.
2026-10-16 17:14:56 +01:00
Mick Cooney
cfe590b4b1 perf(r): scan NAMESPACE conditional blocks in linear time
An unterminated `{` after an `if` scanned to the end of the file, and the
resynchronisation then landed inside the region just scanned, so a file of
`if (a) {` lines with no `}` was quadratic (300 KB took 8.8 s, and the file is
parsed several times per analysis). Index where every block ends in one pass
and answer each block from the index. Parsing results are unchanged.
2026-10-16 17:14:21 +01:00
Mick Cooney
40d3e6c987 fix(r): strip backticks from NAMESPACE export entries in linear time
The pattern /^`+|`+$/g is quadratic on an entry such as x, a long run of
backticks, then y; the entry is repository-controlled text read on every
importFrom lookup of a name the package does not export. Trim with two scans.
2026-10-16 17:12:15 +01:00
Mick Cooney
b270621383 fix(r): rename functions through their backtick-quoted spellings
A backticked name is an identifier whose text keeps its backticks, so the
rename provider never matched `helper`(x) with helper. The call was left
behind, and a local `helper` <- function(...) was not seen as a shadow, so
a call to the local function was silently renamed. Match occurrences,
claims and bindings on the symbol, and compare the symbol in the safety
checks.
2026-10-16 17:11:14 +01:00
Mick Cooney
6c487cffdb fix(r): bind roxygen @param tags to formals written in backticks
A formal written `data` in backticks never matched the tag @param data, so
its documented type was dropped. Look the tag up by the symbol.
2026-10-16 17:11:11 +01:00
Mick Cooney
e57943e6f2 fix(r): match backtick-quoted definitions against NAMESPACE export entries
export(`%+%`) names the symbol %+%, while the definition node keeps its
spelling `%+%`, so the export check never matched and the function was
flagged as not exported (the same for exportPattern()). Compare the symbol
through one shared helper, rBareName.
2026-10-16 17:11:05 +01:00
Mick Cooney
e45fa2e080 fix(r): read slots and fields given as c(...) vectors
The slot pattern matched only list(...) and representation(...), although
the field extractor accepts any call, so setClass("A", slots = c(a =
"numeric")) and setRefClass("R", fields = c(...)) created no Property nodes.

Accept c(...) for both. An unnamed string in slots = c("a", "b") or
fields = c("a", "b") names an untyped member, as in R; an unnamed string in
representation(...) or list(...) is still not a member. The new pattern
captures its callee as @_vecOwner, so the class-naming capture filter does
not mistake these strings for the class name.
2026-10-16 15:52:26 +01:00
Mick Cooney
0476330429 fix(r): attach R members only to classes defined in R
attachDeferredROwners resolved the owner hint through the class registry,
which every language shares. A Python class Circle next to an R Circle made
the name ambiguous, so the R methods and slots lost their HAS_METHOD and
HAS_PROPERTY edges; and with no R Circle, an R setMethod attached to the
Python class.

Keep only candidates whose graph node is an R class before the uniqueness
test. The change is inside R's postParse hook, so shared code is untouched.
2026-10-16 15:49:23 +01:00
Mick Cooney
0698fa1420 fix(r): read the formals of R6 and RefClass methods
extractRParameters tested for identifier and argument nodes, but the grammar
emits one parameter node per formal, so it always returned an empty list.
Every R6 and RefClass method therefore had parameterCount 0 and a #0 id, and
a variadic method was not marked variadic.

Read the parameter nodes: the name field gives the formal, a default makes it
optional, and a dots name makes it variadic (such a method has no count and
no arity tag in its id).
2026-10-16 15:46:33 +01:00
Mick Cooney
fc32e53967 fix(r): qualify R6, RefClass and S4 member ids with their class
Member ids carried no owner, so a second class in one file that shared a
member name with an earlier one (push, items, a setMethod generic, a slot)
minted the same id as the first and lost the member, along with its
HAS_METHOD or HAS_PROPERTY edge.

Register resolveDetachedOwnerName for R. It names the class declared by an
ancestor R6Class assignment, setClass or setRefClass call, or the signature
class of a setMethod call, so ids become Method:<file>:Stack.push#n and
Property:<file>:Stack.items. The owner edge is still attached by postParse
through ownerNameHint. The change is R-only: the hook is optional and
undefined for every other language.

The r-packages characterisation counts now include Child.greet, the member
the id collision used to drop.
2026-10-16 15:43:34 +01:00
Gergő Magyar
faf05f2eb7
fix(install): restore Linux ARM64 npm installation (#3601)
* fix(install): validate and package Linux ARM64 parser replacements

* fix(install): add rebuilt ARM64 grammar binaries

* fix(install): place ARM64 binaries in versioned bundle paths

* refactor(install): share ARM64 prebuild validation

* fix(review): keep grammar rebuild provenance accurate

* test: pin audited ARM64 repair provenance (#3601)
2026-10-16 15:28:35 +01:00
Mick Cooney
750374eb29 docs(r): correct stale wildcard-expansion and escape-digit comments
Three comments named rProvider.expandsWildcardTo, which does not exist for R:
the pipeline consumes the hook from the ScopeResolver, so point them at
rScopeResolver.expandsWildcardTo. State the \x, \u and \U digit limits in
unescapeRString's comment, which are those of R's own parser.

Comments only.
2026-10-16 15:00:33 +01:00
Mick Cooney
7b514f1157 fix(r): make the roxygen @param name and package qualifier parsing linear
The @param name pattern [\w.]*\w[\w.]* backtracks quadratically on a long
name followed by anything but a blank (32,000 characters took about half a
second per line), and parseRQualifier's lazy [\s\S]*? does the same on a
long run of blanks. Match [\w.]+ and require a word character separately,
and take the text before the first '::' directly. Accepted inputs and
results are unchanged (checked against the old patterns on two million
generated strings).

Tests cover large adversarial inputs and the dotted formal names.
2026-10-16 14:58:45 +01:00
Mick Cooney
edbb097616 perf(r): binary-search character classes in the linear regex matcher
inSet() scanned a class's ranges from the front on every state visit, but the
search loop charged one unit per visit regardless of class size, so a wide
class multiplied real work the budget never counted. Ranges are sorted,
merged and disjoint for every CharSet (normalise() for written classes,
constants and complement() for escapes), so a binary search is equivalent.
Charged work is unchanged.

Tests pin the reads per visit, the edges of a large class and the charged
work counters.
2026-10-16 14:55:06 +01:00
Mick Cooney
edc969f5e9 Merge upstream/main into feat/r-language-support 2026-10-16 13:03:19 +01:00
azizur100389
94f167a90f
fix(routes): reject middleware and route metadata false positives (#3561)
* fix(routes): reject middleware and route metadata false positives

* fix(routes): invalidate cached phantom routes on upgrade

* test(routes): cover cache upgrades across merged schema versions

Verify that schemas 137 through 140 invalidate both parse stores after merging main into PR #3561 and advancing the schema to 141.

---------

Co-authored-by: Gergő Magyar <gergomagyar@icloud.com>
2026-10-16 08:02:41 +00:00
Mick Cooney
4736062cb3 Merge upstream/main into feat/r-language-support 2026-10-16 08:48:30 +01:00
dependabot[bot]
6fdff81727
chore(deps)(deps-dev): bump vitest from 5.0.3 to 5.0.4 in /gitnexus (#3596)
Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 5.0.3 to 5.0.4.
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/v5.0.4/packages/vitest)

---
updated-dependencies:
- dependency-name: vitest
  dependency-version: 5.0.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-16 08:09:31 +01:00
Mick Cooney
2d19934dc9 test(r): raise the worker readiness timeout in R worker-backed tests
A reviewer's focused R run hit two worker-startup timeouts and had to rerun
with a 30-second readiness setting. The worker pool waits only 5 seconds by
default (GITNEXUS_WORKER_READY_TIMEOUT_MS), and every R test that parses
through the real worker pool started cold against that budget, unlike
csharp-razor-view-components and structural-pair-coverage, which already
raise it.

Apply the same idiom to the R tests that spawn the pool: stub the variable to
60000 in beforeAll and restore it with vi.unstubAllEnvs() in afterAll. Covers
r-worker-owner-absence, cfg/r-cfg-join, r-post-parse-gating, and the
resolvers/r*.test.ts files. rename-provider-r goes through
rename-integration-cases.ts, which already passes a 15-second budget to its
child process, so it is unchanged.

Tests only; no production code, schema or parse-cache change.
2026-10-16 01:29:45 +01:00
Mick Cooney
aea437fd11 chore(deps): record the audited 0.25.1 tree-sitter peer for the R grammar
CONTRIBUTING.md (Native tree-sitter npm packages) requires the lockfile to pin
the audited grammars' tree-sitter peer to exactly 0.25.1, as it already does for
c, cpp, java, php, ruby, rust and typescript. The R grammar entry still carried
upstream's ^0.21.0. Only the peer range changes; the upstream peerDependenciesMeta
(including its tree_sitter key typo) is untouched.

Checked: npm ci --dry-run --ignore-scripts passes in the repository root and in
gitnexus/, npm ls --depth=0 reports nothing invalid, and a fresh npm pack
(including prepack) installed into an isolated prefix passes
scripts/assert-native-parsers.mjs (20 grammars, R included) with the R
manifest's peer at 0.25.1.
2026-10-15 20:45:40 +01:00
Mick Cooney
bb3e2279cd docs(r): mention CFG and rename in the README R paragraphs
Both R paragraphs now say that --pdg builds a control-flow graph for R and that
rename is conservative. The shared Control flow paragraph no longer implies
reaching definitions for R, which has control flow only.
2026-10-15 20:44:56 +01:00
Mick Cooney
725f4f511c fix(r): bind roxygen @param types for dotted formal names
parseRoxygenParams read the parameter name with `\w+`, which stops at the first
dot, so `#' @param na.rm Data` documented nothing and the formal got no type
(the old unit test pinned that as "does not bind a dotted parameter name").

Reproduction: four new cases in type-env-r.test.ts (na.rm, .data,
max_n.rows, braced form with a continuation line) returned undefined instead of
'Data' on the unfixed pattern. The name pattern is now `[\w.]*\w[\w.]*`, so a
dotted identifier matches while `...` and `x,y` stay unbound; the former
"does not bind" case is replaced by positive cases plus a not-a-formal control.
2026-10-15 20:43:34 +01:00
Mick Cooney
f80cfa09f2 fix(r): limit library() wildcard expansion to top-level definitions
expandRWildcardNames walked the flat localDefs of the target file and filtered
only dotted names, so a function nested inside another function
(`outer <- function() { helper <- function() 1 }`) was offered as a
package-level name to every file that calls library()/require() on the package.

Reproduction: two new cases in r-dotted-s3-hooks.test.ts failed on the
unfixed code (['outer', 'helper', 'top'] instead of ['outer', 'top'];
['a', 'b', 'c', 'd'] instead of ['a']). The expansion now keeps only names bound
at module scope (rFileTopLevel().names, which already feeds the dotted-tail
guard); top-level functions and bare-call S4/R6 classes are still listed
(controls added; test/integration/resolvers/r.test.ts unchanged and green).
2026-10-15 20:42:56 +01:00
Mick Cooney
abcc165088 fix(r): decode string literals in the rename dynamic-lookup guard
The R rename guard compared the raw text of each `string_content` node with the
old and new name. An escaped spelling (`"f\u006fo"`, `'f\x6fo'`, octal) keeps
its escape inside string_content, and a raw string (`r"(foo)"`) has no
string_content node at all, so renaming `foo` proceeded while a get() or
do.call() on the escaped or raw spelling still resolved the old name.

Reproduction: 10 cases in the new test/unit/r-rename-string-guard.test.ts
returned 'ok' instead of unsupported_occurrence on the unfixed provider, and the
two new fixtures string-lookup-escaped and string-lookup-raw (rename-provider-r)
renamed successfully on the unfixed build. The guard now decodes each `string`
node (escapes, octal, raw strings) and compares the value.

docs/languages/r-provider.md said "spelled as a string literal"; it now states
the whole-value rule and what is still not detected (substring, paste0(),
non-indexed files).
2026-10-15 20:42:05 +01:00
Mick Cooney
2a342d1619 fix(r): skip the body of an else if in NAMESPACE as conditional
skipConditionalBody returned just after the `if` of `else if (cond) body`, so
the main scan then read `(cond)` as stray text and emitted the body's
importFrom, S3method, export, exportClasses, exportMethods and exportPattern
directives as unconditional (the same for `if (a) if (b) body`).

Reproduction: 12 new cases in r-namespace-parser.test.ts failed on the
unfixed scanner (e.g. `if (a) {} else if (b) importFrom(x, y)` returned x::y;
`else if (b) export(hidden)` exported `hidden`). The nested `if (cond)` is now
stepped over iteratively (no recursion, tested with 50,000 nested ifs) and the
body that follows it is skipped.
2026-10-15 20:36:03 +01:00
Mick Cooney
5aa257b8f6 fix(r): charge the start-state filter to the matcher work budget
LinearRegex.seed() filtered the closure's character states against the start
character before charging only 1 + (accepting states), so the range scans of
the failed state tests were free. A pattern of a few large character classes
could be probed with distinct start characters (each a filter miss, memoised
only up to 4096 keys) at almost no recorded cost.

Reproduction: for 20 alternated classes of 200 ranges, one miss on a
non-matching name recorded work 1 (expected >= 4000 range checks); a loop of
600 distinct start characters never exhausted a 1,000,000 budget. The filter
now charges 1 + ranges.length per examined state on a cache miss; hits stay
cheap. New tests in r-export-pattern-shared-budget.test.ts.
2026-10-15 20:35:14 +01:00
Mick Cooney
9c2c3ed595 docs(r): document that namespace-qualified S4 constructors are not recognised
Review finding: `methods::setClass(...)` is ignored by the S4 field detector.
Confirmed by test, and wider than fields: every S4/RefClass pattern
(setClass, setRefClass, setGeneric, setMethod in R_QUERIES, plus the field and
method extractors) requires a bare identifier callee, so a namespace_operator
callee creates no class, slot, generic or method. R6::R6Class is supported.

Widening touches nine files (queries, naming-argument, captures, owner hooks,
post-parse, scope resolver, both extractors) and the qualifier-veto logic, so
it is not a trivial change. Documented as a known limit in
docs/languages/r-provider.md and pinned by characterisation tests in
r-definition-anchors.test.ts (each paired with its unqualified control).
2026-10-15 20:33:36 +01:00
Mick Cooney
9c39aefdb6 test(r): pin the CFG edge structure and CDG labels for empty if arms
Review finding: an empty then/else arm loses its cond-true/cond-false edge.
Not reproducible as lost information: an empty `{}` arm (like a missing
`else`) is the header's seq fall-through edge, the same convention as every
other CFG visitor, and control dependence labels it as the complement of the
sibling explicit arm. Probed on the current code: `if (c) {} else work()`
gives c-cond-false->work() with CDG c->work():F, and
`if (c) work() else {}` gives CDG c->work():T.

Adds exact edge-structure and CDG-label tests (all passed on the unmodified
visitor) and documents the fall-through convention in the visitor header.
No behaviour change.
2026-10-15 20:32:49 +01:00
Mick Cooney
3b8682f23e fix(r): create an R6 field Property for every non-function value kind
The R6 public/private field queries listed only some expression kinds, so
`public = list(x = NA)` (also Inf, NaN, complex, if/for/while/repeat, a$b,
pkg::v, v[1], v[[1]], {..}, (..)) produced no Property although
RFieldExtractor accepts any value that is not a function_definition.

Reproduction: new test/unit/r-r6-field-values.test.ts failed 46 of 76 cases
on the unfixed query (expected ['x'], received []). The query now enumerates
every named grammar expression kind except function_definition, shared by the
namespaced and bare R6Class patterns.
2026-10-15 20:31:40 +01:00
Mick Cooney
f114d5e754 Merge upstream/main into feat/r-language-support 2026-10-15 20:15:16 +01:00
Richie Wee
b51f25606c
fix(routes): match configured fetch wrapper calls that pass type arguments (#3567)
Some checks failed
Devcontainer Smoke / Build devcontainer image (push) Has been cancelled
Devcontainer Smoke / Config-transform unit tests (push) Has been cancelled
Skill copy sync / shipped skills drift guard (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Waiting to run
Gitleaks / gitleaks (push) Waiting to run
Trivy Image Scan / Trivy (gitnexus-cli) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
Publish / Classify release event (push) Waiting to run
Publish / RC guard (marker + release-PR skip) (push) Blocked by required conditions
Publish / ci (push) Blocked by required conditions
Publish / Publish to npm (push) Blocked by required conditions
Publish / Build & Push RC Docker images (push) Blocked by required conditions
Scorecard / Scorecard analysis (push) Waiting to run
Trivy Image Scan / Trivy (gitnexus-web) (push) Waiting to run
2026-10-15 20:08:56 +03:00
Mick Cooney
eac10308fc chore(r): do not bump SCHEMA_BUMP for the new R language
Restore parse-cache.ts and incremental-parse-cache.test.ts to upstream/main,
so this branch no longer touches either file.

- R files were never parsed before this branch, so no parse-cache entry for
  them can be stale: .r files had no language and were in no chunk.
- Chunk keys are a hash of the chunk's file paths and content hashes with no
  language or grammar component, so chunks of existing languages keep exactly
  the same keys and entries; adding R only adds new R chunks.
- The cache version is `${SCHEMA_BUMP}+${package version}`, so any release
  changes the package part and invalidates every entry anyway.
- The bump only protected reviewers re-testing successive heads of this branch
  on a single package version, and it kept conflicting with upstream's own
  bumps on every merge.

The diff against upstream/main adds no capture or ParseWorkerResult change for
any other language: shared edits are optional provider hooks that only R
defines (postParse, resolveMemberOwnerNode, cfgVisitor, rename).
2026-10-15 17:26:01 +01:00
Mick Cooney
52ea6649b0 Merge upstream/main into feat/r-language-support 2026-10-15 17:25:44 +01:00
Mick Cooney
3dbf1017ce feat(r): add conservative semantic rename provider
Plain R functions rename through the scope graph; S3, string-spelled,
S4, R6 and NAMESPACE-exported names are refused. Adds fixtures, the
rename-provider-r test and its cross-platform shard entries.
2026-10-15 15:43:32 +01:00
Mick Cooney
a1b2dc9f4a feat(r): add a control-flow CFG visitor for R functions
R now provides a cfgVisitor (if/else, for, while, repeat, break, next,
return(...), nested functions), so the CFG provider gate holds for R and
--pdg emits BasicBlock, CFG and CDG data. There is no def/use harvest, so
reaching definitions report no-facts for R. The v142 parse-cache comment
notes that cached R results lack a CFG side channel.
2026-10-15 15:43:15 +01:00