c# - 在 Roslyn 如何找出两个符号是等价的?
问题描述
假设我创建了两个Compilation
对象,都用相同的 初始化SyntaxTree
,获得了两个SemanticModel
对象并使用每个对象来获得同一个声明的符号。
这是完整的单元测试。
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using NUnit.Framework;
using System.Linq;
namespace CSTool.UnitTests
{
public class RoslynScratch
{
private const string CODE = @"namespace N
{
public class T
{
}
}";
[Test]
public void SameSymbols()
{
var syntaxTree = CSharpSyntaxTree.ParseText(CODE);
var node = syntaxTree.GetCompilationUnitRoot().DescendantNodes().OfType<TypeDeclarationSyntax>().FirstOrDefault();
Assert.IsNotNull(node);
var s1 = GetDeclSymbol(node);
var s2 = GetDeclSymbol(node);
Assert.IsFalse(SymbolEqualityComparer.Default.Equals(s1, s2));
Assert.IsNotNull(GetDeclNode(s1));
Assert.AreEqual(GetDeclNode(s1), GetDeclNode(s2));
}
private static SyntaxNode GetDeclNode(ISymbol s) => s.DeclaringSyntaxReferences.FirstOrDefault().GetSyntax();
private static ISymbol GetDeclSymbol(TypeDeclarationSyntax node)
{
var compilation = CSharpCompilation.Create("test", new[] { node.SyntaxTree });
var model = compilation.GetSemanticModel(node.SyntaxTree);
return model.GetDeclaredSymbol(node);
}
}
}
注意这两个符号不相等,但我们可以得到它们各自的声明,因为这两个符号都与同一个SyntaxTree
对象相关联,我们可以确定它们是等价的。
如果语法树不同,但代码相同,如何确定这些符号是等价的?
编辑 1
我稍微修改了这个问题 - 如果语法树不同,我正在寻找建立等效性的方法,但是两种树的源代码完全相同。
编辑 2
我刚刚意识到,如果源代码相同,那么我们可以不比较节点:
SyntaxNode
比较与符号关联的各个对象的跨度。- 如果相等,则比较
SourceText
与语法树关联的两个对象
我想知道是否有更好的方法。
解决方案
IsEquivalentTo (...)方法可用于比较两个 trees
、或nodes
的相等性。例如tokens
trivias
var syntaxTree1 = CSharpSyntaxTree.ParseText(CODE);
var syntaxTree2 = CSharpSyntaxTree.ParseText(CODE);
Assert.IsTrue(syntaxTree1.IsEquivalentTo(syntaxTree2));
推荐阅读
- python - 如果文件与给定的文件名匹配,如何打开文件(使用语音识别获得的文件名)
- go - 在 Go Gorm 中添加具有多对多反向引用的记录
- python-3.x - Jupyter Notebook:终端不可用
- angular - 如何在 Angular 9 组件单元测试中调用假函数
- uart - UART 使能后 PIC18F67K22 TX 引脚为低电平
- xamarin.forms - MVVMCross 如何在 View Code 后面获取 ViewModel 实例
- javascript - 如何修复d3中的多画笔图表
- angular - 移除 Angular Material 切换按钮焦点样式
- java - Selenium Java 元素不可交互
- javascript - 将背景图像设置为画布并使用文本+图像将其导出