public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.MoveBaseClassBeforeAnyInterface)) { return; } SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false); BaseListSyntax baseList = root .FindNode(context.Span, getInnermostNodeForTie: true)? .FirstAncestorOrSelf <BaseListSyntax>(); Debug.Assert(baseList != null, $"{nameof(baseList)} is null"); if (baseList == null || baseList.ContainsDiagnostics) { return; } foreach (Diagnostic diagnostic in context.Diagnostics) { switch (diagnostic.Id) { case CompilerDiagnosticIdentifiers.BaseClassMustComeBeforeAnyInterface: { SeparatedSyntaxList <BaseTypeSyntax> types = baseList.Types; if (types.Count > 1) { BaseTypeSyntax baseType = types.First(f => context.Span.Contains(f.Span)); CodeAction codeAction = CodeAction.Create( $"Move '{baseType.Type}' before any interface", cancellationToken => { BaseTypeSyntax firstType = types[0]; SeparatedSyntaxList <BaseTypeSyntax> newTypes = types .Replace(baseType, firstType.WithTriviaFrom(baseType)) .ReplaceAt(0, baseType.WithTriviaFrom(firstType)); BaseListSyntax newBaseList = baseList.WithTypes(newTypes); return(context.Document.ReplaceNodeAsync(baseList, newBaseList, context.CancellationToken)); }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); } break; } } } }
private static StructDeclarationSyntax AddBaseType(StructDeclarationSyntax structDeclaration, BaseTypeSyntax baseType) { BaseListSyntax baseList = structDeclaration.BaseList; if (baseList == null) { baseList = BaseList(baseType); TypeParameterListSyntax typeParameterList = structDeclaration.TypeParameterList; if (typeParameterList != null) { return(structDeclaration .WithTypeParameterList(typeParameterList.WithoutTrailingTrivia()) .WithBaseList(baseList.WithTrailingTrivia(typeParameterList.GetTrailingTrivia()))); } else { SyntaxToken identifier = structDeclaration.Identifier; return(structDeclaration .WithIdentifier(identifier.WithoutTrailingTrivia()) .WithBaseList(baseList.WithTrailingTrivia(identifier.TrailingTrivia))); } } else { SeparatedSyntaxList <BaseTypeSyntax> types = baseList.Types; BaseTypeSyntax lastType = types.LastOrDefault(); if (lastType == null || (types.Count == 1 && types[0].IsMissing)) { SyntaxToken colonToken = baseList.ColonToken; baseType = baseType .WithLeadingTrivia(Space) .WithTrailingTrivia(colonToken.TrailingTrivia); baseList = baseList .WithColonToken(colonToken.WithoutTrailingTrivia()) .WithTypes(SingletonSeparatedList(baseType)); return(structDeclaration.WithBaseList(baseList)); } else { types = types .Replace(lastType, lastType.WithoutTrailingTrivia()) .Add(baseType.WithTrailingTrivia(lastType.GetTrailingTrivia())); return(structDeclaration.WithBaseList(baseList.WithTypes(types))); } } }