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; } } } }
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; }
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)); } }
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.")); } } }
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>(); }
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>(); }