コード例 #1
0
        private static void HandleTypeDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
        {
            var elementOrder  = settings.OrderingRules.ElementOrder;
            int readonlyIndex = elementOrder.IndexOf(OrderingTrait.Readonly);

            if (readonlyIndex < 0)
            {
                return;
            }

            var typeDeclaration = (TypeDeclarationSyntax)context.Node;

            // This variable is null when the previous member is not a field.
            FieldDeclarationSyntax previousField = null;
            var previousFieldConst    = true;
            var previousFieldStatic   = false;
            var previousFieldReadonly = false;
            var previousAccessLevel   = AccessLevel.NotSpecified;

            foreach (var member in typeDeclaration.Members)
            {
                if (!(member is FieldDeclarationSyntax field))
                {
                    previousField = null;
                    continue;
                }

                var  modifiers            = member.GetModifiers();
                var  currentAccessLevel   = MemberOrderHelper.GetAccessLevelForOrdering(member, modifiers);
                bool currentFieldConst    = modifiers.Any(SyntaxKind.ConstKeyword);
                bool currentFieldStatic   = currentFieldConst || modifiers.Any(SyntaxKind.StaticKeyword);
                bool currentFieldReadonly = currentFieldConst || modifiers.Any(SyntaxKind.ReadOnlyKeyword);
                if (previousField == null)
                {
                    previousField         = field;
                    previousFieldConst    = currentFieldConst;
                    previousFieldStatic   = currentFieldStatic;
                    previousFieldReadonly = currentFieldReadonly;
                    previousAccessLevel   = currentAccessLevel;
                    continue;
                }

                bool compareReadonly = true;
                for (int j = 0; compareReadonly && j < readonlyIndex; j++)
                {
                    switch (elementOrder[j])
                    {
                    case OrderingTrait.Kind:
                        // This analyzer only ever looks at sequences of fields.
                        continue;

                    case OrderingTrait.Accessibility:
                        if (previousAccessLevel != currentAccessLevel)
                        {
                            compareReadonly = false;
                        }

                        continue;

                    case OrderingTrait.Constant:
                        if (previousFieldConst != currentFieldConst)
                        {
                            compareReadonly = false;
                        }

                        continue;

                    case OrderingTrait.Static:
                        if (previousFieldStatic != currentFieldStatic)
                        {
                            compareReadonly = false;
                        }

                        continue;

                    case OrderingTrait.Readonly:
                    default:
                        continue;
                    }
                }

                if (compareReadonly)
                {
                    if (currentFieldReadonly && !previousFieldReadonly)
                    {
                        context.ReportDiagnostic(Diagnostic.Create(Descriptor, NamedTypeHelpers.GetNameOrIdentifierLocation(member)));
                    }
                }

                previousField         = field;
                previousFieldConst    = currentFieldConst;
                previousFieldStatic   = currentFieldStatic;
                previousFieldReadonly = currentFieldReadonly;
                previousAccessLevel   = currentAccessLevel;
            }
        }
        private static void HandleMemberList(SyntaxNodeAnalysisContext context, ImmutableArray <OrderingTrait> elementOrder, int staticIndex, SyntaxList <MemberDeclarationSyntax> members)
        {
            var previousSyntaxKind     = SyntaxKind.None;
            var previousAccessLevel    = AccessLevel.NotSpecified;
            var previousMemberStatic   = true;
            var previousMemberConstant = false;
            var previousMemberReadonly = false;

            foreach (var member in members)
            {
                var modifiers = member.GetModifiers();

                var currentSyntaxKind = member.Kind();
                currentSyntaxKind = currentSyntaxKind == SyntaxKind.EventFieldDeclaration ? SyntaxKind.EventDeclaration : currentSyntaxKind;
                var  currentAccessLevel    = MemberOrderHelper.GetAccessLevelForOrdering(member, modifiers);
                bool currentMemberConstant = modifiers.Any(SyntaxKind.ConstKeyword);
                bool currentMemberReadonly = currentMemberConstant || modifiers.Any(SyntaxKind.ReadOnlyKeyword);
                bool currentMemberStatic   = currentMemberConstant || modifiers.Any(SyntaxKind.StaticKeyword);
                bool compareStatic         = true;
                for (int j = 0; compareStatic && j < staticIndex; j++)
                {
                    switch (elementOrder[j])
                    {
                    case OrderingTrait.Accessibility:
                        if (currentAccessLevel != previousAccessLevel)
                        {
                            compareStatic = false;
                        }

                        continue;

                    case OrderingTrait.Readonly:
                        if (currentMemberReadonly != previousMemberReadonly)
                        {
                            compareStatic = false;
                        }

                        continue;

                    case OrderingTrait.Constant:
                        if (currentMemberConstant != previousMemberConstant)
                        {
                            compareStatic = false;
                        }

                        continue;

                    case OrderingTrait.Kind:
                        if (previousSyntaxKind != currentSyntaxKind)
                        {
                            compareStatic = false;
                        }

                        continue;

                    case OrderingTrait.Static:
                    default:
                        continue;
                    }
                }

                if (compareStatic)
                {
                    if (currentMemberStatic && !previousMemberStatic)
                    {
                        context.ReportDiagnostic(
                            Diagnostic.Create(
                                Descriptor,
                                NamedTypeHelpers.GetNameOrIdentifierLocation(member),
                                AccessLevelHelper.GetName(currentAccessLevel)));
                    }
                }

                previousSyntaxKind     = currentSyntaxKind;
                previousAccessLevel    = currentAccessLevel;
                previousMemberStatic   = currentMemberStatic;
                previousMemberConstant = currentMemberConstant;
                previousMemberReadonly = currentMemberReadonly;
            }
        }
        private static void HandleTypeDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
        {
            var elementOrder  = settings.OrderingRules.ElementOrder;
            int constantIndex = elementOrder.IndexOf(OrderingTrait.Constant);

            if (constantIndex < 0)
            {
                return;
            }

            var typeDeclaration = (TypeDeclarationSyntax)context.Node;

            var members = typeDeclaration.Members;
            var previousFieldConstant = true;
            var previousFieldStatic   = false;
            var previousFieldReadonly = false;
            var previousAccessLevel   = AccessLevel.NotSpecified;

            foreach (var member in members)
            {
                var field = member as FieldDeclarationSyntax;
                if (field == null)
                {
                    continue;
                }

                AccessLevel currentAccessLevel   = MemberOrderHelper.GetAccessLevelForOrdering(field, field.Modifiers);
                bool        currentFieldConstant = field.Modifiers.Any(SyntaxKind.ConstKeyword);
                bool        currentFieldReadonly = currentFieldConstant || field.Modifiers.Any(SyntaxKind.ReadOnlyKeyword);
                bool        currentFieldStatic   = currentFieldConstant || field.Modifiers.Any(SyntaxKind.StaticKeyword);
                bool        compareConst         = true;
                for (int j = 0; compareConst && j < constantIndex; j++)
                {
                    switch (elementOrder[j])
                    {
                    case OrderingTrait.Accessibility:
                        if (currentAccessLevel != previousAccessLevel)
                        {
                            compareConst = false;
                        }

                        continue;

                    case OrderingTrait.Readonly:
                        if (currentFieldReadonly != previousFieldReadonly)
                        {
                            compareConst = false;
                        }

                        continue;

                    case OrderingTrait.Static:
                        if (currentFieldStatic != previousFieldStatic)
                        {
                            compareConst = false;
                        }

                        continue;

                    case OrderingTrait.Kind:
                        // Only fields may be marked const, and all fields have the same kind.
                        continue;

                    case OrderingTrait.Constant:
                    default:
                        continue;
                    }
                }

                if (compareConst)
                {
                    if (!previousFieldConstant && currentFieldConstant)
                    {
                        context.ReportDiagnostic(Diagnostic.Create(Descriptor, NamedTypeHelpers.GetNameOrIdentifierLocation(member)));
                    }
                }

                previousFieldConstant = currentFieldConstant;
                previousFieldReadonly = currentFieldReadonly;
                previousFieldStatic   = currentFieldStatic;
                previousAccessLevel   = currentAccessLevel;
            }
        }
        private static void HandleMemberList(SyntaxNodeAnalysisContext context, ImmutableArray <OrderingTrait> elementOrder, int accessibilityIndex, SyntaxList <MemberDeclarationSyntax> members, AccessLevel defaultAccessLevel)
        {
            MemberDeclarationSyntax previousMember = null;
            var  previousSyntaxKind  = SyntaxKind.None;
            var  previousAccessLevel = AccessLevel.NotSpecified;
            bool previousIsConst     = false;
            bool previousIsReadonly  = false;
            bool previousIsStatic    = false;

            foreach (var member in members)
            {
                var currentSyntaxKind = member.Kind();
                currentSyntaxKind = currentSyntaxKind == SyntaxKind.EventFieldDeclaration ? SyntaxKind.EventDeclaration : currentSyntaxKind;

                // if the SyntaxKind of this member (e.g. SyntaxKind.IncompleteMember) will not
                // be handled, skip early.
                if (!MemberKinds.Contains(currentSyntaxKind))
                {
                    continue;
                }

                var         modifiers          = member.GetModifiers();
                AccessLevel currentAccessLevel = MemberOrderHelper.GetAccessLevelForOrdering(member, modifiers);
                bool        currentIsConst     = modifiers.Any(SyntaxKind.ConstKeyword);
                bool        currentIsReadonly  = modifiers.Any(SyntaxKind.ReadOnlyKeyword);
                bool        currentIsStatic    = modifiers.Any(SyntaxKind.StaticKeyword);

                if (previousAccessLevel != AccessLevel.NotSpecified)
                {
                    bool compareAccessLevel = true;
                    for (int j = 0; compareAccessLevel && j < accessibilityIndex; j++)
                    {
                        switch (elementOrder[j])
                        {
                        case OrderingTrait.Kind:
                            if (previousSyntaxKind != currentSyntaxKind)
                            {
                                compareAccessLevel = false;
                            }

                            continue;

                        case OrderingTrait.Constant:
                            if (previousIsConst != currentIsConst)
                            {
                                compareAccessLevel = false;
                            }

                            continue;

                        case OrderingTrait.Readonly:
                            if (previousIsReadonly != currentIsReadonly)
                            {
                                compareAccessLevel = false;
                            }

                            continue;

                        case OrderingTrait.Static:
                            if (previousIsStatic != currentIsStatic)
                            {
                                compareAccessLevel = false;
                            }

                            continue;

                        case OrderingTrait.Accessibility:
                        default:
                            continue;
                        }
                    }

                    if (compareAccessLevel && currentAccessLevel > previousAccessLevel)
                    {
                        context.ReportDiagnostic(
                            Diagnostic.Create(
                                Descriptor,
                                NamedTypeHelpers.GetNameOrIdentifierLocation(member),
                                AccessLevelHelper.GetName(currentAccessLevel),
                                AccessLevelHelper.GetName(previousAccessLevel)));
                    }
                }

                previousMember      = member;
                previousSyntaxKind  = currentSyntaxKind;
                previousAccessLevel = currentAccessLevel;
                previousIsConst     = currentIsConst;
                previousIsReadonly  = currentIsReadonly;
                previousIsStatic    = currentIsStatic;
            }
        }
        private static void HandleMemberList(SyntaxNodeAnalysisContext context, ImmutableArray <OrderingTrait> elementOrder, int kindIndex, SyntaxList <MemberDeclarationSyntax> members, ImmutableArray <SyntaxKind> order)
        {
            for (int i = 0; i < members.Count - 1; i++)
            {
                if (members[i + 1].IsKind(SyntaxKind.IncompleteMember))
                {
                    i++;
                    continue;
                }

                if (members[i].IsKind(SyntaxKind.IncompleteMember))
                {
                    continue;
                }

                bool compareKind = true;
                for (int j = 0; compareKind && j < kindIndex; j++)
                {
                    switch (elementOrder[j])
                    {
                    case OrderingTrait.Accessibility:
                        if (MemberOrderHelper.GetAccessLevelForOrdering(members[i + 1], members[i + 1].GetModifiers())
                            != MemberOrderHelper.GetAccessLevelForOrdering(members[i], members[i].GetModifiers()))
                        {
                            compareKind = false;
                        }

                        continue;

                    case OrderingTrait.Constant:
                    case OrderingTrait.Readonly:
                        // Only fields may be marked const or readonly, and all fields have the same kind.
                        continue;

                    case OrderingTrait.Static:
                        bool currentIsStatic = members[i].GetModifiers().Any(SyntaxKind.StaticKeyword);
                        bool nextIsStatic    = members[i + 1].GetModifiers().Any(SyntaxKind.StaticKeyword);
                        if (currentIsStatic != nextIsStatic)
                        {
                            compareKind = false;
                        }

                        continue;

                    case OrderingTrait.Kind:
                    default:
                        continue;
                    }
                }

                if (!compareKind)
                {
                    continue;
                }

                var elementSyntaxKind = members[i].Kind();
                elementSyntaxKind = elementSyntaxKind == SyntaxKind.EventFieldDeclaration ? SyntaxKind.EventDeclaration : elementSyntaxKind;
                int index = order.IndexOf(elementSyntaxKind);

                var nextElementSyntaxKind = members[i + 1].Kind();
                nextElementSyntaxKind = nextElementSyntaxKind == SyntaxKind.EventFieldDeclaration ? SyntaxKind.EventDeclaration : nextElementSyntaxKind;
                int nextIndex = order.IndexOf(nextElementSyntaxKind);

                if (index > nextIndex)
                {
                    context.ReportDiagnostic(Diagnostic.Create(Descriptor, NamedTypeHelpers.GetNameOrIdentifierLocation(members[i + 1]), MemberNames[nextElementSyntaxKind], MemberNames[elementSyntaxKind]));
                }
            }
        }