2 // import.cs: System.Reflection conversions
4 // Authors: Marek Safar (marek.safar@gmail.com)
6 // Dual licensed under the terms of the MIT X11 or GNU GPL
8 // Copyright 2009, 2010 Novell, Inc
12 using System
.Reflection
;
13 using System
.Runtime
.CompilerServices
;
20 public static FieldSpec
CreateField (FieldInfo fi
)
22 // TODO MemberCache: remove
23 var cs
= TypeManager
.GetConstant (fi
);
26 var fb
= TypeManager
.GetFieldCore (fi
);
32 var fa
= fi
.Attributes
;
33 switch (fa
& FieldAttributes
.FieldAccessMask
) {
34 case FieldAttributes
.Public
:
35 mod
= Modifiers
.PUBLIC
;
37 case FieldAttributes
.Assembly
:
38 mod
= Modifiers
.INTERNAL
;
40 case FieldAttributes
.Family
:
41 mod
= Modifiers
.PROTECTED
;
43 case FieldAttributes
.FamORAssem
:
44 mod
= Modifiers
.PROTECTED
| Modifiers
.INTERNAL
;
47 mod
= Modifiers
.PRIVATE
;
51 // TODO MemberCache: Remove completely and use only Imported
52 IMemberDefinition definition
;
53 var gfd
= TypeManager
.GetGenericFieldDefinition (fi
);
54 fb
= TypeManager
.GetFieldCore (gfd
);
58 cs
= TypeManager
.GetConstant (gfd
);
60 definition
= cs
.MemberDefinition
;
62 definition
= new ImportedMemberDefinition (fi
);
65 if ((fa
& FieldAttributes
.Literal
) != 0) {
67 if (gfd
is System
.Reflection
.Emit
.FieldBuilder
) {
68 // TODO: Remove after MemberCache
69 c
= TypeManager
.GetConstant (gfd
).Value
;
71 c
= Constant
.CreateConstantFromValue (fi
.FieldType
, gfd
.GetValue (gfd
), Location
.Null
);
74 return new ConstSpec (definition
, fi
, mod
, c
);
77 if ((fa
& FieldAttributes
.InitOnly
) != 0) {
78 if (fi
.FieldType
== TypeManager
.decimal_type
) {
79 var dc
= ReadDecimalConstant (gfd
);
81 return new ConstSpec (definition
, fi
, mod
, dc
);
84 mod
|= Modifiers
.READONLY
;
87 if ((fa
& FieldAttributes
.Static
) != 0)
88 mod
|= Modifiers
.STATIC
;
90 if (!TypeManager
.IsReferenceType (fi
.FieldType
)) {
91 PredefinedAttribute pa
= PredefinedAttributes
.Get
.FixedBuffer
;
93 if (gfd
is System
.Reflection
.Emit
.FieldBuilder
) {
94 // TODO: Remove this after MemberCache fix
95 } else if (gfd
.IsDefined (pa
.Type
, false)) {
96 var element_field
= fi
.FieldType
.GetField (FixedField
.FixedElementName
);
97 return new FixedFieldSpec (definition
, fi
, element_field
, mod
);
104 return new FieldSpec (definition
, fi
, mod
);
107 public static EventSpec
CreateEvent (EventInfo ei
)
109 // TODO MemberCache: Remove
110 var ef
= TypeManager
.GetEventField (ei
);
114 var add_accessor
= CreateMethod (TypeManager
.GetAddMethod (ei
));
115 var remove_accessor
= CreateMethod (TypeManager
.GetRemoveMethod (ei
));
117 if (add_accessor
.Modifiers
!= remove_accessor
.Modifiers
)
118 throw new NotImplementedException ("Different accessor modifiers " + ei
.Name
);
120 var definition
= new ImportedMemberDefinition (ei
);
121 return new EventSpec (definition
, ei
, add_accessor
.Modifiers
, add_accessor
, remove_accessor
) {
122 EventType
= ei
.EventHandlerType
126 public static MethodSpec
CreateMethod (MethodBase mb
)
128 // TODO MemberCache: Remove
129 MethodCore mc
= TypeManager
.GetMethod (mb
) as MethodCore
;
134 var ma
= mb
.Attributes
;
135 switch (ma
& MethodAttributes
.MemberAccessMask
) {
136 case MethodAttributes
.Public
:
137 mod
= Modifiers
.PUBLIC
;
139 case MethodAttributes
.Assembly
:
140 mod
= Modifiers
.INTERNAL
;
142 case MethodAttributes
.Family
:
143 mod
= Modifiers
.PROTECTED
;
145 case MethodAttributes
.FamORAssem
:
146 mod
= Modifiers
.PROTECTED
| Modifiers
.INTERNAL
;
149 mod
= Modifiers
.PRIVATE
;
153 if ((ma
& MethodAttributes
.Static
) != 0)
154 mod
|= Modifiers
.STATIC
;
155 if ((ma
& MethodAttributes
.Virtual
) != 0)
156 mod
|= Modifiers
.VIRTUAL
;
157 if ((ma
& MethodAttributes
.Abstract
) != 0)
158 mod
|= Modifiers
.ABSTRACT
;
159 if ((ma
& MethodAttributes
.Final
) != 0)
160 mod
|= Modifiers
.SEALED
;
162 IMemberDefinition definition
;
163 var gmd
= mb
as MethodInfo
;
164 if (gmd
!= null && gmd
.IsGenericMethodDefinition
) {
165 definition
= new ImportedGenericMethodDefinition (gmd
);
166 } else if (mb
.IsGenericMethod
) { // TODO MemberCache: Remove me
167 definition
= new ImportedGenericMethodDefinition ((MethodInfo
) TypeManager
.DropGenericMethodArguments (mb
));
169 definition
= new ImportedMemberDefinition (mb
);
172 // TODO MemberCache: Use AParametersCollection p = ParametersImported.Create (mb);
173 AParametersCollection p
= TypeManager
.GetParameterData (mb
);
176 if (mb
.IsConstructor
) {
177 kind
= MemberKind
.Constructor
;
180 // Detect operators and destructors
182 string name
= mb
.Name
;
183 kind
= MemberKind
.Method
;
184 if (!mb
.DeclaringType
.IsInterface
&& name
.Length
> 6) {
185 if ((mod
& Modifiers
.STATIC
) != 0 && name
[2] == '_' && name
[1] == 'p' && name
[0] == 'o') {
186 var op_type
= Operator
.GetType (name
);
187 if (op_type
.HasValue
) {
188 kind
= MemberKind
.Operator
;
190 } else if (p
.IsEmpty
&& (mod
& Modifiers
.STATIC
) == 0 && name
== Destructor
.MetadataName
) {
191 kind
= MemberKind
.Destructor
;
196 MethodSpec ms
= new MethodSpec (kind
, definition
, mb
, p
, mod
);
200 public static PropertySpec
CreateProperty (PropertyInfo pi
)
202 var definition
= new ImportedMemberDefinition (pi
);
203 var mod
= Modifiers
.PRIVATE
; // TODO: modifiers
204 return new PropertySpec (MemberKind
.Property
| MemberKind
.Indexer
, definition
, pi
, mod
);
207 static TypeSpec
CreateType (Type type
)
210 var ma
= type
.Attributes
;
211 switch (ma
& TypeAttributes
.VisibilityMask
) {
212 case TypeAttributes
.Public
:
213 case TypeAttributes
.NestedPublic
:
214 mod
= Modifiers
.PUBLIC
;
216 case TypeAttributes
.NestedPrivate
:
217 mod
= Modifiers
.PRIVATE
;
219 case TypeAttributes
.NestedFamily
:
220 mod
= Modifiers
.PROTECTED
;
222 case TypeAttributes
.NestedFamORAssem
:
223 mod
= Modifiers
.PROTECTED
| Modifiers
.INTERNAL
;
226 mod
= Modifiers
.INTERNAL
;
230 var type_def
= TypeManager
.DropGenericTypeArguments (type
);
233 if (type_def
.IsInterface
)
234 kind
= MemberKind
.Interface
;
235 else if (type_def
.IsEnum
)
236 kind
= MemberKind
.Enum
;
237 else if (type_def
.IsClass
) {
238 if (type_def
.BaseType
== TypeManager
.multicast_delegate_type
)
239 kind
= MemberKind
.Delegate
;
241 kind
= MemberKind
.Class
;
243 kind
= MemberKind
.Struct
;
246 if (type
.IsGenericType
) {
247 throw new NotImplementedException ();
250 var definition
= new ImportedTypeDefinition (type_def
);
251 var spec
= new TypeSpec (kind
, definition
, type
, type
.Name
, mod
);
253 // TODO: BaseType for class only?
258 public static TypeSpec
ImportType (Type type
)
260 if (type
.IsDefined (typeof (CompilerGeneratedAttribute
), false))
263 return CreateType (type
);
267 // Decimal constants cannot be encoded in the constant blob, and thus are marked
268 // as IsInitOnly ('readonly' in C# parlance). We get its value from the
269 // DecimalConstantAttribute metadata.
271 static Constant
ReadDecimalConstant (FieldInfo fi
)
273 PredefinedAttribute pa
= PredefinedAttributes
.Get
.DecimalConstant
;
277 object[] attrs
= fi
.GetCustomAttributes (pa
.Type
, false);
278 if (attrs
.Length
!= 1)
281 return new DecimalConstant (((DecimalConstantAttribute
) attrs
[0]).Value
, Location
.Null
);
285 class ImportedMemberDefinition
: IMemberDefinition
287 protected readonly ICustomAttributeProvider provider
;
289 public ImportedMemberDefinition (ICustomAttributeProvider provider
)
291 this.provider
= provider
;
294 public ObsoleteAttribute
GetObsoleteAttribute ()
296 var res
= provider
.GetCustomAttributes (typeof (ObsoleteAttribute
), false);
297 if (res
== null || res
.Length
< 1)
300 return res
[0] as ObsoleteAttribute
;
303 public void SetIsUsed ()
305 // Unused for imported members
309 class ImportedGenericMethodDefinition
: ImportedMemberDefinition
, IGenericMethodDefinition
311 public ImportedGenericMethodDefinition (MethodInfo provider
)
316 public MethodInfo
MakeGenericMethod (Type
[] targs
)
318 return ((MethodInfo
) provider
).MakeGenericMethod (targs
);
322 class ImportedTypeDefinition
: ImportedMemberDefinition
, ITypeDefinition
324 public ImportedTypeDefinition (Type type
)
329 public void LoadMembers (MemberCache cache
)
331 throw new NotImplementedException ();