【问题标题】:Roslyn: Current Workspace in Diagnostic with code fix projectRoslyn:带有代码修复项目的诊断中的当前工作区
【发布时间】:2014-04-21 18:16:47
【问题描述】:

如何在带有代码修复项目的诊断中获取有关当前工作区的信息(例如项目路径、解决方案路径)?

我正在实施 ISyntaxNodeAnalyzer 类型的诊断

我需要访问 SymbolFinder.FindImplementationsAsync,但要这样做,我需要解决方案实例

编辑:我有这样的代码:

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

我想了解 typeSymbol 的所有用法/引用。 TypeSymbol 表示位于源代码中的类。

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

【问题讨论】:

    标签: c# roslyn


    【解决方案1】:

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

    如果您只想找到一个类实现另一个类的所有地方,您可以制作一个编译范围的诊断分析器并在决定诊断之前检查所有声明。您可以通过同时实现 ICompilationStartedAnalyzer 和 ICompilationEndedAnalyzer 来做到这一点。

    【讨论】:

    • 我能以某种方式从实际诊断中获取解决方案实例吗?还是文档实例?旧版本的 Roslyn 将 Document 作为方法参数。
    • 或者我可以获取当前正在诊断的解决方案的路径吗?
    • 你无法得到那些——在编译器级别,不能保证这些东西甚至存在。我希望您更新您的问题以解释您希望您的诊断做什么,我们可以提供更好的指导。
    【解决方案2】:

    如果你真的需要这样做,你可以,但它通过反射没有 gaurentee 它将适用于所有环境或任何未来版本等...我只在 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();
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多