f6fb66fc39bbddb28ba2a4c3ea788581360cb99b
[mono.git] / mcs / class / referencesource / mscorlib / system / reflection / emit / symboltype.cs
1 // ==++==
2 // 
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6 // <OWNER>Microsoft</OWNER>
7 // 
8
9 namespace System.Reflection.Emit 
10 {
11     using System.Runtime.InteropServices;
12     using System;
13     using System.Reflection;
14     using System.Diagnostics.Contracts;
15     using CultureInfo = System.Globalization.CultureInfo;
16
17     [Serializable]
18     internal enum TypeKind
19     {
20         IsArray   = 1,
21         IsPointer = 2,
22         IsByRef   = 3,
23     }
24
25     // This is a kind of Type object that will represent the compound expression of a parameter type or field type.
26     internal sealed class SymbolType : TypeInfo
27     {
28         public override bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo){
29             if(typeInfo==null) return false;            
30             return IsAssignableFrom(typeInfo.AsType());
31         }
32
33         #region Static Members
34         internal static Type FormCompoundType(char[] bFormat, Type baseType, int curIndex)
35         {
36             // This function takes a string to describe the compound type, such as "[,][]", and a baseType.
37             // 
38             // Example: [2..4]  - one dimension array with lower bound 2 and size of 3
39             // Example: [3, 5, 6] - three dimension array with lower bound 3, 5, 6
40             // Example: [-3, ] [] - one dimensional array of two dimensional array (with lower bound -3 for 
41             //          the first dimension)
42             // Example: []* - pointer to a one dimensional array
43             // Example: *[] - one dimensional array. The element type is a pointer to the baseType
44             // Example: []& - ByRef of a single dimensional array. Only one & is allowed and it must appear the last!
45             // Example: [?] - Array with unknown bound
46
47             SymbolType symbolType;
48             int iLowerBound;
49             int iUpperBound;
50
51             if (bFormat == null || curIndex == bFormat.Length)
52             {
53                 // we have consumed all of the format string
54                 return baseType;
55             }
56
57               
58              
59
60             if (bFormat[curIndex] == '&')
61             {
62                 // ByRef case
63
64                 symbolType = new SymbolType(TypeKind.IsByRef);
65                 symbolType.SetFormat(bFormat, curIndex, 1);
66                 curIndex++;
67                 
68                 if (curIndex != bFormat.Length)
69                     // ByRef has to be the last char!!
70                     throw new ArgumentException(Environment.GetResourceString("Argument_BadSigFormat"));
71
72                 symbolType.SetElementType(baseType);
73                 return symbolType;
74             }
75
76             if (bFormat[curIndex] == '[')
77             {
78                 // Array type.
79                 symbolType = new SymbolType(TypeKind.IsArray);
80                 int startIndex = curIndex;
81                 curIndex++;
82
83                 iLowerBound = 0;
84                 iUpperBound = -1;
85
86                 // Example: [2..4]  - one dimension array with lower bound 2 and size of 3
87                 // Example: [3, 5, 6] - three dimension array with lower bound 3, 5, 6
88                 // Example: [-3, ] [] - one dimensional array of two dimensional array (with lower bound -3 sepcified)
89                 
90                 while (bFormat[curIndex] != ']')
91                 {
92                     if (bFormat[curIndex] == '*')
93                     {
94                         symbolType.m_isSzArray = false;
95                         curIndex++;                        
96                     }
97                     // consume, one dimension at a time
98                     if ((bFormat[curIndex] >= '0' && bFormat[curIndex] <= '9') || bFormat[curIndex] == '-')
99                     {
100                         bool isNegative = false;
101                         if (bFormat[curIndex] == '-')
102                         {
103                             isNegative = true;
104                             curIndex++;
105                         }
106
107                         // lower bound is specified. Consume the low bound
108                         while (bFormat[curIndex] >= '0' && bFormat[curIndex] <= '9')
109                         {
110                             iLowerBound = iLowerBound * 10;
111                             iLowerBound += bFormat[curIndex] - '0';
112                             curIndex++;
113                         }
114
115                         if (isNegative)
116                         {
117                             iLowerBound = 0 - iLowerBound;
118                         }
119
120                         // set the upper bound to be less than LowerBound to indicate that upper bound it not specified yet!
121                         iUpperBound = iLowerBound - 1;
122
123                     }
124                     if (bFormat[curIndex] == '.')
125                     {                       
126                         // upper bound is specified
127
128                         // skip over ".."
129                         curIndex++;
130                         if (bFormat[curIndex] != '.')
131                         {
132                             // bad format!! Throw exception
133                             throw new ArgumentException(Environment.GetResourceString("Argument_BadSigFormat"));
134                         }
135
136                         curIndex++;
137                         // consume the upper bound
138                         if ((bFormat[curIndex] >= '0' && bFormat[curIndex] <= '9') || bFormat[curIndex] == '-')
139                         {
140                             bool isNegative = false;
141                             iUpperBound = 0;
142                             if (bFormat[curIndex] == '-')
143                             {
144                                 isNegative = true;
145                                 curIndex++;
146                             }
147
148                             // lower bound is specified. Consume the low bound
149                             while (bFormat[curIndex] >= '0' && bFormat[curIndex] <= '9')
150                             {
151                                 iUpperBound = iUpperBound * 10;
152                                 iUpperBound += bFormat[curIndex] - '0';
153                                 curIndex++;
154                             }
155                             if (isNegative)
156                             {
157                                 iUpperBound = 0 - iUpperBound;
158                             }
159                             if (iUpperBound < iLowerBound)
160                             {
161                                 // User specified upper bound less than lower bound, this is an error.
162                                 // Throw error exception.
163                                 throw new ArgumentException(Environment.GetResourceString("Argument_BadSigFormat"));
164                             }
165                         }
166                     }
167
168                     if (bFormat[curIndex] == ',')
169                     {
170                         // We have more dimension to deal with.
171                         // now set the lower bound, the size, and increase the dimension count!
172                         curIndex++;
173                         symbolType.SetBounds(iLowerBound, iUpperBound);
174
175                         // clear the lower and upper bound information for next dimension
176                         iLowerBound = 0;
177                         iUpperBound = -1;
178                     }
179                     else if (bFormat[curIndex] != ']')
180                     {
181                         throw new ArgumentException(Environment.GetResourceString("Argument_BadSigFormat"));
182                     }
183                 }
184                 
185                 // The last dimension information
186                 symbolType.SetBounds(iLowerBound, iUpperBound);
187
188                 // skip over ']'
189                 curIndex++;
190
191                 symbolType.SetFormat(bFormat, startIndex, curIndex - startIndex);
192
193                 // set the base type of array
194                 symbolType.SetElementType(baseType);
195                 return FormCompoundType(bFormat, symbolType, curIndex);
196             }
197             else if (bFormat[curIndex] == '*')
198             {
199                 // pointer type.
200
201                 symbolType = new SymbolType(TypeKind.IsPointer);
202                 symbolType.SetFormat(bFormat, curIndex, 1);
203                 curIndex++;
204                 symbolType.SetElementType(baseType);
205                 return FormCompoundType(bFormat, symbolType, curIndex);
206             }
207
208             return null;
209         }
210
211         #endregion
212
213         #region Data Members
214         internal TypeKind       m_typeKind;
215         internal Type           m_baseType;
216         internal int            m_cRank;        // count of dimension
217         // If LowerBound and UpperBound is equal, that means one element. 
218         // If UpperBound is less than LowerBound, then the size is not specified.
219         internal int[]          m_iaLowerBound;
220         internal int[]          m_iaUpperBound; // count of dimension
221         private char[]          m_bFormat;      // format string to form the full name.
222         private bool            m_isSzArray = true;
223         #endregion
224
225         #region Constructor
226         internal SymbolType(TypeKind typeKind)
227         {
228             m_typeKind = typeKind;            
229             m_iaLowerBound = new int[4];
230             m_iaUpperBound = new int[4];
231         }
232
233         #endregion
234
235         #region Internal Members
236         internal void SetElementType(Type baseType)
237         {
238             if (baseType == null)
239                 throw new ArgumentNullException("baseType");
240             Contract.EndContractBlock();
241
242             m_baseType = baseType;
243         }
244
245         private void SetBounds(int lower, int upper)
246         {
247             // Increase the rank, set lower and upper bound
248
249             if (lower != 0 || upper != -1)
250                 m_isSzArray = false;
251             
252             if (m_iaLowerBound.Length <= m_cRank)
253             {
254                 // resize the bound array
255                 int[]  iaTemp = new int[m_cRank * 2];
256                 Array.Copy(m_iaLowerBound, iaTemp, m_cRank);
257                 m_iaLowerBound = iaTemp;            
258                 Array.Copy(m_iaUpperBound, iaTemp, m_cRank);
259                 m_iaUpperBound = iaTemp;            
260             }
261
262             m_iaLowerBound[m_cRank] = lower;
263             m_iaUpperBound[m_cRank] = upper;
264             m_cRank++;
265         }
266
267         internal void SetFormat(char[] bFormat, int curIndex, int length)
268         {
269             // Cache the text display format for this SymbolType
270
271             char[] bFormatTemp = new char[length];
272             Array.Copy(bFormat, curIndex, bFormatTemp, 0, length);
273             m_bFormat = bFormatTemp;
274         }
275         #endregion
276         
277         #region Type Overrides
278         internal override bool IsSzArray 
279         { 
280             get 
281             { 
282                 if (m_cRank > 1)
283                     return false;
284                 
285                 return m_isSzArray;
286             }
287         }
288
289         public override Type MakePointerType() 
290         { 
291             return SymbolType.FormCompoundType((new String(m_bFormat) + "*").ToCharArray(), m_baseType, 0);
292         }
293
294         public override Type MakeByRefType() 
295         { 
296             return SymbolType.FormCompoundType((new String(m_bFormat) + "&").ToCharArray(), m_baseType, 0);
297         }
298         
299         public override Type MakeArrayType() 
300         { 
301             return SymbolType.FormCompoundType((new String(m_bFormat) + "[]").ToCharArray(), m_baseType, 0);
302         }
303         
304         public override Type MakeArrayType(int rank) 
305         { 
306             if (rank <= 0)
307                 throw new IndexOutOfRangeException();
308             Contract.EndContractBlock();
309
310             string szrank = "";
311             if (rank == 1)
312             {
313                 szrank = "*";
314             }
315             else 
316             {
317                 for(int i = 1; i < rank; i++)
318                     szrank += ",";
319             }
320
321             string s = String.Format(CultureInfo.InvariantCulture, "[{0}]", szrank); // [,,]
322             SymbolType st = SymbolType.FormCompoundType((new String(m_bFormat) + s).ToCharArray(), m_baseType, 0) as SymbolType;
323             return st;
324         }
325
326         public override int GetArrayRank()
327         {
328             if (!IsArray)
329                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride"));
330             Contract.EndContractBlock();
331
332             return m_cRank;
333         }
334         
335         public override Guid GUID 
336         {
337             get { throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); }
338         }
339
340         public override Object InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, 
341             Object[] args, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParameters)
342         {
343             throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));      
344         }
345
346         public override Module Module 
347         {
348             get 
349             {
350                 Type baseType;
351
352                 for (baseType = m_baseType; baseType is SymbolType; baseType = ((SymbolType) baseType).m_baseType);
353
354                 return baseType.Module;
355             }
356         }
357         public override Assembly Assembly 
358         {
359             get 
360             {
361                 Type baseType;
362
363                 for (baseType = m_baseType; baseType is SymbolType; baseType = ((SymbolType) baseType).m_baseType);
364
365                 return baseType.Assembly;
366             }
367         }
368                 
369         public override RuntimeTypeHandle TypeHandle 
370         {
371              get { throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); }     
372         }
373             
374         public override String Name 
375         {
376             get 
377             { 
378                 Type baseType;
379                 String sFormat = new String(m_bFormat);
380
381                 for (baseType = m_baseType; baseType is SymbolType; baseType = ((SymbolType)baseType).m_baseType)
382                     sFormat = new String(((SymbolType)baseType).m_bFormat) + sFormat;
383
384                 return baseType.Name + sFormat;
385             }
386         }
387                 
388         public override String FullName 
389         {
390             get 
391             { 
392                 return TypeNameBuilder.ToString(this, TypeNameBuilder.Format.FullName);
393             }
394         }
395
396         public override String AssemblyQualifiedName 
397         {
398             get 
399             { 
400                 return TypeNameBuilder.ToString(this, TypeNameBuilder.Format.AssemblyQualifiedName);
401             }
402         }
403
404         public override String ToString()
405         {            
406                 return TypeNameBuilder.ToString(this, TypeNameBuilder.Format.ToString);
407         }
408     
409         public override String Namespace 
410         {
411             get { return m_baseType.Namespace; }
412         }
413     
414         public override Type BaseType 
415         {
416              
417             get { return typeof(System.Array); }
418         }
419         
420         protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr,Binder binder,
421                 CallingConventions callConvention, Type[] types,ParameterModifier[] modifiers)
422         {
423             throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));      
424         }
425         
426 [System.Runtime.InteropServices.ComVisible(true)]
427         public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr)
428         {
429             throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));      
430         }
431         
432         protected override MethodInfo GetMethodImpl(String name,BindingFlags bindingAttr,Binder binder,
433                 CallingConventions callConvention, Type[] types,ParameterModifier[] modifiers)
434         {
435             throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));      
436         }
437     
438         public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
439         {
440             throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));      
441         }
442     
443         public override FieldInfo GetField(String name, BindingFlags bindingAttr)
444         {
445             throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));      
446         }
447         
448         public override FieldInfo[] GetFields(BindingFlags bindingAttr)
449         {
450             throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));      
451         }
452     
453         public override Type GetInterface(String name,bool ignoreCase)
454         {
455             throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));      
456         }
457     
458         public override Type[] GetInterfaces()
459         {
460             throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));      
461         }
462     
463         public override EventInfo GetEvent(String name,BindingFlags bindingAttr)
464         {
465             throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));      
466         }
467     
468         public override EventInfo[] GetEvents()
469         {
470             throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));      
471         }
472     
473         protected override PropertyInfo GetPropertyImpl(String name, BindingFlags bindingAttr, Binder binder, 
474                 Type returnType, Type[] types, ParameterModifier[] modifiers)
475         {
476             throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));      
477         }
478     
479         public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
480         {
481             throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));      
482         }
483
484         public override Type[] GetNestedTypes(BindingFlags bindingAttr)
485         {
486             throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));      
487         }
488    
489         public override Type GetNestedType(String name, BindingFlags bindingAttr)
490         {
491             throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));      
492         }
493
494         public override MemberInfo[] GetMember(String name,  MemberTypes type, BindingFlags bindingAttr)
495         {
496             throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));      
497         }
498         
499         public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
500         {
501             throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));      
502         }
503
504 [System.Runtime.InteropServices.ComVisible(true)]
505         public override InterfaceMapping GetInterfaceMap(Type interfaceType)
506         {
507             throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));      
508         }
509
510         public override EventInfo[] GetEvents(BindingFlags bindingAttr)
511         {
512             throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));      
513         }
514     
515         protected override TypeAttributes GetAttributeFlagsImpl()
516         {
517             // Return the attribute flags of the base type?
518             Type baseType;
519             for (baseType = m_baseType; baseType is SymbolType; baseType = ((SymbolType)baseType).m_baseType);
520             return baseType.Attributes;
521         }
522         
523         protected override bool IsArrayImpl()
524         {
525             return m_typeKind == TypeKind.IsArray;
526         }
527
528         protected override bool IsPointerImpl()
529         {
530             return m_typeKind == TypeKind.IsPointer;
531         }
532
533         protected override bool IsByRefImpl()
534         {
535             return m_typeKind == TypeKind.IsByRef;
536         }
537
538         protected override bool IsPrimitiveImpl()
539         {
540             return false;
541         }
542         
543         protected override bool IsValueTypeImpl() 
544         {
545             return false;
546         }
547         
548         protected override bool IsCOMObjectImpl()
549         {
550             return false;
551         }
552
553         public override bool IsConstructedGenericType
554         {
555             get
556             {
557                 return false;
558             }
559         }
560
561         public override Type GetElementType()
562         {
563             return m_baseType;
564         }
565         
566         protected override bool HasElementTypeImpl()
567         {
568             return m_baseType != null;
569         }
570     
571         public override Type UnderlyingSystemType 
572         {
573              
574             get { return this; }
575         }
576             
577         public override Object[] GetCustomAttributes(bool inherit)
578         {
579             throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));      
580         }
581
582         public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
583         {
584             throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));      
585         }
586
587         public override bool IsDefined (Type attributeType, bool inherit)
588         {
589             throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));      
590         }
591         #endregion
592     }
593 }
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610