Ответ 1
Roslyn предоставляет услуги завершения кода через интерфейсы ICompletionService
и ICompletionProvider
, но они, похоже, в основном являются внутренними и предназначены для доступа при размещении в Visual Studio. Тем не менее, можно получить сцепление с типами завершения кода С#, используя пару рефлекторных хаков, как показано на рисунке ScriptCS Pad. Если вы можете заставить это работать, я ожидаю, что вы должны получить завершение кода VS-класса.
В качестве альтернативы вы можете сделать это "вручную", используя общедоступные API, предоставленные Roslyn. Я не очень разбираюсь в них, но следующее должно начинаться с перечисления членов выражения слева от точки доступа к члену. Обратите внимание, что он игнорирует методы расширения и правила видимости, не обрабатывает ошибки и, вероятно, ошибочен многими другими способами. Тем не менее сделать это надежно, возможно, не квалифицирует как "простое" завершение кода.
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.