예제 #1
0
        static void VerifyProperty(DiagnosticsReportContext context, IPropertySymbol property, HashSet <ITypeSymbol> alreadyAnalyzed, HashSet <int> definedIndexes)
        {
            if (property.DeclaredAccessibility != Accessibility.Public)
            {
                return;
            }

            var attributes = property.GetAttributes();

            if (attributes.FindAttributeShortName(IgnoreShortName) != null)
            {
                return;
            }

            if (property.FindAttributeIncludeBasePropertyShortName(UnionKeyAttributeShortName) != null)
            {
                return;
            }

            if (!property.IsVirtual && !property.ContainingType.IsValueType)
            {
                if (property.IsOverride && !property.IsSealed)
                {
                    // ok, base type's override property.
                }
                else
                {
                    context.Add(Diagnostic.Create(PublicPropertyMustBeVirtual, property.Locations[0], property.ContainingType?.Name, property.Name));
                    return;
                }
            }

            var indexAttr = attributes.FindAttributeShortName(IndexAttributeShortName);

            if (indexAttr == null || indexAttr.ConstructorArguments.Length == 0)
            {
                context.Add(Diagnostic.Create(PublicPropertyNeedsIndex, property.Locations[0], property.ContainingType?.Name, property.Name));
                return;
            }

            var index = indexAttr.ConstructorArguments[0];

            if (index.IsNull)
            {
                return; // null is normal compiler error.
            }

            if (!definedIndexes.Add((int)index.Value))
            {
                context.Add(Diagnostic.Create(IndexAttributeDuplicate, property.Locations[0], property.ContainingType?.Name, property.Name, index.Value));
                return;
            }

            if ((int)index.Value >= 100)
            {
                context.Add(Diagnostic.Create(IndexIsTooLarge, property.Locations[0], index.Value, property.Name));
            }

            if (!property.ContainingType.IsValueType)
            {
                if (property.GetMethod == null || property.SetMethod == null ||
                    property.GetMethod.DeclaredAccessibility == Accessibility.Private ||
                    property.SetMethod.DeclaredAccessibility == Accessibility.Private)
                {
                    context.Add(Diagnostic.Create(PublicPropertyNeedsGetAndSetAccessor, property.Locations[0], property.ContainingType?.Name, property.Name));
                    return;
                }
            }

            var namedType = property.Type as INamedTypeSymbol;

            if (namedType != null) // if <T> is unnamed type, it can't analyze.
            {
                VerifyType(context, property.Locations[0], property.Type, alreadyAnalyzed, property);
            }
        }