Objects in IntelliPrompt

SyntaxEditor for Windows Forms Forum

Posted 6 years ago by Dominik K
Version: 12.1.0302
Avatar

Hey,

I have added "System" and "myProject" as Reference (AddExternalReferenceForSystemAssembly).
This works pretty fine, but I have two questions now:

1. How can I add Objectlists to IntelliPrompt?
I have a Objectlist with the name "MD" and Objects with names like "M_Object1", "M_Object2" in this List.
My goal is to open the IntelliPromptList and can choose "MD" and if I write "MD." there should be my list of the objects. I just need the name of the objects.
(eg. "MD.M_Object1").

2. Is there a possibility to add the property "Desc" to the QuickInfo as Description in the IntelliPromptList?

 

Sorry, I am new to SyntaxEditor :)

Greetings,
Dominik

[Modified 6 years ago]

Comments (22)

Answer - Posted 6 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Dominik,

It sounds like you are using the .NET Languages Add-on here.  All the automated IntelliPrompt there comes from the reflection data it builds, based on referenced assemblies you designate and/or source code files it parses.  So one option is in your "myProject" to make a static class called MD and have properties on it like M_Object1.  Then if you do that, you should see it showing up in the member list.  The descriptions come from XML comments for the related classes.  So if you set summary comments on the MD and M_Object1, etc., they should show up.  That is the best way to go.

You can also use the SourceProjectContent to add in "source" files and have all these MD, M_Object1 declarations in that.  Then you could dynamically update as needed to in case that is important to you.  So basically this way is similar to the above except you are managing a SyntaxEditor document that contains your type info in the background instead of referencing a pre-compiled assembly with it.


Actipro Software Support

Posted 6 years ago by Dominik K
Avatar

Hello,

I have a problem with this.
To get my memberlist I added the HeaderText and FooterText and Reparsed it. That should do the trick?

SyntaxEditor.Document.Language = new ActiproSoftware.SyntaxEditor.Addons.CSharp.CSharpSyntaxLanguage();
SyntaxEditor.Document.LanguageData = new ActiproSoftware.SyntaxEditor.Addons.DotNet.Dom.DotNetProjectResolver();

SyntaxEditor.Document.HeaderText = @"
using System;

namespace MyProject.Editor
{
   public class PVs
   {
      public double PV1 { get { return 0; } }
      public double PV2 { get { return 0; } }
   }

   public class Formula
   {
      PVs PV = null;
      public void Formula()
      {";

SyntaxEditor.Document.FooterText = @"
      }
   }
}";
SyntaxEditor.Document.Reparse();

But in my Editor I can't access to my member (PV1, PV2). Why is that?
I tried it with <summary>'s and "public static class PVs" too, but without success.

Thanks,
Dominik

[Modified 6 years ago]

Posted 6 years ago by Tobias Lingemann - Software Devolpment Engineer, Vector Informatik GmbH
Avatar

You shoud add the needed external references. Most importantly the mscorelib.

resolver.AddExternalReferenceForMSCorLib();

If other source files are involved you need to add them to your SourceProjectContent.
Just take a look at the "Project Resolver" topic in the help. It is all explained there.

[Modified 6 years ago]


Best regards, Tobias Lingemann.

Posted 6 years ago by Dominik K
Avatar

Hello Tobias,

I want to create the Data dynamically within the Document like this:

SyntaxEditor.Document.HeaderText = 
"using System;" + NewLine +
"namespace Domain.MyProject.Editor {" + NewLine +
  "public class PV {" + NewLine;
    foreach(PVItem pv in PVs)
    {
      SyntaxEditor.Document.HeaderText += "///<summary>My Description</summary>" + NewLine;
      SyntaxEditor.Document.HeaderText += "public double " + pv.Key + " { get { return 0; } }" + NewLine;
    }
   SyntaxEditor.Document.HeaderText += "}" + NewLine +
   "public void Formula() {";

SyntaxEditor.Document.FooterText = "} } }";
  

Your solution won't solve the problem.

Posted 6 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Dominik,

On thing that is required is that you set a FileName on the document.  Please see the "Key Steps for Getting Started" section of the main .NET Languages Add-on to make sure you are doing all the things needed to get automated IntelliPrompt working properly.  If you miss any of those, like the filename setting, then things won't work as expected.


Actipro Software Support

Posted 6 years ago by Dominik K
Avatar

Hi,

thanks a lot! This was the solution: I just needed to add "SyntaxEditor.Document.FileName = "Editor";".

Regards,

Dominik

Posted 6 years ago by Dominik K
Avatar

So I just checked it and it doesn't seem to important, whats within the string. Even "SyntaxEditor.Document.Filename = """ still works.

So what does the Filename-Propertie do? I can't seem to figure it out.

Posted 6 years ago by Tobias Lingemann - Software Devolpment Engineer, Vector Informatik GmbH
Avatar

Just a few sections from the help.

A filename that uniquely identifies the text to parse.

 

