我正在尝试使用 获取被调用方法的 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
有两个静态方法可以通过传递文件或字节来获取实例,但我不知道如何使用它来实现我的目标......