I am trying to reliably compare two instances of ITypeSymbol with the simplest and most direct way in the following situation (I ran into these problems in a larger project and tried to simplify it as much as possible):
I have CSharpCompilation with this SyntaxTree:
namespace MyAssembly { public class Foo { public Foo(Foo x) { } } }
We walk the tree with CSharpSyntaxRewriter , change the class, and update Compilation . In the first run, we remember ITypeSymbol first constructor parameter (which is the type of the class itself in this case). After updating the compilation, we again call the same rewriting element and again get ITypeSymbol from the constructor parameter. After that, I compare two ITypeSymbols, which I assume are the same type of MyAssembly.Foo .
My first comparison method simply called the ITypeSymbol.Equals() method, but returned it false . It basically returns false because we changed the compilation and got a new SemanticModel in the meantime. If we do not, the Equals () method does return true.
Comparing DeclaringSyntaxReferences (as indicated here How to compare characters of type (ITypeSymbol) from different projects in Roslyn? ) Returns false because we changed the Foo class in this way. The behavior will be the same if the constructor parameter is of type Bar , and we rewrote Bar . To make sure of this, just uncomment the line
and replace the constructor parameter type with Bar in the sample code.
Conclusion: ITypeSymbol.Equals() does not work with the new compilation and semantic model, and the DeclaringSyntaxReferences comparison DeclaringSyntaxReferences not work with the type that we changed during this time. (I also tested the behavior with the type of the external assembly - in this case ITypeSymbol.Equals () worked for me.
So my questions are:
- What is the intended way to compare types in the described situation?
- Is there any single catch solution or still mix / combine different approaches to determining type equality (possibly also taking a string representation of the full name)
This is a complete test program with which the problem reproduces for me. Just copy, enable Roslyn links and do:
using System; using System.Collections.Generic; using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Demo.TypeSymbol { class Program { static void Main(string[] args) { var compilation = (CSharpCompilation) GetTestCompilation(); var rewriter = new Rewriter(changeSomething: true); var tree = compilation.SyntaxTrees.First();
Merrit
source share