Пример #1
0
        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);
        }
Пример #2
0
        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);
        }