예제 #1
0
        public static void Analyze(
            SyntaxNodeAnalysisContext context,
            InvocationExpressionSyntax invocation,
            MemberAccessExpressionSyntax memberAccess,
            string methodName)
        {
            if (memberAccess.Expression?.IsKind(SyntaxKind.InvocationExpression) == true)
            {
                var invocation2 = (InvocationExpressionSyntax)memberAccess.Expression;

                if (invocation2.ArgumentList?.Arguments.Count == 1 &&
                    invocation2.Expression?.IsKind(SyntaxKind.SimpleMemberAccessExpression) == true)
                {
                    var memberAccess2 = (MemberAccessExpressionSyntax)invocation2.Expression;

                    if (memberAccess2.Name?.Identifier.ValueText == "Where" &&
                        SyntaxAnalyzer.IsEnumerableExtensionMethod(invocation, methodName, 1, context.SemanticModel, context.CancellationToken) &&
                        (SyntaxAnalyzer.IsEnumerableWhereOrImmutableArrayWhereMethod(invocation2, context.SemanticModel, context.CancellationToken)))
                    {
                        TextSpan span = TextSpan.FromBounds(memberAccess2.Name.Span.Start, invocation.Span.End);

                        if (!invocation.ContainsDirectives(span))
                        {
                            context.ReportDiagnostic(
                                DiagnosticDescriptors.SimplifyLinqMethodChain,
                                Location.Create(invocation.SyntaxTree, span));
                        }
                    }
                }
            }
        }
