我想在Roslyn中开始代码完成,但找不到任何显示如何完成代码的简单示例。
完成此代码的最佳示例是什么,以便我可以在caretIndex
获取所有可能的完成项目(AKA智能感知或CTRL +空间完成)?
static void Main(string[] args)
{
var code = @"
using System;
public class Test
{
public void TestMethod()
{
var now = DateTime.Now;
now.
}
}";
Console.WriteLine(code);
var st = SyntaxTree.ParseText(code);
var caretIndex = code.IndexOf("now.") + 4;
//how to get possible code completions at caret index? (Intellisense)
}
答案 0 :(得分:14)
Roslyn确实通过ICompletionService
和ICompletionProvider
接口提供代码完成服务,但它们似乎主要是内部的,并且意味着在Visual Studio中托管时可以访问。但是,如ScriptCS Pad项目所示,可以使用几个反射黑客来获取C#代码完成类型。如果你能让它工作,我希望你能获得VS级代码。
或者,您可以使用Roslyn提供的公共API“手动”执行此操作。我并不熟悉它们,但以下内容应该让您开始列出成员访问点左侧的表达式成员。请注意,它忽略了扩展方法和可见性规则,没有错误处理,并且可能在许多其他方面存在缺陷。但是,可靠地执行此操作可能不符合“简单”代码完成的要求。
var code = @"
using System;
public class Test
{
public void TestMethod()
{
var now = DateTime.Now;
now.
}
}";
Console.WriteLine(code);
var syntaxTree = CSharpSyntaxTree.ParseText(code);
var compilation = CSharpCompilation.Create("foo")
.AddReferences(MetadataReference.CreateAssemblyReference(typeof(DateTime).Assembly.FullName))
.AddSyntaxTrees(syntaxTree);
var semanticModel = compilation.GetSemanticModel(syntaxTree);
var dotTextSpan = new TextSpan(code.IndexOf("now.") + 3, 1);
var memberAccessNode = (MemberAccessExpressionSyntax)syntaxTree.GetRoot().DescendantNodes(dotTextSpan).Last();
var lhsType = semanticModel.GetTypeInfo(memberAccessNode.Expression).Type;
foreach (var symbol in lhsType.GetMembers())
{
if (!symbol.CanBeReferencedByName
|| symbol.DeclaredAccessibility != Accessibility.Public
|| symbol.IsStatic)
continue;
Console.WriteLine(symbol.Name);
}
编辑:请注意,这个答案可能已被新的Roslyn位淘汰。
答案 1 :(得分:4)
如果您拥有Workspace
个实例,则可以使用Microsoft.CodeAnalysys.Workspaces
包中的公开推荐API:
public static class Recommender
{
public static IEnumerable<ISymbol> GetRecommendedSymbolsAtPosition(SemanticModel semanticModel, int position, Workspace workspace, OptionSet options = null, CancellationToken cancellationToken = default(CancellationToken));
}
它返回给定偏移处的完成符号。它没有返回关键字,但截至2016年3月,Roslyn家伙正致力于更好的公共api完成:https://github.com/dotnet/roslyn/issues/3538