Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect "no visible binding for global variable" #666

Closed
bersbersbers opened this issue Dec 4, 2020 · 9 comments · Fixed by #709
Closed

Incorrect "no visible binding for global variable" #666

bersbersbers opened this issue Dec 4, 2020 · 9 comments · Fixed by #709
Labels
bug an unexpected problem or unintended behavior
Milestone

Comments

@bersbersbers
Copy link

This example code

foo <- data.frame(0)
foo$bar <- 1
zero <- function() {
    file.info("/dev/null")$size
}
message(zero())

lints with this error:

<text>:5:28: warning: no visible binding for global variable ‘size’
    file.info("/dev/null")$size
                           ^~~~
lintr::lint('
foo <- data.frame(0)
foo$bar <- 1
zero <- function() {
    file.info("/dev/null")$size
}
message(zero())
')

The error disappears when you take away the foo$bar <- 1:

lintr::lint('
foo <- data.frame(0)
zero <- function() {
    file.info("/dev/null")$size
}
message(zero())
')
@AshesITR AshesITR added the bug an unexpected problem or unintended behavior label Dec 4, 2020
@AshesITR
Copy link
Collaborator

AshesITR commented Dec 4, 2020

Confirmed. The problem lies somewhere in the way object_usage_linter uses codetools::checkUsage().

@dmurdoch
Copy link
Contributor

dmurdoch commented Jan 7, 2021

I think the problem lies in the get_assignment_symbols function: it returns c( "foo", "foo", "$", "bar", "zero") as left_assignment_symbols. If I edit that to return just c("foo", "zero"), I don't get the false positive.

Here's the line that produces the bad result:

left_assignment_symbols <-
    xml2::xml_text(xml2::xml_find_all(xml, "expr[LEFT_ASSIGN]/expr[1]/*"))

I think it needs a predicate saying that expr[1] is a SYMBOL, not an expression like foo$bar. Unfortunately, I don't know XML well enough to know how to write that.

@AshesITR
Copy link
Collaborator

AshesITR commented Jan 7, 2021

@dmurdoch Thanks for the hint.
I've figured out an XPath that should always work for a$b$c$d-chains (returning a) as well as direct assignments:

expr[LEFT_ASSIGN]/expr[1]/*[1]/descendant-or-self::SYMBOL[1]

The *[1] makes sure we're inside the LHS of the assignment operator and descendant-or-self::SYMBOL[1] ensures we only take the first SYMBOL element per result.

AshesITR added a commit that referenced this issue Jan 7, 2021
Fixes #666

Makes sure foo$bar$duh <- 42L returns "foo" as the only used (global) symbol.
@dmurdoch
Copy link
Contributor

dmurdoch commented Jan 8, 2021

That appears to miss complex assignments like names(x) <- "y". But I don't understand the code well enough to know if this would be a problem.

@AshesITR
Copy link
Collaborator

AshesITR commented Jan 8, 2021

Hmm I see. Maybe a better Idea would be to check that the parent expression is no DOLLAR-OP...

@russHyde
Copy link
Collaborator

The same bug occured in #445 (which I have closed to remove duplicate issues)

@AshesITR
Copy link
Collaborator

@russHyde do you mind taking a look at #709?
I'm not sure whether the changed XPath works for all possible assignments.

@russHyde
Copy link
Collaborator

Sure. I'm not an XPath expert by any means. I can compare object-usage over some packages before/after your changes if that's helpful.

@AshesITR
Copy link
Collaborator

That would be very useful indeed.
Seeing no observable side-effects would increase my confidence in the XPath-fu job.

@AshesITR AshesITR added this to the 3.0.0 milestone Jan 31, 2021
MichaelChirico pushed a commit that referenced this issue Feb 16, 2021
* only extract the first symbol for equal and left assignments

Fixes #666

Makes sure foo$bar$duh <- 42L returns "foo" as the only used (global) symbol.

* add tests and update NEWS

* add another test with different assignments

fix weird test file indentation

* add test with dollar-assignment; make XPath only return top-level symbols
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug an unexpected problem or unintended behavior
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants