Example #1
0
        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));
        }
Example #2
0
        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));
        }
Example #3
0
        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;