예제 #1
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveTypeParameter))
            {
                return;
            }

            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            TypeParameterSyntax typeParameter = root
                                                .FindNode(context.Span, getInnermostNodeForTie: true)?
                                                .FirstAncestorOrSelf <TypeParameterSyntax>();

            Debug.Assert(typeParameter != null, $"{nameof(typeParameter)} is null");

            if (typeParameter == null)
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.TypeParameterHasSameNameAsTypeParameterFromOuterType:
                {
                    TypeParameterInfo info;
                    if (TypeParameterInfo.TryCreate(typeParameter, out info))
                    {
                        CodeAction codeAction = CodeAction.Create(
                            $"Remove type parameter '{info.Name}'",
                            cancellationToken =>
                            {
                                SeparatedSyntaxList <TypeParameterSyntax> parameters = info.TypeParameterList.Parameters;

                                TypeParameterListSyntax newTypeParameterList = (parameters.Count == 1)
                                            ? default(TypeParameterListSyntax)
                                            : info.TypeParameterList.WithParameters(parameters.Remove(typeParameter));

                                SyntaxNode newNode = GenericDeclarationHelper.WithTypeParameterList(info.Declaration, newTypeParameterList);

                                TypeParameterConstraintClauseSyntax constraintClause = info.ConstraintClause;

                                if (constraintClause != null)
                                {
                                    newNode = GenericDeclarationHelper.WithConstraintClauses(newNode, info.ConstraintClauses.Remove(constraintClause));
                                }

                                return(context.Document.ReplaceNodeAsync(info.Declaration, newNode, cancellationToken));
                            },
                            GetEquivalenceKey(diagnostic));

                        context.RegisterCodeFix(codeAction, diagnostic);
                    }

                    break;
                }
                }
            }
        }
예제 #2
0
        private void MoveConstraint(
            CodeFixContext context,
            Diagnostic diagnostic,
            TypeParameterConstraintSyntax constraint,
            SeparatedSyntaxList <TypeParameterConstraintSyntax> constraints,
            int index)
        {
            CodeAction codeAction = CodeAction.Create(
                $"Move constraint '{constraint}'",
                cancellationToken =>
            {
                var constraintClause = (TypeParameterConstraintClauseSyntax)constraint.Parent;

                SeparatedSyntaxList <TypeParameterConstraintSyntax> newConstraints = constraints.Remove(constraint).Insert(index, constraint);

                TypeParameterConstraintClauseSyntax newNode = constraintClause
                                                              .WithConstraints(newConstraints)
                                                              .WithFormatterAnnotation();

                return(context.Document.ReplaceNodeAsync(constraintClause, newNode, cancellationToken));
            },
                GetEquivalenceKey(diagnostic));

            context.RegisterCodeFix(codeAction, diagnostic);
        }
예제 #3
0
        private TypeParameterListSyntax RemoveTypeParameterHelper(TypeParameterSyntax typeParameter)
        {
            SeparatedSyntaxList <TypeParameterSyntax> parameters = TypeParameters;

            return((parameters.Count == 1)
                ? default(TypeParameterListSyntax)
                : TypeParameterList.WithParameters(parameters.Remove(typeParameter)));
        }
예제 #4
0
        private static InvocationExpressionSyntax GetNewInvocation(InvocationExpressionSyntax invocation)
        {
            ExpressionSyntax   expression   = invocation.Expression;
            ArgumentListSyntax argumentList = invocation.ArgumentList;
            SeparatedSyntaxList <ArgumentSyntax> arguments = argumentList.Arguments;
            ArgumentSyntax argument = arguments.First();

            MemberAccessExpressionSyntax newMemberAccess = null;

            switch (expression.Kind())
            {
            case SyntaxKind.IdentifierName:
            case SyntaxKind.GenericName:
            {
                ExpressionSyntax newExpression = argument.Expression
                                                 .WithLeadingTrivia(expression.GetLeadingTrivia())
                                                 .Parenthesize();

                newMemberAccess = SimpleMemberAccessExpression(
                    newExpression,
                    (SimpleNameSyntax)expression.WithoutLeadingTrivia());

                break;
            }

            case SyntaxKind.SimpleMemberAccessExpression:
            {
                var memberAccess = (MemberAccessExpressionSyntax)expression;

                ExpressionSyntax newExpression = argument.Expression
                                                 .WithTriviaFrom(memberAccess.Expression)
                                                 .Parenthesize();

                newMemberAccess = memberAccess.WithExpression(newExpression);

                break;
            }

            default:
            {
                Debug.Fail(expression.Kind().ToString());
                return(invocation);
            }
            }

            return(invocation
                   .WithExpression(newMemberAccess)
                   .WithArgumentList(argumentList.WithArguments(arguments.Remove(argument))));
        }
