Example #1
0
        private static NullCheckExpressionInfo Create(
            BinaryExpressionSyntax binaryExpression,
            SyntaxKind binaryExpressionKind,
            ExpressionSyntax expression1,
            ExpressionSyntax expression2,
            NullCheckKind allowedKinds,
            bool allowMissing,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            switch (expression1.Kind())
            {
            case SyntaxKind.NullLiteralExpression:
            {
                NullCheckKind kind = (binaryExpressionKind == SyntaxKind.EqualsExpression) ? NullCheckKind.EqualsToNull : NullCheckKind.NotEqualsToNull;

                if ((allowedKinds & kind) == 0)
                {
                    break;
                }

                return(new NullCheckExpressionInfo(
                           binaryExpression,
                           expression2,
                           kind));
            }

            case SyntaxKind.TrueLiteralExpression:
            {
                NullCheckKind kind = (binaryExpressionKind == SyntaxKind.EqualsExpression) ? NullCheckKind.HasValue : NullCheckKind.NotHasValue;

                return(Create(
                           binaryExpression,
                           expression2,
                           kind,
                           allowedKinds,
                           allowMissing,
                           semanticModel,
                           cancellationToken));
            }

            case SyntaxKind.FalseLiteralExpression:
            {
                NullCheckKind kind = (binaryExpressionKind == SyntaxKind.EqualsExpression) ? NullCheckKind.NotHasValue : NullCheckKind.HasValue;

                return(Create(
                           binaryExpression,
                           expression2,
                           kind,
                           allowedKinds,
                           allowMissing,
                           semanticModel,
                           cancellationToken));
            }
            }

            return(Default);
        }
 public NullCheckExpression(
     ExpressionSyntax containingNode,
     ExpressionSyntax expression,
     NullCheckKind kind)
 {
     ContainingNode = containingNode;
     Expression     = expression;
     Kind           = kind;
 }
Example #3
0
 private NullCheckExpressionInfo(
     ExpressionSyntax containingExpression,
     ExpressionSyntax expression,
     NullCheckKind kind)
 {
     ContainingExpression = containingExpression;
     Expression           = expression;
     Kind = kind;
 }
Example #4
0
 public static NullCheckExpressionInfo NullCheckExpressionInfo(
     SyntaxNode node,
     NullCheckKind allowedKinds          = NullCheckKind.All,
     bool walkDownParentheses            = true,
     bool allowMissing                   = false,
     SemanticModel semanticModel         = null,
     CancellationToken cancellationToken = default(CancellationToken))
 {
     return(Syntax.NullCheckExpressionInfo.Create(
                node,
                allowedKinds,
                walkDownParentheses,
                allowMissing,
                semanticModel,
                cancellationToken));
 }
Example #5
0
        private static NullCheckExpressionInfo Create(
            BinaryExpressionSyntax binaryExpression,
            ExpressionSyntax expression,
            NullCheckKind kind,
            NullCheckKind allowedKinds,
            bool allowMissing,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            if ((allowedKinds & (NullCheckKind.HasValueProperty)) == 0)
            {
                return(Default);
            }

            if (!(expression is MemberAccessExpressionSyntax memberAccessExpression))
            {
                return(Default);
            }

            if (memberAccessExpression.Kind() != SyntaxKind.SimpleMemberAccessExpression)
            {
                return(Default);
            }

            if (!IsPropertyOfNullableOfT(memberAccessExpression.Name, "HasValue", semanticModel, cancellationToken))
            {
                return(Default);
            }

            if ((allowedKinds & kind) == 0)
            {
                return(Default);
            }

            ExpressionSyntax expression2 = memberAccessExpression.Expression;

            if (!Check(expression2, allowMissing))
            {
                return(Default);
            }

            return(new NullCheckExpressionInfo(binaryExpression, expression2, kind));
        }
Example #6
0
        private static void Analyze(SyntaxNodeAnalysisContext context, BinaryExpressionSyntax binaryExpression, NullCheckKind allowedKinds)
        {
            NullCheckExpressionInfo nullCheck = SyntaxInfo.NullCheckExpressionInfo(binaryExpression, allowedKinds: allowedKinds);

            if (nullCheck.Success &&
                IsUnconstrainedTypeParameter(context.SemanticModel.GetTypeSymbol(nullCheck.Expression, context.CancellationToken)) &&
                !binaryExpression.SpanContainsDirectives())
            {
                context.ReportDiagnostic(DiagnosticDescriptors.UnconstrainedTypeParameterCheckedForNull, binaryExpression);
            }
        }
Example #7
0
        internal static NullCheckExpressionInfo Create(
            SyntaxNode node,
            NullCheckKind allowedKinds          = NullCheckKind.All,
            bool walkDownParentheses            = true,
            bool allowMissing                   = false,
            SemanticModel semanticModel         = null,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            if (semanticModel == null &&
                (allowedKinds & NullCheckKind.HasValueProperty) != 0)
            {
                return(Default);
            }

            ExpressionSyntax expression = WalkAndCheck(node, allowMissing, walkDownParentheses);

            if (expression == null)
            {
                return(Default);
            }

            SyntaxKind kind = expression.Kind();

            switch (kind)
            {
            case SyntaxKind.EqualsExpression:
            case SyntaxKind.NotEqualsExpression:
            {
                var binaryExpression = (BinaryExpressionSyntax)expression;

                ExpressionSyntax left = WalkAndCheck(binaryExpression.Left, allowMissing, walkDownParentheses);

                if (left == null)
                {
                    break;
                }

                ExpressionSyntax right = WalkAndCheck(binaryExpression.Right, allowMissing, walkDownParentheses);

                if (right == null)
                {
                    break;
                }

                NullCheckExpressionInfo info = Create(binaryExpression, kind, left, right, allowedKinds, allowMissing, semanticModel, cancellationToken);

                if (info.Success)
                {
                    return(info);
                }
                else
                {
                    return(Create(binaryExpression, kind, right, left, allowedKinds, allowMissing, semanticModel, cancellationToken));
                }
            }

            case SyntaxKind.SimpleMemberAccessExpression:
            {
                if ((allowedKinds & NullCheckKind.HasValue) == 0)
                {
                    break;
                }

                var memberAccessExpression = (MemberAccessExpressionSyntax)expression;

                if (!IsPropertyOfNullableOfT(memberAccessExpression.Name, "HasValue", semanticModel, cancellationToken))
                {
                    break;
                }

                return(new NullCheckExpressionInfo(expression, memberAccessExpression.Expression, NullCheckKind.HasValue));
            }

            case SyntaxKind.LogicalNotExpression:
            {
                if ((allowedKinds & NullCheckKind.NotHasValue) == 0)
                {
                    break;
                }

                var logicalNotExpression = (PrefixUnaryExpressionSyntax)expression;

                ExpressionSyntax operand = WalkAndCheck(logicalNotExpression.Operand, allowMissing, walkDownParentheses);

                if (!(operand is MemberAccessExpressionSyntax memberAccessExpression))
                {
                    break;
                }

                if (memberAccessExpression.Kind() != SyntaxKind.SimpleMemberAccessExpression)
                {
                    break;
                }

                if (!IsPropertyOfNullableOfT(memberAccessExpression.Name, "HasValue", semanticModel, cancellationToken))
                {
                    break;
                }

                return(new NullCheckExpressionInfo(expression, memberAccessExpression.Expression, NullCheckKind.NotHasValue));
            }
            }

            return(Default);
        }