Posted 12 years ago by Igor Velikorossov - Sydney, Australia
Version: 4.0.0246
Avatar
I'm trying to build some sort of class view based on DocumentOutlineTreeView in the original example. I want to display a member info similar to QuickInfo once a node is clicked in the tree.

There seems to be no easy way to retrieve information I want (or perhaps I'm just missing it). I hacked it using reflection but I wonder if there is an easier way to do that.

IDomMember type = e.Node.Tag as IDomMember;
object[] param;

object offset = null;
// CSharpSyntaxLanguage: 
// protected override DotNetContext GetContext(SyntaxEditor, int, bool, bool)
MethodInfo m = typeof(DotNetSyntaxLanguage).GetMethod("GetContext", BindingFlags.NonPublic | BindingFlags.Instance);

if (m == null)
    return;
param = new object[] { this.buddyCodeEditor.Editor, offset, false, false };
DotNetContext context = (DotNetContext)m.Invoke(this.buddyCodeEditor.Document.Language, 
                                                param);

// DotNetProjectResolver: 
// internal string a(DotNetLanguage, DotNetContext, IDomType, IDomMember, int, bool)
m = typeof(DotNetProjectResolver).GetMethod("a",
                                            BindingFlags.NonPublic | BindingFlags.Instance,
                                            null,
                                            new Type[] { typeof(DotNetLanguage), 
                                                           typeof(DotNetContext), 
                                                           typeof(IDomType), typeof(IDomMember), typeof(int), typeof(bool) }, null);
if (m == null)
    return;
param = new object[] { DotNetLanguage.CSharp, context, null, type, -1, true };
object o = m.Invoke(this.classViewUpdater.ProjectResolver, param);
if (o != null && o is string)
{
    string html = o as string;
    this.markupLabel.Text = html;
}

Comments (7)

Posted 12 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Would you like us to add a GetQuickInfo method that takes a DotNetContext and returns the formatted quick info markup?


Actipro Software Support

Posted 12 years ago by Igor Velikorossov - Sydney, Australia
Avatar
That would be great.

While we are at it, how do I get hold of the context object without resorting to reflection? And is there way of getting DotNetLanguage from the SE.Document.Language?
Posted 12 years ago by Igor Velikorossov - Sydney, Australia
Avatar
It also appears that the GetQuickInfo method (or whatever it is called at the moment) does not alway generate correct output.

First problem is when any of parameters or return type is an array (ie contains []).

This behaviour is present in the example:

1. Create a method:

public int[] M(double[] x) 
{
    return null;
}
2. In a body of any other method type "M(" and quick info is "int M(double x)" instead of "int[] TestClass.M(double[] x)"


Second problem is that it seems to pick the base's method while generating the info, not the method from very top class in case of overriden methods. Whilst the return type and parameters do not change, summary may as well be different from the original, and the reference to base class (in the tooltip) may be somewhat misleading (to a user).

This behaviour is present in the example:

1. Create a following objects:

    class A 
    {
        /// <summary>
        /// summary for A.M
        /// </summary>
        /// <param name="x"></param>
        public virtual int M(int x) {
            
        }
    }
    
    class B : A {
        /// <summary>
        /// summary for B.M
        /// </summary>
        /// <param name="x"></param>
        public override int M(int x) {
            
        }
        
    }
2. When you request a quick info for B's method M you will get "int A.M(int)\nsummary for A.M"
Posted 12 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
The CSharpContext and VBContext classes have some static methods for getting the context. However maybe we can add a DotNetSyntaxLanguage method that calls the appropriate one for you in the future.

There isn't a way right now to get the DotNetLanguage for a DotNetSyntaxLanguage but I've added it for you last minute before a maintenance release today.

For the quick info array issue, that is something we have on our TODO list but relates to the other array issues we still need to sort out.

Thanks for the other quick info code, that is now fixed for the upcoming maintenance release.


Actipro Software Support

Posted 12 years ago by Igor Velikorossov - Sydney, Australia
Avatar
Sweet, looking forward to testing the update.
Thank you.
Posted 12 years ago by Igor Velikorossov - Sydney, Australia
Avatar
Thank you for the DotNetProjectResolver.GetQuickInfo method, but I'm afraid that it does not solve my problem. It always returns null.

I suspect that the reason behind that you rely on the actual context object from which you determine of what type the token is and generate its quick info. In my case context is always None, because the member may not be present in the editor at all.
The method I invoke through reflection as one of its parameters takes IDomMember, which what the treenode is.

Your suggestion of using CSharpContext.GetContextAtOffset unfortunately neither worked. From what I could gather through the .Net Reflector - the context object is populated from Document.Tokens, which in my case may be empty (most of my code is in either HeaderText or FooterText, and it doesn't seem to be present in Document.Tokens collection). As a result the {context = None}.
I have also tried CSharpContext.GetContextBeforeOffset but it yeilds {context = AnyCode}, which again causes GetQuickInfo fall through to returning null.
Posted 12 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Yes you are correct, the context determines how the quick info is populated. Since you are doing something a little different than most people, try doing this...

Make a class that inherits DotNetContext (since it is abstract). For constructor params, give it a target offset of 0, DotNetContextType.NamespaceTypeOrMember, and an ArrayList of items.

The two items should be a IDomType followed by an IDomMember. So to initialize the items, the TextRange can be anything, the Text should be the name of the type/member, the Type should be DotNetContextItemType.Type and DotNetContextItemType.Member, and the ResolvedInfo should be the reference to the IDomType and IDomMember.

If you do that, I believe you will build up what the context needs for quick info.


Actipro Software Support

The latest build of this product (v2018.1 build 0341) was released 8 months ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.