예제 #5
0
        private static InvocationExpressionSyntax GetNewInvocation(InvocationExpressionSyntax invocation)
        {
            ExpressionSyntax   expression   = invocation.Expression;
            ArgumentListSyntax argumentList = invocation.ArgumentList;
            SeparatedSyntaxList <ArgumentSyntax> arguments = argumentList.Arguments;
            ArgumentSyntax argument = arguments[0];

            MemberAccessExpressionSyntax newMemberAccess = CreateNewMemberAccessExpression();

            if (newMemberAccess == null)
            {
                return(null);
            }

            return(invocation
                   .WithExpression(newMemberAccess)
                   .WithArgumentList(argumentList.WithArguments(arguments.Remove(argument))));

            MemberAccessExpressionSyntax CreateNewMemberAccessExpression()
            {
                switch (expression.Kind())
                {
                case SyntaxKind.IdentifierName:
                case SyntaxKind.GenericName:
                {
                    return(SimpleMemberAccessExpression(
                               ParenthesizedExpression(argument.Expression),
                               (SimpleNameSyntax)expression));
                }

                case SyntaxKind.SimpleMemberAccessExpression:
                {
                    var memberAccess = (MemberAccessExpressionSyntax)expression;

                    return(memberAccess.WithExpression(ParenthesizedExpression(argument.Expression)));
                }

                default:
                {
                    Debug.Fail(expression.Kind().ToString());
                    return(null);
                }
                }
            }
        }
예제 #6
0
        private static InvocationExpressionSyntax GetNewInvocation(InvocationExpressionSyntax invocation)
        {
            ExpressionSyntax   expression   = invocation.Expression;
            ArgumentListSyntax argumentList = invocation.ArgumentList;
            SeparatedSyntaxList <ArgumentSyntax> arguments = argumentList.Arguments;
            ArgumentSyntax argument = arguments.First();

            MemberAccessExpressionSyntax newMemberAccess = CreateNewMemberAccessExpression();

            return(invocation
                   .WithExpression(newMemberAccess)
                   .WithArgumentList(argumentList.WithArguments(arguments.Remove(argument))));

            MemberAccessExpressionSyntax CreateNewMemberAccessExpression()
            {
                switch (expression.Kind())
                {
                case SyntaxKind.IdentifierName:
                case SyntaxKind.GenericName:
                {
                    ExpressionSyntax newExpression = argument.Expression
                                                     .WithLeadingTrivia(expression.GetLeadingTrivia())
                                                     .Parenthesize();

                    return(SimpleMemberAccessExpression(
                               newExpression,
                               (SimpleNameSyntax)expression.WithoutLeadingTrivia()));
                }

                case SyntaxKind.SimpleMemberAccessExpression:
                {
                    var memberAccess = (MemberAccessExpressionSyntax)expression;

                    ExpressionSyntax newExpression = argument.Expression
                                                     .WithTriviaFrom(memberAccess.Expression)
                                                     .Parenthesize();

                    return(memberAccess.WithExpression(newExpression));
                }
                }

                throw new InvalidOperationException();
            }
        }
