C # code execution using NRefactory 5

I just found out about NRefactory 5, and I would suggest that this is the most suitable solution for my current problem. I am currently developing a small C # scripting application for which I would like to provide code completion. Until recently, I did this using the Roslyn project from Microsoft. But since the last update of this project requires .Net Framework 4.5, I can no longer use this, since I would like the application to run under Win XP. So I have to switch to another technology here.

My problem is not compilation. This can be done with some additional .Net CodeDomProvider efforts. The problem is the content of the code. As far as I know, NRefactory 5 provides everything you need to ensure code completion (parser, type system, etc.), but I just can't figure out how to use it. I took a look at the source code of SharpDevelop, but they do not use NRefactory 5 to complete the code there, they only use it as a decompiler. Since I could not find an example on how to use it to complete code on the network, I thought I could find some help here.

The situation is as follows. I have one file containing the script code. In fact, this is not even a file, but a string that I get from the editor control (by the way: I use AvalonEdit for this. Great editor!) And some assemblies that need to be referenced. Thus, no decision files, project files, etc. Only one line of source code and assembly.

I read the demo that comes with NRefactory 5 and the article on code project, and got up with something like this:

var unresolvedTypeSystem = syntaxTree.ToTypeSystem(); IProjectContent pc = new CSharpProjectContent(); // Add parsed files to the type system pc = pc.AddOrUpdateFiles(unresolvedTypeSystem); // Add referenced assemblies: pc = pc.AddAssemblyReferences(new CecilLoader().LoadAssemblyFile( System.Reflection.Assembly.GetAssembly(typeof(Object)).Location)); 

My problem is that I do not know how to do this. I’m not even sure that this is the right approach to achieve my goal. How to use CSharpCompletionEngine? What else is required? etc. You see that a lot is not clear at the moment, and I hope that you can bring light to this.

Thank you all in advance!

+6
source share
3 answers

Take a look at the ICSharpCode.NRefactory.CSharp.CodeCompletion.CreateEngine method. You need to create an instance of CSharpCompletionEngine and pass in the desired document and permissions. I managed to get it to work for the CTRL + Space script. However, I am having problems referencing types that are in other namespaces. It appears that CSharpTypeResolveContext does not account for the use of namespace operators. If I resolve links using CSharpAstResolver , they resolve in order, but I cannot use this resolver correctly in the code completion script ...

UPDATE # 1:

I just managed to get the job by getting resolver from an unresolved failure.

Here is a snippet:

 var mb = new DefaultCompletionContextProvider(doc, unresolvedFile); var resolver3 = unresolvedFile.GetResolver(cmp, loc); // get the resolver from unresolvedFile var engine = new CSharpCompletionEngine(doc, mb, new CodeCompletionBugTests.TestFactory(resolver3), pctx, resolver3.CurrentTypeResolveContext ); 

Update # 2:

Here is the complete method. It references the classes from unit test projects, but you will need to reference / copy them to your project:

 public static IEnumerable<ICompletionData> DoCodeComplete(string editorText, int offset) // not the best way to put in the whole string every time { var doc = new ReadOnlyDocument(editorText); var location = doc.GetLocation(offset); string parsedText = editorText; // TODO: Why there are different values in test cases? var syntaxTree = new CSharpParser().Parse(parsedText, "program.cs"); syntaxTree.Freeze(); var unresolvedFile = syntaxTree.ToTypeSystem(); var mb = new DefaultCompletionContextProvider(doc, unresolvedFile); IProjectContent pctx = new CSharpProjectContent(); var refs = new List<IUnresolvedAssembly> { mscorlib.Value, systemCore.Value, systemAssembly.Value}; pctx = pctx.AddAssemblyReferences(refs); pctx = pctx.AddOrUpdateFiles(unresolvedFile); var cmp = pctx.CreateCompilation(); var resolver3 = unresolvedFile.GetResolver(cmp, location); var engine = new CSharpCompletionEngine(doc, mb, new CodeCompletionBugTests.TestFactory(resolver3), pctx, resolver3.CurrentTypeResolveContext ); engine.EolMarker = Environment.NewLine; engine.FormattingPolicy = FormattingOptionsFactory.CreateMono(); var data = engine.GetCompletionData(offset, controlSpace: false); return data; } 

}

Hope this helps, Matra

+2
source

I just compiled an example project that completes the execution of C # code using AvalonEdit and NRefactory.

It can be found here on Github.

+5
source

NRefactory 5 is used in SharpDevelop 5. The source code for SharpDevelop 5 is currently available on the newNR branch on github . I would look at the CSharpCompletionBinding class , which has code to display the completion list window, using the information from the NRefactory CSharpCompletionEngine.

+2
source

Source: https://habr.com/ru/post/925814/


All Articles