예제 #1
0
        private void MoveConstraint(
            CodeFixContext context,
            Diagnostic diagnostic,
            TypeParameterConstraintInfo constraintInfo,
            int index)
        {
            CodeAction codeAction = CodeAction.Create(
                $"Move constraint '{constraintInfo.Constraint}'",
                ct =>
            {
                SeparatedSyntaxList <TypeParameterConstraintSyntax> newConstraints = constraintInfo.Constraints
                                                                                     .Remove(constraintInfo.Constraint)
                                                                                     .Insert(index, constraintInfo.Constraint);

                TypeParameterConstraintClauseSyntax newNode = constraintInfo.ConstraintClause
                                                              .WithConstraints(newConstraints)
                                                              .WithFormatterAnnotation();

                return(context.Document.ReplaceNodeAsync(constraintInfo.ConstraintClause, newNode, ct));
            },
                GetEquivalenceKey(diagnostic));

            context.RegisterCodeFix(codeAction, diagnostic);
        }
예제 #2
0
        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out TypeParameterConstraintSyntax constraint))
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.CS0401_NewConstraintMustBeLastConstraintSpecified:
                {
                    if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.MoveConstraint, context.Document, root.SyntaxTree))
                    {
                        break;
                    }

                    TypeParameterConstraintInfo constraintInfo = SyntaxInfo.TypeParameterConstraintInfo(constraint);

                    if (!constraintInfo.Success)
                    {
                        break;
                    }

                    MoveConstraint(context, diagnostic, constraintInfo, constraintInfo.Constraints.Count - 1);

                    break;
                }

                case CompilerDiagnosticIdentifiers.CS0405_DuplicateConstraintForTypeParameter:
                {
                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveConstraint, context.Document, root.SyntaxTree))
                    {
                        RemoveConstraint(context, diagnostic, constraint);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CS0449_ClassOrStructConstraintMustComeBeforeAnyOtherConstraints:
                {
                    if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.MoveConstraint, context.Document, root.SyntaxTree))
                    {
                        break;
                    }

                    TypeParameterConstraintInfo constraintInfo = SyntaxInfo.TypeParameterConstraintInfo(constraint);

                    if (!constraintInfo.Success)
                    {
                        break;
                    }

                    if (constraintInfo.IsDuplicateConstraint)
                    {
                        RemoveConstraint(context, diagnostic, constraint);
                    }
                    else
                    {
                        MoveConstraint(context, diagnostic, constraintInfo, 0);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CS0450_CannotSpecifyBothConstraintClassAndClassOrStructConstraint:
                {
                    if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveConstraint, context.Document, root.SyntaxTree))
                    {
                        break;
                    }

                    TypeParameterConstraintInfo constraintInfo = SyntaxInfo.TypeParameterConstraintInfo(constraint);

                    if (!constraintInfo.Success)
                    {
                        break;
                    }

                    RemoveConstraint(context, diagnostic, constraint);

                    TypeParameterConstraintSyntax classConstraint = constraintInfo.Constraints.Find(SyntaxKind.ClassConstraint);

                    if (classConstraint != null)
                    {
                        RemoveConstraint(context, diagnostic, classConstraint);
                    }

                    TypeParameterConstraintSyntax structConstraint = constraintInfo.Constraints.Find(SyntaxKind.StructConstraint);

                    if (structConstraint != null)
                    {
                        RemoveConstraint(context, diagnostic, structConstraint);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CS0451_NewConstraintCannotBeUsedWithStructConstraint:
                {
                    if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveConstraint, context.Document, root.SyntaxTree))
                    {
                        break;
                    }

                    RemoveConstraint(context, diagnostic, constraint);

                    TypeParameterConstraintInfo constraintInfo = SyntaxInfo.TypeParameterConstraintInfo(constraint);

                    if (!constraintInfo.Success)
                    {
                        break;
                    }

                    TypeParameterConstraintSyntax structConstraint = constraintInfo.Constraints.Find(SyntaxKind.StructConstraint);

                    RemoveConstraint(context, diagnostic, structConstraint);
                    break;
                }
                }
            }
        }