Пример #1
0
        /// <summary>
        /// Find all invoked methods that have an async counterpart and have not been discovered yet.
        /// </summary>
        /// <param name="methodData">The method data to be searched</param>
        /// <returns>Collection of invoked methods that have an async counterpart</returns>
        private IEnumerable <IMethodSymbol> FindNewlyInvokedMethodsWithAsyncCounterpart(MethodData methodData)
        {
            var result         = new HashSet <IMethodSymbol>();
            var methodDataBody = methodData.GetBodyNode();

            if (methodDataBody == null)
            {
                return(result);
            }
            var documentData  = methodData.TypeData.NamespaceData.DocumentData;
            var semanticModel = documentData.SemanticModel;
            var searchOptions = AsyncCounterpartsSearchOptions.Default;

            if (_configuration.UseCancellationTokenOverload)
            {
                searchOptions |= AsyncCounterpartsSearchOptions.HasCancellationToken;
            }

            foreach (var invocation in methodDataBody.DescendantNodes()
                     .OfType <InvocationExpressionSyntax>())
            {
                var methodSymbol = semanticModel.GetSymbolInfo(invocation.Expression).Symbol as IMethodSymbol;
                if (methodSymbol == null)
                {
                    continue;
                }
                methodSymbol = methodSymbol.OriginalDefinition;
                if (result.Contains(methodSymbol))
                {
                    continue;
                }
                var asyncCounterparts = GetAsyncCounterparts(methodSymbol, searchOptions, true).ToList();
                if (asyncCounterparts.Any())
                {
                    result.Add(methodSymbol);
                }
            }
            return(result);
        }
        private void AnalyzeMethodData(DocumentData documentData, MethodData methodData)
        {
            foreach (var reference in methodData.InvokedMethodReferences)
            {
                AnalyzeMethodReference(documentData, reference);
            }

            var methodBody = methodData.GetBodyNode();

            methodData.HasYields           = methodBody?.DescendantNodes().OfType <YieldStatementSyntax>().Any() == true;
            methodData.MustRunSynchronized = methodData.Symbol.GetAttributes()
                                             .Where(o => o.AttributeClass.Name == "MethodImplAttribute")
                                             .Any(o => ((MethodImplOptions)(int)o.ConstructorArguments.First().Value).HasFlag(MethodImplOptions.Synchronized));
            if (methodBody == null)
            {
                methodData.OmitAsync = true;
            }

            // Check if there is any

            if (methodData.Conversion == MethodConversion.ToAsync)
            {
                return;
            }

            // If a method is never invoked and there is no invocations inside the method body that can be async and there is no related methods we can ignore it
            if (!methodData.InvokedBy.Any() && methodData.InvokedMethodReferences.All(o => o.Ignore) && !methodData.RelatedMethods.Any())
            {
                // If we have to create a new type we need to consider also the external related methods
                if (methodData.TypeData.Conversion != TypeConversion.NewType || !methodData.ExternalRelatedMethods.Any())
                {
                    methodData.Conversion = MethodConversion.Ignore;
                    return;
                }
            }
        }