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; } }
public IEnumerable <IMethodSymbol> FindAsyncCounterparts(IMethodSymbol syncMethodSymbol, ITypeSymbol invokedFromType, AsyncCounterpartsSearchOptions options) { return(_func(syncMethodSymbol, invokedFromType, options)); }
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; } }
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); } } } } }
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); }
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; })); }
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; } }
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; })); }
private IEnumerable <IMethodSymbol> GetAsyncCounterparts(IMethodSymbol methodSymbol, AsyncCounterpartsSearchOptions options, bool onlyNew = false) { return(GetAsyncCounterparts(_methodAsyncConterparts, methodSymbol, null, options, onlyNew)); }
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)); }