static void AnalyzeAsyncMethod(
            [NotNull] IHighlightingConsumer consumer,
            [NotNull] NullnessProvider nullnessProvider,
            [NotNull] IAttributesOwnerDeclaration attributesOwnerDeclaration)
        {
            foreach (var attributeMark in GetAttributeMarks(nullnessProvider, attributesOwnerDeclaration))
            {
                if (attributeMark != null)
                {
                    switch (attributeMark.AnnotationNullableValue)
                    {
                    case CodeAnnotationNullableValue.NOT_NULL:
                        consumer.AddHighlighting(
                            new RedundantAnnotationHighlighting(
                                attributesOwnerDeclaration,
                                attributeMark.Attribute,
                                "Annotation is redundant because the declared element can never be null by default."));
                        break;

                    case CodeAnnotationNullableValue.CAN_BE_NULL:
                        consumer.AddHighlighting(
                            new NotAllowedAnnotationHighlighting(
                                attributesOwnerDeclaration,
                                attributeMark.Attribute,
                                "Annotation is not valid because the declared element can never be null by default."));
                        break;
                    }
                }
            }
        }
Exemple #2
0
        static CSharpControlFlowNullReferenceState GetExpressionNullReferenceState(
            [NotNull] NullnessProvider nullnessProvider,
            [NotNull] CSharpControlFlowGraphInspector inspector,
            [NotNull] HashSet <IAsExpression> alwaysSuccessTryCastExpressions,
            ICSharpExpression expression)
        {
            switch (expression)
            {
            case IReferenceExpression referenceExpression:
                var nullReferenceState = inspector.GetExpressionNullReferenceState(referenceExpression, true);

                if (nullReferenceState == CSharpControlFlowNullReferenceState.UNKNOWN)
                {
                    return(GetExpressionNullReferenceStateByAnnotations(nullnessProvider, referenceExpression));
                }

                return(nullReferenceState);

            case IAsExpression asExpression when alwaysSuccessTryCastExpressions.Contains(asExpression):
                return(CSharpControlFlowNullReferenceState.NOT_NULL);

            case IObjectCreationExpression _: return(CSharpControlFlowNullReferenceState.NOT_NULL);

            case IInvocationExpression invocationExpression:
                if (invocationExpression.InvokedExpression is IReferenceExpression invokedExpression)
                {
                    return(GetExpressionNullReferenceStateByAnnotations(nullnessProvider, invokedExpression));
                }

                goto default;

            default: return(CSharpControlFlowNullReferenceState.UNKNOWN);
            }
        }
        public AnnotationAnalyzer(
            [NotNull] CodeAnnotationsCache codeAnnotationsCache,
            [NotNull] CodeAnnotationsConfiguration codeAnnotationsConfiguration)
        {
            nullnessProvider = codeAnnotationsCache.GetProvider <NullnessProvider>();
            containerElementNullnessProvider = codeAnnotationsCache.GetProvider <ContainerElementNullnessProvider>();

            this.codeAnnotationsConfiguration = codeAnnotationsConfiguration;
        }