예제 #2
0
        private static void Analyze(
            SyntaxNodeAnalysisContext context,
            SimpleMemberInvocationExpressionInfo invocationInfo,
            SimpleMemberInvocationExpressionInfo invocationInfo2)
        {
            ExpressionSyntax expression = invocationInfo.Arguments.First().Expression;

            if (!AreEquivalentLambdas(expression, invocationInfo2.Arguments.First().Expression))
            {
                return;
            }

            InvocationExpressionSyntax invocation = invocationInfo.InvocationExpression;

            TextSpan span = TextSpan.FromBounds(invocationInfo2.Name.SpanStart, invocation.Span.End);

            if (invocation.ContainsDirectives(span))
            {
                return;
            }

            context.ReportDiagnostic(
                DiagnosticDescriptors.CombineEnumerableWhereMethodChain,
                Location.Create(invocation.SyntaxTree, span));

            TextSpan fadeOutSpan = TextSpan.FromBounds(
                invocationInfo.OperatorToken.SpanStart,
                ((LambdaExpressionSyntax)expression).ArrowToken.Span.End);

            context.ReportDiagnostic(DiagnosticDescriptors.CombineEnumerableWhereMethodChainFadeOut, Location.Create(invocation.SyntaxTree, fadeOutSpan));
            context.ReportDiagnostic(DiagnosticDescriptors.CombineEnumerableWhereMethodChainFadeOut, invocation.ArgumentList.CloseParenToken);
        }
        public static void AnalyzeWhere(SyntaxNodeAnalysisContext context, SimpleMemberInvocationExpressionInfo invocationInfo)
        {
            SimpleMemberInvocationExpressionInfo invocationInfo2 = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocationInfo.Expression);

            if (!invocationInfo2.Success)
            {
                return;
            }

            if (invocationInfo2.Arguments.Count != 1)
            {
                return;
            }

            if (invocationInfo2.NameText != "Where")
            {
                return;
            }

            InvocationExpressionSyntax invocation = invocationInfo.InvocationExpression;

            SemanticModel     semanticModel     = context.SemanticModel;
            CancellationToken cancellationToken = context.CancellationToken;

            IMethodSymbol methodSymbol = semanticModel.GetExtensionMethodInfo(invocation, cancellationToken).Symbol;

            if (methodSymbol == null)
            {
                return;
            }

            if (!SymbolUtility.IsLinqExtensionOfIEnumerableOfTWithoutParameters(methodSymbol, invocationInfo.NameText, semanticModel))
            {
                return;
            }

            IMethodSymbol methodSymbol2 = semanticModel.GetExtensionMethodInfo(invocationInfo2.InvocationExpression, cancellationToken).Symbol;

            if (methodSymbol2 == null)
            {
                return;
            }

            if (!SymbolUtility.IsLinqWhere(methodSymbol2, semanticModel, allowImmutableArrayExtension: true))
            {
                return;
            }

            TextSpan span = TextSpan.FromBounds(invocationInfo2.Name.SpanStart, invocation.Span.End);

            if (invocation.ContainsDirectives(span))
            {
                return;
            }

            context.ReportDiagnostic(
                DiagnosticDescriptors.SimplifyLinqMethodChain,
                Location.Create(invocation.SyntaxTree, span));
        }
        internal static void Analyze(SyntaxNodeAnalysisContext context, InvocationExpressionSyntax invocation)
        {
            ExpressionSyntax expression = invocation.Expression;

            if (expression?.IsKind(SyntaxKind.SimpleMemberAccessExpression) == true)
            {
                var memberAccess = (MemberAccessExpressionSyntax)expression;

                ArgumentListSyntax argumentList = invocation.ArgumentList;

                if (argumentList?.IsMissing == false)
                {
                    SeparatedSyntaxList <ArgumentSyntax> arguments = argumentList.Arguments;

                    if (arguments.Count == 0)
                    {
                        SimpleNameSyntax name = memberAccess.Name;

                        if (name != null)
                        {
                            string methodName = name.Identifier.ValueText;

                            if (methodName == "Cast")
                            {
                                SemanticModel     semanticModel     = context.SemanticModel;
                                CancellationToken cancellationToken = context.CancellationToken;

                                ExtensionMethodInfo info = semanticModel.GetExtensionMethodInfo(invocation, ExtensionMethodKind.Reduced, cancellationToken);

                                if (info.IsLinqCast())
                                {
                                    ImmutableArray <ITypeSymbol> typeArguments = info.OriginalSymbol.TypeArguments;

                                    if (typeArguments.Length == 1)
                                    {
                                        ExpressionSyntax memberAccessExpression = memberAccess.Expression;

                                        if (memberAccessExpression != null)
                                        {
                                            var memberAccessExpressionType = semanticModel.GetTypeSymbol(memberAccessExpression, cancellationToken) as INamedTypeSymbol;

                                            if (memberAccessExpressionType?.IsConstructedFromIEnumerableOfT() == true &&
                                                typeArguments[0].Equals(memberAccessExpressionType.TypeArguments[0]) &&
                                                !invocation.ContainsDirectives(TextSpan.FromBounds(memberAccessExpression.Span.End, invocation.Span.End)))
                                            {
                                                context.ReportDiagnostic(
                                                    DiagnosticDescriptors.RemoveRedundantCast,
                                                    Location.Create(invocation.SyntaxTree, TextSpan.FromBounds(name.SpanStart, argumentList.Span.End)));
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #5
0
        public static void Analyze(SyntaxNodeAnalysisContext context, MemberInvocationExpressionInfo invocationInfo)
        {
            InvocationExpressionSyntax invocationExpression = invocationInfo.InvocationExpression;

            SemanticModel     semanticModel     = context.SemanticModel;
            CancellationToken cancellationToken = context.CancellationToken;

            var methodSymbol = semanticModel.GetSymbol(invocationExpression, cancellationToken) as IMethodSymbol;

            if (methodSymbol == null)
            {
                return;
            }

            if (!ExtensionMethodInfo.TryCreate(methodSymbol, semanticModel, out ExtensionMethodInfo extensionMethodInfo, ExtensionMethodKind.Reduced))
            {
                return;
            }

            if (!extensionMethodInfo.MethodInfo.IsLinqCast())
            {
                return;
            }

            ITypeSymbol typeArgument = extensionMethodInfo.ReducedSymbol.TypeArguments.SingleOrDefault(shouldThrow: false);

            if (typeArgument == null)
            {
                return;
            }

            var memberAccessExpressionType = semanticModel.GetTypeSymbol(invocationInfo.Expression, cancellationToken) as INamedTypeSymbol;

            if (memberAccessExpressionType?.IsConstructedFromIEnumerableOfT() != true)
            {
                return;
            }

            if (!typeArgument.Equals(memberAccessExpressionType.TypeArguments[0]))
            {
                return;
            }

            if (invocationExpression.ContainsDirectives(TextSpan.FromBounds(invocationInfo.Expression.Span.End, invocationExpression.Span.End)))
            {
                return;
            }

            context.ReportDiagnostic(
                DiagnosticDescriptors.RemoveRedundantCast,
                Location.Create(invocationExpression.SyntaxTree, TextSpan.FromBounds(invocationInfo.Name.SpanStart, invocationInfo.ArgumentList.Span.End)));
        }
        public static void Analyze(SyntaxNodeAnalysisContext context, InvocationExpressionSyntax invocation)
        {
            if (CanRefactor(invocation, context.SemanticModel, context.CancellationToken))
            {
                var memberAccess = (MemberAccessExpressionSyntax)invocation.Expression;

                TextSpan span = TextSpan.FromBounds(memberAccess.OperatorToken.Span.Start, invocation.Span.End);

                if (!invocation.ContainsDirectives(span))
                {
                    context.ReportDiagnostic(DiagnosticDescriptors.RemoveRedundantStringToCharArrayCall, Location.Create(invocation.SyntaxTree, span));
                }
            }
        }
예제 #7
0
        public static void Analyze(SyntaxNodeAnalysisContext context, MemberInvocationExpression memberInvocation)
        {
            if (IsFixable(memberInvocation, context.SemanticModel, context.CancellationToken))
            {
                InvocationExpressionSyntax invocationExpression = memberInvocation.InvocationExpression;

                TextSpan span = TextSpan.FromBounds(memberInvocation.OperatorToken.Span.Start, invocationExpression.Span.End);

                if (!invocationExpression.ContainsDirectives(span))
                {
                    context.ReportDiagnostic(
                        DiagnosticDescriptors.RemoveRedundantToStringCall,
                        Location.Create(invocationExpression.SyntaxTree, span));
                }
            }
        }
        public static void Analyze(
            SyntaxNodeAnalysisContext context,
            InvocationExpressionSyntax invocation,
            MemberAccessExpressionSyntax memberAccess)
        {
            if (CanRefactor(invocation, context.SemanticModel, context.CancellationToken))
            {
                TextSpan span = TextSpan.FromBounds(memberAccess.Name.Span.Start, invocation.Span.End);

                if (!invocation.ContainsDirectives(span))
                {
                    context.ReportDiagnostic(
                        DiagnosticDescriptors.UseCastMethodInsteadOfSelectMethod,
                        Location.Create(invocation.SyntaxTree, span));
                }
            }
        }
예제 #9
0
        public static void Analyze(
            SyntaxNodeAnalysisContext context,
            MemberInvocationExpression memberInvocation)
        {
            InvocationExpressionSyntax invocationExpression = memberInvocation.InvocationExpression;

            if (IsFixable(invocationExpression, context.SemanticModel, context.CancellationToken))
            {
                TextSpan span = TextSpan.FromBounds(memberInvocation.Name.Span.Start, invocationExpression.Span.End);

                if (!invocationExpression.ContainsDirectives(span))
                {
                    context.ReportDiagnostic(
                        DiagnosticDescriptors.CallCastInsteadOfSelect,
                        Location.Create(invocationExpression.SyntaxTree, span));
                }
            }
        }
        public static void Analyze(
            SyntaxNodeAnalysisContext context,
            InvocationExpressionSyntax invocation,
            MemberAccessExpressionSyntax memberAccess,
            string methodName)
        {
            if (memberAccess.Expression?.IsKind(SyntaxKind.InvocationExpression) == true)
            {
                var invocation2 = (InvocationExpressionSyntax)memberAccess.Expression;

                if (invocation2.ArgumentList?.Arguments.Count == 1 &&
                    invocation2.Expression?.IsKind(SyntaxKind.SimpleMemberAccessExpression) == true)
                {
                    var memberAccess2 = (MemberAccessExpressionSyntax)invocation2.Expression;

                    if (memberAccess2.Name?.Identifier.ValueText == "Where")
                    {
                        SemanticModel     semanticModel     = context.SemanticModel;
                        CancellationToken cancellationToken = context.CancellationToken;

                        MethodInfo methodInfo;
                        if (semanticModel.TryGetExtensionMethodInfo(invocation, out methodInfo, ExtensionMethodKind.None, cancellationToken) &&
                            methodInfo.IsLinqExtensionOfIEnumerableOfTWithoutParameters(methodName))
                        {
                            MethodInfo methodInfo2;
                            if (semanticModel.TryGetExtensionMethodInfo(invocation2, out methodInfo2, ExtensionMethodKind.None, cancellationToken) &&
                                methodInfo2.IsLinqWhere(allowImmutableArrayExtension: true))
                            {
                                TextSpan span = TextSpan.FromBounds(memberAccess2.Name.Span.Start, invocation.Span.End);

                                if (!invocation.ContainsDirectives(span))
                                {
                                    context.ReportDiagnostic(
                                        DiagnosticDescriptors.SimplifyLinqMethodChain,
                                        Location.Create(invocation.SyntaxTree, span));
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #11
0
        public static void Analyze(SyntaxNodeAnalysisContext context, SimpleMemberInvocationExpressionInfo invocationInfo)
        {
            if (!IsFixable(invocationInfo, context.SemanticModel, context.CancellationToken))
            {
                return;
            }

            InvocationExpressionSyntax invocationExpression = invocationInfo.InvocationExpression;

            TextSpan span = TextSpan.FromBounds(invocationInfo.OperatorToken.SpanStart, invocationExpression.Span.End);

            if (invocationExpression.ContainsDirectives(span))
            {
                return;
            }

            context.ReportDiagnostic(
                DiagnosticDescriptors.RemoveRedundantToStringCall,
                Location.Create(invocationExpression.SyntaxTree, span));
        }
예제 #12
0
        private static void Analyze(
            SyntaxNodeAnalysisContext context,
            InvocationExpressionSyntax invocation1,
            InvocationExpressionSyntax invocation2,
            MemberAccessExpressionSyntax memberAccess1,
            MemberAccessExpressionSyntax memberAccess2)
        {
            ExpressionSyntax expression1 = invocation1.ArgumentList.Arguments.First().Expression;
            ExpressionSyntax expression2 = invocation2.ArgumentList.Arguments.First().Expression;

            if (CheckLambdas(expression1, expression2))
            {
                TextSpan span = TextSpan.FromBounds(memberAccess2.Name.Span.Start, invocation1.Span.End);

                if (!invocation1.ContainsDirectives(span))
                {
                    context.ReportDiagnostic(
                        DiagnosticDescriptors.CombineEnumerableWhereMethodChain,
                        Location.Create(invocation1.SyntaxTree, span));

                    FadeOut(context, invocation1, memberAccess1, (LambdaExpressionSyntax)expression1);
                }
            }
        }
예제 #13
0
        public static bool Analyze(SyntaxNodeAnalysisContext context, InvocationExpressionSyntax invocation)
        {
            var memberAccess = (MemberAccessExpressionSyntax)invocation.Expression;

            ExpressionSyntax expression = memberAccess?.Expression;

            if (expression?.IsKind(SyntaxKind.InvocationExpression) == true)
            {
                var invocation2 = (InvocationExpressionSyntax)expression;

                ArgumentListSyntax argumentList = invocation2.ArgumentList;

                if (argumentList?.IsMissing == false)
                {
                    SeparatedSyntaxList <ArgumentSyntax> arguments = argumentList.Arguments;

                    if (arguments.Count == 1 &&
                        invocation2.Expression?.IsKind(SyntaxKind.SimpleMemberAccessExpression) == true)
                    {
                        var memberAccess2 = (MemberAccessExpressionSyntax)invocation2.Expression;

                        if (string.Equals(memberAccess2.Name?.Identifier.ValueText, "Where", StringComparison.Ordinal))
                        {
                            SemanticModel     semanticModel     = context.SemanticModel;
                            CancellationToken cancellationToken = context.CancellationToken;

                            if (semanticModel
                                .GetExtensionMethodInfo(invocation, ExtensionMethodKind.Reduced, cancellationToken)
                                .IsLinqCast() &&
                                semanticModel
                                .GetExtensionMethodInfo(invocation2, ExtensionMethodKind.Reduced, cancellationToken)
                                .IsLinqWhere())
                            {
                                BinaryExpressionSyntax isExpression = GetIsExpression(arguments.First().Expression);

                                if (isExpression != null)
                                {
                                    var type = isExpression.Right as TypeSyntax;

                                    if (type != null)
                                    {
                                        TypeSyntax type2 = GetTypeArgument(memberAccess.Name);

                                        if (type2 != null)
                                        {
                                            ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(type);

                                            if (typeSymbol != null)
                                            {
                                                ITypeSymbol typeSymbol2 = semanticModel.GetTypeSymbol(type2);

                                                if (typeSymbol.Equals(typeSymbol2))
                                                {
                                                    TextSpan span = TextSpan.FromBounds(memberAccess2.Name.Span.Start, invocation.Span.End);

                                                    if (!invocation.ContainsDirectives(span))
                                                    {
                                                        context.ReportDiagnostic(
                                                            DiagnosticDescriptors.SimplifyLinqMethodChain,
                                                            Location.Create(invocation.SyntaxTree, span));
                                                    }

                                                    return(true);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(false);
        }
예제 #14
0
        public static void Analyze(SyntaxNodeAnalysisContext context, InvocationExpressionSyntax invocation)
        {
            ExpressionSyntax expression = invocation.Expression;

            if (expression?.IsKind(SyntaxKind.SimpleMemberAccessExpression) == true)
            {
                var memberAccess = (MemberAccessExpressionSyntax)expression;

                ArgumentListSyntax argumentList = invocation.ArgumentList;

                if (argumentList != null)
                {
                    SeparatedSyntaxList <ArgumentSyntax> arguments = argumentList.Arguments;

                    if (arguments.Any())
                    {
                        SimpleNameSyntax name = memberAccess.Name;

                        if (name?.Identifier.ValueText == "Join")
                        {
                            SemanticModel     semanticModel     = context.SemanticModel;
                            CancellationToken cancellationToken = context.CancellationToken;

                            MethodInfo info = semanticModel.GetMethodInfo(invocation, cancellationToken);

                            if (info.IsValid &&
                                info.HasName("Join") &&
                                info.IsContainingType(SpecialType.System_String) &&
                                info.IsPublic &&
                                info.IsStatic &&
                                info.IsReturnType(SpecialType.System_String) &&
                                !info.IsGenericMethod &&
                                !info.IsExtensionMethod)
                            {
                                ImmutableArray <IParameterSymbol> parameters = info.Parameters;

                                if (parameters.Length == 2 &&
                                    parameters[0].Type.IsString())
                                {
                                    IParameterSymbol parameter = parameters[1];

                                    if (parameter.IsParamsOf(SpecialType.System_String) ||
                                        parameter.IsParamsOf(SpecialType.System_Object) ||
                                        parameter.Type.IsConstructedFromIEnumerableOfT())
                                    {
                                        ArgumentSyntax   firstArgument      = arguments.First();
                                        ExpressionSyntax argumentExpression = firstArgument.Expression;

                                        if (argumentExpression != null &&
                                            CSharpAnalysis.IsEmptyString(argumentExpression, semanticModel, cancellationToken) &&
                                            !invocation.ContainsDirectives(TextSpan.FromBounds(invocation.SpanStart, firstArgument.Span.End)))
                                        {
                                            context.ReportDiagnostic(
                                                DiagnosticDescriptors.CallStringConcatInsteadOfStringJoin,
                                                name);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #15
0
        public static void Analyze(
            SyntaxNodeAnalysisContext context,
            MemberInvocationExpressionInfo invocationInfo)
        {
            InvocationExpressionSyntax invocationExpression = invocationInfo.InvocationExpression;

            TextSpan span = TextSpan.FromBounds(invocationInfo.Name.Span.Start, invocationExpression.Span.End);

            if (invocationExpression.ContainsDirectives(span))
            {
                return;
            }

            SemanticModel     semanticModel     = context.SemanticModel;
            CancellationToken cancellationToken = context.CancellationToken;

            var methodSymbol = semanticModel.GetSymbol(invocationExpression, cancellationToken) as IMethodSymbol;

            if (methodSymbol == null)
            {
                return;
            }

            if (!ExtensionMethodInfo.TryCreate(methodSymbol, semanticModel, out ExtensionMethodInfo extensionMethodInfo))
            {
                return;
            }

            if (!extensionMethodInfo.MethodInfo.IsLinqSelect(allowImmutableArrayExtension: true))
            {
                return;
            }

            ITypeSymbol typeArgument = extensionMethodInfo.ReducedSymbolOrSymbol.TypeArguments[0];

            if (!typeArgument.IsReferenceType)
            {
                return;
            }

            if (typeArgument.SpecialType == SpecialType.System_Object)
            {
                return;
            }

            ExpressionSyntax expression = invocationExpression.ArgumentList?.Arguments.Last().Expression;

            SingleParameterLambdaExpressionInfo lambdaInfo = SyntaxInfo.SingleParameterLambdaExpressionInfo(expression);

            if (!lambdaInfo.Success)
            {
                return;
            }

            CastExpressionSyntax castExpression = GetCastExpression(lambdaInfo.Body);

            if (castExpression == null)
            {
                return;
            }

            if (!(castExpression.Expression is IdentifierNameSyntax identifierName))
            {
                return;
            }

            if (!string.Equals(lambdaInfo.Parameter.Identifier.ValueText, identifierName.Identifier.ValueText, StringComparison.Ordinal))
            {
                return;
            }

            var castSymbol = semanticModel.GetSymbol(castExpression, cancellationToken) as IMethodSymbol;

            if (castSymbol?.MethodKind == MethodKind.Conversion)
            {
                return;
            }

            context.ReportDiagnostic(
                DiagnosticDescriptors.CallCastInsteadOfSelect,
                Location.Create(invocationExpression.SyntaxTree, span));
        }