Merge pull request #1931 from kasthack/system.web-fixes
[mono.git] / mcs / ilasm / codegen / GenericParameters.cs
1 //
2 // Mono.ILASM.GenericParameters
3 //
4 // Author(s):
5 //  Ankit Jain  <jankit@novell.com>
6 //
7 // Copyright 2006 Novell, Inc (http://www.novell.com)
8 //
9
10 using System;
11 using System.Collections;
12 using System.Text;
13
14 namespace Mono.ILASM {
15
16         public class GenericParameter : ICustomAttrTarget {
17                 string id;
18                 int num;
19                 PEAPI.GenericParamAttributes attr;
20                 ArrayList constraintsList;
21                 ArrayList customattrList;
22                 
23                 public GenericParameter (string id) 
24                         : this (id, 0, null)
25                 {
26                 }
27
28                 public GenericParameter (string id, PEAPI.GenericParamAttributes attr, ArrayList constraints)
29                 {
30                         this.id = id;
31                         this.attr = attr;
32                         num = -1;
33                         constraintsList = null;
34                         customattrList = null;
35                                 
36                         if (constraints != null)
37                                 foreach (BaseTypeRef typeref in constraints)
38                                         AddConstraint (typeref);
39                 }
40
41                 public string Id {
42                         get { return id; }
43                 }
44
45                 public int Num {
46                         get { return num; }
47                         set { num = value; }
48                 }
49
50                 public void AddConstraint (BaseTypeRef constraint)
51                 {
52                         if (constraint == null)
53                                 throw new InternalErrorException ();
54
55                         if (constraintsList == null)
56                                 constraintsList = new ArrayList ();
57
58                         constraintsList.Add (constraint);
59                 }
60
61                 public override string ToString ()
62                 {
63                         return Id;
64                 }
65
66                 public void AddCustomAttribute (CustomAttr customattr)
67                 {
68                         if (customattrList == null)
69                                 customattrList = new ArrayList ();
70
71                         customattrList.Add (customattr);
72                 }
73
74                 public void Resolve (CodeGen code_gen, PEAPI.MethodDef methoddef)
75                 {
76                         PEAPI.GenericParameter gp = methoddef.AddGenericParameter ((short) num, id, attr);
77                         Resolve (code_gen, gp);
78                 }
79
80                 public void Resolve (CodeGen code_gen, PEAPI.ClassDef classdef)
81                 {
82                         PEAPI.GenericParameter gp = classdef.AddGenericParameter ((short) num, id, attr);
83                         Resolve (code_gen, gp);
84                 }
85
86                 private void Resolve (CodeGen code_gen, PEAPI.GenericParameter gp)
87                 {
88                         ResolveConstraints (code_gen, gp);
89                         if (customattrList == null)
90                                 return;
91
92                         foreach (CustomAttr customattr in customattrList)
93                                 customattr.AddTo (code_gen, gp);
94                 }
95
96                 public void ResolveConstraints (GenericParameters type_gen_params, GenericParameters method_gen_params)
97                 {
98                         if (constraintsList == null)
99                                 return;
100                                 
101                         foreach (BaseTypeRef constraint in constraintsList) {
102                                 BaseGenericTypeRef gtr = constraint as BaseGenericTypeRef;
103                                 if (gtr != null)
104                                         gtr.Resolve (type_gen_params, method_gen_params);
105                         }
106                 }
107
108                 private void ResolveConstraints (CodeGen code_gen, PEAPI.GenericParameter gp)
109                 {
110                         if (constraintsList == null)
111                                 return;
112
113                         foreach (BaseTypeRef constraint in constraintsList) {
114                                 constraint.Resolve (code_gen);
115                                 gp.AddConstraint (constraint.PeapiType);
116                         }
117                 }
118
119         }
120
121         public class GenericParameters {
122                 ArrayList param_list;
123                 string param_str;
124
125                 public GenericParameters ()
126                 {
127                         param_list = null;
128                         param_str = null;
129                 }
130
131                 public int Count {
132                         get { return (param_list == null ? 0 : param_list.Count); }
133                 }
134
135                 public GenericParameter this [int index] {
136                         get { return (param_list != null ? (GenericParameter) param_list [index] : null); }
137                         set { Add (value); }
138                 }
139
140                 public void Add (GenericParameter gen_param)
141                 {
142                         if (gen_param == null)
143                                 throw new InternalErrorException ();
144
145                         if (param_list == null)
146                                 param_list = new ArrayList ();
147                         gen_param.Num = param_list.Count;
148                         param_list.Add (gen_param);
149                         param_str = null;
150                 }
151                 
152                 public GenericParameter GetGenericParam (string id)
153                 {
154                         if (param_list == null)
155                                 Report.Error ("Invalid type parameter '" + id + "'");
156
157                         foreach (GenericParameter param in param_list)
158                                 if (param.Id == id)
159                                         return param;
160                         return null;
161                 }
162         
163                 public int GetGenericParamNum (string id)
164                 {
165                         GenericParameter param = GetGenericParam (id);
166                         if (param != null)
167                                 return param.Num;
168
169                         return -1;
170                 }
171
172                 public void Resolve (CodeGen code_gen, PEAPI.ClassDef classdef)
173                 {
174                         foreach (GenericParameter param in param_list)
175                                 param.Resolve (code_gen, classdef);
176                 }
177                 
178                 public void Resolve (CodeGen code_gen, PEAPI.MethodDef methoddef)
179                 {
180                         foreach (GenericParameter param in param_list)
181                                 param.Resolve (code_gen, methoddef);
182                 }
183
184                 public void ResolveConstraints (GenericParameters type_gen_params, GenericParameters method_gen_params)
185                 {
186                         foreach (GenericParameter param in param_list)
187                                 param.ResolveConstraints (type_gen_params, method_gen_params);
188                         param_str = null;
189                 }
190
191                 private void MakeString ()
192                 {
193                         //Build full_name (foo < , >)
194                         StringBuilder sb = new StringBuilder ();
195                         sb.Append ("<");
196                         foreach (GenericParameter param in param_list)
197                                 sb.AppendFormat ("{0}, ", param);
198                         //Remove the extra ', ' at the end
199                         sb.Length -= 2;
200                         sb.Append (">");
201                         param_str = sb.ToString ();
202                 }
203
204                 public override string ToString ()
205                 {
206                         if (param_str == null)
207                                 MakeString ();
208                         return param_str;
209                 }
210         }
211
212 }