2

我正在尝试使用 获取被调用方法的 XML 文档Microsoft.CodeAnalysis,即使此方法是在先前编译的库中定义的。

如果我有一个SymbolAnalysisContext或一个ISymbol. ISymbol具有GetDocumentationCommentXml()返回 xml 字符串的方法。

我的问题是,我找不到被调用方法的 ISymbol 方法。
我正在使用操作操作来查找所有表达式语句,这就是我如何OperationAnalysisContext为每个匹配的表达式获取一个。
在这一点上,我被困住了。

我正在尝试获取SyntaxTree包含类/命名空间或直接获取符号。但我不确定这是否是正确的方法。XML 文档存储在 XML 文档文件中,而不是(反编译的)程序集中。你有什么建议吗?我不需要一个完整的解决方案,但是一些如何到达那里的提示会非常好。

更新:
经过几天的研究,roslyn 编译器似乎并不关心文档,您必须手动加载它。
这就是为什么我开始搜索包含程序集、加载它并使用Assembly.CodeBase属性来获取 xmldocumentation 的路径的原因。
遗憾的是,既没有包含系统组件旁边的文档的 xml 文件,也没有嵌入的文档(例如 system.private.corelib)。系统程序集包含一个嵌入的 xml 文件,但该文件不包含文档(根元素不是doc,它是linker)。

要使用该Assembly.CodeBase属性,我必须将目标框架从升级.netstandard1.3.netstandard1.5.

我更新了代码示例以代表我当前的状态...

以下是一个说明性示例:

那是我的分析器:

[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class Analyzer: DiagnosticAAnalyzer
{
    private static readonly DiagnnosticDescriptor Rule; // is initialized
    
    public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
    {
        get => ImmutableArray.Create(Rule);
    }

    public override void Initialize(AnalysisContext context)
    {
        context.RegisterOperationAction(AnalyzeOperation, OperationKind.ExpressionStatement);
    }
    
    private void AnalyzeOperation(OperationAnalysisContext context)
    {
        if(!(context.Operation is IExpressionStatementOperation expressionStatementOperation))
        {
            throw new InvalidOperationException();
        }

        if(!(expressionStatementOperation.Operation is IInvocationOperation invocationOperation))
        {
            throw new InvalidOperationException();
        }

        IMethodSymbol methodSymbol  = invocationOperation.TargetMethod;

        AssemblyIdentity          identity     = methodSymbol.ContainingAssembly.Identity;
        AssemblyName assemblyName = new AssemblyName
                                    {
                                        Name        = identity.Name,
                                        Version     = identity.Version,
                                        Flags       = identity.Flags,
                                        ContentType = identity.ContentType
                                    };

        Assembly assembly = Assembly.Load(assemblyName);
    }
}

那是一份分析过的文件:

using System.IO;

namespace myProject
{
    public class MyClass
    {
        public void MyMethod(StreamReader reader)
        {
            reader.ReadToEnd();
        }
    }
}

我正在尝试获取 `StreamReader.ReadToEnd() 的整个 XML 文档

编辑:
刚才我发现这个类XmlDocumentationProvider有两个静态方法可以通过传递文件或字节来获取实例,但我不知道如何使用它来实现我的目标......

4

0 回答 0