private void Setup()
        {
            _configuration    = ProjectData.Configuration.AnalyzeConfiguration;
            _solution         = ProjectData.Project.Solution;
            _analyzeDocuments = ProjectData.Project.Documents
                                .Where(o => _configuration.DocumentSelectionPredicate(o))
                                .ToImmutableHashSet();
            _analyzeProjects = new[] { ProjectData.Project }
            .ToImmutableHashSet();
            _searchOptions = AsyncCounterpartsSearchOptions.Default;
            var useTokens = _configuration.UseCancellationTokens | _configuration.ScanForMissingAsyncMembers != null;

            if (useTokens)
            {
                _searchOptions |= AsyncCounterpartsSearchOptions.HasCancellationToken;
            }
        }
Ejemplo n.º 2
0
 public IEnumerable <IMethodSymbol> FindAsyncCounterparts(IMethodSymbol syncMethodSymbol, ITypeSymbol invokedFromType, AsyncCounterpartsSearchOptions options)
 {
     return(_func(syncMethodSymbol, invokedFromType, options));
 }
Ejemplo n.º 3
0
 public IEnumerable <IMethodSymbol> FindAsyncCounterparts(IMethodSymbol syncMethodSymbol, AsyncCounterpartsSearchOptions options)
 {
     return(syncMethodSymbol.GetAsyncCounterparts(options.HasFlag(EqualParameters), options.HasFlag(SearchInheritTypes),
                                                  options.HasFlag(HasCancellationToken), options.HasFlag(IgnoreReturnType)));
 }
        public IEnumerable <IMethodSymbol> FindAsyncCounterparts(IMethodSymbol symbol, ITypeSymbol invokedFromType, AsyncCounterpartsSearchOptions options)
        {
            if (invokedFromType == null)
            {
                yield break;
            }
            var asyncName = symbol.GetAsyncName();

            foreach (var asyncCandidate in _extensionMethodsLookup[asyncName])
            {
                if (!symbol.IsAsyncCounterpart(invokedFromType, asyncCandidate, true, true, false))
                {
                    continue;
                }
                yield return(asyncCandidate);

                yield break;
            }
        }
