Roslyn:诊断中的当前工作空间,带有代码修复项目

时间:2014-04-21 18:16:47

标签: c# roslyn

如何通过代码修复项目获取Diagnostic中当前Workspace的信息(例如项目路径,解决方案路径)?

我正在实施ISyntaxNodeAnalyzer类型的诊断

我需要访问SymbolFinder.FindImplementationsAsync,但为此,我需要解决方案实例

编辑:我有这样的代码:

var syntax = (LocalDeclarationStatementSyntax) node;
var type = syntax.Declaration.Type;
var typeSymbol = semanticModel.GetTypeInfo(type).ConvertedType;

我想找出typeSymbol的所有用法/参考资料。 TypeSymbol表示位于源代码中的Class。

为此,我想使用SymbolFinder,但是SymbolFinder的方法需要Solution的实例...在旧版本的Roslyn中,Document作为诊断的方法参数给出,您可以进入项目和解决方案。

2 个答案:

答案 0 :(得分:6)

在实现诊断分析器时,目前没有获得工作空间或进行多项目分析的方法,因为这些方法需要能够仅使用命令行编译器针对单个编译运行。但是,一旦确定了诊断,您就可以在代码修复提供程序中完成此工作。

如果您只是想找到一个类实现另一个类的所有位置,您可以创建一个编译范围的诊断分析器并在决定诊断之前检查所有声明。您可以通过实现ICompilationStartedAnalyzer和ICompilationEndedAnalyzer来实现此目的。

答案 1 :(得分:2)

如果你确实需要这样做,你可以,但通过反思,没有任何一个人可以在所有环境或任何未来的版本等上工作......我只是在Windows环境中对此进行了测试。

public static class RoslynExtensions
{
    public static Solution GetSolution(this SyntaxNodeAnalysisContext context)
    {
        var workspace = context.Options.GetPrivatePropertyValue<object>("Workspace");
        return workspace.GetPrivatePropertyValue<Solution>("CurrentSolution");
    }

    public static T GetPrivatePropertyValue<T>(this object obj, string propName)
    {
        if (obj == null)
        {
            throw new ArgumentNullException(nameof(obj));
        }

        var pi = obj.GetType().GetRuntimeProperty(propName);

        if (pi == null)
        {
            throw new ArgumentOutOfRangeException(nameof(propName), $"Property {propName} was not found in Type {obj.GetType().FullName}");
        }

        return (T)pi.GetValue(obj, null);
    }
}

从像这样的分析仪调用:

public override void Initialize(AnalysisContext context)
{
    context.RegisterSyntaxNodeAction(AnalyzeConstDeclaration, SyntaxKind.FieldDeclaration);
}

public static void AnalyzeConstDeclaration(SyntaxNodeAnalysisContext context)
{
     var solution = context.GetSolution();
}