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 {
33 internal class DefaultImporter : IImporter {
35 ModuleDefinition m_module;
37 public ModuleDefinition Module {
38 get { return m_module; }
41 public DefaultImporter (ModuleDefinition module)
46 public AssemblyNameReference ImportAssembly (AssemblyNameReference asm)
48 AssemblyNameReference asmRef = GetAssemblyNameReference (asm);
52 asmRef = new AssemblyNameReference (
53 asm.Name, asm.Culture, asm.Version);
54 asmRef.PublicKeyToken = asm.PublicKeyToken;
55 asmRef.HashAlgorithm = asm.HashAlgorithm;
56 m_module.AssemblyReferences.Add (asmRef);
60 AssemblyNameReference GetAssemblyNameReference (AssemblyNameReference asm)
62 foreach (AssemblyNameReference reference in m_module.AssemblyReferences)
63 if (reference.FullName == asm.FullName)
69 TypeSpecification GetTypeSpec (TypeSpecification original, ImportContext context)
71 TypeSpecification typeSpec;
73 TypeReference elementType = ImportTypeReference (original.ElementType, context);
74 if (original is PointerType) {
75 typeSpec = new PointerType (elementType);
76 } else if (original is ArrayType) { // deal with complex arrays
77 typeSpec = new ArrayType (elementType);
78 } else if (original is ReferenceType) {
79 typeSpec = new ReferenceType (elementType);
80 } else if (original is GenericInstanceType) {
81 GenericInstanceType git = original as GenericInstanceType;
82 GenericInstanceType genElemType = new GenericInstanceType (elementType);
84 context.GenericContext.CheckProvider (genElemType.GetOriginalType (), git.GenericArguments.Count);
85 foreach (TypeReference arg in git.GenericArguments)
86 genElemType.GenericArguments.Add (ImportTypeReference (arg, context));
88 typeSpec = genElemType;
89 } else if (original is ModifierOptional) {
90 TypeReference mt = (original as ModifierOptional).ModifierType;
91 typeSpec = new ModifierOptional (elementType, ImportTypeReference (mt, context));
92 } else if (original is ModifierRequired) {
93 TypeReference mt = (original as ModifierRequired).ModifierType;
94 typeSpec = new ModifierRequired (elementType, ImportTypeReference (mt, context));
95 } else if (original is SentinelType) {
96 typeSpec = new SentinelType (elementType);
97 } else if (original is FunctionPointerType) {
98 FunctionPointerType ori = original as FunctionPointerType;
100 FunctionPointerType fnptr = new FunctionPointerType (
103 ori.CallingConvention,
104 new MethodReturnType (ImportTypeReference (ori.ReturnType.ReturnType, context)));
106 foreach (ParameterDefinition parameter in ori.Parameters)
107 fnptr.Parameters.Add (new ParameterDefinition (ImportTypeReference (parameter.ParameterType, context)));
111 throw new ReflectionException ("Unknown element type: {0}", original.GetType ().Name);
116 static GenericParameter GetGenericParameter (GenericParameter gp, ImportContext context)
119 if (gp.Owner is TypeReference)
120 p = context.GenericContext.Type.GenericParameters [gp.Position];
121 else if (gp.Owner is MethodReference)
122 p = context.GenericContext.Method.GenericParameters [gp.Position];
124 throw new NotSupportedException ();
129 TypeReference AdjustReference (TypeReference type, TypeReference reference)
131 if (type.IsValueType && !reference.IsValueType)
132 reference.IsValueType = true;
134 if (type.HasGenericParameters) {
135 for (int i = reference.GenericParameters.Count; i < type.GenericParameters.Count; i++)
136 reference.GenericParameters.Add (new GenericParameter (i, reference));
142 public virtual TypeReference ImportTypeReference (TypeReference t, ImportContext context)
144 if (t.Module == m_module)
147 if (t is TypeSpecification)
148 return GetTypeSpec (t as TypeSpecification, context);
150 if (t is GenericParameter)
151 return GetGenericParameter (t as GenericParameter, context);
153 TypeReference type = m_module.TypeReferences [t.FullName];
155 return AdjustReference (t, type);
157 AssemblyNameReference asm;
158 if (t.Scope is AssemblyNameReference)
159 asm = ImportAssembly ((AssemblyNameReference) t.Scope);
160 else if (t.Scope is ModuleDefinition)
161 asm = ImportAssembly (((ModuleDefinition) t.Scope).Assembly.Name);
163 throw new NotImplementedException ();
165 if (t.DeclaringType != null) {
166 type = new TypeReference (t.Name, string.Empty, asm, t.IsValueType);
167 type.DeclaringType = ImportTypeReference (t.DeclaringType, context);
169 type = new TypeReference (t.Name, t.Namespace, asm, t.IsValueType);
171 TypeReference contextType = context.GenericContext.Type;
173 context.GenericContext.Type = type;
175 GenericParameter.CloneInto (t, type, context);
177 context.GenericContext.Type = contextType;
179 m_module.TypeReferences.Add (type);
183 public virtual FieldReference ImportFieldReference (FieldReference fr, ImportContext context)
185 if (fr.DeclaringType.Module == m_module)
188 FieldReference field = (FieldReference) GetMemberReference (fr);
192 field = new FieldReference (
194 ImportTypeReference (fr.DeclaringType, context),
195 ImportTypeReference (fr.FieldType, context));
197 m_module.MemberReferences.Add (field);
201 MethodReference GetMethodSpec (MethodReference meth, ImportContext context)
203 if (!(meth is GenericInstanceMethod))
206 GenericInstanceMethod gim = meth as GenericInstanceMethod;
207 GenericInstanceMethod ngim = new GenericInstanceMethod (
208 ImportMethodReference (gim.ElementMethod, context));
210 context.GenericContext.CheckProvider (ngim.GetOriginalMethod (), gim.GenericArguments.Count);
211 foreach (TypeReference arg in gim.GenericArguments)
212 ngim.GenericArguments.Add (ImportTypeReference (arg, context));
217 public virtual MethodReference ImportMethodReference (MethodReference mr, ImportContext context)
219 if (mr.DeclaringType.Module == m_module)
222 if (mr is MethodSpecification)
223 return GetMethodSpec (mr, context);
225 MethodReference meth = (MethodReference) GetMemberReference (mr);
229 meth = new MethodReference (
233 mr.CallingConvention);
234 meth.DeclaringType = ImportTypeReference (mr.DeclaringType, context);
236 TypeReference contextType = context.GenericContext.Type;
237 MethodReference contextMethod = context.GenericContext.Method;
239 context.GenericContext.Method = meth;
240 context.GenericContext.Type = meth.DeclaringType.GetOriginalType();
242 GenericParameter.CloneInto (mr, meth, context);
244 meth.ReturnType.ReturnType = ImportTypeReference (mr.ReturnType.ReturnType, context);
246 foreach (ParameterDefinition param in mr.Parameters)
247 meth.Parameters.Add (new ParameterDefinition (
248 ImportTypeReference (param.ParameterType, context)));
250 context.GenericContext.Type = contextType;
251 context.GenericContext.Method = contextMethod;
253 m_module.MemberReferences.Add (meth);
257 MemberReference GetMemberReference (MemberReference member)
259 foreach (MemberReference reference in m_module.MemberReferences)
260 if (reference.ToString () == member.ToString ())