Ejemplo n.º 5
0
        public IEnumerable <IMethodSymbol> FindAsyncCounterparts(IMethodSymbol syncMethodSymbol, ITypeSymbol invokedFromType, AsyncCounterpartsSearchOptions options)
        {
            if (syncMethodSymbol.Name != "That" ||
                syncMethodSymbol.ContainingType.Name != "Assert" ||
                syncMethodSymbol.ContainingType.ContainingNamespace.ToString() != "NUnit.Framework")
            {
                yield break;
            }
            var firstParamType = syncMethodSymbol.Parameters.First().Type;

            switch (firstParamType.Name)
            {
            case "ActualValueDelegate":
                yield return(syncMethodSymbol);

                yield break;

            case "TestDelegate":
                var pair = _thatAsyncCounterparts.FirstOrDefault(o => o.Key.Equals(syncMethodSymbol));
                if (pair.Value != null)
                {
                    yield return(pair.Value);
                }
                break;
            }
        }
        /// <summary>
        /// Set the method conversion to Ignore for all method data that are inside the given document and can not be
        /// converted due to the language limitations or an already existing async counterpart.
        /// </summary>
        /// <param name="documentData">The document data to be pre-analyzed</param>
        private void PreAnalyzeDocumentData(DocumentData documentData)
        {
            _preAnalyzeSearchOptions = AsyncCounterpartsSearchOptions.EqualParameters | AsyncCounterpartsSearchOptions.IgnoreReturnType;
            // When searhing for missing async member we have to search also for overloads with a cancellation token
            var searchWithTokens = _configuration.UseCancellationTokens || _configuration.CanScanForMissingAsyncMembers != null;

            if (searchWithTokens)
            {
                _preAnalyzeSearchOptions |= AsyncCounterpartsSearchOptions.HasCancellationToken;
            }
            if (_configuration.SearchAsyncCounterpartsInInheritedTypes)
            {
                _preAnalyzeSearchOptions |= AsyncCounterpartsSearchOptions.SearchInheritedTypes;
            }

            foreach (var typeNode in documentData.Node
                     .DescendantNodes()
                     .OfType <TypeDeclarationSyntax>())
            {
                var typeData = documentData.GetOrCreateTypeData(typeNode);
                typeData.Conversion = _configuration.GetTypeConversion(typeData.Symbol);
                PreAnalyzeType(typeData);

                var typeIgnored = typeData.GetSelfAndAncestorsTypeData().Any(o => o.Conversion == TypeConversion.Ignore);

                // TODO: fields can have anonymous functions that have async calls
                foreach (var memberNode in typeNode.Members)
                {
                    if (memberNode is BaseMethodDeclarationSyntax methodNode)
                    {
                        var methodData = documentData.GetOrCreateBaseMethodData(methodNode, typeData);
                        if (typeIgnored)
                        {
                            methodData.Ignore(IgnoreReason.TypeConversion, true);
                        }
                        else
                        {
                            PreAnalyzeFunctionData(methodData, documentData.SemanticModel);
                        }

                        foreach (var node in methodNode.DescendantNodes())
                        {
                            switch (node.Kind())
                            {
                            case SyntaxKind.ParenthesizedLambdaExpression:
                            case SyntaxKind.AnonymousMethodExpression:
                            case SyntaxKind.SimpleLambdaExpression:
                                var anonFunData = documentData.GetOrCreateAnonymousFunctionData((AnonymousFunctionExpressionSyntax)node, methodData);
                                if (methodData.Conversion == MethodConversion.Ignore)
                                {
                                    anonFunData.Ignore(IgnoreReason.Cascade, true);
                                }
                                else
                                {
                                    PreAnalyzeAnonymousFunction(anonFunData, documentData.SemanticModel);
                                }
                                break;

                            case SyntaxKind.LocalFunctionStatement:
                                var localFunData = documentData.GetOrCreateLocalFunctionData((LocalFunctionStatementSyntax)node, methodData);
                                if (methodData.Conversion == MethodConversion.Ignore)
                                {
                                    localFunData.Ignore(IgnoreReason.Cascade, true);
                                }
                                else
                                {
                                    PreAnalyzeLocalFunction(localFunData, documentData.SemanticModel);
                                }
                                break;
                            }
                        }
                    }
                    else if (memberNode is PropertyDeclarationSyntax propertyNode)
                    {
                        var propertyData = documentData.GetOrCreatePropertyData(propertyNode, typeData);
                        if (typeIgnored)
                        {
                            propertyData.Ignore(IgnoreReason.TypeConversion, true);
                        }
                        else
                        {
                            PreAnalyzePropertyData(propertyData, documentData.SemanticModel);
                        }
                    }
                    else if (memberNode is BaseFieldDeclarationSyntax fieldNode)
                    {
                        var fieldData = documentData.GetOrCreateBaseFieldData(fieldNode, typeData);
                        if (typeIgnored)
                        {
                            fieldData.Ignore(IgnoreReason.TypeConversion, true);
                        }
                        else
                        {
                            PreAnalyzeFieldData(fieldData, documentData.SemanticModel);
                        }
                    }
                }
            }
        }
Ejemplo n.º 7
0
 public IEnumerable <IMethodSymbol> FindAsyncCounterparts(IMethodSymbol syncMethodSymbol, AsyncCounterpartsSearchOptions options)
 {
     return(_func(syncMethodSymbol, options));
 }
        public IEnumerable <IMethodSymbol> FindAsyncCounterparts(IMethodSymbol syncMethodSymbol, ITypeSymbol invokedFromType, AsyncCounterpartsSearchOptions options)
        {
            if (syncMethodSymbol.Name != "Sleep" || syncMethodSymbol.ContainingType.ToString() != "System.Threading.Thread")
            {
                yield break;
            }

            foreach (var taskDelayMethod in _taskDelayMethods)
            {
                if (syncMethodSymbol.IsAsyncCounterpart(invokedFromType, taskDelayMethod, options.HasFlag(EqualParameters),
                                                        options.HasFlag(HasCancellationToken), options.HasFlag(IgnoreReturnType)))
                {
                    yield return(taskDelayMethod);
                }
            }
        }
 public IEnumerable <IMethodSymbol> FindAsyncCounterparts(IMethodSymbol syncMethodSymbol, ITypeSymbol invokedFromType, AsyncCounterpartsSearchOptions options)
 {
     if ((syncMethodSymbol.Name != "RunVoid" && syncMethodSymbol.Name != "RunGeneric") ||
         syncMethodSymbol.ContainingType.Name != "Runner" ||
         syncMethodSymbol.ContainingType.ContainingNamespace.ToString() != "AsyncGenerator.TestCases")
     {
         yield break;
     }
     yield return(_asyncCounterpart);
 }
