Ejemplo n.º 1
0
        public List <TypeTreeNode> ConvertToTypeTreeNodes()
        {
            var nodes = new List <TypeTreeNode>();

            var baseTypes    = new Stack <TypeReference>();
            var lastBaseType = TypeDef.BaseType;

            while (!UnitySerializationLogic.IsNonSerialized(lastBaseType))
            {
                var genericInstanceType = lastBaseType as GenericInstanceType;
                if (genericInstanceType != null)
                {
                    TypeResolver.Add(genericInstanceType);
                }
                baseTypes.Push(lastBaseType);
                lastBaseType = lastBaseType.Resolve().BaseType;
            }
            while (baseTypes.Count > 0)
            {
                var typeReference  = baseTypes.Pop();
                var typeDefinition = typeReference.Resolve();
                foreach (var fieldDefinition in typeDefinition.Fields.Where(WillUnitySerialize))
                {
                    if (!IsHiddenByParentClass(baseTypes, fieldDefinition, TypeDef))
                    {
                        nodes.AddRange(ProcessingFieldRef(ResolveGenericFieldReference(fieldDefinition)));
                    }
                }

                var genericInstanceType = typeReference as GenericInstanceType;
                if (genericInstanceType != null)
                {
                    TypeResolver.Remove(genericInstanceType);
                }
            }
            foreach (var field in FilteredFields())
            {
                nodes.AddRange(ProcessingFieldRef(field));
            }

            return(nodes);
        }
        private void AddType(TypeReference typeRef, GenericInstanceTypeMap genericInstanceTypeMap)
        {
            // Prevent duplicates
            if (classes_.Any(x => x.name == GetMonoEmbeddedFullTypeNameFor(typeRef)))
            {
                return;
            }

            TypeDefinition type;

            try
            {
                type = typeRef.Resolve();
            } // This will happen for types which we don't have access to, like Windows.Foundation.IAsyncOperation<int>
            catch (AssemblyResolutionException)
            {
                return;
            }
            catch (NotSupportedException) // "NotSupportedException: Version not supported: 255.255.255.255" is thrown when assembly references WinRT assembly (e.g. mscorlib)
            {
                return;
            }

            if (type == null)
            {
                return;
            }

            if (typeRef.IsGenericInstance)
            {
                var arguments  = ((GenericInstanceType)typeRef).GenericArguments;
                var parameters = type.GenericParameters;

                for (int i = 0; i < arguments.Count; i++)
                {
                    if (parameters[i] != arguments[i])
                    {
                        genericInstanceTypeMap[parameters[i]] = arguments[i];
                    }
                }

                typeResolver.Add((GenericInstanceType)typeRef);
            }

            /* Process class itself before nested/base types in case user does something evil, for example:
             *
             *  class Outer
             *  {
             *      class Inner : Child
             *      {
             *      }
             *  }
             *
             *  class Child : Outer
             *  {
             *  }
             */

            bool shouldImplementDeserializable = false;

            try
            {
                shouldImplementDeserializable = UnitySerializationLogic.ShouldImplementIDeserializable(type);
            }
            catch
            {
                // If assembly has unknown reference (for ex., see tests VariousPlugins, where Metro plugins are used), skip field
            }

            if (!shouldImplementDeserializable)
            {
                // In this case we only take care of processing the nested types, if any.
                AddNestedTypes(type, genericInstanceTypeMap);
            }
            else
            {
                var ci = new ClassInfo();
                ci.name   = GetMonoEmbeddedFullTypeNameFor(typeRef);
                ci.fields = GetFields(type, typeRef.IsGenericInstance, genericInstanceTypeMap);

                classes_.Add(ci);

                // Fetch info for inner types
                AddNestedTypes(type, genericInstanceTypeMap);

                // Add base type
                AddBaseType(typeRef, genericInstanceTypeMap);
            }

            if (typeRef.IsGenericInstance)
            {
                typeResolver.Remove((GenericInstanceType)typeRef);
            }
        }