mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-30 06:42:43 +00:00
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).
This commit is contained in:
parent
9c39aefdb6
commit
9c2c3ed595
2 changed files with 59 additions and 0 deletions
|
|
@ -86,6 +86,7 @@ Not supported:
|
|||
- Roxygen `@param` types live in the per-file type environment; no graph edge consumes them.
|
||||
- Argument matching follows R for named and reordered arguments but does not model partial argument names: `setClass(Cla = "D")`, `new(Cla = "E")`, `setRefClass(Cla = "A")` and `setMethod("show", sig = "Foo")` are not recognised, so no definition or owner is attached.
|
||||
- Members are read only from the named forms. The positional second argument of `setClass("A", representation(x = "numeric"))`, `R6Class("X", list(...))` and `setRefClass("A", list(...))` creates no field or slot nodes; use `slots=` / `representation=`, `public =` / `private =` / `active =` and `fields =`.
|
||||
- S4 and RefClass constructors are recognised only as a bare callee: `setClass(...)`, `setRefClass(...)`, `setGeneric(...)` and `setMethod(...)`. A namespace-qualified call such as `methods::setClass("A", slots = list(x = "numeric"))` creates no class, slot, generic or method. `R6::R6Class(...)` is recognised.
|
||||
- For `S3method(generic, class, method)` the positional third argument names the exported method. A named third argument such as `S3method(print, foo, method = impl)` is not read: R registers `impl`, but the export is recorded for `print.foo`.
|
||||
- A leading `]` in a bracket expression of a NAMESPACE `exportPattern()` (for example `[]a]` or `[^]a]`) is read with JavaScript RegExp semantics, not POSIX/TRE, unless the pattern also contains a POSIX class such as `[:digit:]`; R would treat that `]` as a literal member.
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ import { describe, expect, it } from 'vitest';
|
|||
import Parser from 'tree-sitter';
|
||||
import R from '@eagleoutice/tree-sitter-r';
|
||||
import { R_QUERIES } from '../../src/core/ingestion/tree-sitter-queries.js';
|
||||
import { RFieldExtractor } from '../../src/core/ingestion/field-extractors/r.js';
|
||||
import { getRTopLevelMethodOwnerName } from '../../src/core/ingestion/method-extractors/r.js';
|
||||
import { isRNonNamingArgumentCapture } from '../../src/core/ingestion/languages/r/naming-argument.js';
|
||||
import { parseSourceSafe } from '../../src/core/tree-sitter/safe-parse.js';
|
||||
import { MAX_RATIO, SHAPES, measureScaling } from '../helpers/r-argument-scaling.js';
|
||||
|
|
@ -317,6 +319,62 @@ describe('R_QUERIES: documented argument-matching limits', () => {
|
|||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Documented limit (docs/languages/r-provider.md, Known limitations): the S4 and
|
||||
* RefClass constructors and `setGeneric` / `setMethod` are recognised only as a bare
|
||||
* identifier callee. A namespace-qualified call (`methods::setClass(...)`) has a
|
||||
* `namespace_operator` callee, so it creates no class, slot, generic or method, in the
|
||||
* query and in the field and method extractors alike. `R6::R6Class` is supported.
|
||||
* Each case is paired with its unqualified positive control.
|
||||
*/
|
||||
describe('R_QUERIES: namespace-qualified S4 constructors are not recognised (documented)', () => {
|
||||
it.each([
|
||||
[
|
||||
'setClass',
|
||||
'setClass("A", slots = list(x = "numeric"))',
|
||||
['definition.class:A', 'definition.property:x'],
|
||||
],
|
||||
[
|
||||
'setRefClass',
|
||||
'setRefClass("A", fields = list(x = "numeric"))',
|
||||
['definition.class:A', 'definition.property:x'],
|
||||
],
|
||||
[
|
||||
'setGeneric',
|
||||
'setGeneric("area", function(shape) standardGeneric("area"))',
|
||||
['definition.function:area'],
|
||||
],
|
||||
['setMethod', 'setMethod("area", "Circle", function(shape) 1)', ['definition.method:area']],
|
||||
])('%s: bare call is recognised, methods::-qualified call is not', (name, bare, expected) => {
|
||||
expect(definitions(bare)).toEqual(expected);
|
||||
const qualified = bare.replace(name, `methods::${name}`);
|
||||
expect(definitions(qualified)).toEqual([]);
|
||||
});
|
||||
|
||||
it('the field and method extractors also require a bare identifier callee', () => {
|
||||
const callOf = (source: string): Parser.SyntaxNode =>
|
||||
parseR(source).rootNode.descendantsOfType('call')[0];
|
||||
const fields = new RFieldExtractor();
|
||||
expect(fields.isTypeDeclaration(callOf('setClass("A", slots = list(x = "numeric"))'))).toBe(
|
||||
true,
|
||||
);
|
||||
expect(
|
||||
fields.isTypeDeclaration(callOf('methods::setClass("A", slots = list(x = "numeric"))')),
|
||||
).toBe(false);
|
||||
expect(getRTopLevelMethodOwnerName(callOf('setMethod("f", "A", function(x) 1)'))).toBe('A');
|
||||
expect(getRTopLevelMethodOwnerName(callOf('methods::setMethod("f", "A", function(x) 1)'))).toBe(
|
||||
null,
|
||||
);
|
||||
});
|
||||
|
||||
it('R6::R6Class, by contrast, is recognised', () => {
|
||||
expect(definitions('X <- R6::R6Class("X", public = list(f = 1))')).toEqual([
|
||||
'definition.class:X',
|
||||
'definition.property:f',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Selecting the naming argument must stay linear in the argument count: an earlier
|
||||
* query-level formulation (a repeated sibling group before the argument) was
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue