Exemple #1
0
        /// <summary>
        /// Verify member belongs to Non-Public Data Member Region
        /// if member is of type method, throw an error
        /// if member is of type field, check if it is non-public
        /// </summary>
        /// <param name="member"></param>
        /// <param name="locationRange"></param>
        /// <param name="context"></param>
        private static void VerifyMemberForNonPublicDataMemberRegion(MemberDeclarationSyntax member, LocationRangeModel locationRange, SyntaxNodeAnalysisContext context)
        {
            SyntaxTokenList modifiers     = default(SyntaxTokenList);
            bool            shouldProcess = false;

            switch (member.Kind())
            {
            case SyntaxKind.FieldDeclaration:
                modifiers     = ((FieldDeclarationSyntax)member).Modifiers;
                shouldProcess = true;
                break;

            case SyntaxKind.EnumDeclaration:
                modifiers     = ((EnumDeclarationSyntax)member).Modifiers;
                shouldProcess = true;
                break;

            case SyntaxKind.DelegateDeclaration:
                modifiers     = ((DelegateDeclarationSyntax)member).Modifiers;
                shouldProcess = true;
                break;
            }

            if (shouldProcess)
            {
                if (!HasAccessModifier(modifiers))
                {
                    return;
                }
                else if (MemberIsPublic(modifiers))
                {
                    CreateDiagnostic(member.GetLocation(), context, NonPublicDataMembersRegion, EnforceMemberLocation);
                }
                return;
            }

            if (member.Kind() == SyntaxKind.StructDeclaration)
            {
                return;
            }

            switch (member.Kind())
            {
            case SyntaxKind.ConstructorDeclaration:
            case SyntaxKind.MethodDeclaration:
            case SyntaxKind.PropertyDeclaration:
            case SyntaxKind.EventDeclaration:
            case SyntaxKind.EventFieldDeclaration:
            case SyntaxKind.OperatorDeclaration:
            case SyntaxKind.ClassDeclaration:
            case SyntaxKind.IndexerDeclaration:
            case SyntaxKind.DestructorDeclaration:
                CreateDiagnostic(member.GetLocation(), context, NonPublicDataMembersRegion, EnforceMemberLocation);
                break;

            default:
                CreateDiagnostic(member.GetLocation(), context, NonPublicDataMembersRegion, NonCheckedMember);
                break;
            }
        }
Exemple #2
0
        public void InternalFourParameterConstructorSetsAllData()
        {
            MemberDeclarationSyntax decl          = CreateValidDeclaration();
            ICompilationData        compilation   = CreateValidCompilationData(decl.SyntaxTree);
            SemanticModel           semanticModel = compilation.Compilation.GetSemanticModel(decl.SyntaxTree, true);
            ISymbol  symbol   = semanticModel.GetDeclaredSymbol(decl) !;
            Location location = decl.GetLocation();

            ITypeData[]                    containingTypes      = symbol.GetContainingTypes(compilation).ToArray();
            INamespaceSymbol[]             containingNamespaces = symbol.GetContainingNamespaces().ToArray();
            ImmutableArray <AttributeData> attributes           = symbol.GetAttributes();

            Data.MemberData data = new(decl, compilation, symbol, semanticModel, containingTypes, containingNamespaces, attributes);
            Assert.True(
                data.SemanticModel is not null &&
                data.SemanticModel.SyntaxTree.IsEquivalentTo(semanticModel.SyntaxTree) &&
                data.Symbol is not null &&
                SymbolEqualityComparer.Default.Equals(data.Symbol, symbol) &&
                data.Location is not null &&
                data.Location == location &&
                data.Declaration is not null &&
                data.Declaration.IsEquivalentTo(decl) &&
                data.ParentCompilation is not null &&
                data.ParentCompilation == compilation &&
                data._containingTypes is not null &
                data._containingTypes == containingTypes &&
                !data._attributes.IsDefault &&
                data._attributes == attributes &&
                data._containingNamespaces is not null &&
                data._containingNamespaces == containingNamespaces
                );
        }
Exemple #3
0
        /// <summary>
        /// Check is member is present in the given region
        /// </summary>
        /// <param name="member"></param>
        /// <param name="locationRange"></param>
        /// <returns>true if member is inside the given region, else false</returns>
        private static bool MemberPresentInRegion(MemberDeclarationSyntax member, LocationRangeModel locationRange)
        {
            int memberLocation = GetMemberLineNumber(member.GetLocation());

            if (memberLocation > locationRange.StartLine && memberLocation < locationRange.EndLine)
            {
                return(true);
            }
            return(false);
        }
