2 // DefaultReferenceImporter.cs
5 // Jb Evain (jbevain@novell.com)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 namespace Mono.Cecil {
32 using System.Collections;
34 public class DefaultImporter : IImporter {
36 ModuleDefinition m_module;
38 public ModuleDefinition Module {
39 get { return m_module; }
42 public DefaultImporter (ModuleDefinition module)
47 public AssemblyNameReference ImportAssembly (AssemblyNameReference asm)
49 AssemblyNameReference asmRef = GetAssemblyNameReference (asm);
53 asmRef = new AssemblyNameReference (
54 asm.Name, asm.Culture, asm.Version);
55 asmRef.PublicKeyToken = asm.PublicKeyToken;
56 asmRef.HashAlgorithm = asm.HashAlgorithm;
57 m_module.AssemblyReferences.Add (asmRef);
61 AssemblyNameReference GetAssemblyNameReference (AssemblyNameReference asm)
63 foreach (AssemblyNameReference reference in m_module.AssemblyReferences)
64 if (reference.FullName == asm.FullName)
70 TypeReference GetTypeSpec (TypeReference t, ImportContext context)
72 Stack s = new Stack ();
73 while (t is TypeSpecification) {
75 t = (t as TypeSpecification).ElementType;
78 TypeReference elementType = ImportTypeReference (t, context);
80 t = (TypeReference) s.Pop ();
82 elementType = new PointerType (elementType);
83 else if (t is ArrayType) // deal with complex arrays
84 elementType = new ArrayType (elementType);
85 else if (t is ReferenceType)
86 elementType = new ReferenceType (elementType);
87 else if (t is GenericInstanceType) {
88 GenericInstanceType git = t as GenericInstanceType;
89 GenericInstanceType genElemType = new GenericInstanceType (elementType);
90 foreach (TypeReference arg in git.GenericArguments)
91 genElemType.GenericArguments.Add (ImportTypeReference (arg, context));
93 elementType = genElemType;
95 throw new ReflectionException ("Unknown element type: {0}", t.GetType ().Name);
101 static GenericParameter GetGenericParameter (GenericParameter gp, ImportContext context)
104 if (gp.Owner is TypeReference)
105 p = context.GenericContext.Type.GenericParameters [gp.Position];
106 else if (gp.Owner is MethodReference)
107 p = context.GenericContext.Method.GenericParameters [gp.Position];
109 throw new NotSupportedException ();
114 public virtual TypeReference ImportTypeReference (TypeReference t, ImportContext context)
116 if (t.Module == m_module)
119 if (t is TypeSpecification)
120 return GetTypeSpec (t, context);
122 if (t is GenericParameter)
123 return GetGenericParameter (t as GenericParameter, context);
125 TypeReference type = m_module.TypeReferences [t.FullName];
129 AssemblyNameReference asm;
130 if (t.Scope is AssemblyNameReference)
131 asm = ImportAssembly ((AssemblyNameReference) t.Scope);
132 else if (t.Scope is ModuleDefinition)
133 asm = ImportAssembly (((ModuleDefinition) t.Scope).Assembly.Name);
135 throw new NotImplementedException ();
137 type = new TypeReference (t.Name, t.Namespace, asm, t.IsValueType);
139 context.GenericContext.Type = type;
141 foreach (GenericParameter gp in t.GenericParameters)
142 type.GenericParameters.Add (GenericParameter.Clone (gp, context));
144 m_module.TypeReferences.Add (type);
148 public virtual FieldReference ImportFieldReference (FieldReference fr, ImportContext context)
150 if (fr.DeclaringType.Module == m_module)
153 FieldReference field = (FieldReference) GetMemberReference (fr);
157 field = new FieldReference (
159 ImportTypeReference (fr.DeclaringType, context),
160 ImportTypeReference (fr.FieldType, context));
162 m_module.MemberReferences.Add (field);
166 MethodReference GetMethodSpec (MethodReference meth, ImportContext context)
168 if (!(meth is GenericInstanceMethod))
171 GenericInstanceMethod gim = meth as GenericInstanceMethod;
172 GenericInstanceMethod ngim = new GenericInstanceMethod (
173 ImportMethodReference (gim.ElementMethod, context));
175 foreach (TypeReference arg in gim.GenericArguments)
176 ngim.GenericArguments.Add (ImportTypeReference (arg, context));
181 public virtual MethodReference ImportMethodReference (MethodReference mr, ImportContext context)
183 if (mr.DeclaringType.Module == m_module)
186 if (mr is MethodSpecification)
187 return GetMethodSpec (mr, context);
189 MethodReference meth = (MethodReference) GetMemberReference (mr);
193 meth = new MethodReference (
197 mr.CallingConvention);
198 meth.DeclaringType = ImportTypeReference (mr.DeclaringType, context);
200 TypeReference contextType = meth.DeclaringType.GetOriginalType ();
202 context.GenericContext.Method = meth;
203 context.GenericContext.Type = contextType;
205 foreach (GenericParameter gp in mr.GenericParameters)
206 meth.GenericParameters.Add (GenericParameter.Clone (gp, context));
208 meth.ReturnType.ReturnType = ImportTypeReference (mr.ReturnType.ReturnType, context);
210 foreach (ParameterDefinition param in mr.Parameters)
211 meth.Parameters.Add (new ParameterDefinition (
212 ImportTypeReference (param.ParameterType, context)));
214 m_module.MemberReferences.Add (meth);
218 MemberReference GetMemberReference (MemberReference member)
220 foreach (MemberReference reference in m_module.MemberReferences)
221 if (reference.ToString () == member.ToString ())