예제 #7
0
        private void DoTestAddInsertRemoveOnEmptyList(SeparatedSyntaxList <SyntaxNode> list)
        {
            Assert.Equal(0, list.Count);

            SyntaxNode nodeD = SyntaxFactory.ParseExpression("D");
            SyntaxNode nodeE = SyntaxFactory.ParseExpression("E");

            var newList = list.Add(nodeD);

            Assert.Equal(1, newList.Count);
            Assert.Equal("D", newList.ToFullString());

            newList = list.AddRange(new[] { nodeD, nodeE });
            Assert.Equal(2, newList.Count);
            Assert.Equal("D,E", newList.ToFullString());

            newList = list.Insert(0, nodeD);
            Assert.Equal(1, newList.Count);
            Assert.Equal("D", newList.ToFullString());

            newList = list.InsertRange(0, new[] { nodeD, nodeE });
            Assert.Equal(2, newList.Count);
            Assert.Equal("D,E", newList.ToFullString());

            newList = list.Remove(nodeD);
            Assert.Equal(0, newList.Count);

            Assert.Equal(-1, list.IndexOf(nodeD));
            Assert.Throws <ArgumentOutOfRangeException>(() => list.RemoveAt(0));
            Assert.Throws <ArgumentOutOfRangeException>(() => list.Insert(1, nodeD));
            Assert.Throws <ArgumentOutOfRangeException>(() => list.Insert(-1, nodeD));
            Assert.Throws <ArgumentOutOfRangeException>(() => list.InsertRange(1, new[] { nodeD }));
            Assert.Throws <ArgumentOutOfRangeException>(() => list.InsertRange(-1, new[] { nodeD }));
            Assert.Throws <ArgumentNullException>(() => list.Add(null));
            Assert.Throws <ArgumentNullException>(
                () => list.AddRange((IEnumerable <SyntaxNode>)null)
                );
            Assert.Throws <ArgumentNullException>(() => list.Insert(0, null));
            Assert.Throws <ArgumentNullException>(
                () => list.InsertRange(0, (IEnumerable <SyntaxNode>)null)
                );
        }
예제 #8
0
        /// <summary>
        /// Creates a new <see cref="GenericInfo"/> with the specified type parameter removed.
        /// </summary>
        /// <param name="typeParameter"></param>
        /// <returns></returns>
        public GenericInfo RemoveTypeParameter(TypeParameterSyntax typeParameter)
        {
            ThrowInvalidOperationIfNotInitialized();

            var self = this;

            switch (self.Node.Kind())
            {
            case SyntaxKind.ClassDeclaration:
                return(new GenericInfo(((ClassDeclarationSyntax)self.Node).WithTypeParameterList(RemoveTypeParameter())));

            case SyntaxKind.DelegateDeclaration:
                return(new GenericInfo(((DelegateDeclarationSyntax)self.Node).WithTypeParameterList(RemoveTypeParameter())));

            case SyntaxKind.InterfaceDeclaration:
                return(new GenericInfo(((InterfaceDeclarationSyntax)self.Node).WithTypeParameterList(RemoveTypeParameter())));

            case SyntaxKind.LocalFunctionStatement:
                return(new GenericInfo(((LocalFunctionStatementSyntax)self.Node).WithTypeParameterList(RemoveTypeParameter())));

            case SyntaxKind.MethodDeclaration:
                return(new GenericInfo(((MethodDeclarationSyntax)self.Node).WithTypeParameterList(RemoveTypeParameter())));

            case SyntaxKind.StructDeclaration:
                return(new GenericInfo(((StructDeclarationSyntax)self.Node).WithTypeParameterList(RemoveTypeParameter())));
            }

            Debug.Fail(self.Node.Kind().ToString());
            return(this);

            TypeParameterListSyntax RemoveTypeParameter()
            {
                SeparatedSyntaxList <TypeParameterSyntax> parameters = self.TypeParameters;

                return((parameters.Count == 1)
                    ? default(TypeParameterListSyntax)
                    : self.TypeParameterList.WithParameters(parameters.Remove(typeParameter)));
            }
        }
예제 #9
0
        private void DoTestAddInsertRemoveOnEmptyList(SeparatedSyntaxList<SyntaxNode> list)
        {
            Assert.Equal(0, list.Count);

            SyntaxNode nodeD = SyntaxFactory.ParseExpression("D");
            SyntaxNode nodeE = SyntaxFactory.ParseExpression("E");

            var newList = list.Add(nodeD);
            Assert.Equal(1, newList.Count);
            Assert.Equal("D", newList.ToFullString());

            newList = list.AddRange(new[] { nodeD, nodeE });
            Assert.Equal(2, newList.Count);
            Assert.Equal("D,E", newList.ToFullString());

            newList = list.Insert(0, nodeD);
            Assert.Equal(1, newList.Count);
            Assert.Equal("D", newList.ToFullString());

            newList = list.InsertRange(0, new[] { nodeD, nodeE });
            Assert.Equal(2, newList.Count);
            Assert.Equal("D,E", newList.ToFullString());

            newList = list.Remove(nodeD);
            Assert.Equal(0, newList.Count);

            Assert.Equal(-1, list.IndexOf(nodeD));
            Assert.Throws<ArgumentOutOfRangeException>(() => list.RemoveAt(0));
            Assert.Throws<ArgumentOutOfRangeException>(() => list.Insert(1, nodeD));
            Assert.Throws<ArgumentOutOfRangeException>(() => list.Insert(-1, nodeD));
            Assert.Throws<ArgumentOutOfRangeException>(() => list.InsertRange(1, new[] { nodeD }));
            Assert.Throws<ArgumentOutOfRangeException>(() => list.InsertRange(-1, new[] { nodeD }));
            Assert.Throws<ArgumentNullException>(() => list.Add(null));
            Assert.Throws<ArgumentNullException>(() => list.AddRange((IEnumerable<SyntaxNode>)null));
            Assert.Throws<ArgumentNullException>(() => list.Insert(0, null));
            Assert.Throws<ArgumentNullException>(() => list.InsertRange(0, (IEnumerable<SyntaxNode>)null));
        }
 public SeparatedSyntaxList <TItem> Remove(SeparatedSyntaxList <TItem> list, TItem item)
 {
     return(list.Remove(item));
 }
        private static async Task <Document> RefactorAsync(
            Document document,
            InvocationExpressionSyntax invocation,
            CancellationToken cancellationToken)
        {
            ExpressionSyntax   expression   = invocation.Expression;
            ArgumentListSyntax argumentList = invocation.ArgumentList;
            SeparatedSyntaxList <ArgumentSyntax> arguments = argumentList.Arguments;
            ArgumentSyntax argument = arguments.First();

            MemberAccessExpressionSyntax newMemberAccess = null;

            switch (expression.Kind())
            {
            case SyntaxKind.IdentifierName:
            {
                newMemberAccess = SimpleMemberAccessExpression(
                    argument.Expression.WithLeadingTrivia(expression.GetLeadingTrivia()),
                    (SimpleNameSyntax)expression.WithoutLeadingTrivia());

                break;
            }

            case SyntaxKind.SimpleMemberAccessExpression:
            {
                var memberAccess = (MemberAccessExpressionSyntax)expression;

                newMemberAccess = memberAccess
                                  .WithExpression(argument.Expression.WithTriviaFrom(memberAccess.Expression));

                break;
            }

            default:
            {
                Debug.Assert(false, expression.Kind().ToString());
                return(document);
            }
            }

            InvocationExpressionSyntax newInvocation = invocation
                                                       .WithExpression(newMemberAccess)
                                                       .WithArgumentList(argumentList.WithArguments(arguments.Remove(argument)));

            return(await document.ReplaceNodeAsync(invocation, newInvocation, cancellationToken).ConfigureAwait(false));
        }
 public override SeparatedSyntaxListWrapper <TNode> Remove(TNode node)
 => new AutoWrapSeparatedSyntaxList <TSyntax>(syntaxList.Remove((TSyntax)SyntaxWrapper.Unwrap(node)));