1 /* 2 Copyright (C) 2009, 2010 Jeroen Frijters 3 4 This software is provided 'as-is', without any express or implied 5 warranty. In no event will the authors be held liable for any damages 6 arising from the use of this software. 7 8 Permission is granted to anyone to use this software for any purpose, 9 including commercial applications, and to alter it and redistribute it 10 freely, subject to the following restrictions: 11 12 1. The origin of this software must not be misrepresented; you must not 13 claim that you wrote the original software. If you use this software 14 in a product, an acknowledgment in the product documentation would be 15 appreciated but is not required. 16 2. Altered source versions must be plainly marked as such, and must not be 17 misrepresented as being the original software. 18 3. This notice may not be removed or altered from any source distribution. 19 20 Jeroen Frijters 21 jeroen@frijters.net 22 23 */ 24 using System; 25 using System.Collections.Generic; 26 using System.Text; 27 28 namespace IKVM.Reflection 29 { 30 // this represents both generic method instantiations and non-generic methods on generic type instantations 31 // (this means that it can be a generic method declaration as well as a generic method instance) 32 sealed class GenericMethodInstance : MethodInfo 33 { 34 private readonly Type declaringType; 35 private readonly MethodInfo method; 36 private readonly Type[] methodArgs; 37 private MethodSignature lazyMethodSignature; 38 GenericMethodInstance(Type declaringType, MethodInfo method, Type[] methodArgs)39 internal GenericMethodInstance(Type declaringType, MethodInfo method, Type[] methodArgs) 40 { 41 System.Diagnostics.Debug.Assert(!(method is GenericMethodInstance)); 42 this.declaringType = declaringType; 43 this.method = method; 44 this.methodArgs = methodArgs; 45 } 46 Equals(object obj)47 public override bool Equals(object obj) 48 { 49 GenericMethodInstance other = obj as GenericMethodInstance; 50 return other != null 51 && other.method.Equals(method) 52 && other.declaringType.Equals(declaringType) 53 && Util.ArrayEquals(other.methodArgs, methodArgs); 54 } 55 GetHashCode()56 public override int GetHashCode() 57 { 58 return declaringType.GetHashCode() * 33 ^ method.GetHashCode() ^ Util.GetHashCode(methodArgs); 59 } 60 61 public override Type ReturnType 62 { 63 get { return method.ReturnType.BindTypeParameters(this); } 64 } 65 66 public override ParameterInfo ReturnParameter 67 { 68 get { return new GenericParameterInfoImpl(this, method.ReturnParameter); } 69 } 70 GetParameters()71 public override ParameterInfo[] GetParameters() 72 { 73 ParameterInfo[] parameters = method.GetParameters(); 74 for (int i = 0; i < parameters.Length; i++) 75 { 76 parameters[i] = new GenericParameterInfoImpl(this, parameters[i]); 77 } 78 return parameters; 79 } 80 81 internal override int ParameterCount 82 { 83 get { return method.ParameterCount; } 84 } 85 86 public override CallingConventions CallingConvention 87 { 88 get { return method.CallingConvention; } 89 } 90 91 public override MethodAttributes Attributes 92 { 93 get { return method.Attributes; } 94 } 95 GetMethodImplementationFlags()96 public override MethodImplAttributes GetMethodImplementationFlags() 97 { 98 return method.GetMethodImplementationFlags(); 99 } 100 101 public override string Name 102 { 103 get { return method.Name; } 104 } 105 106 public override Type DeclaringType 107 { 108 get { return declaringType.IsModulePseudoType ? null : declaringType; } 109 } 110 111 public override Module Module 112 { 113 get { return method.Module; } 114 } 115 116 public override int MetadataToken 117 { 118 get { return method.MetadataToken; } 119 } 120 GetMethodBody()121 public override MethodBody GetMethodBody() 122 { 123 IKVM.Reflection.Reader.MethodDefImpl md = method as IKVM.Reflection.Reader.MethodDefImpl; 124 if (md != null) 125 { 126 return md.GetMethodBody(this); 127 } 128 throw new NotSupportedException(); 129 } 130 131 public override int __MethodRVA 132 { 133 get { return method.__MethodRVA; } 134 } 135 MakeGenericMethod(params Type[] typeArguments)136 public override MethodInfo MakeGenericMethod(params Type[] typeArguments) 137 { 138 return new GenericMethodInstance(declaringType, method, typeArguments); 139 } 140 141 public override bool IsGenericMethod 142 { 143 get { return method.IsGenericMethod; } 144 } 145 146 public override bool IsGenericMethodDefinition 147 { 148 get { return method.IsGenericMethodDefinition && methodArgs == null; } 149 } 150 151 public override bool ContainsGenericParameters 152 { 153 get 154 { 155 if (declaringType.ContainsGenericParameters) 156 { 157 return true; 158 } 159 if (methodArgs != null) 160 { 161 foreach (Type type in methodArgs) 162 { 163 if (type.ContainsGenericParameters) 164 { 165 return true; 166 } 167 } 168 } 169 return false; 170 } 171 } 172 GetGenericMethodDefinition()173 public override MethodInfo GetGenericMethodDefinition() 174 { 175 if (this.IsGenericMethod) 176 { 177 if (this.IsGenericMethodDefinition) 178 { 179 return this; 180 } 181 else if (declaringType.IsConstructedGenericType) 182 { 183 return new GenericMethodInstance(declaringType, method, null); 184 } 185 else 186 { 187 return method; 188 } 189 } 190 throw new InvalidOperationException(); 191 } 192 __GetMethodOnTypeDefinition()193 public override MethodBase __GetMethodOnTypeDefinition() 194 { 195 return method; 196 } 197 GetGenericArguments()198 public override Type[] GetGenericArguments() 199 { 200 if (methodArgs == null) 201 { 202 return method.GetGenericArguments(); 203 } 204 else 205 { 206 return (Type[])methodArgs.Clone(); 207 } 208 } 209 GetGenericMethodArgument(int index)210 internal override Type GetGenericMethodArgument(int index) 211 { 212 if (methodArgs == null) 213 { 214 return method.GetGenericMethodArgument(index); 215 } 216 else 217 { 218 return methodArgs[index]; 219 } 220 } 221 GetGenericMethodArgumentCount()222 internal override int GetGenericMethodArgumentCount() 223 { 224 return method.GetGenericMethodArgumentCount(); 225 } 226 GetMethodOnTypeDefinition()227 internal override MethodInfo GetMethodOnTypeDefinition() 228 { 229 return method.GetMethodOnTypeDefinition(); 230 } 231 ImportTo(Emit.ModuleBuilder module)232 internal override int ImportTo(Emit.ModuleBuilder module) 233 { 234 if (methodArgs == null) 235 { 236 return module.ImportMethodOrField(declaringType, method.Name, method.MethodSignature); 237 } 238 else 239 { 240 return module.ImportMethodSpec(declaringType, method, methodArgs); 241 } 242 } 243 244 internal override MethodSignature MethodSignature 245 { 246 get { return lazyMethodSignature ?? (lazyMethodSignature = method.MethodSignature.Bind(declaringType, methodArgs)); } 247 } 248 BindTypeParameters(Type type)249 internal override MethodBase BindTypeParameters(Type type) 250 { 251 System.Diagnostics.Debug.Assert(methodArgs == null); 252 return new GenericMethodInstance(declaringType.BindTypeParameters(type), method, null); 253 } 254 255 internal override bool HasThis 256 { 257 get { return method.HasThis; } 258 } 259 __GetMethodImpls()260 public override MethodInfo[] __GetMethodImpls() 261 { 262 MethodInfo[] methods = method.__GetMethodImpls(); 263 for (int i = 0; i < methods.Length; i++) 264 { 265 methods[i] = (MethodInfo)methods[i].BindTypeParameters(declaringType); 266 } 267 return methods; 268 } 269 GetCurrentToken()270 internal override int GetCurrentToken() 271 { 272 return method.GetCurrentToken(); 273 } 274 275 internal override bool IsBaked 276 { 277 get { return method.IsBaked; } 278 } 279 } 280 281 sealed class GenericFieldInstance : FieldInfo 282 { 283 private readonly Type declaringType; 284 private readonly FieldInfo field; 285 GenericFieldInstance(Type declaringType, FieldInfo field)286 internal GenericFieldInstance(Type declaringType, FieldInfo field) 287 { 288 this.declaringType = declaringType; 289 this.field = field; 290 } 291 Equals(object obj)292 public override bool Equals(object obj) 293 { 294 GenericFieldInstance other = obj as GenericFieldInstance; 295 return other != null && other.declaringType.Equals(declaringType) && other.field.Equals(field); 296 } 297 GetHashCode()298 public override int GetHashCode() 299 { 300 return declaringType.GetHashCode() * 3 ^ field.GetHashCode(); 301 } 302 303 public override FieldAttributes Attributes 304 { 305 get { return field.Attributes; } 306 } 307 308 public override string Name 309 { 310 get { return field.Name; } 311 } 312 313 public override Type DeclaringType 314 { 315 get { return declaringType; } 316 } 317 318 public override Module Module 319 { 320 get { return declaringType.Module; } 321 } 322 323 public override int MetadataToken 324 { 325 get { return field.MetadataToken; } 326 } 327 GetRawConstantValue()328 public override object GetRawConstantValue() 329 { 330 return field.GetRawConstantValue(); 331 } 332 __GetDataFromRVA(byte[] data, int offset, int length)333 public override void __GetDataFromRVA(byte[] data, int offset, int length) 334 { 335 field.__GetDataFromRVA(data, offset, length); 336 } 337 338 public override int __FieldRVA 339 { 340 get { return field.__FieldRVA; } 341 } 342 __TryGetFieldOffset(out int offset)343 public override bool __TryGetFieldOffset(out int offset) 344 { 345 return field.__TryGetFieldOffset(out offset); 346 } 347 __GetFieldOnTypeDefinition()348 public override FieldInfo __GetFieldOnTypeDefinition() 349 { 350 return field; 351 } 352 353 internal override FieldSignature FieldSignature 354 { 355 get { return field.FieldSignature.ExpandTypeParameters(declaringType); } 356 } 357 ImportTo(Emit.ModuleBuilder module)358 internal override int ImportTo(Emit.ModuleBuilder module) 359 { 360 return module.ImportMethodOrField(declaringType, field.Name, field.FieldSignature); 361 } 362 BindTypeParameters(Type type)363 internal override FieldInfo BindTypeParameters(Type type) 364 { 365 return new GenericFieldInstance(declaringType.BindTypeParameters(type), field); 366 } 367 GetCurrentToken()368 internal override int GetCurrentToken() 369 { 370 return field.GetCurrentToken(); 371 } 372 373 internal override bool IsBaked 374 { 375 get { return field.IsBaked; } 376 } 377 } 378 379 sealed class GenericParameterInfoImpl : ParameterInfo 380 { 381 private readonly GenericMethodInstance method; 382 private readonly ParameterInfo parameterInfo; 383 GenericParameterInfoImpl(GenericMethodInstance method, ParameterInfo parameterInfo)384 internal GenericParameterInfoImpl(GenericMethodInstance method, ParameterInfo parameterInfo) 385 { 386 this.method = method; 387 this.parameterInfo = parameterInfo; 388 } 389 390 public override string Name 391 { 392 get { return parameterInfo.Name; } 393 } 394 395 public override Type ParameterType 396 { 397 get { return parameterInfo.ParameterType.BindTypeParameters(method); } 398 } 399 400 public override ParameterAttributes Attributes 401 { 402 get { return parameterInfo.Attributes; } 403 } 404 405 public override int Position 406 { 407 get { return parameterInfo.Position; } 408 } 409 410 public override object RawDefaultValue 411 { 412 get { return parameterInfo.RawDefaultValue; } 413 } 414 __GetCustomModifiers()415 public override CustomModifiers __GetCustomModifiers() 416 { 417 return parameterInfo.__GetCustomModifiers().Bind(method); 418 } 419 __TryGetFieldMarshal(out FieldMarshal fieldMarshal)420 public override bool __TryGetFieldMarshal(out FieldMarshal fieldMarshal) 421 { 422 return parameterInfo.__TryGetFieldMarshal(out fieldMarshal); 423 } 424 425 public override MemberInfo Member 426 { 427 get { return method; } 428 } 429 430 public override int MetadataToken 431 { 432 get { return parameterInfo.MetadataToken; } 433 } 434 435 internal override Module Module 436 { 437 get { return method.Module; } 438 } 439 } 440 441 sealed class GenericPropertyInfo : PropertyInfo 442 { 443 private readonly Type typeInstance; 444 private readonly PropertyInfo property; 445 GenericPropertyInfo(Type typeInstance, PropertyInfo property)446 internal GenericPropertyInfo(Type typeInstance, PropertyInfo property) 447 { 448 this.typeInstance = typeInstance; 449 this.property = property; 450 } 451 Equals(object obj)452 public override bool Equals(object obj) 453 { 454 GenericPropertyInfo other = obj as GenericPropertyInfo; 455 return other != null && other.typeInstance == typeInstance && other.property == property; 456 } 457 GetHashCode()458 public override int GetHashCode() 459 { 460 return typeInstance.GetHashCode() * 537 + property.GetHashCode(); 461 } 462 463 public override PropertyAttributes Attributes 464 { 465 get { return property.Attributes; } 466 } 467 468 public override bool CanRead 469 { 470 get { return property.CanRead; } 471 } 472 473 public override bool CanWrite 474 { 475 get { return property.CanWrite; } 476 } 477 Wrap(MethodInfo method)478 private MethodInfo Wrap(MethodInfo method) 479 { 480 if (method == null) 481 { 482 return null; 483 } 484 return new GenericMethodInstance(typeInstance, method, null); 485 } 486 GetGetMethod(bool nonPublic)487 public override MethodInfo GetGetMethod(bool nonPublic) 488 { 489 return Wrap(property.GetGetMethod(nonPublic)); 490 } 491 GetSetMethod(bool nonPublic)492 public override MethodInfo GetSetMethod(bool nonPublic) 493 { 494 return Wrap(property.GetSetMethod(nonPublic)); 495 } 496 GetAccessors(bool nonPublic)497 public override MethodInfo[] GetAccessors(bool nonPublic) 498 { 499 MethodInfo[] accessors = property.GetAccessors(nonPublic); 500 for (int i = 0; i < accessors.Length; i++) 501 { 502 accessors[i] = Wrap(accessors[i]); 503 } 504 return accessors; 505 } 506 GetRawConstantValue()507 public override object GetRawConstantValue() 508 { 509 return property.GetRawConstantValue(); 510 } 511 512 internal override bool IsPublic 513 { 514 get { return property.IsPublic; } 515 } 516 517 internal override bool IsNonPrivate 518 { 519 get { return property.IsNonPrivate; } 520 } 521 522 internal override bool IsStatic 523 { 524 get { return property.IsStatic; } 525 } 526 527 internal override PropertySignature PropertySignature 528 { 529 get { return property.PropertySignature.ExpandTypeParameters(typeInstance); } 530 } 531 532 public override string Name 533 { 534 get { return property.Name; } 535 } 536 537 public override Type DeclaringType 538 { 539 get { return typeInstance; } 540 } 541 542 public override Module Module 543 { 544 get { return typeInstance.Module; } 545 } 546 547 public override int MetadataToken 548 { 549 get { return property.MetadataToken; } 550 } 551 BindTypeParameters(Type type)552 internal override PropertyInfo BindTypeParameters(Type type) 553 { 554 return new GenericPropertyInfo(typeInstance.BindTypeParameters(type), property); 555 } 556 557 internal override bool IsBaked 558 { 559 get { return property.IsBaked; } 560 } 561 GetCurrentToken()562 internal override int GetCurrentToken() 563 { 564 return property.GetCurrentToken(); 565 } 566 } 567 568 sealed class GenericEventInfo : EventInfo 569 { 570 private readonly Type typeInstance; 571 private readonly EventInfo eventInfo; 572 GenericEventInfo(Type typeInstance, EventInfo eventInfo)573 internal GenericEventInfo(Type typeInstance, EventInfo eventInfo) 574 { 575 this.typeInstance = typeInstance; 576 this.eventInfo = eventInfo; 577 } 578 Equals(object obj)579 public override bool Equals(object obj) 580 { 581 GenericEventInfo other = obj as GenericEventInfo; 582 return other != null && other.typeInstance == typeInstance && other.eventInfo == eventInfo; 583 } 584 GetHashCode()585 public override int GetHashCode() 586 { 587 return typeInstance.GetHashCode() * 777 + eventInfo.GetHashCode(); 588 } 589 590 public override EventAttributes Attributes 591 { 592 get { return eventInfo.Attributes; } 593 } 594 Wrap(MethodInfo method)595 private MethodInfo Wrap(MethodInfo method) 596 { 597 if (method == null) 598 { 599 return null; 600 } 601 return new GenericMethodInstance(typeInstance, method, null); 602 } 603 GetAddMethod(bool nonPublic)604 public override MethodInfo GetAddMethod(bool nonPublic) 605 { 606 return Wrap(eventInfo.GetAddMethod(nonPublic)); 607 } 608 GetRaiseMethod(bool nonPublic)609 public override MethodInfo GetRaiseMethod(bool nonPublic) 610 { 611 return Wrap(eventInfo.GetRaiseMethod(nonPublic)); 612 } 613 GetRemoveMethod(bool nonPublic)614 public override MethodInfo GetRemoveMethod(bool nonPublic) 615 { 616 return Wrap(eventInfo.GetRemoveMethod(nonPublic)); 617 } 618 GetOtherMethods(bool nonPublic)619 public override MethodInfo[] GetOtherMethods(bool nonPublic) 620 { 621 MethodInfo[] others = eventInfo.GetOtherMethods(nonPublic); 622 for (int i = 0; i < others.Length; i++) 623 { 624 others[i] = Wrap(others[i]); 625 } 626 return others; 627 } 628 __GetMethods()629 public override MethodInfo[] __GetMethods() 630 { 631 MethodInfo[] others = eventInfo.__GetMethods(); 632 for (int i = 0; i < others.Length; i++) 633 { 634 others[i] = Wrap(others[i]); 635 } 636 return others; 637 } 638 639 public override Type EventHandlerType 640 { 641 get { return eventInfo.EventHandlerType.BindTypeParameters(typeInstance); } 642 } 643 644 public override string Name 645 { 646 get { return eventInfo.Name; } 647 } 648 649 public override Type DeclaringType 650 { 651 get { return typeInstance; } 652 } 653 654 public override Module Module 655 { 656 get { return eventInfo.Module; } 657 } 658 659 public override int MetadataToken 660 { 661 get { return eventInfo.MetadataToken; } 662 } 663 BindTypeParameters(Type type)664 internal override EventInfo BindTypeParameters(Type type) 665 { 666 return new GenericEventInfo(typeInstance.BindTypeParameters(type), eventInfo); 667 } 668 669 internal override bool IsPublic 670 { 671 get { return eventInfo.IsPublic; } 672 } 673 674 internal override bool IsNonPrivate 675 { 676 get { return eventInfo.IsNonPrivate; } 677 } 678 679 internal override bool IsStatic 680 { 681 get { return eventInfo.IsStatic; } 682 } 683 684 internal override bool IsBaked 685 { 686 get { return eventInfo.IsBaked; } 687 } 688 GetCurrentToken()689 internal override int GetCurrentToken() 690 { 691 return eventInfo.GetCurrentToken(); 692 } 693 } 694 } 695