首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用C# 5完成NRefactory代码

用C# 5完成NRefactory代码
EN

Stack Overflow用户
提问于 2012-09-20 05:41:19
回答 3查看 4.5K关注 0票数 8

我刚刚发现了NRefactory 5,我猜想它是解决我当前问题的最合适的解决方案。目前,我正在开发一个小的C#脚本应用程序,我想为它提供代码完成。直到最近,我还使用微软的"Roslyn“项目来完成这项工作。但是由于这个项目的最新更新需要.Net Framework4.5,我不能再使用它了,因为我希望这个应用程序也能在Win XP下运行。所以我要换另一种技术。

我的问题不是汇编资料。通过更多的努力,.Net CodeDomProvider也可以做到这一点。问题是代码完成的问题。据我所知,NRefactory 5提供了提供代码完成所需的一切(解析器、类型系统等)。但我就是想不出怎么用。我看了一下SharpDevelop源代码,但是他们不使用NRefactory 5来完成代码,他们只使用它作为反编译器。由于我也找不到如何在网络中使用它来完成代码的示例,所以我想在这里我可能会找到一些帮助。

情况如下。我有一个包含脚本代码的文件。实际上,它甚至不是一个文件,而是一个从编辑器控件获得的字符串(顺便说一句:我正在为此使用AvalonEdit。伟大的编辑!)和一些需要引用的程序集。因此,没有解决方案文件,没有项目文件等等,只是一个字符串的源代码和程序集。

我看了一下NRefactory 5附带的Demo和关于代码项目的文章,并提出了如下内容:

代码语言:javascript
复制
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));

我的问题是我不知道怎么继续下去。我甚至不确定这是否是实现我的目标的正确途径。如何使用CSharpCompletionEngine?还需要什么?你看,有很多事情目前还很不清楚,我希望你能为这件事带来一些启示。

非常感谢大家提前!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-10-02 19:35:26

看看方法ICSharpCode.NRefactory.CSharp.CodeCompletion.CreateEngine。您需要创建一个CSharpCompletionEngine实例并传入正确的文档和解析器。我设法让它适用于CTRL+Space合谋场景。但是,我在引用其他名称空间中的类型时遇到了问题。看起来CSharpTypeResolveContext没有考虑到使用的命名空间语句--如果我用CSharpAstResolver解析引用,它们就被解析为OK,但是我无法在代码完成场景中正确地使用这个解析器.

更新#1:

我刚刚从未解决的故障中获得了解析器,从而成功地完成了任务。

下面是片段:

代码语言:javascript
复制
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 );

更新#2:

这是完整的方法。它引用了单元测试项目中的类,因此您需要引用/复制它们到项目中:

代码语言:javascript
复制
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;

}

}

希望能帮上忙,马特拉

票数 3
EN

Stack Overflow用户

发布于 2013-02-21 17:00:56

我刚刚编译了一个用AvalonEdit和NRefactory完成AvalonEdit代码的示例项目。

可以是在这里发现的。

票数 7
EN

Stack Overflow用户

发布于 2012-09-20 19:01:57

NRefactory 5正在SharpDevelop 5中使用。SharpDevelop 5的源代码目前可在github上的newNR分支中获得。我想看一下CSharpCompletionBinding类,它的代码可以使用来自CSharpCompletionEngine的信息显示完成列表窗口。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12506646

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档