Exemple #4
0
        static void AnalyzeWhenExpressionIsKnownToBeNullOrNotNull(
            [NotNull] IHighlightingConsumer context,
            [NotNull] NullnessProvider nullnessProvider,
            [NotNull] CSharpControlFlowGraphInspector inspector,
            [NotNull] HashSet <IAsExpression> alwaysSuccessTryCastExpressions,
            [NotNull] Assertion assertion,
            bool isKnownToBeNull)
        {
            if (assertion is AssertionStatement assertionStatement)
            {
                // pattern: Assert(null);
                Debug.Assert(CSharpTokenType.NULL_KEYWORD != null);
                if (isKnownToBeNull && IsLiteral(assertionStatement.Expression, CSharpTokenType.NULL_KEYWORD))
                {
                    context.AddHighlighting(
                        new RedundantAssertionStatementHighlighting(
                            "Assertion is redundant because the expression is always null.",
                            assertionStatement));
                }

                // pattern: Assert(x); when x is known to be null or not null
                switch (GetExpressionNullReferenceState(nullnessProvider, inspector, alwaysSuccessTryCastExpressions, assertionStatement.Expression))
                {
                case CSharpControlFlowNullReferenceState.NOT_NULL:
                    if (!isKnownToBeNull)
                    {
                        context.AddHighlighting(
                            new RedundantAssertionStatementHighlighting(
                                "Assertion is redundant because the expression is never null.",
                                assertionStatement));
                    }
                    break;

                case CSharpControlFlowNullReferenceState.NULL:
                    if (isKnownToBeNull)
                    {
                        context.AddHighlighting(
                            new RedundantAssertionStatementHighlighting(
                                "Assertion is redundant because the expression is always null.",
                                assertionStatement));
                    }
                    break;
                }
            }

            if (!isKnownToBeNull &&
                assertion is InlineAssertion inlineAssertion &&
                GetExpressionNullReferenceState(nullnessProvider, inspector, alwaysSuccessTryCastExpressions, inlineAssertion.QualifierExpression) ==
                CSharpControlFlowNullReferenceState.NOT_NULL)
            {
                context.AddHighlighting(
                    new RedundantInlineAssertionHighlighting("Assertion is redundant because the expression is never null.", inlineAssertion));
            }
        }
Exemple #5
0
        public ImplicitNullabilityProblemAnalyzer(
            CodeAnnotationAttributesChecker annotationAttributesChecker,
            CodeAnnotationsCache codeAnnotationsCache,
            ImplicitNullabilityProvider implicitNullabilityProvider)
        {
            _annotationAttributesChecker      = annotationAttributesChecker;
            _nullnessProvider                 = codeAnnotationsCache.GetProvider <NullnessProvider>();
            _containerElementNullnessProvider = codeAnnotationsCache.GetProvider <ContainerElementNullnessProvider>();
            _implicitNullabilityProvider      = implicitNullabilityProvider;

            _incorrectNullableAttributeUsageAnalyzer = new IncorrectNullableAttributeUsageAnalyzer(codeAnnotationsCache);
        }
        static void AnalyzeOther(
            ValueAnalysisMode valueAnalysisMode,
            [NotNull] IHighlightingConsumer consumer,
            [NotNull] NullnessProvider nullnessProvider,
            [NotNull] CodeAnnotationsConfiguration codeAnnotationsConfiguration,
            [NotNull] IAttributesOwnerDeclaration attributesOwnerDeclaration)
        {
            switch (valueAnalysisMode)
            {
            case ValueAnalysisMode.OPTIMISTIC:
                foreach (var attributeMark in GetAttributeMarks(nullnessProvider, attributesOwnerDeclaration))
                {
                    if (attributeMark == null)
                    {
                        var nonNullAnnotationAttributeType = codeAnnotationsConfiguration.GetAttributeTypeForElement(
                            attributesOwnerDeclaration,
                            NullnessProvider.NotNullAttributeShortName);
                        var canBeNullAnnotationAttributeType = codeAnnotationsConfiguration.GetAttributeTypeForElement(
                            attributesOwnerDeclaration,
                            NullnessProvider.CanBeNullAttributeShortName);
                        if (nonNullAnnotationAttributeType != null || canBeNullAnnotationAttributeType != null)
                        {
                            consumer.AddHighlighting(
                                new MissingAnnotationHighlighting(
                                    string.Format(
                                        @"Declared element is nullable, but is not annotated with '{0}' or '{1}'.",
                                        NullnessProvider.NotNullAttributeShortName,
                                        NullnessProvider.CanBeNullAttributeShortName),
                                    attributesOwnerDeclaration));
                        }
                        break;
                    }
                }
                break;

            case ValueAnalysisMode.PESSIMISTIC:
                foreach (var attributeMark in GetAttributeMarks(nullnessProvider, attributesOwnerDeclaration))
                {
                    if (attributeMark != null && attributeMark.AnnotationNullableValue == CodeAnnotationNullableValue.CAN_BE_NULL)
                    {
                        consumer.AddHighlighting(
                            new RedundantAnnotationHighlighting(
                                attributesOwnerDeclaration,
                                attributeMark.Attribute,
                                "Annotation is redundant because the declared element can be null by default."));
                    }
                }
                break;
            }
        }
 static void AnalyzeOverride(
     [NotNull] IHighlightingConsumer consumer,
     [NotNull] NullnessProvider nullnessProvider,
     [NotNull] IAttributesOwnerDeclaration attributesOwnerDeclaration)
 {
     foreach (var attributeMark in GetAttributeMarks(nullnessProvider, attributesOwnerDeclaration))
     {
         if (attributeMark != null)
         {
             consumer.AddHighlighting(
                 new NotAllowedAnnotationHighlighting(
                     attributesOwnerDeclaration,
                     attributeMark.Attribute,
                     "Annotation is not allowed because the declared element overrides or implements the inherited member."));
         }
     }
 }
