Roslyn 的完全限定命名空间元数据错误
Fully Qualified Namespace Metadata Error with Roslyn
我正在尝试制作一个代码分析器来检查完全合格的 using 语句。这个 link 非常有用,是我的解决方案 () 的基础,但是当我尝试访问 using 指令的符号位置时,我 运行 遇到了问题。我的代码如下所示:
private static void AnalyzeModel(SemanticModelAnalysisContext semanticModelAnalysisContext)
{
var semanticModel = semanticModelAnalysisContext.SemanticModel;
var root = semanticModel.SyntaxTree.GetRoot();
// compare each using statement's name with its fully qualified name
foreach (var usingDirective in root.DescendantNodes().OfType<UsingDirectiveSyntax>())
{
var symbol = semanticModel.GetSymbolInfo(usingDirective.Name).Symbol;
var fullyQualifiedName = symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
if (fullyQualifiedName.Contains(GlobalTag))
{
fullyQualifiedName = fullyQualifiedName.Substring(GlobalTag.Length);
}
if (usingDirective.Name.ToString() != fullyQualifiedName)
{
// for each name that is not fully qualified, produce a diagnostic.
var diagnostic = Diagnostic.Create(Rule, symbol.Locations[0], symbol.Name);
semanticModelAnalysisContext.ReportDiagnostic(diagnostic);
}
}
}
问题是 symbol.Locations[0]
仅包含元数据中的项目,而不包含源中的项目。这会导致以下错误:
Assert.IsTrue failed. Test base does not currently handle diagnostics in metadata locations.
我的单元测试源代码如下所示:
private const string incorrectSourceCode = @"
namespace System
{
using IO;
using Threading;
}";
为什么 symbol.Locations
中没有源代码中的项目?还有其他地方我可以得到这个位置吗?我试过使用 symbol.ContainingSymbol.Locations[0]
或 symbol.ContainingNamespace.Locations[0]
,但这些并不是指我感兴趣的使用特定用途。我已经为此苦苦思索了几个小时,有些清晰度会不胜感激。
提前致谢!
Symbol
包含 MetadateLocation
,因此如果您想查看 SourceLocation
,只需从相应的 SyntaxNode
:
中检索它
var diagnostic = Diagnostic.Create(Rule, usingDirective.Name.GetLocation(), symbol.Name)
而不是
var diagnostic = Diagnostic.Create(Rule, symbol.Locations[0], symbol.Name)
我正在尝试制作一个代码分析器来检查完全合格的 using 语句。这个 link 非常有用,是我的解决方案 (
private static void AnalyzeModel(SemanticModelAnalysisContext semanticModelAnalysisContext)
{
var semanticModel = semanticModelAnalysisContext.SemanticModel;
var root = semanticModel.SyntaxTree.GetRoot();
// compare each using statement's name with its fully qualified name
foreach (var usingDirective in root.DescendantNodes().OfType<UsingDirectiveSyntax>())
{
var symbol = semanticModel.GetSymbolInfo(usingDirective.Name).Symbol;
var fullyQualifiedName = symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
if (fullyQualifiedName.Contains(GlobalTag))
{
fullyQualifiedName = fullyQualifiedName.Substring(GlobalTag.Length);
}
if (usingDirective.Name.ToString() != fullyQualifiedName)
{
// for each name that is not fully qualified, produce a diagnostic.
var diagnostic = Diagnostic.Create(Rule, symbol.Locations[0], symbol.Name);
semanticModelAnalysisContext.ReportDiagnostic(diagnostic);
}
}
}
问题是 symbol.Locations[0]
仅包含元数据中的项目,而不包含源中的项目。这会导致以下错误:
Assert.IsTrue failed. Test base does not currently handle diagnostics in metadata locations.
我的单元测试源代码如下所示:
private const string incorrectSourceCode = @"
namespace System
{
using IO;
using Threading;
}";
为什么 symbol.Locations
中没有源代码中的项目?还有其他地方我可以得到这个位置吗?我试过使用 symbol.ContainingSymbol.Locations[0]
或 symbol.ContainingNamespace.Locations[0]
,但这些并不是指我感兴趣的使用特定用途。我已经为此苦苦思索了几个小时,有些清晰度会不胜感激。
提前致谢!
Symbol
包含 MetadateLocation
,因此如果您想查看 SourceLocation
,只需从相应的 SyntaxNode
:
var diagnostic = Diagnostic.Create(Rule, usingDirective.Name.GetLocation(), symbol.Name)
而不是
var diagnostic = Diagnostic.Create(Rule, symbol.Locations[0], symbol.Name)