public override NullAbstractValue VisitConditionalAccess(IConditionalAccessOperation operation, object argument) { var leftValue = Visit(operation.Operation, argument); var rightValue = Visit(operation.WhenNotNull, argument); switch (leftValue) { case NullAbstractValue.Null: return(GetAbstractDefaultValue(operation.WhenNotNull.Type)); case NullAbstractValue.NotNull: return(rightValue); default: return(NullAbstractValue.MaybeNull); } }
public override TAbstractAnalysisValue VisitConditionalAccess(IConditionalAccessOperation operation, object argument) { var leftValue = Visit(operation.Operation, argument); var whenNullValue = Visit(operation.WhenNotNull, argument); var leftNullValue = GetNullAbstractValue(operation.Operation); switch (leftNullValue) { case NullAbstractValue.Null: return(GetAbstractDefaultValue(operation.WhenNotNull.Type)); case NullAbstractValue.NotNull: return(whenNullValue); default: var value1 = GetAbstractDefaultValue(operation.WhenNotNull.Type); return(ValueDomain.Merge(value1, whenNullValue)); } }
public bool TryCreate(IOperation operation, out AnalysisEntity analysisEntity) { if (_analysisEntityMap.TryGetValue(operation, out analysisEntity)) { return(analysisEntity != null); } analysisEntity = null; ISymbol symbolOpt = null; ImmutableArray <AbstractIndex> indices = ImmutableArray <AbstractIndex> .Empty; IOperation instanceOpt = null; switch (operation) { case ILocalReferenceOperation localReference: symbolOpt = localReference.Local; break; case IParameterReferenceOperation parameterReference: symbolOpt = parameterReference.Parameter; break; case IMemberReferenceOperation memberReference: instanceOpt = memberReference.Instance; GetSymbolAndIndicesForMemberReference(memberReference, ref symbolOpt, ref indices); // Workaround for https://github.com/dotnet/roslyn/issues/22736 (IPropertyReferenceExpressions in IAnonymousObjectCreationExpression are missing a receiver). if (instanceOpt == null && symbolOpt != null && memberReference is IPropertyReferenceOperation propertyReference) { instanceOpt = propertyReference.GetAnonymousObjectCreation(); } break; case IArrayElementReferenceOperation arrayElementReference: instanceOpt = arrayElementReference.ArrayReference; indices = CreateAbstractIndices(arrayElementReference.Indices); break; case IDynamicIndexerAccessOperation dynamicIndexerAccess: instanceOpt = dynamicIndexerAccess.Operation; indices = CreateAbstractIndices(dynamicIndexerAccess.Arguments); break; case IConditionalAccessInstanceOperation conditionalAccessInstance: IConditionalAccessOperation conditionalAccess = conditionalAccessInstance.GetConditionalAccess(); instanceOpt = conditionalAccess.Operation; if (conditionalAccessInstance.Parent is IMemberReferenceOperation memberReferenceParent) { GetSymbolAndIndicesForMemberReference(memberReferenceParent, ref symbolOpt, ref indices); } break; case IInstanceReferenceOperation instanceReference: instanceOpt = instanceReference.GetInstance(); if (instanceOpt == null) { // Reference to this or base instance. analysisEntity = ThisOrMeInstance; } else { var instanceLocation = _getPointsToAbstractValueOpt(instanceReference); analysisEntity = AnalysisEntity.Create(instanceReference, instanceLocation); } break; case IInvocationOperation invocation: symbolOpt = invocation.TargetMethod; instanceOpt = invocation.Instance; break; case IConversionOperation conversion: return(TryCreate(conversion.Operand, out analysisEntity)); case IParenthesizedOperation parenthesized: return(TryCreate(parenthesized.Operand, out analysisEntity)); case IArgumentOperation argument: return(TryCreate(argument.Value, out analysisEntity)); case IDeclarationExpressionOperation declarationExpression: switch (declarationExpression.Expression) { case ILocalReferenceOperation localReference: return(TryCreateForSymbolDeclaration(localReference.Local, out analysisEntity)); case ITupleOperation tupleOperation: // TODO handle tuple operations // https://github.com/dotnet/roslyn-analyzers/issues/1571 break; } break; default: break; } if (symbolOpt != null || !indices.IsEmpty) { TryCreate(symbolOpt, indices, operation.Type, instanceOpt, out analysisEntity); } _analysisEntityMap[operation] = analysisEntity; return(analysisEntity != null); }
public bool TryCreate(IOperation operation, out AnalysisEntity analysisEntity) { if (_analysisEntityMap.TryGetValue(operation, out analysisEntity)) { return(analysisEntity != null); } analysisEntity = null; ISymbol symbolOpt = null; ImmutableArray <AbstractIndex> indices = ImmutableArray <AbstractIndex> .Empty; IOperation instanceOpt = null; ITypeSymbol type = operation.Type; switch (operation) { case ILocalReferenceOperation localReference: symbolOpt = localReference.Local; break; case IParameterReferenceOperation parameterReference: symbolOpt = parameterReference.Parameter; break; case IMemberReferenceOperation memberReference: instanceOpt = memberReference.Instance; GetSymbolAndIndicesForMemberReference(memberReference, ref symbolOpt, ref indices); // Workaround for https://github.com/dotnet/roslyn/issues/22736 (IPropertyReferenceExpressions in IAnonymousObjectCreationExpression are missing a receiver). if (instanceOpt == null && symbolOpt != null && memberReference is IPropertyReferenceOperation propertyReference) { instanceOpt = propertyReference.GetAnonymousObjectCreation(); } break; case IArrayElementReferenceOperation arrayElementReference: instanceOpt = arrayElementReference.ArrayReference; indices = CreateAbstractIndices(arrayElementReference.Indices); break; case IDynamicIndexerAccessOperation dynamicIndexerAccess: instanceOpt = dynamicIndexerAccess.Operation; indices = CreateAbstractIndices(dynamicIndexerAccess.Arguments); break; case IConditionalAccessInstanceOperation conditionalAccessInstance: IConditionalAccessOperation conditionalAccess = conditionalAccessInstance.GetConditionalAccess(); instanceOpt = conditionalAccess.Operation; if (conditionalAccessInstance.Parent is IMemberReferenceOperation memberReferenceParent) { GetSymbolAndIndicesForMemberReference(memberReferenceParent, ref symbolOpt, ref indices); } break; case IInstanceReferenceOperation instanceReference: if (_getPointsToAbstractValueOpt != null) { instanceOpt = instanceReference.GetInstance(_getIsInsideAnonymousObjectInitializer()); if (instanceOpt == null) { // Reference to this or base instance. analysisEntity = _interproceduralCallStackOpt != null && _interproceduralCallStackOpt.Peek().DescendantsAndSelf().Contains(instanceReference) ? _interproceduralThisOrMeInstanceForCallerOpt : ThisOrMeInstance; } else { var instanceLocation = _getPointsToAbstractValueOpt(instanceReference); analysisEntity = AnalysisEntity.Create(instanceReference, instanceLocation); } } break; case IInvocationOperation invocation: symbolOpt = invocation.TargetMethod; instanceOpt = invocation.Instance; break; case IConversionOperation conversion: return(TryCreate(conversion.Operand, out analysisEntity)); case IParenthesizedOperation parenthesized: return(TryCreate(parenthesized.Operand, out analysisEntity)); case IArgumentOperation argument: return(TryCreate(argument.Value, out analysisEntity)); case IFlowCaptureOperation flowCapture: analysisEntity = GetOrCreateForFlowCapture(flowCapture.Id, flowCapture.Value.Type, flowCapture); break; case IFlowCaptureReferenceOperation flowCaptureReference: analysisEntity = GetOrCreateForFlowCapture(flowCaptureReference.Id, flowCaptureReference.Type, flowCaptureReference); break; case IDeclarationExpressionOperation declarationExpression: switch (declarationExpression.Expression) { case ILocalReferenceOperation localReference: return(TryCreateForSymbolDeclaration(localReference.Local, out analysisEntity)); case ITupleOperation tupleOperation: return(TryCreate(tupleOperation, out analysisEntity)); } break; case IVariableDeclaratorOperation variableDeclarator: symbolOpt = variableDeclarator.Symbol; type = variableDeclarator.Symbol.Type; break; case IDeclarationPatternOperation declarationPattern: var declaredLocal = declarationPattern.DeclaredSymbol as ILocalSymbol; symbolOpt = declaredLocal; type = declaredLocal?.Type; break; default: break; } if (symbolOpt != null || !indices.IsEmpty) { TryCreate(symbolOpt, indices, type, instanceOpt, out analysisEntity); } _analysisEntityMap[operation] = analysisEntity; return(analysisEntity != null); }
public override IOperation VisitConditionalAccess(IConditionalAccessOperation operation, object argument) { return(new ConditionalAccessExpression(Visit(operation.WhenNotNull), Visit(operation.Operation), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit)); }
public override void VisitConditionalAccess(IConditionalAccessOperation operation) { Assert.Equal(OperationKind.ConditionalAccess, operation.Kind); AssertEx.Equal(new[] { operation.Operation, operation.WhenNotNull }, operation.Children); }
public virtual void VisitConditionalAccess(IConditionalAccessOperation operation) { DefaultVisit(operation); }
public override void VisitConditionalAccess([NotNull] IConditionalAccessOperation operation) { base.VisitConditionalAccess(operation); }
public override TAbstractAnalysisValue VisitConditionalAccessInstance(IConditionalAccessInstanceOperation operation, object argument) { IConditionalAccessOperation conditionalAccess = operation.GetConditionalAccess(); return(GetCachedAbstractValue(conditionalAccess.Operation)); }
public override bool VisitConditionalAccess([NotNull] IConditionalAccessOperation operation1, [CanBeNull] IOperation argument) { return(argument is IConditionalAccessOperation operation2 && AreBaseOperationsEqual(operation1, operation2)); }