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