1 /* Copyright (C) 2005 Versant Inc. http://www.db4o.com */ 2 using System; 3 using System.Reflection; 4 using System.Text; 5 6 namespace Sharpen.Lang 7 { 8 public abstract class TypeReference 9 { FromString(string s)10 public static TypeReference FromString(string s) 11 { 12 if (null == s) throw new ArgumentNullException("s"); 13 return new TypeReferenceParser(s).Parse(); 14 } 15 FromType(Type type)16 public static TypeReference FromType(Type type) 17 { 18 if (null == type) throw new ArgumentNullException("type"); 19 return FromString(type.AssemblyQualifiedName); 20 } 21 22 public abstract string SimpleName 23 { 24 get; 25 } 26 27 public abstract AssemblyName AssemblyName 28 { 29 get; 30 } 31 Resolve()32 public abstract Type Resolve(); 33 AppendTypeName(StringBuilder builder)34 public abstract void AppendTypeName(StringBuilder builder); 35 ToString()36 public override string ToString() 37 { 38 return GetUnversionedName(); 39 } 40 GetUnversionedName()41 public string GetUnversionedName() 42 { 43 StringBuilder builder = new StringBuilder(); 44 AppendUnversionedName(builder); 45 return builder.ToString(); 46 } 47 AppendUnversionedName(StringBuilder builder)48 internal virtual void AppendUnversionedName(StringBuilder builder) 49 { 50 AppendTypeName(builder); 51 AppendUnversionedAssemblyName(builder); 52 } 53 AppendUnversionedAssemblyName(StringBuilder builder)54 protected void AppendUnversionedAssemblyName(StringBuilder builder) 55 { 56 AssemblyName assemblyName = AssemblyName; 57 if (null == assemblyName) return; 58 59 builder.Append(", "); 60 builder.Append(assemblyName.Name); 61 } 62 } 63 64 public partial class SimpleTypeReference : TypeReference 65 { 66 protected string _simpleName; 67 68 protected AssemblyName _assemblyName; 69 SimpleTypeReference(string simpleName)70 internal SimpleTypeReference(string simpleName) 71 { 72 _simpleName = simpleName; 73 } 74 75 public override string SimpleName 76 { 77 get { return _simpleName; } 78 } 79 80 public override AssemblyName AssemblyName 81 { 82 get { return _assemblyName; } 83 } 84 Resolve()85 public override Type Resolve() 86 { 87 return _assemblyName == null 88 ? Type.GetType(SimpleName) 89 : ResolveAssembly().GetType(SimpleName); 90 } 91 AppendTypeName(StringBuilder builder)92 public override void AppendTypeName(StringBuilder builder) 93 { 94 builder.Append(SimpleName); 95 } 96 Equals(object obj)97 public override bool Equals(object obj) 98 { 99 SimpleTypeReference other = obj as SimpleTypeReference; 100 if (null == other) return false; 101 return _simpleName == other._simpleName; 102 } 103 SetSimpleName(string simpleName)104 internal void SetSimpleName(string simpleName) 105 { 106 _simpleName = simpleName; 107 } 108 SetAssemblyName(AssemblyName assemblyName)109 internal void SetAssemblyName(AssemblyName assemblyName) 110 { 111 _assemblyName = assemblyName; 112 } 113 ResolveAssembly()114 private Assembly ResolveAssembly() 115 { 116 #if SILVERLIGHT 117 return ResolveAssemblySilverlight(); 118 #else 119 if (null == _assemblyName.Version) 120 { 121 return LoadUnversionedAssembly(_assemblyName); 122 } 123 124 Assembly found; 125 try 126 { 127 found = Assembly.Load(_assemblyName); 128 } 129 catch (Exception) 130 { 131 AssemblyName unversioned = (AssemblyName)_assemblyName.Clone(); 132 unversioned.Version = null; 133 found = LoadUnversionedAssembly(unversioned); 134 } 135 return found; 136 #endif 137 } 138 LoadUnversionedAssembly(AssemblyName unversioned)139 private Assembly LoadUnversionedAssembly(AssemblyName unversioned) 140 { 141 #if CF || SILVERLIGHT 142 return Assembly.Load(unversioned); 143 #else 144 Assembly found = Assembly.LoadWithPartialName(unversioned.FullName); 145 return found == null 146 ? Assembly.Load(unversioned) 147 : found; 148 #endif 149 } 150 } 151 152 public abstract class QualifiedTypeReference : TypeReference 153 { 154 protected TypeReference _elementType; 155 QualifiedTypeReference(TypeReference elementType)156 protected QualifiedTypeReference(TypeReference elementType) 157 { 158 _elementType = elementType; 159 } 160 161 public override string SimpleName 162 { 163 get 164 { 165 return _elementType.SimpleName; 166 } 167 } 168 169 public override AssemblyName AssemblyName 170 { 171 get { return _elementType.AssemblyName; } 172 } 173 AppendTypeName(StringBuilder builder)174 public override void AppendTypeName(StringBuilder builder) 175 { 176 _elementType.AppendTypeName(builder); 177 AppendQualifier(builder); 178 } 179 AppendQualifier(StringBuilder builder)180 protected abstract void AppendQualifier(StringBuilder builder); 181 } 182 183 public class PointerTypeReference : QualifiedTypeReference 184 { PointerTypeReference(TypeReference elementType)185 public PointerTypeReference(TypeReference elementType) 186 : base(elementType) 187 { 188 } 189 AppendQualifier(StringBuilder builder)190 protected override void AppendQualifier(StringBuilder builder) 191 { 192 builder.Append('*'); 193 } 194 Resolve()195 public override Type Resolve() 196 { 197 #if !CF 198 return _elementType.Resolve().MakePointerType(); 199 #else 200 StringBuilder builder = new StringBuilder(); 201 AppendTypeName(builder); 202 return _elementType.Resolve().Assembly.GetType(builder.ToString(), true); 203 #endif 204 } 205 } 206 207 public class ArrayTypeReference : QualifiedTypeReference 208 { MakeArrayType(Type elementType, int rank)209 public static Type MakeArrayType(Type elementType, int rank) 210 { 211 #if !CF 212 if (rank == 1) return elementType.MakeArrayType(); 213 return elementType.MakeArrayType(rank); 214 #else 215 if (rank == 1) return Array.CreateInstance(elementType, 0).GetType(); 216 return Array.CreateInstance(elementType, new int[rank]).GetType(); 217 #endif 218 } 219 220 221 private readonly int _rank; 222 ArrayTypeReference(TypeReference elementType, int rank)223 internal ArrayTypeReference(TypeReference elementType, int rank) : base(elementType) 224 { 225 _rank = rank; 226 } 227 228 public int Rank 229 { 230 get { return _rank; } 231 } 232 Resolve()233 public override Type Resolve() 234 { 235 return MakeArrayType(_elementType.Resolve(), _rank); 236 } 237 AppendQualifier(StringBuilder builder)238 protected override void AppendQualifier(StringBuilder builder) 239 { 240 builder.Append('['); 241 for (int i = 1; i < _rank; ++i) 242 { 243 builder.Append(','); 244 } 245 builder.Append(']'); 246 } 247 } 248 249 public class GenericTypeReference : SimpleTypeReference 250 { 251 private readonly TypeReference[] _genericArguments; 252 GenericTypeReference(string simpleName, TypeReference[] genericArguments)253 internal GenericTypeReference(string simpleName, TypeReference[] genericArguments) 254 : base(simpleName) 255 { 256 _genericArguments = genericArguments; 257 } 258 259 public TypeReference[] GenericArguments 260 { 261 get { return _genericArguments; } 262 } 263 Resolve()264 public override Type Resolve() 265 { 266 Type baseType = base.Resolve(); 267 return _genericArguments.Length > 0 268 ? baseType.MakeGenericType(Resolve(_genericArguments)) 269 : baseType; 270 } 271 Resolve(TypeReference[] typeRefs)272 static Type[] Resolve(TypeReference[] typeRefs) 273 { 274 Type[] types = new Type[typeRefs.Length]; 275 for (int i = 0; i < types.Length; ++i) 276 { 277 types[i] = typeRefs[i].Resolve(); 278 } 279 return types; 280 } 281 AppendTypeName(StringBuilder builder)282 public override void AppendTypeName(StringBuilder builder) 283 { 284 builder.Append(_simpleName); 285 AppendUnversionedGenericArguments(builder); 286 } 287 AppendUnversionedGenericArguments(StringBuilder builder)288 private void AppendUnversionedGenericArguments(StringBuilder builder) 289 { 290 if (_genericArguments.Length == 0) return; 291 292 builder.Append("["); 293 for (int i = 0; i < _genericArguments.Length; ++i) 294 { 295 if (i > 0) builder.Append(", "); 296 builder.Append("["); 297 _genericArguments[i].AppendUnversionedName(builder); 298 builder.Append("]"); 299 } 300 builder.Append("]"); 301 } 302 } 303 } 304