TypeReference AddAndResolveTypeDef(TypeReference t) { var resolved = Replace(t); // do not add system references, but leave them in the code if (resolved == null) { return(t); } if (resolved.CustomAttributes.Any(att => att.AttributeType.Name == "Skip")) { return(null); } // do not include the private implementation if (resolved.Name.StartsWith("<PrivateImplementationDetails>")) { return(null); } if (m_all.Contains(resolved)) { return(resolved); } var existing = m_all.SingleOrDefault(x => x.FullName == resolved.FullName); if (existing != null) { // this might be a problem with re-resolving types // Make sure we always return the existing type return(existing); } // Use copied type var copy = CopyTypeHelper.CopyType(resolved); // nested classes need to keep a valid name if (resolved.DeclaringType != null) { copy.Name = resolved.DeclaringType.Name + "/" + copy.Name; copy.Namespace = resolved.DeclaringType.Namespace; } //copy.DeclaringType = resolved.DeclaringType; // Names need to be the same, otherwise this logic doesn't work Debug.Assert(resolved.FullName == copy.FullName); m_all.Add(copy); // It's a newly discovered type so we shouldn't try to process it already Debug.Assert(!m_toProcess.Any(x => x.FullName == copy.FullName)); //if (!m_toProcess.Any(x=>x.FullName == copy.FullName)) m_toProcess.Add(copy); return(copy); }
TypeDefinition ExpandGenericType(GenericInstanceType genericType) { var genericName = GetGenericName(genericType); if (m_genericTypeCache.ContainsKey(genericName)) { return(m_genericTypeCache[genericName]); } var ot = genericType.Resolve(); var nt = new TypeDefinition("", genericName, TypeAttributes.Class); m_genericTypeCache[genericName] = nt; nt.BaseType = ot.BaseType; // update fields foreach (var f in ot.Fields) { var ft = f.FieldType; ft = ResolveGenericParameter(ft, genericType); var nf = new FieldDefinition(f.Name, f.Attributes, ft); nt.Fields.Add(nf); } // update Methods foreach (var m in ot.Methods) { var rt = ResolveGenericParameter(m.ReturnType, genericType); var nm = new MethodDefinition(m.Name, m.Attributes, rt); nt.Methods.Add(nm); foreach (var p in m.Parameters) { nm.Parameters.Add(new ParameterDefinition(p.Name, p.Attributes, ResolveGenericParameter(p.ParameterType, genericType))); } if (m.HasBody) { CopyTypeHelper.CopyMethodBody(m, nm); foreach (var v in nm.Body.Variables) { if (v.VariableType.ContainsGenericParameter) { v.VariableType = ResolveGenericParameter(v.VariableType, genericType); if (v.VariableType.ContainsGenericParameter || v.VariableType.IsGenericInstance) { v.VariableType = ExpandGenericType((GenericInstanceType)v.VariableType); } } } var ilp = nm.Body.GetILProcessor(); foreach (var i in nm.Body.Instructions) { if (i.Operand is MemberReference fr && fr.ContainsGenericParameter) { if (fr.DeclaringType.ContainsGenericParameter) { fr.DeclaringType = ResolveGenericParameter(fr.DeclaringType, genericType); if (fr.DeclaringType.ContainsGenericParameter || fr.DeclaringType.IsGenericInstance) { fr.DeclaringType = ExpandGenericType((GenericInstanceType)fr.DeclaringType); } } } } } } return(nt); }