Merge pull request #4246 from Unity-Technologies/mcs-generic-constraint-enumerator
[mono.git] / mcs / ilasm / codegen / ModifiableType.cs
1 //
2 // Mono.ILASM.ModifiableType
3 //
4 // Author(s):
5 //  Jackson Harper (Jackson@LatitudeGeo.com)
6 //
7 // (C) 2003 Jackson Harper (Jackson@LatitudeGeo.com)
8 //
9
10
11 using System;
12 using System.Collections;
13
14 namespace Mono.ILASM {
15
16         public abstract class ModifiableType {
17
18                 private ArrayList conversion_list;
19                 private bool is_pinned;
20                 private bool is_ref;
21                 private bool is_array;
22                 private bool use_type_spec;
23
24                 private enum ConversionMethod {
25                         MakeArray,
26                         MakeBoundArray,
27                         MakeManagedPointer,
28                         MakeUnmanagedPointer,
29                         MakeCustomModified
30                 }
31
32                 public ModifiableType ()
33                 {
34                         conversion_list = new ArrayList (5);
35                 }
36
37                 public abstract string SigMod {
38                         get;
39                         set;
40                 }
41
42                 protected ArrayList ConversionList {
43                         get { return conversion_list; }
44                         set { conversion_list = value; }
45                 }
46                 
47                 public bool IsPinned {
48                         get { return is_pinned; }
49                 }
50
51                 public bool IsArray {
52                         get { return is_array; }
53                 }
54
55                 public bool IsRef {
56                         get { return is_ref; }
57                 }
58
59                 public bool UseTypeSpec {
60                         get { return use_type_spec; }
61                 }
62
63                 public void MakeArray ()
64                 {
65                         use_type_spec = true;
66                         conversion_list.Add (ConversionMethod.MakeArray);
67                         is_array = true;
68                         SigMod += "[]";
69                 }
70
71                 public void MakeBoundArray (ArrayList bounds)
72                 {
73                         use_type_spec = true;
74                         conversion_list.Add (ConversionMethod.MakeBoundArray);
75                         conversion_list.Add (bounds);
76                         is_array = true;
77                         SigMod += "[";
78                         for (int i=0; i<bounds.Count; i++) {
79                                 DictionaryEntry e = (DictionaryEntry) bounds [i];
80                                 if (e.Key != TypeRef.Ellipsis)
81                                         SigMod += e.Key;
82                                 SigMod += "...";
83                                 if (e.Value != TypeRef.Ellipsis)
84                                         SigMod += e.Value;
85                                 if (i + 1 < bounds.Count)
86                                         SigMod += ", ";
87                         }
88                         SigMod += "]";
89                 }
90
91                 public void MakeManagedPointer ()
92                 {
93                         use_type_spec = true;
94                         conversion_list.Add (ConversionMethod.MakeManagedPointer);
95                         is_ref = true;
96                         SigMod += "&";
97                 }
98
99                 public void MakeUnmanagedPointer ()
100                 {
101                         use_type_spec = true;
102                         conversion_list.Add (ConversionMethod.MakeUnmanagedPointer);
103                         SigMod += "*";
104                 }
105
106                 public void MakeCustomModified (CodeGen code_gen, PEAPI.CustomModifier modifier,
107                                 BaseTypeRef klass)
108                 {
109                         use_type_spec = true;
110                         conversion_list.Add (ConversionMethod.MakeCustomModified);
111                         conversion_list.Add (modifier);
112                         conversion_list.Add (klass);
113
114                         if (modifier == PEAPI.CustomModifier.modreq)
115                                 SigMod += ("modreq (" + klass.FullName + ")");
116                         else if (modifier == PEAPI.CustomModifier.modopt)
117                                 SigMod += ("modopt (" + klass.FullName + ")");
118                 }
119
120                 public void MakePinned ()
121                 {
122                         use_type_spec = true;
123                         is_pinned = true;
124                 }
125
126                 protected PEAPI.Type Modify (CodeGen code_gen, PEAPI.Type type)
127                 {
128                         PeapiTypeRef peapi_type = new PeapiTypeRef (type);
129                         int count = conversion_list.Count;
130                         for (int i=0; i<count; i++) {
131                                 switch ((ConversionMethod) conversion_list[i]) {
132                                 case ConversionMethod.MakeArray:
133                                         peapi_type.MakeArray ();
134                                         break;
135                                 case ConversionMethod.MakeBoundArray:
136                                         peapi_type.MakeBoundArray ((ArrayList) conversion_list[++i]);
137                                         break;
138                                 case ConversionMethod.MakeManagedPointer:
139                                         peapi_type.MakeManagedPointer ();
140                                         break;
141                                 case ConversionMethod.MakeUnmanagedPointer:
142                                         peapi_type.MakeUnmanagedPointer ();
143                                         break;
144                                 case ConversionMethod.MakeCustomModified:
145                                         peapi_type.MakeCustomModified (code_gen, (PEAPI.CustomModifier) conversion_list[++i],
146                                                 (BaseTypeRef) conversion_list[++i]);
147                                         break;
148                                 }
149
150                         }
151
152                         return peapi_type.PeapiType;
153                 }
154
155         }
156
157 }
158
159