This would be caused if you didn't assign a valid value to the Document.Filename property. SyntaxEditor uses the Document.Filename property value as the source key when merging code being edited into the project resolver. If there is no source key (blank filename) then the project resolver will not have any reflection data stored for the compilation unit you are editing in the SyntaxEditor.

 

If the DotNetSyntaxLanguage.SourceProjectContentUpdateEnabled property is set to true (the default value) then the add-on will automatically update the source project content using the filename specified in the Document.Filename property. The document's filename must be set in order for this feature to work properly.

So basically it's used as an ID. If you would have two documents with the same file name within one ProjectContentResolver instance, you would get problems too.

[Modified 6 years ago]


Best regards, Tobias Lingemann.

Posted 6 years ago by Dominik K
Avatar

Thanks Tobias,

you helped a lot!

I still got a question though:

My Editor works fine but the ErrorHighlighting doesn't seem to work that great, so is there a property which I need to enable to get it to work?

To be precise:

Header: "public decimal Formula() {"
Footer: "}"

 So, the editor should mark everything as error until I return a decimal value?

Or do I must write my own method to check the syntax?

 

Thanks,

Dominik

[Modified 6 years ago]

Posted 6 years ago by Tobias Lingemann - Software Devolpment Engineer, Vector Informatik GmbH
Avatar

The error highlighting is pretty basic and not comprehensive.

What we do is that we run the .net compiler in the background, extract the error information there and create SpanIndicator for each error or warning. It works pretty good, since you can do the whole compilation in memory. Just take a look at the System.CodeDom.Compiler.CodeDomProvider class.

Of course you could extend the already implementd error highlighting checks, but that would be quite complex.

To be fair, it might take a while for you to implement everything, but we need that part anyway for different use cases. Same thing applies for managing external references in your DotNetProjectResolver. We basically use the same source to get the references the compiler uses and update our DotNetProjectResolver instances whenever the user adds or remove any references.

[Modified 6 years ago]


Best regards, Tobias Lingemann.

Posted 6 years ago by Dominik K
Avatar

Question solved, another showes up:

I got my IntelliPromptList like I wanted but now we want to have a simple version of it which means, I just want to show the members which I created in the HeaderText without! the System-Options and methods like "GetHash(), ToString()".

Is it possible to remove all the unnecessary objects in the list or do I must create my own language?

Thanks!

Posted 6 years ago by Tobias Lingemann - Software Devolpment Engineer, Vector Informatik GmbH
Avatar

That's a tricky one. We hide some of our internal namespaces in the IntelliPrompt. If you don't have the source code of the .net-addon, I don't think there is a good way to realize it.

If you have the source code, your starting point is the ShowIntelliPromptMemberList() method in DotNetSyntaxLanguage. There you can see how the data is collected. In my case i modified the methods GetTypes() and GetChildNamespaceNames() in DotNetProjectResolver not to consider types and namespaces that fit my condition.

I think your case would be easier, since the intelli objects have a property that indicates the source. I am not sure which one it was, but when debugging you will find it. In case the source is a file, there will be the file name, otherwise it will be an assembly. If you just ignore all that don't match your file name, that would be it.


Best regards, Tobias Lingemann.

Posted 6 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Dominik,

Actually the documentation for the .NET Languages Add-on has a "Member List Pre-Filtering" topic that talks about an event where you can add/remove items before the member list shows.  That's what you'd want to use.


Actipro Software Support

Posted 6 years ago by Dominik K
Avatar

I got my result finally, thanks a lot.

I looked the documentation and the forum for my new problem but didn't find a solution:

I want to use my own icons additionally for my IntelliPromptMemberListItem but I can just use Icons from the IconResource Enumeration. My Icon/Image is in the Project.Resources with the name "Icon1.ico". Is there a possibility to use that icon?

Thanks again for your time.

Posted 6 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

The member list itself has an ImageList property you can assign any custom ImageList to.  Then the item image index will refer to that list.


Actipro Software Support

Posted 6 years ago by Dominik K
Avatar

I have another thing I would like your help:

I have two modus:

1. the expertmode where the intellipromptList is filled with everything (like I did in the replies above)
2. the normal mode where I want to create my own List without the Reflection, etc.

So I do following:

 

