首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >可拓方法的SymbolInfo

可拓方法的SymbolInfo
EN

Stack Overflow用户
提问于 2018-12-24 21:04:39
回答 1查看 506关注 0票数 12

我需要分析一些扩展方法。例如,Enumerable.ToList

代码示例用于分析:

代码语言:javascript
运行
复制
var test = @"
using System.Linq;

namespace Test
{
    public class TestType
    {
        void TestMethod()
        {
            var empty = new[] {0};
            var test = empty.ToList();
        }
    }
}";

诊断:

代码语言:javascript
运行
复制
public override void Initialize(AnalysisContext context)
{
    context.RegisterSyntaxNodeAction(AnalyzeSymbol, SyntaxKind.InvocationExpression);
}

private static void AnalyzeSymbol(SyntaxNodeAnalysisContext context)
{
    var symbolInfo = context.SemanticModel.GetSymbolInfo(context.Node);
}

然而,symbolInfo.Symbol是空的,没有任何候选人。如果我像这样修改代码示例:

代码语言:javascript
运行
复制
var test = @"
using System.Linq;

namespace Test
{
    public class TestType
    {
        void TestMethod()
        {
            var empty = new[] {0};
            var test = Enumerable.ToList(empty);
        }
    }
}";

那么symbolInfo有一个候选人,但仍然没有符号。如何获取扩展方法调用的符号信息?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-01-10 13:18:52

如果您使用的是自动从“Analyzer with Code Fix”项目模板创建的默认单元测试助手类,那么您应该知道以下几点。

GetSortedDiagnosticsFromDocuments方法尝试运行分析器,即使在处理作为输入提供的代码时存在编译错误。当然,当存在编译错误时,语义模型可能是不完整的或缺失的。

您可以通过以下方式更改此方法:

代码语言:javascript
运行
复制
// old version: no compilation errors detection
var compilationWithAnalyzers = project.GetCompilationAsync().Result.WithAnalyzers(ImmutableArray.Create(analyzer));


// new version: detect the compilation errors
var compilation = project.GetCompilationAsync().Result;             
var compilerErrors = compilation.GetDiagnostics().Where(i => i.Severity == DiagnosticSeverity.Error);

if (compilerErrors.Any())
{
    return compilerErrors.ToArray();
}

var compilationWithAnalyzers = compilation.WithAnalyzers(ImmutableArray.Create(analyzer));

如果然后尝试使用此代码和输入字符串运行单元测试,您将注意到至少有两个编译错误:

错误CS0012:类型'List<>‘是在未引用的程序集中定义的。您必须添加对程序集'System.Collections,Version=4.1.0.0,Culture=neutral,PublicKeyToken=b03f5f7f7f11d50a3a‘的引用。

(版本号可能不同)

错误CS5001:程序不包含适合入口点的静态“主”方法

您需要解决这些错误才能编译代码,以便能够访问有效的语义模型。

  • void TestMethod()更改为static void Main()。这并不是真正必要的,但最好有一个有效的代码,没有编译器错误。
  • 将对System.CollectionsSystem.Runtime的引用添加到动态生成的项目中。当您使用项目模板中的辅助代码时,在单元测试中没有方便的方法来实现这一点。但是要测试它,您可以更改CreateProject方法。

默认情况下,配置了4个其他引用。添加缺失的引用:

代码语言:javascript
运行
复制
var collectionsReference = MetadataReference.CreateFromFile(typeof(Stack<>).Assembly.Location);
var runtimeReference = MetadataReference.CreateFromFile(typeof(ISet<>).Assembly.Location);

var solution = new AdhocWorkspace()
    .CurrentSolution
    .AddProject(projectId, TestProjectName, TestProjectName, language)
    .AddMetadataReference() //...
    // ...extend the AddMetadataReference chain
    .AddMetadataReference(projectId, collectionsReference)
    .AddMetadataReference(projectId, runtimeReference);

然后,您应该能够在单元测试中编译代码并获得有效的语义模型。

您可能愿意实现该动态引用功能,例如,将正在创建的项目对象公开给单元测试调用者。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53917675

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档