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); } }