예제 #1
0
        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)));
                }
            }
        }