Author Topic: Feature/Macro request: display call trees  (Read 11450 times)

RobFreundlich

  • Community Member
  • Posts: 47
  • Hero Points: 2
Feature/Macro request: display call trees
« on: September 07, 2006, 07:33:06 PM »
I was in a situation recently where I needed to know all of the possible call-stack paths that could lead to (or from) a specific method.  Consider it a sort of "impact analysis" - if I change this method, what will be affected, and what might it affect?

I was able to manually create it by using push-tag and pop-tag and writing things down as I went, but it'd be really neat to have a way to automate it. I envision tree-like output something like this:

Code: [Select]
Class1.method1
    Class2.method2
        MyClass.myMethod
    Class3.method3
        MyClass.myMethod
Class1.method1a
    MyClass.myMethod
Class4.method4
    Class2.method2
         MyClass.myMethod
    Class5.method5
        MyClass.myMethod

That would be the "what are the call stacks leading to me?" output.  "What are the call stacks beneath me?" would be like this:

Code: [Select]
MyClass.myMethod
    Class6.method6
        Class7.method7
        Class8.method8
            Class9.method9
    Class9.method9a

Ideally, there will be two modes.  In the first mode, I get an interactive tree (sort of like the Base Classes/Derived Classes display).  In the second mode, I get plain/colored text (or possibly XML?) that I can either print or feed to some other application for processing.

Anyone have any suggestions?

Kohei

  • Senior Community Member
  • Posts: 192
  • Hero Points: 25
Re: Feature/Macro request: display call trees
« Reply #1 on: September 08, 2006, 02:39:49 PM »
We have something similar to what you are requesting.

In the Defs tab, right-click on a method of your choice, and select "Show Call Tree...".  This will execute a dialog displaying the call stack tree of that particular method.

Will this work for you?

--Kohei

RobFreundlich

  • Community Member
  • Posts: 47
  • Hero Points: 2
Re: Feature/Macro request: display call trees
« Reply #2 on: September 08, 2006, 05:17:08 PM »
We have something similar to what you are requesting.

In the Defs tab, right-click on a method of your choice, and select "Show Call Tree...".  This will execute a dialog displaying the call stack tree of that particular method.

Will this work for you?

Sweet!  It's very close to the "what's the call stack beneath me" piece of what I'm looking for.  To fully cover that, it'd need to have an "expand all" option and/or a "print fully expanded" option.  I think those would probably need to have some kind of package exclusion setting so that (for example) I could have it expand (or print) all of my stuff but stop the expansion/print at any classes in the standard java packages.

Is there anything that goes the other way?  That is, given a method foo, show me all call stacks leading down to foo?

Rob

RobFreundlich

  • Community Member
  • Posts: 47
  • Hero Points: 2
Re: Feature/Macro request: display call trees
« Reply #3 on: September 08, 2006, 05:23:24 PM »
Oh - one more question.  Is there a way I can attach that call to my normal editing right-click menu so that I can get the call tree for the method I'm currently in?

Rob

Kohei

  • Senior Community Member
  • Posts: 192
  • Hero Points: 25
Re: Feature/Macro request: display call trees
« Reply #4 on: September 11, 2006, 02:25:45 PM »
Quote
Is there anything that goes the other way?  That is, given a method foo, show me all call stacks leading down to foo?
My answer would be no, unless the other SlickEdit members know of such feature.

Quote
Is there a way I can attach that call to my normal editing right-click menu so that I can get the call tree for the method I'm currently in?
Not right off hand, although, by looking at the command named cb_calltree - the command that gets executed when you select "Show Call Tree..." - it looks like it could be done if you are willing to invest some time to create a new command based on cb_calltree.  The only change that should be needed is, instead of getting the current context information from the class browser view, you get the info from the current context of your editor window.

For instance, go take a look at cb_calltree command by running fp cb_calltree.  It's a very short function, and you'll immediately notice the following lines:
Code: [Select]
struct VS_TAG_BROWSE_INFO cm;
f.ctl_class_tree_view.get_user_tag_info(currIndex, cm, false);
Make a copy of cbrowser.e and save it where you have write permission. Make a copy of cb_calltree and name it something like cb_calltree_rob.  Place the code of this function somewhere within cbrowser.e.  Replace the above two lines inside cb_calltree_rob with the following lines:

Code: [Select]
struct VS_TAG_BROWSE_INFO cm;
int context_id = tag_current_context();
tag_get_context_info(context_id, cm);

and load the module (F12 by default) and call this new function you just created from the SlickEdit command line (press ESC) while the cursor is within some function.  It should give you the call tree of the function you're in.

The only thing you need to do now is bind this command to the right-click menu, and you're done. :-)
« Last Edit: September 12, 2006, 02:38:44 PM by Kohei »

RobFreundlich

  • Community Member
  • Posts: 47
  • Hero Points: 2
Re: Feature/Macro request: display call trees
« Reply #5 on: September 12, 2006, 02:10:47 PM »
You totally rock!  One slight change to your instructions, and it works great.  You said to replace

Code: [Select]
struct VS_TAG_BROWSE_INFO cm;
f.ctl_class_tree_view.get_user_tag_info(currIndex, cm, false);

with

Code: [Select]
int context_id = tag_current_context();
tag_get_context_info(context_id, cm);

