Beispiel #1
0
            private EnumerationCount GetEnumerationCount(IOperation parameterOrLocalReferenceOperation, WellKnownSymbolsInfo wellKnownSymbolsInfo)
            {
                var(linqChainTailOperation, linqChainEnumerationCount) = SkipLinqChainAndConversionMethod(
                    parameterOrLocalReferenceOperation,
                    wellKnownSymbolsInfo);

                if (IsOperationEnumeratedByInvocation(linqChainTailOperation, wellKnownSymbolsInfo) ||
                    IsGetEnumeratorOfForEachLoopInvoked(linqChainTailOperation))
                {
                    return(InvocationSetHelpers.AddInvocationCount(linqChainEnumerationCount, EnumerationCount.One));
                }

                return(linqChainEnumerationCount);
            }
Beispiel #2
0
            static (IOperation linqChainTailOperation, EnumerationCount enumerationCount) VisitLinqChainAndCoversionMethod(
                IOperation operation,
                EnumerationCount enumerationCount,
                WellKnownSymbolsInfo wellKnownSymbolsInfo)
            {
                if (IsValidImplicitConversion(operation.Parent, wellKnownSymbolsInfo))
                {
                    // Go to the implicit conversion if needed
                    // e.g.
                    // void Bar (IOrderedEnumerable<T> c)
                    // {
                    //      c.First();
                    // }
                    // here 'c' would be converted to IEnumerable<T>
                    return(VisitLinqChainAndCoversionMethod(operation.Parent, enumerationCount, wellKnownSymbolsInfo));
                }

                if (IsOperationIsArgumentOfLinqChainInvocation(operation.Parent, wellKnownSymbolsInfo, out var enumerateArgument))
                {
                    // This operation is used as an argument of a deferred execution method.
                    // Check if the invocation of the deferred execution method is used in another deferred execution method.
                    return(VisitLinqChainAndCoversionMethod(
                               operation.Parent.Parent,
                               enumerateArgument
                            ? InvocationSetHelpers.AddInvocationCount(enumerationCount, EnumerationCount.One)
                            : enumerationCount,
                               wellKnownSymbolsInfo));
                }

                if (IsInstanceOfLinqChainInvocation(operation, wellKnownSymbolsInfo, out var enumerateInstance))
                {
                    // If the extension method could be used as reduced method, also check its invocation instance.
                    // Like in VB,
                    // 'i.Select(Function(a) a)', 'i' is the invocation instance of 'Select'
                    return(VisitLinqChainAndCoversionMethod(
                               operation.Parent,
                               enumerateInstance
                            ? InvocationSetHelpers.AddInvocationCount(enumerationCount, EnumerationCount.One)
                            : enumerationCount,
                               wellKnownSymbolsInfo));
                }

                return(operation, enumerationCount);
            }