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);
        }