Code-Inspect / flowr

A program slicer and dataflow analyzer for the R programming language.
https://github.com/Code-Inspect/flowr/wiki
GNU General Public License v3.0
14 stars 2 forks source link

Inconsistencies when reconstructing with closures #821

Closed Ellpeck closed 1 month ago

Ellpeck commented 1 month ago

Specifically, these two tests produce (seemingly) unexpected results.

The first test's reconstruction doesn't include the implicit return value of f, which I'm not 100% sure is an error:

        assertSliced(label('nested closures w/ default arguments', ['name-normal', ...OperatorDatabase['<-'].capabilities, 'formals-default', 'numbers', 'newlines', 'lambda-syntax', 'implicit-return', ...OperatorDatabase['+'].capabilities, 'closures', 'grouping']),
            shell, `f <- function(x = 1) {
  (\\(y = 2) function(z = 3) x + y + z)()
}
g <- f(8)
print(g())`, ['5@g'], `f <- function(x=1) {} 
g <- f(8)
g()`)

The second test's reconstruction only calls f once, meaning x's new value will never actually be set.

        assertSliced(label('closure w/ side effects', ['name-normal', ...OperatorDatabase['<-'].capabilities, 'normal-definition', 'newlines', 'closures', ...OperatorDatabase['<<-'].capabilities, 'side-effects-in-function-call', ...OperatorDatabase['+'].capabilities, 'numbers']),
            shell, `f <- function() {
  function() {
    x <<- x + 1
    x
  }
}
x <- 2
f()()
print(x)`, ['9@x'], `f <- function() { function() x <<- x + 1 }
x <- 2
f()
x`)
EagleoutIce commented 1 month ago

This was caused by two independent errors. The first one was due to unnamed function calls linking the body as entry point, and not the call itself, leading to the df-graph being incapable of detecting that the implicit return of the function (i.e., the inner lambda with \) is actually called. The second one was an old and outdated guard in the reconstruction which just plainly prevented two () from being set right after each other.

EagleoutIce commented 1 month ago

The test-updates should happen in #800.