Acutally, the "struct VS_TAG_BROWSE_INFO cm" line needs to be kept.  (Not intending to nitpick or sound ungrateful - I just want anyone else looking at this to know what to do).

Thanks again,
Rob

Kohei

  • Senior Community Member
  • Posts: 192
  • Hero Points: 25
Re: Feature/Macro request: display call trees
« Reply #6 on: September 12, 2006, 02:37:57 PM »
Quote
the "struct VS_TAG_BROWSE_INFO cm" line needs to be kept
Oh yeah, you're right.  I've corrected it in my original post.  Thanks for spotting it! :-)

Dswag89

  • Community Member
  • Posts: 63
  • Hero Points: 4
Re: Feature/Macro request: display call trees
« Reply #7 on: September 21, 2006, 02:22:19 PM »
I just tried the steps above and get an error.  I added cb_calltree_current in addition to cb_calltree and made the mods suggested.  However, when I <ESC> and then type cb-calltree-current while I'm in a function, I get a message on the bottom of the screen saying "_tcbbrowser_form not found".  I can see the slick-C code that is creating this message, and even went to the function that is apparently returning 0 to cause the error message.  From looking at the code, I'm guessing that gtbcbrowser_wid is 0 (or I guess either of the other two conditions could be messed up), which is causing the problem?  However, I'm not used to looking into this stuff, so I'm stuck.  Any help would be appreciated.

Dan

Kohei

  • Senior Community Member
  • Posts: 192
  • Hero Points: 25
Re: Feature/Macro request: display call trees
« Reply #8 on: September 21, 2006, 02:40:33 PM »
From what I can see, this custom function relies on the Classes tab displayed within the editor to get a non-zero window ID of the class browser.  Turn this tab on by View > Toolbars > Classes, then try running the command again to see if that does the trick.

hs2

  • Senior Community Member
  • Posts: 2764
  • Hero Points: 292
Re: Feature/Macro request: display call trees
« Reply #9 on: September 21, 2006, 02:44:52 PM »
I also had a few problems w/ it. This is my solution:
Code: [Select]
_command hs2_calltree() name_info(','VSARG2_EDITORCTL)
{
   int f = GetCBViewWid();
   if (!f) {
      messageNwait("_tbcbrowser_form " nls("not found"));
      return('');
   }

   struct VS_TAG_BROWSE_INFO cm;
   _UpdateContext(true);
   _UpdateLocals(true,true);
   int context_id = tag_current_context();
   if (context_id > 0)
   {
      tag_get_context_info(context_id, cm);

      // check if there is a load-tags function, if so, bail out
      _str ext=_bufname2ext( cm.file_name );
      int index=find_index('vs'ext'-load-tags',PROC_TYPE);
      if (index_callable(index)) {
         _message_box(nls('Can not locate source code for %s.',cm.file_name));
         return(1);
      }

      // This has to be patched from 'static' to 'global' in cbrowser.e
      maybe_convert_proto_to_proc(cm);
      f.show("-xy _cbcalls_form", cm);
   }
}

and in cbbrowser.e:
Code: [Select]
// HS2: removed static
// static void maybe_convert_proto_to_proc(VS_TAG_BROWSE_INFO &cm)
void maybe_convert_proto_to_proc(VS_TAG_BROWSE_INFO &cm)
{
...

This tiny patch allows that this macro can reside in an external module along w/ your other stuff...

BTW: ClassBrowser Tab has just to be there, but doesn't need to be activated.

HS2
« Last Edit: September 21, 2006, 02:51:46 PM by hs2 »

Dswag89

  • Community Member
  • Posts: 63
  • Hero Points: 4
Re: Feature/Macro request: display call trees
« Reply #10 on: September 21, 2006, 02:59:17 PM »
Kohei: Thanks, it worked! [thumbs up]

HS2: Boy, I'm not sure if I like this whole "go back and edit an old post" thing that this forum supplies!  When I first read your post, it said that yours was "independent of the Class Browser", I thought.  I looked at the code and thought "how could it be?".  But I tried it anyway and found that it failed.  I went to reply to these two posts and see that you've updated your post (I know because I read two different things, not that I can see any "forum indicator" that you have updated it ).  Boy, talk about confusing when you're changing things real-time!

Thanks to both of you for the tips!  HS2, how does yours differ?  Is it better in any way than the other suggestion?  Also, I noted that you didn't follow the initial directions to keep the new function in the existing cbrowser.e file, and rather put it in your own.  Was that because you wanted to make MINIMAL changes to cbrowser.e?  Or because you want to keep all of your custom commands together so they don't get blown away by any new SE patches?

hs2

  • Senior Community Member
  • Posts: 2764
  • Hero Points: 292
Re: Feature/Macro request: display call trees
« Reply #11 on: September 21, 2006, 03:26:18 PM »
Sorry for my 1st mis-post :(
Dswag89: You must have set your (web)browser to 'reload every 3 seconds', right ?
I tried my very best to correct it, but you were faster ;)

And yes, both of your assumptions are perfectly right.
I try to keep as much as possible outside the product sources.
This makes the merge job after an upgrade a bit easier...
And I still maintain only 1 hs2.e ;), which contains all my private stuff.
It's (still) not worth it to split it into more modules.

HS2