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

how to generate call graph on a function and not a package #46

Open
rmflight opened this issue Feb 25, 2021 · 5 comments
Open

how to generate call graph on a function and not a package #46

rmflight opened this issue Feb 25, 2021 · 5 comments

Comments

@rmflight
Copy link

rmflight commented Feb 25, 2021

How is one supposed to create a call-graph using makeCallGraph on a function call?

For example, if I wanted to know all the functions that get called by doing:

lm(mpg ~ hp, data = mtcars)

I would have thought I would do something like:

gg = makeCallGraph("lm(mpg ~ hp, data = mtcars)")

But I get the error:

Error in .local(obj, all, ...) : 
Don't know how to make a call graph from this string: lm(mpg ~ hp, data = mtcars)
@natereal
Copy link

natereal commented Apr 6, 2022

I was also wondering if this is possible. From the documentation at
https://cran.r-project.org/web/packages/CodeDepends/CodeDepends.pdf
it appears that it currently only accepts packages. However in the vignette it says "We can also create call graphs for functions or entire packages", so I am not sure

@gmbecker
Copy link
Collaborator

gmbecker commented Apr 8, 2022

Hi, so sorry this apparently slipped by my radar for a full year (mea culpa).

The issue here is that you can't build a callGraph for a specific invocation, only for functions or packages as a whole.

gg <- makeCallGraph("lm", all  = TRUE)
> nodes(gg)
 [1] "-"              "!"              "!="             ".getXlevels"   
 [5] "["              "[[<-"           "{"              "*"             
 [9] "&&"             "<-"             "=="             "$<-"           
[13] "as.vector"      "attr"           "c"              "class<-"       
[17] "eval"           "gettextf"       "if"             "is.empty.model"
[21] "is.matrix"      "is.null"        "is.numeric"     "length"        
[25] "list"           "lm.fit"         "lm.wfit"        "match"         
[29] "match.call"     "matrix"         "model.matrix"   "model.offset"  
[33] "model.response" "model.weights"  "names"          "ncol"          
[37] "nrow"           "NROW"           "numeric"        "parent.frame"  
[41] "quote"          "return"         "stop"           "sum"           
[45] "warning"        "lm"            

does work for me, though from what I'm seeing its not properly (fully) recursive, as .getXlevels contains a call to vapply which doesn't appear here. I will try to find time to investigate that.

@duncantl
Copy link
Owner

The CodeAnalysis package is probably a better place to get this functionality.
You will also need to install rstatic. Both packages should be installed directly from the code on github.

@gmbecker
Copy link
Collaborator

@duncantl does the functionality in https://github.com/duncantl/CodeAnalysis fully subsume makeCallGraph in this package? If so, we should deprecate/remove the functions in this package (instead of me going in to fix them).

A very brief glance at callGraph.R didn't show me the option for being recursive, but then, the recursive argument here isn't connected to anything, so I guess that's a wash?

@duncantl
Copy link
Owner

FYI, I added this top-level functionality in CodeAnalysis, i.e.,

g = callGraph(quote ( lm ( mpg ~ wt + cyl, mtcars) )  ), recursive = 2)
plot(g)

gives the call information and draws the graph. One can use recursive = TRUE or recursive = positive.integer to get the entire call graph (typically way to big and takes a while) or the first "positive.integer" descendants/layers from the current call.

One can use callGraph( "lm ( mpg ~ wt + cyl, mtcars) ", recursive = 3) but working directly with the language objects is better, e.g., quote above or

callGraph(parse(text = codeString) , recursive = 2)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants