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 
GenericParameter(string id)23 		public GenericParameter (string id)
24 			: this (id, 0, null)
25 		{
26 		}
27 
GenericParameter(string id, PEAPI.GenericParamAttributes attr, ArrayList constraints)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 
AddConstraint(BaseTypeRef constraint)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 
ToString()61 		public override string ToString ()
62 		{
63 			return Id;
64 		}
65 
AddCustomAttribute(CustomAttr customattr)66 		public void AddCustomAttribute (CustomAttr customattr)
67 		{
68 			if (customattrList == null)
69 				customattrList = new ArrayList ();
70 
71 			customattrList.Add (customattr);
72 		}
73 
Resolve(CodeGen code_gen, PEAPI.MethodDef methoddef)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 
Resolve(CodeGen code_gen, PEAPI.ClassDef classdef)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 
Resolve(CodeGen code_gen, PEAPI.GenericParameter gp)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 
ResolveConstraints(GenericParameters type_gen_params, GenericParameters method_gen_params)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 
ResolveConstraints(CodeGen code_gen, PEAPI.GenericParameter gp)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 
GenericParameters()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 
Add(GenericParameter gen_param)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 
GetGenericParam(string id)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 
GetGenericParamNum(string id)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 
Resolve(CodeGen code_gen, PEAPI.ClassDef classdef)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 
Resolve(CodeGen code_gen, PEAPI.MethodDef methoddef)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 
ResolveConstraints(GenericParameters type_gen_params, GenericParameters method_gen_params)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 
MakeString()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 
ToString()204 		public override string ToString ()
205 		{
206 			if (param_str == null)
207 				MakeString ();
208 			return param_str;
209 		}
210 	}
211 
212 }
213