8

NRefactory 5について知りましたが、これが現在の問題に最も適したソリューションだと思います。現在、コード補完を提供したい小さなC#スクリプトアプリケーションを開発しています。最近まで、私はMicrosoftの「Roslyn」プロジェクトを使用してこれを行ってきました。ただし、このプロジェクトの最新の更新には.Net Framework 4.5が必要なため、アプリをWin XPでも実行したいので、これを使用することはできません。そのため、ここで別のテクノロジーに切り替える必要があります。

私の問題はコンパイルのものではありません。これは、.Net CodeDomProviderによっても、もう少し努力して行うことができます。問題はコード補完のものです。私の知る限り、NRefactory 5は、コード補完を提供するために必要なすべてのもの(パーサー、型システムなど)を提供しますが、その使用方法がわかりません。SharpDevelopのソースコードを調べましたが、コードの補完にNRefactory 5を使用せず、逆コンパイラとしてのみ使用しています。ネットでコード補完に使用する方法の例も見つからなかったので、ここで役立つかもしれないと思いました。

状況は以下のとおりです。スクリプトコードを含む単一のファイルがあります。実際には、ファイルではなく、エディターコントロールから取得した文字列(ちなみに、これにはAvalonEditを使用しています。すばらしいエディターです!)と、参照する必要のあるいくつかのアセンブリです。したがって、ソリューションファイルやプロジェクトファイルなどはなく、ソースコードとアセンブリの1つの文字列だけです。

NRefactory 5に付属しているデモとコードプロジェクトに関する記事を見て、次のようなものを思いつきました。

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の使用方法は?他に何が必要ですか?現時点では非常に不明確なことがたくさんありますので、これに光を当てていただければ幸いです。

よろしくお願いします!

4

3 に答える 3

7

AvalonEditとNRefactoryを使用してC#コード補完を行うプロジェクトの例をコンパイルしました。

こちらのGithubで見つけることができます。

于 2013-02-21T17:00:56.213 に答える
3

メソッドを見てくださいICSharpCode.NRefactory.CSharp.CodeCompletion.CreateEngine。のインスタンスを作成CSharpCompletionEngineし、正しいドキュメントとリゾルバーを渡す必要があります。私はそれをCTRL+スペースコンプリーションシナリオで機能させることができました。ただし、他の名前空間にある型への参照に問題があります。CSharpTypeResolveContext名前空間ステートメントの使用を考慮していないようです-で参照を解決すると、CSharpAstResolverそれらは正常に解決されますが、コード完了シナリオでこのリゾルバーを正しく使用できません...

更新#1:

未解決の失敗からリゾルバーを取得することで、うまく機能するようになりました。

スニペットは次のとおりです。

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:

これが完全な方法です。単体テストプロジェクトのクラスを参照するため、それらを参照/プロジェクトにコピーする必要があります。

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;

}

}

お役に立てば幸い、マトラ

于 2012-10-02T19:35:26.440 に答える
2

NRefactory5はSharpDevelop5で使用されています。SharpDevelop5のソースコードは、現在githubのnewNRブランチで入手できます。NRefactoryのCSharpCompletionEngineからの情報を使用して、完了リストウィンドウを表示するコードを持つCSharpCompletionBindingクラスを見てみましょう。

于 2012-09-20T19:01:57.467 に答える