mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-30 06:42:43 +00:00
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.
This commit is contained in:
parent
f80cfa09f2
commit
725f4f511c
2 changed files with 48 additions and 4 deletions
|
|
@ -66,8 +66,9 @@ const collectRoxygenBlock = (node: SyntaxNode): string => {
|
|||
/**
|
||||
* Split a roxygen block into its `@param` tags. A tag's description is the
|
||||
* rest of its line plus every following line up to the next `@tag`, joined by
|
||||
* single spaces. A tag whose name is not one plain identifier (`x,y`, `...`,
|
||||
* `na.rm`) is skipped, and its continuation lines belong to no tag.
|
||||
* single spaces. A tag whose name is not one identifier (`x,y`, `...`) is skipped,
|
||||
* and its continuation lines belong to no tag. Dots are part of an R name
|
||||
* (`na.rm`, `.data`).
|
||||
*/
|
||||
const parseRoxygenParams = (block: string): RoxygenParam[] => {
|
||||
const params: RoxygenParam[] = [];
|
||||
|
|
@ -85,7 +86,7 @@ const parseRoxygenParams = (block: string): RoxygenParam[] => {
|
|||
if (tag) {
|
||||
flush();
|
||||
if (tag[1] !== 'param') continue;
|
||||
const head = /^(\w+)(?:[ \t]+(.*))?$/.exec(tag[2] ?? '');
|
||||
const head = /^([\w.]*\w[\w.]*)(?:[ \t]+(.*))?$/.exec(tag[2] ?? '');
|
||||
if (!head) continue;
|
||||
name = head[1];
|
||||
if (head[2]) parts.push(head[2]);
|
||||
|
|
|
|||
|
|
@ -509,13 +509,56 @@ save <- function(repo, backup) {
|
|||
});
|
||||
});
|
||||
|
||||
describe('dotted formal names', () => {
|
||||
it.each([
|
||||
['na.rm', 'na.rm'],
|
||||
['a leading dot', '.data'],
|
||||
['dots and underscores', 'max_n.rows'],
|
||||
])('binds the documented type of %s', (_label, formal) => {
|
||||
const tree = parse(`
|
||||
Data <- R6::R6Class("Data", public = list(fit = function() 1))
|
||||
|
||||
#' @param ${formal} Data
|
||||
#' @param other Data
|
||||
run <- function(${formal}, other) {
|
||||
${formal}
|
||||
}
|
||||
`);
|
||||
const typeEnv = buildTypeEnv(tree, SupportedLanguages.R);
|
||||
expect(flatGet(typeEnv, formal)).toBe('Data');
|
||||
expect(flatGet(typeEnv, 'other')).toBe('Data');
|
||||
});
|
||||
|
||||
it('keeps the braced form and the continuation lines of a dotted name', () => {
|
||||
const tree = parse(`
|
||||
Data <- R6::R6Class("Data", public = list(fit = function() 1))
|
||||
|
||||
#' @param na.rm {Data}
|
||||
#' second line of prose
|
||||
run <- function(na.rm) na.rm
|
||||
`);
|
||||
expect(flatGet(buildTypeEnv(tree, SupportedLanguages.R), 'na.rm')).toBe('Data');
|
||||
});
|
||||
|
||||
it('binds nothing for a dotted name the function does not have', () => {
|
||||
const tree = parse(`
|
||||
Data <- R6::R6Class("Data", public = list(fit = function() 1))
|
||||
|
||||
#' @param na.rm Data
|
||||
run <- function(x) x
|
||||
`);
|
||||
const typeEnv = buildTypeEnv(tree, SupportedLanguages.R);
|
||||
expect(flatGet(typeEnv, 'na.rm')).toBeUndefined();
|
||||
expect(flatGet(typeEnv, 'x')).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('forms that are not bound (guards)', () => {
|
||||
it.each([
|
||||
['\\code{Data} markup', "#' @param df \\code{Data}", ['df']],
|
||||
['\\linkS4class{Data} markup', "#' @param df \\linkS4class{Data}", ['df']],
|
||||
['a comma-separated name list', "#' @param x,y Data", ['x', 'y']],
|
||||
['the dots parameter', "#' @param ... Data", ['...']],
|
||||
['a dotted parameter name', "#' @param na.rm Data", ['na.rm']],
|
||||
])('does not bind %s', (_label, tag, names) => {
|
||||
const tree = parse(`
|
||||
Data <- R6::R6Class("Data", public = list(fit = function() 1))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue