Exemple #1
0
        public static void ComputeRefactoring(RefactoringContext context, UnsafeStatementSyntax unsafeStatement)
        {
            SyntaxToken unsafeKeyword = unsafeStatement.UnsafeKeyword;

            if (!context.Span.IsEmptyAndContainedInSpan(unsafeKeyword))
            {
                return;
            }

            SyntaxNode parent = unsafeStatement.FirstAncestor(f => CSharpFacts.CanHaveUnsafeModifier(f.Kind()));

            if (parent == null)
            {
                return;
            }

            ModifierListInfo modifiersInfo = SyntaxInfo.ModifierListInfo(parent);

            if (modifiersInfo.IsUnsafe)
            {
                return;
            }

            context.RegisterRefactoring(
                GetTitle(parent.Kind()),
                ct => RefactorAsync(context.Document, unsafeStatement, parent, ct),
                RefactoringIdentifiers.MoveUnsafeContextToContainingDeclaration);
        }
Exemple #2
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            if (!Settings.IsAnyEnabled(
                    CodeFixIdentifiers.AddStaticModifier,
                    CodeFixIdentifiers.MakeMemberNonStatic))
            {
                return;
            }

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

            if (!TryFindNode(root, context.Span, out SyntaxNode node))
            {
                return;
            }

            Diagnostic diagnostic = context.Diagnostics[0];

            for (SyntaxNode parent = node.Parent; parent != null; parent = parent.Parent)
            {
                if (parent is MemberDeclarationSyntax memberDeclaration)
                {
                    Debug.Assert(SyntaxInfo.ModifierListInfo(memberDeclaration).IsStatic, memberDeclaration.ToString());

                    if (SyntaxInfo.ModifierListInfo(memberDeclaration).IsStatic)
                    {
                        if (Settings.IsEnabled(CodeFixIdentifiers.MakeMemberNonStatic))
                        {
                            ModifiersCodeFixRegistrator.RemoveModifier(
                                context,
                                diagnostic,
                                memberDeclaration,
                                SyntaxKind.StaticKeyword,
                                title: $"Make containing {CSharpFacts.GetTitle(memberDeclaration)} non-static",
                                additionalKey: CodeFixIdentifiers.MakeMemberNonStatic);
                        }

                        if (Settings.IsEnabled(CodeFixIdentifiers.AddStaticModifier))
                        {
                            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                            AddStaticModifier(context, diagnostic, node, semanticModel);
                        }
                    }

                    return;
                }
                else if (parent is ConstructorInitializerSyntax)
                {
                    if (Settings.IsEnabled(CodeFixIdentifiers.AddStaticModifier))
                    {
                        SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                        AddStaticModifier(context, diagnostic, node, semanticModel);
                    }

                    return;
                }
            }
        }
Exemple #3
0
        private static Task <Document> ChangeTypeAndAddAwait(
            Document document,
            SyntaxNode declaration,
            VariableDeclarationSyntax variableDeclaration,
            TypeSyntax type,
            ExpressionSyntax expression,
            ITypeSymbol newTypeSymbol,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            AwaitExpressionSyntax newExpression = SyntaxFactory.AwaitExpression(expression).WithTriviaFrom(expression);

            VariableDeclarationSyntax newVariableDeclaration = variableDeclaration.ReplaceNode(expression, newExpression);

            TypeSyntax newType = newTypeSymbol.ToMinimalTypeSyntax(semanticModel, type.SpanStart).WithTriviaFrom(type);

            newVariableDeclaration = newVariableDeclaration.WithType(newType);

            if (!SyntaxInfo.ModifierListInfo(declaration).IsAsync)
            {
                SyntaxNode newDeclaration = declaration
                                            .ReplaceNode(variableDeclaration, newVariableDeclaration)
                                            .InsertModifier(SyntaxKind.AsyncKeyword);

                return(document.ReplaceNodeAsync(declaration, newDeclaration, cancellationToken));
            }

            return(document.ReplaceNodeAsync(variableDeclaration, newVariableDeclaration, cancellationToken));
        }
Exemple #4
0
        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            Diagnostic diagnostic = context.Diagnostics[0];

            if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.MarkOperatorAsPublicAndStatic))
            {
                return;
            }

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

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out MemberDeclarationSyntax memberDeclaration))
            {
                return;
            }

            ModifierListInfo info = SyntaxInfo.ModifierListInfo(memberDeclaration);

            var title = "Add ";

            if (info.ExplicitAccessibility == Accessibility.Public)
            {
                title += "modifier 'static'";
            }
            else if (info.IsStatic)
            {
                title += "modifier 'public'";
            }
            else
            {
                title += "modifiers 'public static'";
            }

            CodeAction codeAction = CodeAction.Create(
                title,
                cancellationToken =>
            {
                SyntaxNode newNode = memberDeclaration;

                if (info.Modifiers.ContainsAny(SyntaxKind.InternalKeyword, SyntaxKind.ProtectedKeyword, SyntaxKind.PrivateKeyword))
                {
                    newNode = SyntaxAccessibility.WithoutExplicitAccessibility(newNode);
                }

                if (!info.Modifiers.Contains(SyntaxKind.PublicKeyword))
                {
                    newNode = ModifierList.Insert(newNode, SyntaxKind.PublicKeyword);
                }

                if (!info.IsStatic)
                {
                    newNode = ModifierList.Insert(newNode, SyntaxKind.StaticKeyword);
                }

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

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

            if (!TryFindNode(root, context.Span, out SyntaxNode node))
            {
                return;
            }

            Diagnostic diagnostic = context.Diagnostics[0];

            for (SyntaxNode parent = node.Parent; parent != null; parent = parent.Parent)
            {
                if (parent is MemberDeclarationSyntax memberDeclaration)
                {
                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    ISymbol symbol = semanticModel.GetSymbol(node, context.CancellationToken);

                    if (symbol?.IsErrorType() != false)
                    {
                        return;
                    }

                    SyntaxDebug.Assert(SyntaxInfo.ModifierListInfo(memberDeclaration).IsStatic, memberDeclaration);

                    if (SyntaxInfo.ModifierListInfo(memberDeclaration).IsStatic)
                    {
                        if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.MakeMemberNonStatic, context.Document, root.SyntaxTree))
                        {
                            ModifiersCodeFixRegistrator.RemoveModifier(
                                context,
                                diagnostic,
                                memberDeclaration,
                                SyntaxKind.StaticKeyword,
                                title: $"Make containing {CSharpFacts.GetTitle(memberDeclaration)} non-static",
                                additionalKey: CodeFixIdentifiers.MakeMemberNonStatic);
                        }

                        if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddStaticModifier, context.Document, root.SyntaxTree))
                        {
                            AddStaticModifier(context, diagnostic, node, semanticModel);
                        }
                    }

                    return;
                }
                else if (parent is ConstructorInitializerSyntax)
                {
                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddStaticModifier, context.Document, root.SyntaxTree))
                    {
                        SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                        AddStaticModifier(context, diagnostic, node, semanticModel);
                    }

                    return;
                }
            }
        }
        private static void ComputeRefactoring(RefactoringContext context, SyntaxNode node, SyntaxToken unsafeModifier)
        {
            if (unsafeModifier.Kind() != SyntaxKind.UnsafeKeyword)
            {
                return;
            }

            if (!context.Span.IsEmptyAndContainedInSpan(unsafeModifier))
            {
                return;
            }

            SyntaxNode parent = node.FirstAncestor(f => CSharpFacts.CanHaveUnsafeModifier(f.Kind()));

            if (parent == null)
            {
                return;
            }

            ModifierListInfo modifiersInfo = SyntaxInfo.ModifierListInfo(parent);

            if (!modifiersInfo.Success)
            {
                return;
            }

            if (modifiersInfo.IsUnsafe)
            {
                return;
            }

            context.RegisterRefactoring(
                GetTitle(parent.Kind()),
                ct => RefactorAsync(context.Document, node, parent, ct));
        }
Exemple #7
0
        public static void RemoveModifiers(
            CodeFixContext context,
            Diagnostic diagnostic,
            SyntaxNode node,
            string additionalKey = null)
        {
            SyntaxToken modifier = SyntaxInfo.ModifierListInfo(node).Modifiers.SingleOrDefault(shouldThrow: false);

            if (modifier != default)
            {
                RemoveModifier(context, diagnostic, node, modifier, additionalKey);
            }
            else
            {
                CodeAction codeAction = CodeAction.Create(
                    "Remove modifiers",
                    cancellationToken =>
                {
                    SyntaxNode newNode = ModifierList.RemoveAll(node);

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

                context.RegisterCodeFix(codeAction, diagnostic);
            }
        }
Exemple #8
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            if (!Settings.IsAnyEnabled(
                    CodeFixIdentifiers.AddOverrideModifier,
                    CodeFixIdentifiers.AddNewModifier,
                    CodeFixIdentifiers.RemoveMemberDeclaration))
            {
                return;
            }

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

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out MemberDeclarationSyntax memberDeclaration))
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.MemberHidesInheritedMemberUseNewKeywordIfHidingWasIntended:
                {
                    if (Settings.IsEnabled(CodeFixIdentifiers.AddNewModifier))
                    {
                        ModifiersCodeFixRegistrator.AddModifier(context, diagnostic, memberDeclaration, SyntaxKind.NewKeyword, additionalKey: nameof(SyntaxKind.NewKeyword));
                    }

                    if (Settings.IsEnabled(CodeFixIdentifiers.RemoveMemberDeclaration))
                    {
                        CodeFixRegistrator.RemoveMemberDeclaration(context, diagnostic, memberDeclaration);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.MemberHidesInheritedMemberToMakeCurrentMethodOverrideThatImplementationAddOverrideKeyword:
                {
                    if (Settings.IsEnabled(CodeFixIdentifiers.AddOverrideModifier) &&
                        !SyntaxInfo.ModifierListInfo(memberDeclaration).IsStatic)
                    {
                        ModifiersCodeFixRegistrator.AddModifier(context, diagnostic, memberDeclaration, SyntaxKind.OverrideKeyword, additionalKey: nameof(SyntaxKind.OverrideKeyword));
                    }

                    if (Settings.IsEnabled(CodeFixIdentifiers.AddNewModifier))
                    {
                        ModifiersCodeFixRegistrator.AddModifier(context, diagnostic, memberDeclaration, SyntaxKind.NewKeyword, additionalKey: nameof(SyntaxKind.NewKeyword));
                    }

                    if (Settings.IsEnabled(CodeFixIdentifiers.RemoveMemberDeclaration))
                    {
                        CodeFixRegistrator.RemoveMemberDeclaration(context, diagnostic, memberDeclaration);
                    }

                    break;
                }
                }
            }
        }
Exemple #9
0
        private static void AddStaticModifier(
            CodeFixContext context,
            Diagnostic diagnostic,
            SyntaxNode node,
            SemanticModel semanticModel)
        {
            ISymbol symbol = semanticModel.GetSymbol(node, context.CancellationToken);

            if (symbol == null)
            {
                return;
            }

            SyntaxNode syntax = symbol.GetSyntaxOrDefault(context.CancellationToken);

            if (syntax == null)
            {
                return;
            }

            if (syntax.Kind() == SyntaxKind.VariableDeclarator)
            {
                syntax = syntax.Parent?.Parent;
            }

            Debug.Assert(syntax.IsKind(SyntaxKind.EventDeclaration, SyntaxKind.EventFieldDeclaration, SyntaxKind.FieldDeclaration, SyntaxKind.MethodDeclaration, SyntaxKind.PropertyDeclaration), syntax.ToString());

            if (!(syntax is MemberDeclarationSyntax memberDeclaration))
            {
                return;
            }

            if (SyntaxInfo.ModifierListInfo(memberDeclaration).IsStatic)
            {
                return;
            }

            Document document = context.Document;

            SyntaxTree tree = memberDeclaration.SyntaxTree;

            if (tree != node.SyntaxTree)
            {
                document = context.Solution().GetDocument(tree);
            }

            ModifiersCodeFixRegistrator.AddModifier(
                context,
                document,
                diagnostic,
                memberDeclaration,
                SyntaxKind.StaticKeyword,
                title: $"Make '{symbol.Name}' static",
                additionalKey: CodeFixIdentifiers.AddStaticModifier);
        }
