Пример #1
0
        private static bool IsEnumerableElementAtMethod(
            InvocationExpressionSyntax invocation,
            SemanticModel semanticModel)
        {
            var methodSymbol = semanticModel.GetSymbolInfo(invocation).Symbol as IMethodSymbol;

            if (methodSymbol?.ReducedFrom != null)
            {
                methodSymbol = methodSymbol.ReducedFrom;

                return(methodSymbol.MetadataName == "ElementAt" &&
                       methodSymbol.Parameters.Length == 2 &&
                       methodSymbol.ContainingType?.Equals(semanticModel.Compilation.GetTypeByMetadataName("System.Linq.Enumerable")) == true &&
                       SyntaxAnalyzer.IsGenericIEnumerable(methodSymbol.Parameters[0].Type) &&
                       methodSymbol.Parameters[1].Type.IsInt32());
            }

            return(false);
        }
Пример #2
0
        private static string GetCountOrLengthPropertyName(
            ExpressionSyntax expression,
            SemanticModel semanticModel,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            ITypeSymbol typeSymbol = semanticModel
                                     .GetTypeInfo(expression, cancellationToken)
                                     .Type;

            if (typeSymbol?.IsErrorType() == false &&
                !SyntaxAnalyzer.IsGenericIEnumerable(typeSymbol))
            {
                if (typeSymbol.BaseType?.SpecialType == SpecialType.System_Array)
                {
                    return("Length");
                }

                if (SyntaxAnalyzer.IsGenericImmutableArray(typeSymbol, semanticModel))
                {
                    return("Length");
                }

                ImmutableArray <INamedTypeSymbol> allInterfaces = typeSymbol.AllInterfaces;

                for (int i = 0; i < allInterfaces.Length; i++)
                {
                    if (allInterfaces[i].ConstructedFrom.SpecialType == SpecialType.System_Collections_Generic_ICollection_T)
                    {
                        foreach (ISymbol members in typeSymbol.GetMembers("Count"))
                        {
                            if (members.IsProperty() &&
                                members.IsPublic())
                            {
                                return("Count");
                            }
                        }
                    }
                }
            }

            return(null);
        }
        public static async Task ComputeRefactoringsAsync(RefactoringContext context, YieldStatementSyntax yieldStatement)
        {
            if (context.IsAnyRefactoringEnabled(
                    RefactoringIdentifiers.ChangeMemberTypeAccordingToYieldReturnExpression,
                    RefactoringIdentifiers.AddCastExpression,
                    RefactoringIdentifiers.CallToMethod,
                    RefactoringIdentifiers.CreateConditionFromBooleanExpression) &&
                yieldStatement.IsYieldReturn() &&
                yieldStatement.Expression != null &&
                context.SupportsSemanticModel)
            {
                if (context.IsAnyRefactoringEnabled(
                        RefactoringIdentifiers.ChangeMemberTypeAccordingToYieldReturnExpression,
                        RefactoringIdentifiers.AddCastExpression,
                        RefactoringIdentifiers.CallToMethod))
                {
                    MemberDeclarationSyntax containingMember = ReturnExpressionRefactoring.GetContainingMethodOrPropertyOrIndexer(yieldStatement.Expression);

                    if (containingMember != null)
                    {
                        TypeSyntax memberType = ReturnExpressionRefactoring.GetMemberType(containingMember);

                        if (memberType != null)
                        {
                            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                            ITypeSymbol memberTypeSymbol = semanticModel
                                                           .GetTypeInfo(memberType, context.CancellationToken)
                                                           .Type;

                            if (memberTypeSymbol?.SpecialType != SpecialType.System_Collections_IEnumerable)
                            {
                                ITypeSymbol typeSymbol = semanticModel
                                                         .GetTypeInfo(yieldStatement.Expression, context.CancellationToken)
                                                         .Type;

                                if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeMemberTypeAccordingToYieldReturnExpression) &&
                                    typeSymbol?.IsErrorType() == false &&
                                    (memberTypeSymbol == null ||
                                     memberTypeSymbol.IsErrorType() ||
                                     !SyntaxAnalyzer.IsGenericIEnumerable(memberTypeSymbol) ||
                                     !((INamedTypeSymbol)memberTypeSymbol).TypeArguments[0].Equals(typeSymbol)))
                                {
                                    TypeSyntax newType = QualifiedName(
                                        ParseName("System.Collections.Generic"),
                                        GenericName(
                                            Identifier("IEnumerable"),
                                            TypeArgumentList(
                                                SingletonSeparatedList(
                                                    CSharpFactory.Type(typeSymbol)))));

                                    context.RegisterRefactoring(
                                        $"Change {ReturnExpressionRefactoring.GetText(containingMember)} type to 'IEnumerable<{typeSymbol.ToDisplayString(SyntaxUtility.DefaultSymbolDisplayFormat)}>'",
                                        cancellationToken =>
                                    {
                                        return(ChangeTypeRefactoring.ChangeTypeAsync(
                                                   context.Document,
                                                   memberType,
                                                   newType,
                                                   cancellationToken));
                                    });
                                }

                                if (context.IsAnyRefactoringEnabled(RefactoringIdentifiers.AddCastExpression, RefactoringIdentifiers.CallToMethod) &&
                                    yieldStatement.Expression.Span.Contains(context.Span) &&
                                    memberTypeSymbol?.IsNamedType() == true)
                                {
                                    var namedTypeSymbol = (INamedTypeSymbol)memberTypeSymbol;

                                    if (namedTypeSymbol.ConstructedFrom.SpecialType == SpecialType.System_Collections_Generic_IEnumerable_T)
                                    {
                                        ITypeSymbol argumentSymbol = namedTypeSymbol.TypeArguments[0];

                                        if (argumentSymbol != typeSymbol)
                                        {
                                            ModifyExpressionRefactoring.ComputeRefactoring(
                                                context,
                                                yieldStatement.Expression,
                                                argumentSymbol,
                                                semanticModel);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                if (context.IsRefactoringEnabled(RefactoringIdentifiers.CreateConditionFromBooleanExpression))
                {
                    await CreateConditionFromBooleanExpressionRefactoring.ComputeRefactoringAsync(context, yieldStatement.Expression).ConfigureAwait(false);
                }
            }
        }
        public static void Analyze(
            SyntaxNodeAnalysisContext context,
            InvocationExpressionSyntax invocation,
            MemberAccessExpressionSyntax memberAccess)
        {
            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;

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

                    if (string.Equals(memberAccess2.Name?.Identifier.ValueText, "Where", StringComparison.Ordinal))
                    {
                        IMethodSymbol methodSymbol = semanticModel.GetMethodSymbol(invocation2, cancellationToken);

                        if (methodSymbol != null)
                        {
                            IMethodSymbol reducedFrom = methodSymbol.ReducedFrom;

                            if (reducedFrom?.Name.Equals("Where", StringComparison.Ordinal) == true)
                            {
                                ImmutableArray <IParameterSymbol> parameters = methodSymbol.Parameters;

                                if (parameters.Length == 1 &&
                                    SyntaxAnalyzer.IsContainedInEnumerable(reducedFrom, semanticModel) &&
                                    SyntaxAnalyzer.IsGenericIEnumerable(reducedFrom.Parameters.First().Type))
                                {
                                    if (SyntaxAnalyzer.IsPredicateFunc(
                                            parameters[0].Type,
                                            methodSymbol.TypeArguments[0],
                                            semanticModel))
                                    {
                                        if (SyntaxAnalyzer.IsEnumerableWhereMethod(invocation, semanticModel, cancellationToken))
                                        {
                                            Analyze(context, invocation, invocation2, memberAccess, memberAccess2);
                                        }
                                    }
                                    else if (SyntaxAnalyzer.IsPredicateFunc(
                                                 parameters[0].Type,
                                                 methodSymbol.TypeArguments[0],
                                                 semanticModel.Compilation.GetSpecialType(SpecialType.System_Int32),
                                                 semanticModel))
                                    {
                                        if (SyntaxAnalyzer.IsEnumerableWhereMethodWithIndex(invocation, semanticModel, cancellationToken))
                                        {
                                            Analyze(context, invocation, invocation2, memberAccess, memberAccess2);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }