public void Inherited() { var syntaxTree = CSharpSyntaxTree.ParseText( @" namespace RoslynSandbox { public class Foo { protected int Bar; } public class Bar : Foo { public Bar() { var temp = this.Bar; } } }"); var compilation = CSharpCompilation.Create("test", new[] { syntaxTree }); var semanticModel = compilation.GetSemanticModel(syntaxTree); var node1 = syntaxTree.FindFieldDeclaration("Bar"); var symbol1 = semanticModel.GetDeclaredSymbol(node1.Declaration.Variables[0], CancellationToken.None); var node2 = syntaxTree.FindMemberAccessExpression("this.Bar"); var symbol2 = semanticModel.GetSymbolInfo(node2, CancellationToken.None).Symbol; Assert.AreEqual(true, SymbolComparer.Equals(symbol1, symbol1)); Assert.AreEqual(true, SymbolComparer.Equals(symbol1, symbol2)); Assert.AreEqual(true, FieldSymbolComparer.Equals((IFieldSymbol)symbol1, (IFieldSymbol)symbol1)); Assert.AreEqual(true, FieldSymbolComparer.Equals((IFieldSymbol)symbol1, (IFieldSymbol)symbol2)); Assert.AreEqual(SymbolComparer.Default.GetHashCode(symbol1), FieldSymbolComparer.Default.GetHashCode((IFieldSymbol)symbol1)); Assert.AreEqual(SymbolComparer.Default.GetHashCode(symbol1), FieldSymbolComparer.Default.GetHashCode((IFieldSymbol)symbol2)); }
public void Equals() { var syntaxTree = CSharpSyntaxTree.ParseText( @" namespace RoslynSandbox { public class Foo { private int bar1; private int bar2; } }"); var compilation = CSharpCompilation.Create("test", new[] { syntaxTree }); var semanticModel = compilation.GetSemanticModel(syntaxTree); var node1 = syntaxTree.FindFieldDeclaration("bar1"); var symbol1 = semanticModel.GetDeclaredSymbol(node1.Declaration.Variables[0], CancellationToken.None); var node2 = syntaxTree.FindFieldDeclaration("bar2"); var symbol2 = semanticModel.GetDeclaredSymbol(node2.Declaration.Variables[0], CancellationToken.None); Assert.AreEqual(true, SymbolComparer.Equals(symbol1, symbol1)); Assert.AreEqual(false, SymbolComparer.Equals(symbol1, symbol2)); Assert.AreEqual(true, FieldSymbolComparer.Equals((IFieldSymbol)symbol1, (IFieldSymbol)symbol1)); Assert.AreEqual(false, FieldSymbolComparer.Equals((IFieldSymbol)symbol1, (IFieldSymbol)symbol2)); Assert.AreEqual(SymbolComparer.Default.GetHashCode(symbol1), FieldSymbolComparer.Default.GetHashCode((IFieldSymbol)symbol1)); Assert.AreNotEqual(SymbolComparer.Default.GetHashCode(symbol1), FieldSymbolComparer.Default.GetHashCode((IFieldSymbol)symbol2)); }
internal static bool TryGetConversionTypes(ClassDeclarationSyntax classDeclaration, SemanticModel semanticModel, CancellationToken cancellationToken, out ITypeSymbol sourceType, out ITypeSymbol targetType) { sourceType = null; targetType = null; if (classDeclaration.TryFindMethod("Convert", out var convertMethod) && convertMethod.ReturnType is PredefinedTypeSyntax returnType && returnType.Keyword.ValueText == "object" && convertMethod.ParameterList != null && convertMethod.ParameterList.Parameters.Count == 4 && convertMethod.ParameterList.Parameters.TryFirst(out var valueParameter)) { using (var returnValues = ReturnValueWalker.Borrow(convertMethod)) { using (var returnTypes = PooledSet <ITypeSymbol> .Borrow()) { foreach (var returnValue in returnValues.ReturnValues) { AddReturnType(returnTypes, returnValue); } return(returnTypes.TrySingle(out targetType) && ConversionWalker.TryGetCommonBase( convertMethod, semanticModel.GetDeclaredSymbolSafe(valueParameter, cancellationToken), semanticModel, cancellationToken, out sourceType)); } } } return(false); void AddReturnType(PooledSet <ITypeSymbol> returnTypes, ExpressionSyntax returnValue) { switch (returnValue) { case LiteralExpressionSyntax literal when literal.IsKind(SyntaxKind.NullLiteralExpression): break; case ConditionalExpressionSyntax ternary: AddReturnType(returnTypes, ternary.WhenTrue); AddReturnType(returnTypes, ternary.WhenFalse); break; case BinaryExpressionSyntax coalesce when coalesce.IsKind(SyntaxKind.CoalesceExpression): AddReturnType(returnTypes, coalesce.Left); AddReturnType(returnTypes, coalesce.Right); break; case IdentifierNameSyntax _: case MemberAccessExpressionSyntax _: var type = semanticModel.GetTypeInfoSafe(returnValue, cancellationToken).Type; if (type == KnownSymbol.Object && semanticModel.GetSymbolSafe(returnValue, cancellationToken) is ISymbol symbol && symbol.IsEither <IFieldSymbol, IPropertySymbol>()) { switch (symbol) { case IFieldSymbol field: if (field.Type == KnownSymbol.Object && field.DeclaredAccessibility == Accessibility.Private && returnValue.FirstAncestor <TypeDeclarationSyntax>() is TypeDeclarationSyntax typeDeclaration) { using (var walker = AssignmentExecutionWalker.Borrow(typeDeclaration, Scope.Instance, semanticModel, cancellationToken)) { foreach (var assignment in walker.Assignments) { if (semanticModel.TryGetSymbol(assignment.Left, cancellationToken, out IFieldSymbol assigned) && FieldSymbolComparer.Equals(assigned, field)) { returnTypes.Add(semanticModel.GetTypeInfoSafe(assignment.Right, cancellationToken).Type); } } } } else { returnTypes.Add(field.Type); } return; case IPropertySymbol property: returnTypes.Add(property.Type); return; } } else { returnTypes.Add(type); } break;