Exemple #10
0
        public static async Task <Solution> RefactorAsync(
            Solution solution,
            MemberDeclarationListSelection selectedMembers,
            Accessibility newAccessibility,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            var members = new HashSet <MemberDeclarationSyntax>();

            foreach (MemberDeclarationSyntax member in selectedMembers)
            {
                ModifierFilter filter = SyntaxInfo.ModifierListInfo(member).GetFilter();

                if (filter.HasAnyFlag(ModifierFilter.Partial))
                {
                    ISymbol symbol = semanticModel.GetDeclaredSymbol(member, cancellationToken);

                    foreach (SyntaxReference reference in symbol.DeclaringSyntaxReferences)
                    {
                        members.Add((MemberDeclarationSyntax)reference.GetSyntax(cancellationToken));
                    }
                }
                else if (filter.HasAnyFlag(ModifierFilter.AbstractVirtualOverride))
                {
                    ISymbol symbol = GetBaseSymbolOrDefault(member, semanticModel, cancellationToken);

                    if (symbol != null)
                    {
                        foreach (MemberDeclarationSyntax member2 in GetMemberDeclarations(symbol, cancellationToken))
                        {
                            members.Add(member2);
                        }

                        foreach (MemberDeclarationSyntax member2 in await FindOverridingMemberDeclarationsAsync(symbol, solution, cancellationToken).ConfigureAwait(false))
                        {
                            members.Add(member2);
                        }
                    }
                    else
                    {
                        members.Add(member);
                    }
                }
                else
                {
                    members.Add(member);
                }
            }

            return(await solution.ReplaceNodesAsync(
                       members,
                       (node, _) => SyntaxAccessibility.WithExplicitAccessibility(node, newAccessibility),
                       cancellationToken)
                   .ConfigureAwait(false));
        }
Exemple #11
0
        public static void RemoveModifiers(
            CodeFixContext context,
            Diagnostic diagnostic,
            SyntaxNode node,
            Func <SyntaxToken, bool> predicate,
            string additionalKey = null)
        {
            SyntaxTokenList modifiers = SyntaxInfo.ModifierListInfo(node).Modifiers;

            RemoveModifiers(context, diagnostic, node, modifiers, predicate, additionalKey);
        }
        internal static Task <Document> RefactorAsync(
            Document document,
            ExpressionStatementSyntax expressionStatement,
            ITypeSymbol typeSymbol,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            MemberDeclarationSyntax containingMember = expressionStatement.FirstAncestor <MemberDeclarationSyntax>();

            var containingType = (TypeDeclarationSyntax)containingMember.Parent;

            string name = NameGenerator.CreateName(typeSymbol, firstCharToLower: true) ?? DefaultNames.Variable;

            if (RefactoringSettings.Current.PrefixFieldIdentifierWithUnderscore)
            {
                name = "_" + name;
            }

            name = NameGenerator.Default.EnsureUniqueLocalName(
                name,
                semanticModel,
                expressionStatement.SpanStart,
                cancellationToken: cancellationToken);

            name = NameGenerator.Default.EnsureUniqueName(
                name,
                semanticModel,
                containingType.OpenBraceToken.Span.End);

            ExpressionSyntax expression = expressionStatement.Expression;

            ExpressionStatementSyntax newExpressionStatement = ExpressionStatement(
                SimpleAssignmentExpression(
                    IdentifierName(Identifier(name).WithRenameAnnotation()),
                    expression.WithoutTrivia())
                .WithTriviaFrom(expression));

            newExpressionStatement = newExpressionStatement
                                     .WithTriviaFrom(expressionStatement)
                                     .WithFormatterAnnotation();

            FieldDeclarationSyntax fieldDeclaration = FieldDeclaration(
                (SyntaxInfo.ModifierListInfo(containingMember).IsStatic) ? Modifiers.Private_Static() : Modifiers.Private(),
                typeSymbol.ToMinimalTypeSyntax(semanticModel, containingType.OpenBraceToken.Span.End),
                name);

            fieldDeclaration = fieldDeclaration.WithFormatterAnnotation();

            TypeDeclarationSyntax newNode = containingType.ReplaceNode(expressionStatement, newExpressionStatement);

            newNode = MemberDeclarationInserter.Default.Insert(newNode, fieldDeclaration);

            return(document.ReplaceNodeAsync(containingType, newNode, cancellationToken));
        }
Exemple #13
0
        public static async Task <Document> RefactorAsync(
            Document document,
            LockStatementSyntax lockStatement,
            CancellationToken cancellationToken = default)
        {
            MemberDeclarationSyntax containingMember = lockStatement.FirstAncestor <MemberDeclarationSyntax>();

            Debug.Assert(containingMember != null);

            if (containingMember == null)
            {
                return(document);
            }

            TypeDeclarationSyntax containingType = containingMember.FirstAncestor <TypeDeclarationSyntax>();

            Debug.Assert(containingType != null);

            if (containingType == null)
            {
                return(document);
            }

            SyntaxList <MemberDeclarationSyntax> members = containingType.Members;

            int index = members.IndexOf(containingMember);

            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            string name = NameGenerator.Default.EnsureUniqueLocalName(
                LockObjectName,
                semanticModel,
                lockStatement.Expression.SpanStart,
                cancellationToken: cancellationToken);

            LockStatementSyntax newLockStatement = lockStatement
                                                   .WithExpression(IdentifierName(Identifier(name).WithRenameAnnotation()));

            MemberDeclarationSyntax newContainingMember = containingMember
                                                          .ReplaceNode(lockStatement, newLockStatement);

            bool isStatic = SyntaxInfo.ModifierListInfo(containingMember).IsStatic;

            FieldDeclarationSyntax field = CreateFieldDeclaration(name, isStatic).WithFormatterAnnotation();

            SyntaxList <MemberDeclarationSyntax> newMembers = members.ReplaceAt(index, newContainingMember);

            newMembers = MemberDeclarationInserter.Default.Insert(newMembers, field);

            MemberDeclarationSyntax newNode = containingType.WithMembers(newMembers);

            return(await document.ReplaceNodeAsync(containingType, newNode, cancellationToken).ConfigureAwait(false));
        }
Exemple #14
0
        public static void ComputeRefactoring(RefactoringContext context, MemberDeclarationSyntax memberDeclaration)
        {
            ModifierListInfo modifiersInfo = SyntaxInfo.ModifierListInfo(memberDeclaration);

            if (!modifiersInfo.Success)
            {
                return;
            }

            SyntaxToken unsafeModifier = modifiersInfo.Modifiers.Find(SyntaxKind.UnsafeKeyword);

            ComputeRefactoring(context, memberDeclaration, unsafeModifier);
        }
