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); }
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; } } } }