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