Exemple #4
0
        public void LocationReturnsActualNodeLocation()
        {
            MemberDeclarationSyntax member = CreateValidDeclaration();
            Location location = member.GetLocation();

            Data.MemberData data         = new(member, CreateValidCompilationData(member.SyntaxTree));
            Location        dataLocation = data.Location;

            Assert.True(dataLocation is not null && dataLocation == location);
        }
Exemple #5
0
        private void ProcessMemberDeclaration(
            SyntaxTreeAnalysisContext context, SyntaxGenerator generator,
            CodeStyleOption <AccessibilityModifiersRequired> option, MemberDeclarationSyntax member)
        {
            if (member.IsKind(SyntaxKind.NamespaceDeclaration, out NamespaceDeclarationSyntax namespaceDeclaration))
            {
                ProcessMembers(context, generator, option, namespaceDeclaration.Members);
            }

            // If we have a class or struct, recurse inwards.
            if (member.IsKind(SyntaxKind.ClassDeclaration, out TypeDeclarationSyntax typeDeclaration) ||
                member.IsKind(SyntaxKind.StructDeclaration, out typeDeclaration))
            {
                ProcessMembers(context, generator, option, typeDeclaration.Members);
            }

#if false
            // Add this once we have the language version for C# that supports accessibility
            // modifiers on interface methods.
            if (option.Value == AccessibilityModifiersRequired.Always &&
                member.IsKind(SyntaxKind.InterfaceDeclaration, out typeDeclaration))
            {
                // Only recurse into an interface if the user wants accessibility modifiers on
                ProcessTypeDeclaration(context, generator, option, typeDeclaration);
            }
#endif

            // Have to have a name to report the issue on.
            var name = member.GetNameToken();
            if (name.Kind() == SyntaxKind.None)
            {
                return;
            }

            // Certain members never have accessibility. Don't bother reporting on them.
            if (!generator.CanHaveAccessibility(member))
            {
                return;
            }

            // If they already have accessibility, no need to report anything.
            var accessibility = generator.GetAccessibility(member);
            if (accessibility != Accessibility.NotApplicable)
            {
                return;
            }

            // Missing accessibility.  Report issue to user.
            var additionalLocations = ImmutableArray.Create(member.GetLocation());
            context.ReportDiagnostic(Diagnostic.Create(
                                         CreateDescriptorWithSeverity(option.Notification.Value),
                                         name.GetLocation(),
                                         additionalLocations: additionalLocations));
        }
Exemple #6
0
        protected CodeItem(MemberDeclarationSyntax memberDeclarationSyntax, TextSelection selection)
        {
            if (memberDeclarationSyntax == null)
            {
                return;
            }

            this.selection = selection;


            this.location  = memberDeclarationSyntax.GetLocation();
            this.modifiers = memberDeclarationSyntax.Modifiers.Select(m => m.ValueText);
            this.name      = GetNameFromDeclarationSyntaxCore(memberDeclarationSyntax);
        }
Exemple #7
0
        private void ProcessMemberDeclaration(
            SyntaxTreeAnalysisContext context,
            CodeStyleOption2 <AccessibilityModifiersRequired> option, MemberDeclarationSyntax member)
        {
            if (member is BaseNamespaceDeclarationSyntax namespaceDeclaration)
            {
                ProcessMembers(context, option, namespaceDeclaration.Members);
            }

            // If we have a class or struct, recurse inwards.
            if (member.IsKind(SyntaxKind.ClassDeclaration, out TypeDeclarationSyntax? typeDeclaration) ||
                member.IsKind(SyntaxKind.StructDeclaration, out typeDeclaration) ||
                member.IsKind(SyntaxKind.RecordDeclaration, out typeDeclaration) ||
                member.IsKind(SyntaxKind.RecordStructDeclaration, out typeDeclaration))
            {
                ProcessMembers(context, option, typeDeclaration.Members);
            }

#if false
            // Add this once we have the language version for C# that supports accessibility
            // modifiers on interface methods.
            if (option.Value == AccessibilityModifiersRequired.Always &&
                member.IsKind(SyntaxKind.InterfaceDeclaration, out typeDeclaration))
            {
                // Only recurse into an interface if the user wants accessibility modifiers on
                ProcessTypeDeclaration(context, generator, option, typeDeclaration);
            }
#endif

            if (!CSharpAddAccessibilityModifiers.Instance.ShouldUpdateAccessibilityModifier(CSharpAccessibilityFacts.Instance, member, option.Value, out var name))
            {
                return;
            }

            // Have an issue to flag, either add or remove. Report issue to user.
            var additionalLocations = ImmutableArray.Create(member.GetLocation());
            context.ReportDiagnostic(DiagnosticHelper.Create(
                                         Descriptor,
                                         name.GetLocation(),
                                         option.Notification.Severity,
                                         additionalLocations: additionalLocations,
                                         properties: null));
        }
