private AnalysisEntity Create(ISymbol symbolOpt, ImmutableArray <AbstractIndex> indices, ITypeSymbol type, PointsToAbstractValue instanceLocationOpt, AnalysisEntity parentOpt) { instanceLocationOpt = EnsureLocation(instanceLocationOpt, symbolOpt, parentOpt); Debug.Assert(instanceLocationOpt != null); var analysisEntity = AnalysisEntity.Create(symbolOpt, indices, type, instanceLocationOpt, parentOpt); return(analysisEntity); }
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); }