Exemple #8
0
        static CSharpControlFlowNullReferenceState GetExpressionNullReferenceStateByAnnotations(
            [NotNull] NullnessProvider nullnessProvider,
            [NotNull] IReferenceExpression referenceExpression)
        {
            switch (referenceExpression.Reference.Resolve().DeclaredElement)
            {
            case IFunction function when nullnessProvider.GetInfo(function) == CodeAnnotationNullableValue.NOT_NULL:
                return(CSharpControlFlowNullReferenceState.NOT_NULL);

            case ITypeOwner typeOwner when !typeOwner.Type.IsDelegateType():
                if (typeOwner is IAttributesOwner attributesOwner &&
                    nullnessProvider.GetInfo(attributesOwner) == CodeAnnotationNullableValue.NOT_NULL)
                {
                    return(CSharpControlFlowNullReferenceState.NOT_NULL);
                }

                goto default;

            default: return(CSharpControlFlowNullReferenceState.UNKNOWN);
            }
        }
 static void AnalyzeIteratorMethod(
     [NotNull] IHighlightingConsumer consumer,
     [NotNull] IAttributesOwnerDeclaration attributesOwnerDeclaration,
     [NotNull] NullnessProvider nullnessProvider,
     [NotNull] CodeAnnotationsConfiguration codeAnnotationsConfiguration)
 {
     foreach (var attributeMark in GetAttributeMarks(nullnessProvider, attributesOwnerDeclaration))
     {
         if (attributeMark != null)
         {
             if (attributeMark.AnnotationNullableValue == CodeAnnotationNullableValue.CAN_BE_NULL)
             {
                 consumer.AddHighlighting(
                     new NotAllowedAnnotationHighlighting(
                         attributesOwnerDeclaration,
                         attributeMark.Attribute,
                         "Annotation is not valid because the declared element can never be null by default."));
             }
         }
         else
         {
             var nonNullAnnotationAttributeType = codeAnnotationsConfiguration.GetAttributeTypeForElement(
                 attributesOwnerDeclaration,
                 NullnessProvider.NotNullAttributeShortName);
             if (nonNullAnnotationAttributeType != null)
             {
                 consumer.AddHighlighting(
                     new MissingAnnotationHighlighting(
                         string.Format(
                             "Declared element can never be null by default, but is not annotated with '{0}'.",
                             NullnessProvider.NotNullAttributeShortName),
                         attributesOwnerDeclaration));
             }
             break;
         }
     }
 }
        static IEnumerable <AttributeMark> GetAttributeMarks(
            [NotNull] NullnessProvider nullnessProvider,
            [NotNull] IAttributesOwnerDeclaration declaration)
        {
            var markFound = false;

            foreach (var attribute in declaration.AttributesEnumerable)
            {
                Debug.Assert(attribute != null);

                var mark = nullnessProvider.GetNullableAttributeMark(attribute.GetAttributeInstance());
                if (mark != null)
                {
                    yield return(new AttributeMark((CodeAnnotationNullableValue)mark, attribute));

                    markFound = true;
                }
            }

            if (!markFound)
            {
                yield return(null);
            }
        }
 public TypeHighlightingProblemAnalyzer(CodeAnnotationsCache codeAnnotationsCache)
 {
     _nullnessProvider = codeAnnotationsCache.GetProvider <NullnessProvider>();
     _containerElementNullnessProvider = codeAnnotationsCache.GetProvider <ContainerElementNullnessProvider>();
 }