void cSharp_SyntaxEditorIntelliPromptMemberListPreFilter(object sender, ActiproSoftware.SyntaxEditor.IntelliPromptMemberListPreFilterEventArgs e)
    {
      if (((CSharpContext)e.Context).Items == null)
      {
        //----------------------------------------------------
        //Erstelle alle Gruppen
        //----------------------------------------------------
        e.Items.Clear();
        e.Items.Add("PV", new ActiproSoftware.SyntaxEditor.IntelliPromptMemberListItem("PV", (int)IconResource.PrivateClass)
        {
          Tag = new ActiproSoftware.SyntaxEditor.Addons.DotNet.Ast.PropertyDeclaration(ActiproSoftware.SyntaxEditor.Addons.DotNet.Ast.Modifiers.None
                                                                                      , new ActiproSoftware.SyntaxEditor.Addons.DotNet.Ast.QualifiedIdentifier("PV"))
          {
            Documentation = "<summary>Liste aller Planungsgrößen</summary>"
          }
        });

        foreach (Shared.Data.FormulaEditorData.FN func in _data.FNs)
        {
          ActiproSoftware.SyntaxEditor.Addons.DotNet.Ast.MethodDeclaration tag =  
            new ActiproSoftware.SyntaxEditor.Addons.DotNet.Ast.MethodDeclaration(ActiproSoftware.SyntaxEditor.Addons.DotNet.Ast.Modifiers.Public
                                                                                , new ActiproSoftware.SyntaxEditor.Addons.DotNet.Ast.QualifiedIdentifier(func.Name));
          tag.Documentation = "<summary>Funktion " + func.Name + "</summary>";
          
          foreach (Shared.Data.FormulaEditorData.PRM prm in func.Params)
          {
            tag.Parameters.Add(new ActiproSoftware.SyntaxEditor.Addons.DotNet.Ast.ParameterDeclaration(ActiproSoftware.SyntaxEditor.Addons.DotNet.Ast.ParameterModifiers.None, prm.Name)
            {
              ParameterType = new ActiproSoftware.SyntaxEditor.Addons.DotNet.Ast.TypeReference(prm.Type, new TextRange())
            }); 
            tag.Documentation += "<param name=\"" + prm.Name + "\">" + prm.Desc + "</param>";
          }
          tag.Documentation += "<returns></returns>";
          tag.ReturnType = new ActiproSoftware.SyntaxEditor.Addons.DotNet.Ast.TypeReference(func.ReturnType, new TextRange());
          tag.Modifiers = ActiproSoftware.SyntaxEditor.Addons.DotNet.Ast.Modifiers.Public;
          e.Items.Add(func.Name, new ActiproSoftware.SyntaxEditor.IntelliPromptMemberListItem(func.Name, (int)IconResource.PublicMethod) { Tag = tag });
        }
      }
 
// Fill the PV-Group

 Everything works fine and I get my Groups with the necessary Items. The problem are the functions.

If I open the Intellipromptlist I get (e.g. "Function1" - "decimal function(int x, int y)" with description below) but if I use the function and write "function(" in the editor, the editor won't show me the parameter which is necessary for the function which should be first "int x" and after I type "function(1," "int y".

So I want the IntelliSense to show me which parametertype is awaited.

I hope it's understandable.

Thanks for your help.

[Modified 6 years ago]

Posted 6 years ago by Dominik K
Avatar

Ok, I am one step further and I know the problem:

Within the IntelliSense there is only ".Function(int x, int y)" but there should be "Formula.Function(int x, int y)".

So I must set the ParentNode, right? And how do I do it manually?

Posted 6 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Dominik,

Parameter info is a separate UI feature from member lists.  It sounds like you'd want to make custom parameter info tip display for your mode where you aren't using the reflection features.

You can read about parameter info in the documentation and can look at examples like in the SimpleSyntaxLanguage to see a real world usage of it.

For the other question, in general, you can't really manually inject things into the system by manipulating the AST, etc.  You need to make another source file content file that contains your classes and let that get registered into the IntelliPrompt relfection database with its own filename.  Then you can manipulate and change that document however you see fit.  That is a better way to add in reflection data that doesn't come from an assembly and is more dynamic.


Actipro Software Support

Posted 6 years ago by Dominik K
Avatar

The problem with the method of creating a new document with Language, LanguageData, Filename, HeaderText and FooterText is that I get all the System-Objects, Methods, etc and I don't want that. I want only! my classes and object which I create in the HeaderText without anything from the Language or System. (the "Keywords")

Is this possible?

/edit:

Okay, please forgive my stupidy, I totally forgot that I mentioned this earlier and got some tips for the way to handle it.

I got my list with following:

void cSharp_SyntaxEditorIntelliPromptMemberListPreFilter(object sender, IntelliPromptMemberListPreFilterEventArgs e)
    {
      List<object> del = new List<object>();
      if (e.Items != null)
      {
        foreach (object key in e.Items.Keys)
        {
          if (((IntelliPromptMemberListItem)e.Items[key]).Tag == null)
          {
            del.Add(key);
          }
        }
      }
      foreach (object key in del)
      {
        e.Items.Remove(key);
      }
    }

[Modified 6 years ago]

Posted 6 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

What I was suggesting is effectively similar to if you put your custom class in the HeaderText of the same document you're editing.  I was just saying splitting it out to a separate document is sometimes easier.

And as you saw, the member list pre-filtering is your only real option here to allow for filtering out things you don't want.


Actipro Software Support

Posted 6 years ago by Dominik K
Avatar

Yep, the method is pretty good.

I only got one problem: If I change from one mode to another, my MemberList is not updated on it's Width.

Which means, if I have a List with shorter Items and change the mode, the MemberList will pop up with the same width as before and only change after the second try.

I can't see a property to change or refresh the Width on runtime.

Posted 6 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

The WinForms member list wasn't really built with dynamic resizing in mind so there isn't anything to resize it.  You may have to close and reopen it right away to get it to update.  Is that what you are doing?


Actipro Software Support

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

Add Comment

Please log in to a validated account to post comments.