public bool ShouldUseTap(MemberAccessExpressionSyntax memberAccessExpression)
        {
            if (memberAccessExpression.IsWrappedInAwaitExpression() || memberAccessExpression.IsWrappedInLock())
            {
                return false;
            }

            var identifierName = memberAccessExpression.Name as IdentifierNameSyntax;
            if (identifierName?.Identifier.ValueText != nameof(Task<int>.Result))
            {
                return false;
            }

            var lambdaExpression = memberAccessExpression.FirstAncestorOrSelf<LambdaExpressionSyntax>();
            if (lambdaExpression == null)
            {
                var methodDeclaration = memberAccessExpression.FirstAncestorOrSelf<MethodDeclarationSyntax>();
                if (methodDeclaration == null || methodDeclaration.HasOutOrRefParameters())
                {
                    return false;
                }
            }

            var symbol = FindSymbol(memberAccessExpression.Expression);
            if (symbol == null)
            {
                return false;
            }
            var taskSymbol = semanticModel.Compilation.GetTypeByMetadataName(typeof(Task).FullName);
            var taskOfTSymbol = semanticModel.Compilation.GetTypeByMetadataName(typeof(Task).FullName + "`1");

            return symbol.IsGenericType ?
                symbol.ConstructedFrom.Equals(taskOfTSymbol) :
                symbol.Equals(taskSymbol);
        }
Exemplo n.º 2
0
        public bool ShouldUseTap(MemberAccessExpressionSyntax memberAccessExpression)
        {
            if (memberAccessExpression.IsWrappedInAwaitExpression() || memberAccessExpression.IsWrappedInLock())
            {
                return(false);
            }

            var identifierName = memberAccessExpression.Name as IdentifierNameSyntax;

            if (identifierName?.Identifier.ValueText != nameof(Task <int> .Result))
            {
                return(false);
            }

            var lambdaExpression = memberAccessExpression.FirstAncestorOrSelf <LambdaExpressionSyntax>();

            if (lambdaExpression == null)
            {
                var methodDeclaration = memberAccessExpression.FirstAncestorOrSelf <MethodDeclarationSyntax>();
                if (methodDeclaration == null || methodDeclaration.HasOutOrRefParameters())
                {
                    return(false);
                }
            }

            var symbol = FindSymbol(memberAccessExpression.Expression);

            if (symbol == null)
            {
                return(false);
            }
            var taskSymbol    = semanticModel.Compilation.GetTypeByMetadataName(typeof(Task).FullName);
            var taskOfTSymbol = semanticModel.Compilation.GetTypeByMetadataName(typeof(Task).FullName + "`1");

            return(symbol.IsGenericType ?
                   symbol.ConstructedFrom.Equals(taskOfTSymbol) :
                   symbol.Equals(taskSymbol));
        }
Exemplo n.º 3
0
        private async Task <Document> UseAwait(Document document, MemberAccessExpressionSyntax memberAccessExpression, SyntaxNode root, CancellationToken x)
        {
            if (memberAccessExpression == null)
            {
                return(document);
            }

            var newExpression      = AwaitExpression(memberAccessExpression.Expression);
            var originalInvocation = memberAccessExpression.FirstAncestorOrSelf <InvocationExpressionSyntax>();


            var newRoot = root.ReplaceNode(originalInvocation, newExpression);

            return(document.WithSyntaxRoot(newRoot));
        }
Exemplo n.º 4
0
        private static bool IsAwaited(SyntaxNodeAnalysisContext context, MemberAccessExpressionSyntax simpleMemberAccess)
        {
            var accessedSymbol = new Lazy <ISymbol>(() => context.SemanticModel.GetSymbolInfo(simpleMemberAccess.Expression).Symbol);

            return(simpleMemberAccess.FirstAncestorOrSelf <StatementSyntax>() is { } currentStatement &&
                   currentStatement.GetPreviousStatements().Any(statement =>
                                                                statement.DescendantNodes()
                                                                .OfType <InvocationExpressionSyntax>()
                                                                .Where(x => x.Expression.IsKind(SyntaxKind.SimpleMemberAccessExpression))
                                                                .Any(IsTaskAwaited)));

            bool IsTaskAwaited(InvocationExpressionSyntax invocation) =>
            IsAwaitForMultipleTasksExecutionCall(invocation, context.SemanticModel, accessedSymbol) ||
            IsAwaitForSingleTaskExecutionCall(invocation, context.SemanticModel, accessedSymbol);
        }
Exemplo n.º 5
0
        private static bool IsMemberAccessADynamicInvocation(MemberAccessExpressionSyntax memberAccess, SemanticModel semanticModel)
        {
            var ancestorInvocation = memberAccess.FirstAncestorOrSelf <InvocationExpressionSyntax>();

            if (ancestorInvocation != null && ancestorInvocation.SpanStart == memberAccess.SpanStart)
            {
                var typeInfo = semanticModel.GetTypeInfo(ancestorInvocation);
                if (typeInfo.Type != null &&
                    typeInfo.Type.Kind == SymbolKind.DynamicType)
                {
                    return(true);
                }
            }

            return(false);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Tells if the member access is dynamically invoked and cannot be reduced. In the case of
        /// <c>NS1.NS2.T1.T2.Method(...dynamic...)</c> we can only remove the <c>NS1.NS2</c>
        /// portion. The namespace part is not encoded into the IL, but the specific types in
        /// <c>T1.T2</c> and cannot be removed.
        /// </summary>
        private static bool IsNonRemovablePartOfDynamicMethodInvocation(
            SemanticModel semanticModel, MemberAccessExpressionSyntax memberAccess, CancellationToken cancellationToken)
        {
            var ancestorInvocation = memberAccess.FirstAncestorOrSelf<InvocationExpressionSyntax>();
            if (ancestorInvocation?.SpanStart == memberAccess.SpanStart)
            {
                var leftSymbol = semanticModel.GetSymbolInfo(memberAccess.Expression, cancellationToken).GetAnySymbol();
                if (leftSymbol is INamedTypeSymbol)
                {
                    var type = semanticModel.GetTypeInfo(memberAccess.Parent, cancellationToken).Type;
                    if (type?.Kind == SymbolKind.DynamicType)
                    {
                        return true;
                    }
                }
            }

            return false;
        }
        /// <summary>
        /// Tells if the Member access is the starting part of a Dynamic Invocation
        /// </summary>
        /// <param name="memberAccess"></param>
        /// <param name="semanticModel"></param>
        /// <returns>Return true, if the member access is the starting point of a Dynamic Invocation</returns>
        private static bool IsMemberAccessADynamicInvocation(MemberAccessExpressionSyntax memberAccess, SemanticModel semanticModel)
        {
            var ancestorInvocation = memberAccess.FirstAncestorOrSelf<InvocationExpressionSyntax>();

            if (ancestorInvocation != null && ancestorInvocation.SpanStart == memberAccess.SpanStart)
            {
                var typeInfo = semanticModel.GetTypeInfo(ancestorInvocation);
                if (typeInfo.Type != null &&
                    typeInfo.Type.Kind == SymbolKind.DynamicType)
                {
                    return true;
                }
            }

            return false;
        }