Ejemplo n.º 10
0
        private IEnumerable <IMethodSymbol> GetAsyncCounterparts(IMethodSymbol methodSymbol, AsyncCounterpartsSearchOptions options, bool onlyNew = false)
        {
            var dict = _methodAsyncConterparts.GetOrAdd(methodSymbol, new ConcurrentDictionary <AsyncCounterpartsSearchOptions, HashSet <IMethodSymbol> >());
            HashSet <IMethodSymbol> asyncMethodSymbols;

            if (dict.TryGetValue(options, out asyncMethodSymbols))
            {
                return(onlyNew ? Enumerable.Empty <IMethodSymbol>() : asyncMethodSymbols);
            }
            asyncMethodSymbols = new HashSet <IMethodSymbol>(_configuration.FindAsyncCounterpartsFinders
                                                             .SelectMany(o => o.FindAsyncCounterparts(methodSymbol, options)));
            return(dict.AddOrUpdate(
                       options,
                       asyncMethodSymbols,
                       (k, v) =>
            {
                Logger.Debug($"Performance hit: Multiple GetAsyncCounterparts method calls for method symbol {methodSymbol}");
                return asyncMethodSymbols;
            }));
        }
Ejemplo n.º 11
0
        public IEnumerable <IMethodSymbol> FindAsyncCounterparts(IMethodSymbol syncMethodSymbol, ITypeSymbol invokedFromType, AsyncCounterpartsSearchOptions options)
        {
            switch (syncMethodSymbol.Name)
            {
            case "ForEach" when syncMethodSymbol.Equals(_forEachMethod):
                yield return(_whenAllMethod);

                break;

            case "For" when _forMethod.Equals(syncMethodSymbol):
                yield return(_whenAllMethod);

                break;
            }
        }
Ejemplo n.º 12
0
        private IEnumerable <IMethodSymbol> GetAsyncCounterparts(ConcurrentDictionary <IMethodSymbol, ConcurrentDictionary <AsyncCounterpartsSearchOptions, HashSet <IMethodSymbol> > > asyncCounterparts,
                                                                 IMethodSymbol methodSymbol, ITypeSymbol invokedFromType, AsyncCounterpartsSearchOptions options, bool onlyNew = false)
        {
            var dict = asyncCounterparts.GetOrAdd(methodSymbol, new ConcurrentDictionary <AsyncCounterpartsSearchOptions, HashSet <IMethodSymbol> >());

            if (dict.TryGetValue(options, out var asyncMethodSymbols))
            {
                return(onlyNew ? Enumerable.Empty <IMethodSymbol>() : asyncMethodSymbols);
            }
            asyncMethodSymbols = _configuration.CanSearchForAsyncCounterparts(methodSymbol)
                                ? new HashSet <IMethodSymbol>(_configuration.AsyncCounterpartsFinders
                                                              .SelectMany(o => o.FindAsyncCounterparts(methodSymbol, invokedFromType, options)))
                                : new HashSet <IMethodSymbol>();
            return(dict.AddOrUpdate(
                       options,
                       asyncMethodSymbols,
                       (k, v) =>
            {
                _logger.Debug($"Performance hit: Multiple GetAsyncCounterparts method calls for method symbol {methodSymbol}");
                return asyncMethodSymbols;
            }));
        }
Ejemplo n.º 13
0
 private IEnumerable <IMethodSymbol> GetAsyncCounterparts(IMethodSymbol methodSymbol, AsyncCounterpartsSearchOptions options, bool onlyNew = false)
 {
     return(GetAsyncCounterparts(_methodAsyncConterparts, methodSymbol, null, options, onlyNew));
 }
Ejemplo n.º 14
0
        private IEnumerable <IMethodSymbol> GetAsyncCounterparts(IMethodSymbol methodSymbol, ITypeSymbol invokedFromType, AsyncCounterpartsSearchOptions options, bool onlyNew = false)
        {
            if (invokedFromType == null)
            {
                return(GetAsyncCounterparts(methodSymbol, options, onlyNew));
            }
            var typeDict = _methodByTypeAsyncConterparts.GetOrAdd(invokedFromType.OriginalDefinition, new ConcurrentDictionary <IMethodSymbol, ConcurrentDictionary <AsyncCounterpartsSearchOptions, HashSet <IMethodSymbol> > >());

            return(GetAsyncCounterparts(typeDict, methodSymbol, invokedFromType.OriginalDefinition, options, onlyNew));
        }