Exemple #12
0
        static void AnalyzeWhenExpressionIsKnownToBeTrueOrFalse(
            [NotNull] IHighlightingConsumer context,
            [NotNull] NullnessProvider nullnessProvider,
            [NotNull] CSharpControlFlowGraphInspector inspector,
            [NotNull] HashSet <IAsExpression> alwaysSuccessTryCastExpressions,
            [NotNull] Assertion assertion,
            bool isKnownToBeTrue)
        {
            if (assertion is AssertionStatement assertionStatement)
            {
                // pattern: Assert(true); or Assert(false);
                Debug.Assert(CSharpTokenType.TRUE_KEYWORD != null);
                Debug.Assert(CSharpTokenType.FALSE_KEYWORD != null);
                if (IsLiteral(assertionStatement.Expression, isKnownToBeTrue ? CSharpTokenType.TRUE_KEYWORD : CSharpTokenType.FALSE_KEYWORD))
                {
                    context.AddHighlighting(
                        new RedundantAssertionStatementHighlighting(
                            $"Assertion is redundant because the expression is always {(isKnownToBeTrue ? "true" : "false")}.",
                            assertionStatement));
                }

                if (assertionStatement.Expression is IEqualityExpression equalityExpression)
                {
                    // pattern: Assert(x != null); when x is known to be null or not null
                    Debug.Assert(CSharpTokenType.NULL_KEYWORD != null);
                    var expression = TryGetOtherOperand(equalityExpression, EqualityExpressionType.NE, CSharpTokenType.NULL_KEYWORD);
                    if (expression != null)
                    {
                        switch (GetExpressionNullReferenceState(nullnessProvider, inspector, alwaysSuccessTryCastExpressions, expression))
                        {
                        case CSharpControlFlowNullReferenceState.NOT_NULL:
                            if (isKnownToBeTrue)
                            {
                                context.AddHighlighting(
                                    new RedundantAssertionStatementHighlighting(
                                        "Assertion is redundant because the expression is always true.",
                                        assertionStatement));
                            }
                            break;

                        case CSharpControlFlowNullReferenceState.NULL:
                            if (!isKnownToBeTrue)
                            {
                                context.AddHighlighting(
                                    new RedundantAssertionStatementHighlighting(
                                        "Assertion is redundant because the expression is always false.",
                                        assertionStatement));
                            }
                            break;
                        }
                    }

                    // pattern: Assert(x == null); when x is known to be null or not null
                    expression = TryGetOtherOperand(equalityExpression, EqualityExpressionType.EQEQ, CSharpTokenType.NULL_KEYWORD);
                    if (expression != null)
                    {
                        switch (GetExpressionNullReferenceState(nullnessProvider, inspector, alwaysSuccessTryCastExpressions, expression))
                        {
                        case CSharpControlFlowNullReferenceState.NOT_NULL:
                            if (!isKnownToBeTrue)
                            {
                                context.AddHighlighting(
                                    new RedundantAssertionStatementHighlighting(
                                        "Assertion is redundant because the expression is always false.",
                                        assertionStatement));
                            }
                            break;

                        case CSharpControlFlowNullReferenceState.NULL:
                            if (isKnownToBeTrue)
                            {
                                context.AddHighlighting(
                                    new RedundantAssertionStatementHighlighting(
                                        "Assertion is redundant because the expression is always true.",
                                        assertionStatement));
                            }
                            break;
                        }
                    }
                }
            }
        }
 public ControlFlowAnalyzer([NotNull] CodeAnnotationsCache codeAnnotationsCache)
 {
     nullnessProvider = codeAnnotationsCache.GetProvider <NullnessProvider>();
     assertionMethodAnnotationProvider    = codeAnnotationsCache.GetProvider <AssertionMethodAnnotationProvider>();
     assertionConditionAnnotationProvider = codeAnnotationsCache.GetProvider <AssertionConditionAnnotationProvider>();
 }