private static Accessibility?GetPartialAccessModifier(
            SyntaxNodeAnalysisContext context,
            MemberDeclarationSyntax declaration)
        {
            var accessibility = Accessibility.NotApplicable;

            ISymbol symbol = context.SemanticModel.GetDeclaredSymbol(declaration, context.CancellationToken);

            if (symbol != null)
            {
                foreach (SyntaxReference syntaxReference in symbol.DeclaringSyntaxReferences)
                {
                    if (syntaxReference.GetSyntax(context.CancellationToken) is MemberDeclarationSyntax declaration2)
                    {
                        Accessibility accessibility2 = SyntaxAccessibility.GetExplicitAccessibility(declaration2);

                        if (accessibility2 != Accessibility.NotApplicable)
                        {
                            if (accessibility == Accessibility.NotApplicable || accessibility == accessibility2)
                            {
                                accessibility = accessibility2;
                            }
                            else
                            {
                                return(null);
                            }
                        }
                    }
                }
            }

            return(accessibility);
        }
Пример #2
0
        public static Task <Document> RefactorAsync(
            Document document,
            PropertyDeclarationSyntax propertyDeclaration,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            AccessorListSyntax accessorList = AccessorList();

            if (propertyDeclaration.ExpressionBody != null)
            {
                accessorList = accessorList
                               .AddAccessors(AutoGetAccessorDeclaration());
            }
            else
            {
                AccessorDeclarationSyntax getter = propertyDeclaration.Getter();
                if (getter != null)
                {
                    if (SyntaxAccessibility.GetExplicitAccessibility(getter) == Accessibility.Private)
                    {
                        getter = SyntaxAccessibility.WithExplicitAccessibility(getter, Accessibility.Protected);
                    }

                    accessorList = accessorList.AddAccessors(getter
                                                             .WithBody(null)
                                                             .WithSemicolonToken(SemicolonToken()));
                }

                AccessorDeclarationSyntax setter = propertyDeclaration.Setter();
                if (setter != null)
                {
                    if (SyntaxAccessibility.GetExplicitAccessibility(setter) == Accessibility.Private)
                    {
                        setter = SyntaxAccessibility.WithExplicitAccessibility(setter, Accessibility.Protected);
                    }

                    accessorList = accessorList.AddAccessors(setter
                                                             .WithBody(null)
                                                             .WithSemicolonToken(SemicolonToken()));
                }
            }

            PropertyDeclarationSyntax newNode = propertyDeclaration
                                                .WithExpressionBody(null)
                                                .WithSemicolonToken(default(SyntaxToken))
                                                .WithAccessorList(accessorList)
                                                .InsertModifier(SyntaxKind.AbstractKeyword)
                                                .RemoveModifier(SyntaxKind.VirtualKeyword)
                                                .WithTriviaFrom(propertyDeclaration)
                                                .WithFormatterAnnotation();

            return(document.ReplaceNodeAsync(propertyDeclaration, newNode, cancellationToken));
        }
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            Diagnostic diagnostic = context.Diagnostics[0];

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

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

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

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

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

            ImmutableArray <MemberDeclarationSyntax> memberDeclarations = ImmutableArray.CreateRange(
                symbol.DeclaringSyntaxReferences,
                f => (MemberDeclarationSyntax)f.GetSyntax(context.CancellationToken));

            foreach (Accessibility accessibility in memberDeclarations
                     .Select(f => SyntaxAccessibility.GetExplicitAccessibility(f))
                     .Where(f => f != Accessibility.NotApplicable))
            {
                if (SyntaxAccessibility.IsValidAccessibility(memberDeclaration, accessibility))
                {
                    CodeAction codeAction = CodeAction.Create(
                        $"Change accessibility to '{SyntaxFacts.GetText(accessibility)}'",
                        cancellationToken => ChangeAccessibilityRefactoring.RefactorAsync(context.Solution(), memberDeclarations, accessibility, cancellationToken),
                        GetEquivalenceKey(CompilerDiagnosticIdentifiers.PartialDeclarationsHaveConfictingAccessibilityModifiers, accessibility.ToString()));

                    context.RegisterCodeFix(codeAction, diagnostic);
                }
            }
        }
        public static void AnalyzeConstructorDeclaration(SyntaxNodeAnalysisContext context)
        {
            var constructorDeclaration = (ConstructorDeclarationSyntax)context.Node;

            if (!SyntaxAccessibility.GetExplicitAccessibility(constructorDeclaration).Is(Accessibility.Public, Accessibility.ProtectedOrInternal))
            {
                return;
            }

            if (!constructorDeclaration.IsParentKind(SyntaxKind.ClassDeclaration))
            {
                return;
            }

            var classDeclaration = (ClassDeclarationSyntax)constructorDeclaration.Parent;

            SyntaxTokenList modifiers = classDeclaration.Modifiers;

            bool isAbstract = modifiers.Contains(SyntaxKind.AbstractKeyword);

            if (!isAbstract &&
                modifiers.Contains(SyntaxKind.PartialKeyword))
            {
                INamedTypeSymbol classSymbol = context.SemanticModel.GetDeclaredSymbol(classDeclaration, context.CancellationToken);

                if (classSymbol != null)
                {
                    isAbstract = classSymbol.IsAbstract;
                }
            }

            if (!isAbstract)
            {
                return;
            }

            context.ReportDiagnostic(DiagnosticDescriptors.AbstractTypeShouldNotHavePublicConstructors, constructorDeclaration.Identifier);
        }
        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);
        }
Пример #6
0
        public static Accessibilities GetValidAccessibilities(MemberDeclarationListSelection selectedMembers, bool allowOverride = false)
        {
            if (selectedMembers.Count < 2)
            {
                return(Accessibilities.None);
            }

            var all = Accessibilities.None;

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

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

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

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

                Accessibilities accessibilities = accessibility.GetAccessibilities();

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

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

                foreach (Accessibility accessibility2 in AvailableAccessibilities)
                {
                    if (accessibility != accessibility2 &&
                        !SyntaxAccessibility.IsValidAccessibility(member, accessibility2, ignoreOverride: allowOverride))
                    {
                        valid &= ~accessibility2.GetAccessibilities();
                    }
                }
            }

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

            return(valid);
        }