Skip to content
This repository has been archived by the owner on Sep 14, 2018. It is now read-only.

Find the Target of a CallExpression #1429

Open
lafrank opened this issue Sep 22, 2016 · 4 comments
Open

Find the Target of a CallExpression #1429

lafrank opened this issue Sep 22, 2016 · 4 comments

Comments

@lafrank
Copy link

lafrank commented Sep 22, 2016

Walking PythonAst I try to collect calls to other functions from within a function body. The aim is to provide a call tree displayed in a TreeView, like in Visual Studio,

I have a question. During iteration of statements in function body, when I encounter a CallExpression and its Target is a NameExpression, how can I find out whether the given NameExpression refers to a FunctionDefinition ? I only have the Name of the NameExpression and can't figure out how to match it to any FunctionDefinition.

@slide
Copy link
Contributor

slide commented Oct 5, 2016

Can you provide an example of what you are trying to do in code?

@lafrank
Copy link
Author

lafrank commented Oct 5, 2016

Once I acquired target in GetFunctionCalls() , I'd like to find out whether it refers to a FunctionDefiniton and I want to add this to the return list of FunctionDefinition,

    public  List<FunctionDefinition> GetCallsFromFunction(FunctionDefinition func)
    {
      SuiteStatement functionBody = (SuiteStatement)func.Body;
      return GetFunctionCalls(functionBody.Statements);
    }

    private List<FunctionDefinition> GetFunctionCalls(IEnumerable<Statement> Statements, int LineNumber = -1, int ColumnNumber = -1)
    {
      List<FunctionDefinition> result = new List<FunctionDefinition>();
      foreach (Statement thisStatement in Statements)
      {
        if (thisStatement is ExpressionStatement)
        {
          Expression exp = (thisStatement as ExpressionStatement).Expression;
          if (exp is CallExpression)
          {
            NameExpression target = (exp as CallExpression).Target as NameExpression;
            result.Add(target.Parent as FunctionDefinition); // this is wrong as it is the calling function, not the called function

// ------- code truncated --------

@jdhardy
Copy link
Member

jdhardy commented Oct 7, 2016

It's correct, as .Parent refers to the enclosing scope.

Python's name lookup occurs at runtime, so you'll have to do the same.
Since you're traversing the Python code, not running is, the best you'll be
able to keep track of function definitions/imports as you see them and use
that to try and find the FunctionDefinition. It should cover most of the
cases, but of course not every callable is actually a function.

On Wed, Oct 5, 2016 at 10:18 AM, Laszlo Frank [email protected]
wrote:

Once I acquired target in GetFunctionCalls() , I'd like to find out
whether it refers to a FunctionDefiniton and I want to add this to the
return list of FunctionDefinition,

public  List<FunctionDefinition> GetCallsFromFunction(FunctionDefinition func)
{
  SuiteStatement functionBody = (SuiteStatement)func.Body;
  return GetFunctionCalls(functionBody.Statements);
}

private List<FunctionDefinition> GetFunctionCalls(IEnumerable<Statement> Statements, int LineNumber = -1, int ColumnNumber = -1)
{
  List<FunctionDefinition> result = new List<FunctionDefinition>();
  foreach (Statement thisStatement in Statements)
  {
    if (thisStatement is ExpressionStatement)
    {
      Expression exp = (thisStatement as ExpressionStatement).Expression;
      if (exp is CallExpression)
      {
        NameExpression target = (exp as CallExpression).Target as NameExpression;
        result.Add(target.Parent as FunctionDefinition); // this is wrong as it is the calling function, not the called function

// ------- code truncated --------


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#1429 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAGmdYVjqhNjyLHBvbdcibjbxjvcDDjlks5qw9v4gaJpZM4KDlQy
.

@lafrank
Copy link
Author

lafrank commented Oct 7, 2016

Many thanks for the answer jdhardy.

Although I can - and I actually do - keep track of all function names I don't think it would be correct to simply rely on name matching, because - as you pointed out - not every callable is a function. Even worse if there are overlapping names and only correct scoping can resolve the correct callable item.

Can you explain in a nutshell what would be my best option to find the correct matching name ? In other words, is there any supporting code built into IronPython runtime (I believe there should be) what I could leverage for name resolution mimicking Python name lookup ?

Thanks in advance.

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

No branches or pull requests

3 participants