Exemple #15
0
        private static SyntaxNode WithAccessibility(MemberDeclarationSyntax node, Accessibility newAccessibility)
        {
            ModifierListInfo info = SyntaxInfo.ModifierListInfo(node);

            if (info.ExplicitAccessibility == Accessibility.NotApplicable)
            {
                return(node);
            }

            ModifierListInfo newInfo = info.WithExplicitAccessibility(newAccessibility, ModifierKindComparer.Default);

            return(newInfo.Parent);
        }
        private static Task<Document> OrderModifiersAsync(
            Document document,
            MemberDeclarationSyntax declaration,
            CancellationToken cancellationToken = default)
        {
            ModifierListInfo info = SyntaxInfo.ModifierListInfo(declaration);

            SyntaxTokenList modifiers = info.Modifiers;

            SyntaxToken[] newModifiers = modifiers.OrderBy(f => f, ModifierComparer.Default).ToArray();

            for (int i = 0; i < modifiers.Count; i++)
                newModifiers[i] = newModifiers[i].WithTriviaFrom(modifiers[i]);

            return document.ReplaceModifiersAsync(info, newModifiers, cancellationToken);
        }
Exemple #17
0
        public static void RemoveAccessibility(
            CodeFixContext context,
            Diagnostic diagnostic,
            SyntaxNode node,
            string additionalKey = null)
        {
            var accessModifier = default(SyntaxToken);

            foreach (SyntaxToken modifier in SyntaxInfo.ModifierListInfo(node).Modifiers)
            {
                if (IsAccessibilityModifier(modifier.Kind()))
                {
                    if (IsAccessibilityModifier(accessModifier.Kind()))
                    {
                        accessModifier = default;
                        break;
                    }
                    else
                    {
                        accessModifier = modifier;
                    }
                }
            }

            if (IsAccessibilityModifier(accessModifier.Kind()))
            {
                RemoveModifier(context, diagnostic, node, accessModifier, additionalKey: additionalKey);
            }
            else
            {
                CodeAction codeAction = CodeAction.Create(
                    "Remove access modifiers",
                    cancellationToken =>
                {
                    SyntaxNode newNode = SyntaxAccessibility.WithoutExplicitAccessibility(node);

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

                context.RegisterCodeFix(codeAction, diagnostic);
            }
        }
        public static Task <Document> RefactorAsync(
            Document document,
            ParenthesizedLambdaExpressionSyntax parenthesizedLambda,
            MemberDeclarationSyntax memberDeclaration,
            TypeDeclarationSyntax typeDeclaration,
            string methodName,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            methodName = NameGenerator.Default.EnsureUniqueLocalName(methodName, semanticModel, parenthesizedLambda.SpanStart, cancellationToken: cancellationToken);

            MemberDeclarationSyntax newMemberDeclaration = memberDeclaration.ReplaceNode(parenthesizedLambda, IdentifierName(methodName).WithTriviaFrom(parenthesizedLambda));

            IMethodSymbol lambdaSymbol = semanticModel.GetMethodSymbol(parenthesizedLambda, cancellationToken);

            ParameterListSyntax parameterList = parenthesizedLambda.ParameterList;

            SeparatedSyntaxList <ParameterSyntax> parameters = parameterList.Parameters;

            ImmutableArray <IParameterSymbol> parameterSymbols = lambdaSymbol.Parameters;

            parameters = parameters
                         .ReplaceAt(0, AddTypeIfMissing(parameters[0], parameterSymbols[0]))
                         .ReplaceAt(1, AddTypeIfMissing(parameters[1], parameterSymbols[1]));

            cancellationToken.ThrowIfCancellationRequested();

            MethodDeclarationSyntax newMethodDeclaration = MethodDeclaration(
                (SyntaxInfo.ModifierListInfo(memberDeclaration).IsStatic) ? Modifiers.Private_Static() : Modifiers.Private(),
                VoidType(),
                Identifier(methodName).WithRenameAnnotation(),
                parameterList.WithParameters(parameters),
                CreateMethodBody(parenthesizedLambda.Body))
                                                           .WithFormatterAnnotation();

            SyntaxList <MemberDeclarationSyntax> newMembers = typeDeclaration.Members.Replace(memberDeclaration, newMemberDeclaration);

            newMembers = MemberDeclarationInserter.Default.Insert(newMembers, newMethodDeclaration);

            return(document.ReplaceNodeAsync(typeDeclaration, typeDeclaration.WithMembers(newMembers), cancellationToken));
Exemple #19
0
        public static void AnalyzeNamedType(SymbolAnalysisContext context)
        {
            var symbol = (INamedTypeSymbol)context.Symbol;

            if (!symbol.TypeKind.Is(TypeKind.Class, TypeKind.Struct, TypeKind.Interface))
            {
                return;
            }

            SyntaxReference syntaxReference = symbol.DeclaringSyntaxReferences.SingleOrDefault(shouldThrow: false);

            if (syntaxReference == null)
            {
                return;
            }

            if (!(syntaxReference.GetSyntax(context.CancellationToken) is MemberDeclarationSyntax memberDeclaration))
            {
                return;
            }

            SyntaxToken partialKeyword = SyntaxInfo.ModifierListInfo(memberDeclaration).Modifiers.Find(SyntaxKind.PartialKeyword);

            if (!partialKeyword.IsKind(SyntaxKind.PartialKeyword))
            {
                return;
            }

            if (SyntaxInfo.MemberDeclarationListInfo(memberDeclaration)
                .Members
                .Any(member => member.Kind() == SyntaxKind.MethodDeclaration && ((MethodDeclarationSyntax)member).Modifiers.Contains(SyntaxKind.PartialKeyword)))
            {
                return;
            }

            DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.RemovePartialModifierFromTypeWithSinglePart, partialKeyword);
        }
Exemple #20
0
        private static bool ParentDeclarationsContainsUnsafeModifier(SyntaxNode node)
        {
            while (node.IsKind(SyntaxKind.LocalFunctionStatement))
            {
                var localFunction = (LocalFunctionStatementSyntax)node;

                if (localFunction.Modifiers.Contains(SyntaxKind.UnsafeKeyword))
                {
                    return(true);
                }

                node = node.Parent;

                Debug.Assert(node.IsKind(SyntaxKind.Block), node.Kind().ToString());

                if (node.Kind() != SyntaxKind.Block)
                {
                    break;
                }

                node = node.Parent;
            }

            Debug.Assert(node is MemberDeclarationSyntax, node.Kind().ToString());

            if (node is MemberDeclarationSyntax memberDeclaration)
            {
                if (SyntaxInfo.ModifierListInfo(memberDeclaration).IsUnsafe)
                {
                    return(true);
                }

                return(ParentTypeDeclarationsContainsUnsafeModifier(memberDeclaration));
            }

            return(false);
        }
Exemple #21
0
        private static void Analyze(SymbolAnalysisContext context, ISymbol symbol)
        {
            if (symbol.IsImplicitlyDeclared)
            {
                return;
            }

            if (!symbol.IsSealed)
            {
                return;
            }

            if (symbol.ContainingType?.IsSealed != true)
            {
                return;
            }

            Debug.Assert(symbol.ContainingType.TypeKind == TypeKind.Class, symbol.ContainingType.TypeKind.ToString());

            SyntaxNode node = symbol.GetSyntax(context.CancellationToken);

            Debug.Assert(node.IsKind(SyntaxKind.MethodDeclaration, SyntaxKind.PropertyDeclaration, SyntaxKind.IndexerDeclaration), node.Kind().ToString());

            ModifierListInfo info = SyntaxInfo.ModifierListInfo(node);

            Debug.Assert(info.IsSealed, info.Modifiers.ToString());

            if (!info.IsSealed)
            {
                return;
            }

            SyntaxToken sealedKeyword = info.Modifiers.Find(SyntaxKind.SealedKeyword);

            DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.RemoveRedundantSealedModifier, sealedKeyword);
        }
        public static AccessibilityFilter GetValidAccessibilityFilter(
            MemberDeclarationListSelection selectedMembers,
            SemanticModel semanticModel,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            if (selectedMembers.Count < 2)
            {
                return(AccessibilityFilter.None);
            }

            ImmutableArray <Accessibility> avaiableAccessibilities = AvailableAccessibilities;

            var all = AccessibilityFilter.None;

            AccessibilityFilter valid = AccessibilityFilter.Public
                                        | AccessibilityFilter.Internal
                                        | AccessibilityFilter.Protected
                                        | AccessibilityFilter.Private;

            foreach (MemberDeclarationSyntax member in selectedMembers)
            {
                Accessibility accessibility = SyntaxAccessibility.GetExplicitAccessibility(member);

                if (accessibility == Accessibility.NotApplicable)
                {
                    accessibility = SyntaxAccessibility.GetDefaultExplicitAccessibility(member);

                    if (accessibility == Accessibility.NotApplicable)
                    {
                        return(AccessibilityFilter.None);
                    }
                }

                switch (accessibility)
                {
                case Accessibility.Private:
                case Accessibility.Protected:
                case Accessibility.ProtectedAndInternal:
                case Accessibility.ProtectedOrInternal:
                case Accessibility.Internal:
                case Accessibility.Public:
                {
                    all |= accessibility.GetAccessibilityFilter();
                    break;
                }

                default:
                {
                    Debug.Fail(accessibility.ToString());
                    return(AccessibilityFilter.None);
                }
                }

                ModifierListInfo modifiersInfo = SyntaxInfo.ModifierListInfo(member);

                if (modifiersInfo.Modifiers.ContainsAny(
                        SyntaxKind.AbstractKeyword,
                        SyntaxKind.VirtualKeyword,
                        SyntaxKind.OverrideKeyword))
                {
                    valid &= ~AccessibilityFilter.Private;
                }

                if (modifiersInfo.IsOverride &&
                    IsBaseDeclarationWithoutSource(member, semanticModel, cancellationToken))
                {
                    switch (accessibility)
                    {
                    case Accessibility.Private:
                    case Accessibility.Protected:
                    case Accessibility.Internal:
                    case Accessibility.Public:
                    {
                        valid &= accessibility.GetAccessibilityFilter();

                        if (valid == AccessibilityFilter.None)
                        {
                            return(AccessibilityFilter.None);
                        }

                        avaiableAccessibilities = _accessibilityArrayMap[accessibility];
                        continue;
                    }

                    default:
                    {
                        return(AccessibilityFilter.None);
                    }
                    }
                }

                foreach (Accessibility accessibility2 in avaiableAccessibilities)
                {
                    if (accessibility != accessibility2 &&
                        !SyntaxAccessibility.IsValidAccessibility(member, accessibility2, ignoreOverride: true))
                    {
                        valid &= ~accessibility2.GetAccessibilityFilter();

                        if (valid == AccessibilityFilter.None)
                        {
                            return(AccessibilityFilter.None);
                        }
                    }
                }
            }

            switch (all)
            {
            case AccessibilityFilter.Private:
            case AccessibilityFilter.Protected:
            case AccessibilityFilter.Internal:
            case AccessibilityFilter.Public:
            {
                valid &= ~all;
                break;
            }
            }

            return(valid);
        }
Exemple #23
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindToken(root, context.Span.Start, out SyntaxToken token))
            {
                return;
            }

            SyntaxNode node = token.Parent;

            if (!CSharpFacts.CanHaveModifiers(node.Kind()))
            {
                node = node.FirstAncestor(f => CSharpFacts.CanHaveModifiers(f.Kind()));
            }

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

            if (node == null)
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.ModifierIsNotValidForThisItem:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier))
                    {
                        break;
                    }

                    SyntaxTokenList modifiers = SyntaxInfo.ModifierListInfo(node).Modifiers;

                    if (modifiers.Contains(token))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, token);
                        break;
                    }
                    else if (IsInterfaceMemberOrExplicitInterfaceImplementation(node))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifiers(context, diagnostic, node, modifiers, f =>
                            {
                                switch (f.Kind())
                                {
                                case SyntaxKind.PublicKeyword:
                                case SyntaxKind.ProtectedKeyword:
                                case SyntaxKind.InternalKeyword:
                                case SyntaxKind.PrivateKeyword:
                                case SyntaxKind.StaticKeyword:
                                case SyntaxKind.VirtualKeyword:
                                case SyntaxKind.OverrideKeyword:
                                case SyntaxKind.AbstractKeyword:
                                    {
                                        return(true);
                                    }
                                }

                                return(false);
                            });
                    }
                    else if (node.IsKind(SyntaxKind.MethodDeclaration, SyntaxKind.PropertyDeclaration, SyntaxKind.IndexerDeclaration, SyntaxKind.EventDeclaration, SyntaxKind.EventFieldDeclaration) &&
                             node.IsParentKind(SyntaxKind.StructDeclaration) &&
                             modifiers.Contains(SyntaxKind.VirtualKeyword))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.VirtualKeyword);
                    }
                    else if (node.IsKind(SyntaxKind.IndexerDeclaration) &&
                             modifiers.Contains(SyntaxKind.StaticKeyword))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.StaticKeyword);
                    }
                    else if (node.IsKind(SyntaxKind.PropertyDeclaration, SyntaxKind.IndexerDeclaration, SyntaxKind.EventDeclaration, SyntaxKind.EventFieldDeclaration) &&
                             modifiers.Contains(SyntaxKind.AsyncKeyword))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.AsyncKeyword);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.MoreThanOneProtectionModifier:
                {
                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, token);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.AccessibilityModifiersMayNotBeUsedOnAccessorsInInterface:
                case CompilerDiagnosticIdentifiers.AccessModifiersAreNotAllowedOnStaticConstructors:
                {
                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier))
                    {
                        ModifiersCodeFixRegistrator.RemoveAccessibility(context, diagnostic, node);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.ModifiersCannotBePlacedOnEventAccessorDeclarations:
                {
                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifiers(context, diagnostic, node);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.OnlyMethodsClassesStructsOrInterfacesMayBePartial:
                {
                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.PartialKeyword);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.ClassCannotBeBothStaticAndSealed:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier))
                    {
                        break;
                    }

                    ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.StaticKeyword, additionalKey: nameof(SyntaxKind.StaticKeyword));
                    ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.SealedKeyword, additionalKey: nameof(SyntaxKind.SealedKeyword));
                    break;
                }

                case CompilerDiagnosticIdentifiers.FieldCanNotBeBothVolatileAndReadOnly:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier))
                    {
                        break;
                    }

                    var fieldDeclaration = (FieldDeclarationSyntax)node;

                    ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, fieldDeclaration, SyntaxKind.VolatileKeyword, additionalKey: nameof(SyntaxKind.VolatileKeyword));
                    ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, fieldDeclaration, SyntaxKind.ReadOnlyKeyword, additionalKey: nameof(SyntaxKind.ReadOnlyKeyword));
                    break;
                }

                case CompilerDiagnosticIdentifiers.NewProtectedMemberDeclaredInSealedClass:
                case CompilerDiagnosticIdentifiers.StaticClassesCannotContainProtectedMembers:
                {
                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeAccessibility))
                    {
                        ModifiersCodeFixRegistrator.ChangeAccessibility(context, diagnostic, node, _publicOrInternalOrPrivate);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.VirtualOrAbstractMembersCannotBePrivate:
                {
                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveVirtualModifier))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.VirtualKeyword, additionalKey: nameof(SyntaxKind.VirtualKeyword));
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeAccessibility))
                    {
                        ModifiersCodeFixRegistrator.ChangeAccessibility(context, diagnostic, node, _publicOrInternalOrProtected);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.AbstractPropertiesCannotHavePrivateAccessors:
                {
                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier))
                    {
                        ModifiersCodeFixRegistrator.RemoveAccessibility(context, diagnostic, node, additionalKey: CodeFixIdentifiers.RemoveInvalidModifier);
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeAccessibility))
                    {
                        ModifiersCodeFixRegistrator.ChangeAccessibility(context, diagnostic, node, _publicOrInternalOrProtected);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.StaticMemberCannotBeMarkedOverrideVirtualOrAbstract:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier))
                    {
                        break;
                    }

                    if (!node.IsParentKind(SyntaxKind.ClassDeclaration) ||
                        !((ClassDeclarationSyntax)node.Parent).Modifiers.Contains(SyntaxKind.StaticKeyword))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.StaticKeyword, additionalKey: nameof(SyntaxKind.StaticKeyword));
                    }

                    ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.OverrideKeyword, additionalKey: nameof(SyntaxKind.OverrideKeyword));
                    ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.VirtualKeyword, additionalKey: nameof(SyntaxKind.VirtualKeyword));
                    ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.AbstractKeyword, additionalKey: nameof(SyntaxKind.AbstractKeyword));
                    break;
                }

                case CompilerDiagnosticIdentifiers.AsyncModifierCanOnlyBeUsedInMethodsThatHaveBody:
                {
                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.AsyncKeyword);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.PartialMethodCannotHaveAccessModifiersOrVirtualAbstractOverrideNewSealedOrExternModifiers:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier))
                    {
                        break;
                    }

                    ModifiersCodeFixRegistrator.RemoveModifiers(context, diagnostic, node, f =>
                        {
                            switch (f.Kind())
                            {
                            case SyntaxKind.PublicKeyword:
                            case SyntaxKind.ProtectedKeyword:
                            case SyntaxKind.InternalKeyword:
                            case SyntaxKind.PrivateKeyword:
                            case SyntaxKind.VirtualKeyword:
                            case SyntaxKind.AbstractKeyword:
                            case SyntaxKind.OverrideKeyword:
                            case SyntaxKind.NewKeyword:
                            case SyntaxKind.SealedKeyword:
                            case SyntaxKind.ExternKeyword:
                                {
                                    return(true);
                                }
                            }

                            return(false);
                        });

                    break;
                }

                case CompilerDiagnosticIdentifiers.ExtensionMethodMustBeStatic:
                {
                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddStaticModifier))
                    {
                        AddStaticModifier(context, diagnostic, node, CodeFixIdentifiers.AddStaticModifier);
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveThisModifier))
                    {
                        var methodDeclaration = (MethodDeclarationSyntax)node;

                        ParameterSyntax parameter = methodDeclaration.ParameterList.Parameters[0];

                        SyntaxToken modifier = parameter.Modifiers.Find(SyntaxKind.ThisKeyword);

                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, parameter, modifier, additionalKey: CodeFixIdentifiers.RemoveThisModifier);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.ExtensionMethodMustBeDefinedInNonGenericStaticClass:
                {
                    if (!(node is ClassDeclarationSyntax classDeclaration))
                    {
                        return;
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddStaticModifier) &&
                        !classDeclaration.Modifiers.Contains(SyntaxKind.StaticKeyword))
                    {
                        AddStaticModifier(context, diagnostic, node, CodeFixIdentifiers.AddStaticModifier);
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveThisModifier))
                    {
                        IEnumerable <ParameterSyntax> thisParameters = classDeclaration.Members
                                                                       .Where(f => f.IsKind(SyntaxKind.MethodDeclaration))
                                                                       .Cast <MethodDeclarationSyntax>()
                                                                       .Select(f => f.ParameterList?.Parameters.FirstOrDefault())
                                                                       .Where(f => f?.Modifiers.Contains(SyntaxKind.ThisKeyword) == true);

                        ModifiersCodeFixRegistrator.RemoveModifier(
                            context,
                            diagnostic,
                            thisParameters,
                            SyntaxKind.ThisKeyword,
                            title: "Remove 'this' modifier from extension methods",
                            additionalKey: CodeFixIdentifiers.RemoveThisModifier);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.NoDefiningDeclarationFoundForImplementingDeclarationOfPartialMethod:
                {
                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.PartialKeyword);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.MethodHasParameterModifierThisWhichIsNotOnFirstParameter:
                {
                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveThisModifier))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, token.Parent, token);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CannotDeclareInstanceMembersInStaticClass:
                case CompilerDiagnosticIdentifiers.StaticClassesCannotHaveInstanceConstructors:
                {
                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddStaticModifier))
                    {
                        AddStaticModifier(context, diagnostic, node, CodeFixIdentifiers.AddStaticModifier);
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.MakeContainingClassNonStatic))
                    {
                        var classDeclaration = (ClassDeclarationSyntax)node.Parent;

                        ModifiersCodeFixRegistrator.RemoveModifier(
                            context,
                            diagnostic,
                            classDeclaration,
                            classDeclaration.Modifiers.Find(SyntaxKind.StaticKeyword),
                            title: "Make containing class non-static",
                            additionalKey: CodeFixIdentifiers.MakeContainingClassNonStatic);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.ElementsDefinedInNamespaceCannotBeExplicitlyDeclaredAsPrivateProtectedOrProtectedInternal:
                {
                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeAccessibility))
                    {
                        ModifiersCodeFixRegistrator.ChangeAccessibility(context, diagnostic, node, _publicOrInternal);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.NamespaceAlreadyContainsDefinition:
                case CompilerDiagnosticIdentifiers.TypeAlreadyContainsDefinition:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddPartialModifier))
                    {
                        break;
                    }

                    if (!node.IsKind(
                            SyntaxKind.ClassDeclaration,
                            SyntaxKind.StructDeclaration,
                            SyntaxKind.InterfaceDeclaration,
                            SyntaxKind.MethodDeclaration))
                    {
                        return;
                    }

                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    ISymbol symbol = semanticModel.GetDeclaredSymbol(node, context.CancellationToken);

                    ImmutableArray <SyntaxReference> syntaxReferences = symbol.DeclaringSyntaxReferences;

                    if (syntaxReferences.Length <= 1)
                    {
                        break;
                    }

                    ModifiersCodeFixRegistrator.AddModifier(
                        context,
                        diagnostic,
                        ImmutableArray.CreateRange(syntaxReferences, f => f.GetSyntax(context.CancellationToken)),
                        SyntaxKind.PartialKeyword,
                        title: $"Make {CSharpFacts.GetTitle(node)} partial");

                    break;
                }

                case CompilerDiagnosticIdentifiers.NoSuitableMethodFoundToOverride:
                {
                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.OverrideKeyword);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.AsyncMethodsCannotHaveRefOrOutParameters:
                case CompilerDiagnosticIdentifiers.IteratorsCannotHaveRefOrOutParameters:
                case CompilerDiagnosticIdentifiers.ReadOnlyFieldCannotBePassedAsRefOrOutValue:
                {
                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveRefModifier))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.RefKeyword, additionalKey: nameof(SyntaxKind.RefKeyword));
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveOutModifier))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.OutKeyword, additionalKey: nameof(SyntaxKind.OutKeyword));
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CannotHaveInstancePropertyOrFieldInitializersInStruct:
                {
                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddStaticModifier))
                    {
                        AddStaticModifier(context, diagnostic, node);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.MemberMustDeclareBodyBecauseItIsNotMarkedAbstractExternOrPartial:
                {
                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddModifierAbstract) &&
                        node.Kind() == SyntaxKind.MethodDeclaration &&
                        (node.Parent as ClassDeclarationSyntax)?.Modifiers.Contains(SyntaxKind.AbstractKeyword) == true)
                    {
                        ModifiersCodeFixRegistrator.AddModifier(context, diagnostic, node, SyntaxKind.AbstractKeyword);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.NewVirtualMemberInSealedClass:
                {
                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveVirtualModifier))
                    {
                        if (node is AccessorDeclarationSyntax &&
                            SyntaxInfo.ModifierListInfo(node.Parent.Parent).IsVirtual)
                        {
                            node = node.Parent.Parent;
                        }

                        ModifiersCodeFixRegistrator.RemoveModifier(
                            context,
                            diagnostic,
                            node,
                            SyntaxKind.VirtualKeyword,
                            additionalKey: CodeFixIdentifiers.RemoveVirtualModifier);
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.MakeContainingClassUnsealed) &&
                        node.Parent is ClassDeclarationSyntax classDeclaration)
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(
                            context,
                            diagnostic,
                            classDeclaration,
                            SyntaxKind.SealedKeyword,
                            title: "Make containing class unsealed",
                            additionalKey: CodeFixIdentifiers.MakeContainingClassUnsealed);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.InstanceFieldsOfReadOnlyStructsMustBeReadOnly:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.MakeMemberReadOnly))
                    {
                        break;
                    }

                    ModifiersCodeFixRegistrator.AddModifier(context, diagnostic, node, SyntaxKind.ReadOnlyKeyword);
                    break;
                }

                case CompilerDiagnosticIdentifiers.MemberCannotBeSealedBecauseItIsNotOverride:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveSealedModifier))
                    {
                        break;
                    }

                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    if (semanticModel.GetDiagnostic(
                            CompilerDiagnosticIdentifiers.MemberHidesInheritedMemberToMakeCurrentMethodOverrideThatImplementationAddOverrideKeyword,
                            CSharpUtility.GetIdentifier(node).Span,
                            context.CancellationToken) != null)
                    {
                        break;
                    }

                    ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.SealedKeyword);
                    break;
                }
                }
            }
        }
        public static async Task ComputeRefactoringsAsync(RefactoringContext context, SyntaxToken modifier)
        {
            SyntaxNode node = modifier.Parent;

            if (node.IsKind(SyntaxKind.DestructorDeclaration))
            {
                return;
            }

            ModifierListInfo modifiersInfo = SyntaxInfo.ModifierListInfo(node);

            if (node.IsKind(
                    SyntaxKind.ClassDeclaration,
                    SyntaxKind.InterfaceDeclaration,
                    SyntaxKind.StructDeclaration,
                    SyntaxKind.RecordStructDeclaration))
            {
                SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                var symbol = (INamedTypeSymbol)semanticModel.GetDeclaredSymbol(node, context.CancellationToken);

                ImmutableArray <SyntaxReference> syntaxReferences = symbol.DeclaringSyntaxReferences;

                if (syntaxReferences.Length > 1)
                {
                    ImmutableArray <MemberDeclarationSyntax> memberDeclarations = ImmutableArray.CreateRange(
                        syntaxReferences,
                        f => (MemberDeclarationSyntax)f.GetSyntax(context.CancellationToken));

                    foreach (Accessibility accessibility in AvailableAccessibilities)
                    {
                        if (accessibility != modifiersInfo.ExplicitAccessibility &&
                            SyntaxAccessibility.IsValidAccessibility(node, accessibility))
                        {
                            context.RegisterRefactoring(
                                GetTitle(accessibility),
                                ct => RefactorAsync(context.Solution, memberDeclarations, accessibility, ct),
                                RefactoringDescriptors.ChangeAccessibility,
                                accessibility.ToString());
                        }
                    }

                    return;
                }
            }

            foreach (Accessibility accessibility in AvailableAccessibilities)
            {
                if (accessibility == modifiersInfo.ExplicitAccessibility)
                {
                    continue;
                }

                SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                ISymbol symbol = GetBaseSymbolOrDefault(semanticModel, context.CancellationToken);

                if (symbol != null)
                {
                    if (SyntaxAccessibility.IsValidAccessibility(node, accessibility, ignoreOverride: true))
                    {
                        context.RegisterRefactoring(
                            GetTitle(accessibility),
                            ct => RefactorAsync(context.Solution, symbol, accessibility, ct),
                            RefactoringDescriptors.ChangeAccessibility,
                            accessibility.ToString());
                    }
                }
                else if (SyntaxAccessibility.IsValidAccessibility(node, accessibility))
                {
                    context.RegisterRefactoring(
                        GetTitle(accessibility),
                        ct => RefactorAsync(context.Document, node, accessibility, ct),
                        RefactoringDescriptors.ChangeAccessibility,
                        accessibility.ToString());
                }
            }

            ISymbol GetBaseSymbolOrDefault(SemanticModel semanticModel, CancellationToken cancellationToken)
            {
                if (modifiersInfo.GetFilter().HasAnyFlag(ModifierFilter.AbstractVirtualOverride))
                {
                    return(ChangeAccessibilityRefactoring.GetBaseSymbolOrDefault(node, semanticModel, cancellationToken));
                }

                return(null);
            }
        }
        public static Task <Document> RefactorAsync(
            Document document,
            ParenthesizedLambdaExpressionSyntax parenthesizedLambda,
            MemberDeclarationSyntax memberDeclaration,
            TypeDeclarationSyntax typeDeclaration,
            string methodName,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            methodName = NameGenerator.Default.EnsureUniqueLocalName(methodName, semanticModel, parenthesizedLambda.SpanStart, cancellationToken: cancellationToken);

            MemberDeclarationSyntax newMemberDeclaration = memberDeclaration.ReplaceNode(parenthesizedLambda, IdentifierName(methodName).WithTriviaFrom(parenthesizedLambda));

            IMethodSymbol lambdaSymbol = semanticModel.GetMethodSymbol(parenthesizedLambda, cancellationToken);

            ParameterListSyntax parameterList = parenthesizedLambda.ParameterList;

            SeparatedSyntaxList <ParameterSyntax> parameters = parameterList.Parameters;

            ImmutableArray <IParameterSymbol> parameterSymbols = lambdaSymbol.Parameters;

            parameters = parameters
                         .ReplaceAt(0, AddTypeIfMissing(parameters[0], parameterSymbols[0]))
                         .ReplaceAt(1, AddTypeIfMissing(parameters[1], parameterSymbols[1]));

            cancellationToken.ThrowIfCancellationRequested();

            MethodDeclarationSyntax newMethodDeclaration = MethodDeclaration(
                (SyntaxInfo.ModifierListInfo(memberDeclaration).IsStatic) ? Modifiers.Private_Static() : Modifiers.Private(),
                VoidType(),
                Identifier(methodName).WithRenameAnnotation(),
                parameterList.WithParameters(parameters),
                CreateMethodBody(parenthesizedLambda.Body)).WithFormatterAnnotation();

            SyntaxList <MemberDeclarationSyntax> newMembers = typeDeclaration.Members.Replace(memberDeclaration, newMemberDeclaration);

            newMembers = MemberDeclarationInserter.Default.Insert(newMembers, newMethodDeclaration);

            return(document.ReplaceNodeAsync(typeDeclaration, typeDeclaration.WithMembers(newMembers), cancellationToken));

            BlockSyntax CreateMethodBody(CSharpSyntaxNode lambdaBody)
            {
                switch (lambdaBody)
                {
                case BlockSyntax block:
                    return(block);

                case ExpressionSyntax expression:
                    return(Block(ExpressionStatement(expression)));

                default:
                    return(Block());
                }
            }

            ParameterSyntax AddTypeIfMissing(ParameterSyntax parameter, IParameterSymbol parameterSymbol)
            {
                TypeSyntax type = parameter.Type;

                if (type?.IsMissing == false)
                {
                    return(parameter);
                }

                type = parameterSymbol.Type.ToMinimalTypeSyntax(semanticModel, typeDeclaration.OpenBraceToken.Span.End);

                return(parameter.WithType(type));
            }
        }