private void IdentifyAndMakeSerializableRecursively(ITypeSignature type, MessageLocation location)
        {
            switch (type.TypeSignatureElementKind)
            {
            case TypeSignatureElementKind.Intrinsic:
                // This works automatically for most, but:
                // Consider an error for object, IntPtr, but also consider that those fields may be marked as [NonSerialized].
                // In the future, we might want to exclude such fields.
                break;

            case TypeSignatureElementKind.TypeDef:
                TypeDefDeclaration typeDef = (TypeDefDeclaration)type;
                if (typeDef.DeclaringAssembly == this.Project.Module.DeclaringAssembly)
                {
                    MakeSerializableRecursively(typeDef);
                }
                else
                {
                    VerifySerializable(typeDef, location);
                }
                break;

            case TypeSignatureElementKind.TypeRef:
                IdentifyAndMakeSerializableRecursively(type.GetTypeDefinition(), location);
                break;

            case TypeSignatureElementKind.GenericInstance:
                GenericTypeInstanceTypeSignature
                    genericInstanceSignature = type as GenericTypeInstanceTypeSignature;
                IdentifyAndMakeSerializableRecursively(genericInstanceSignature.ElementType, location);
                foreach (ITypeSignature argument in genericInstanceSignature.GenericArguments)
                {
                    IdentifyAndMakeSerializableRecursively(argument, location);
                }
                break;

            case TypeSignatureElementKind.Array:
                ArrayTypeSignature arraySignature = type as ArrayTypeSignature;
                IdentifyAndMakeSerializableRecursively(arraySignature.ElementType, location);
                break;

            default:
                // Other possible signature types can be ignored:
                //  Pointers: they cannot be serialized
                //  Custom modifiers: they should not be used on fields.
                break;
            }
        }
예제 #2
0
        public override bool Execute()
        {
            // Get the type EnumConstraintAttribute.
            ITypeSignature attributeType = this.Project.Module.FindType(
                typeof(EnumConstraintAttribute),
                BindingOptions.OnlyDefinition | BindingOptions.DontThrowException);

            if (attributeType == null)
            {
                // The type is not referenced in the current module. There cannot be a custom attribute
                // of this type, so we are done.
                return(true);
            }

            var enumType = this.Project.Module.FindType(
                typeof(Enum),
                BindingOptions.OnlyDefinition | BindingOptions.DontThrowException);

            // Enumerate custom attributes of type EnumConstraintAttribute.
            var annotationRepository = AnnotationRepositoryTask.GetTask(this.Project);
            IEnumerator <IAnnotationInstance> customAttributesEnumerator =
                annotationRepository.GetAnnotationsOfType(attributeType.GetTypeDefinition(), false);

            while (customAttributesEnumerator.MoveNext())
            {
                var current = customAttributesEnumerator.Current;

                // Get the target of the custom attribute.
                GenericParameterDeclaration target = current.TargetElement as GenericParameterDeclaration;

                // Add a generic constraint.
                target.Constraints.Add(enumType);

                // Remove the custom attribute.
                (current as CustomAttributeDeclaration).Remove();
            }

            return(base.Execute());
        }