Exemple #8
0
        public void InternalTwoParameterConstructorSetsAllData()
        {
            MemberDeclarationSyntax decl          = CreateValidDeclaration();
            ICompilationData        compilation   = CreateValidCompilationData(decl.SyntaxTree);
            SemanticModel           semanticModel = compilation.Compilation.GetSemanticModel(decl.SyntaxTree, true);
            ISymbol  symbol   = semanticModel.GetDeclaredSymbol(decl) !;
            Location location = decl.GetLocation();

            Data.MemberData data = new(symbol, compilation);
            Assert.True(
                data.SemanticModel is not null &&
                data.SemanticModel.SyntaxTree.IsEquivalentTo(semanticModel.SyntaxTree) &&
                data.Symbol is not null &&
                SymbolEqualityComparer.Default.Equals(data.Symbol, symbol) &&
                data.Location is not null &&
                data.Location == location &&
                data.Declaration is not null &&
                data.Declaration.IsEquivalentTo(decl) &&
                data.ParentCompilation is not null &&
                data.ParentCompilation == compilation
                );
        }
        private void ProcessMemberDeclaration(
            SyntaxTreeAnalysisContext context,
            CodeStyleOption2 <AccessibilityModifiersRequired> option, MemberDeclarationSyntax member)
        {
            if (member.IsKind(SyntaxKind.NamespaceDeclaration, out NamespaceDeclarationSyntax namespaceDeclaration))
            {
                ProcessMembers(context, option, namespaceDeclaration.Members);
            }

            // If we have a class or struct, recurse inwards.
            if (member.IsKind(SyntaxKind.ClassDeclaration, out TypeDeclarationSyntax typeDeclaration) ||
                member.IsKind(SyntaxKind.StructDeclaration, out typeDeclaration))
            {
                ProcessMembers(context, option, typeDeclaration.Members);
            }

#if false
            // Add this once we have the language version for C# that supports accessibility
            // modifiers on interface methods.
            if (option.Value == AccessibilityModifiersRequired.Always &&
                member.IsKind(SyntaxKind.InterfaceDeclaration, out typeDeclaration))
            {
                // Only recurse into an interface if the user wants accessibility modifiers on
                ProcessTypeDeclaration(context, generator, option, typeDeclaration);
            }
#endif

            // Have to have a name to report the issue on.
            var name = member.GetNameToken();
            if (name.Kind() == SyntaxKind.None)
            {
                return;
            }

            // Certain members never have accessibility. Don't bother reporting on them.
            if (!SyntaxFacts.CanHaveAccessibility(member))
            {
                return;
            }

            // This analyzer bases all of its decisions on the accessibility
            var accessibility = SyntaxFacts.GetAccessibility(member);

            // Omit will flag any accessibility values that exist and are default
            // The other options will remove or ignore accessibility
            var isOmit = option.Value == AccessibilityModifiersRequired.OmitIfDefault;

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

                var parentKind = member.Parent.Kind();
                switch (parentKind)
                {
                // Check for default modifiers in namespace and outside of namespace
                case SyntaxKind.CompilationUnit:
                case SyntaxKind.NamespaceDeclaration:
                {
                    // Default is internal
                    if (accessibility != Accessibility.Internal)
                    {
                        return;
                    }
                }
                break;

                case SyntaxKind.ClassDeclaration:
                case SyntaxKind.StructDeclaration:
                {
                    // Inside a type, default is private
                    if (accessibility != Accessibility.Private)
                    {
                        return;
                    }
                }
                break;

                default:
                    return;     // Unknown parent kind, don't do anything
                }
            }
            else
            {
                // Mode is always, so we have to flag missing modifiers
                if (accessibility != Accessibility.NotApplicable)
                {
                    return;
                }
            }

            // Have an issue to flag, either add or remove. Report issue to user.
            var additionalLocations = ImmutableArray.Create(member.GetLocation());
            context.ReportDiagnostic(DiagnosticHelper.Create(
                                         Descriptor,
                                         name.GetLocation(),
                                         option.Notification.Severity,
                                         additionalLocations: additionalLocations,
                                         properties: null));
        }