33
44using System . Collections . Generic ;
55using System . Collections . ObjectModel ;
6+ using System . Diagnostics . CodeAnalysis ;
67using System . Globalization ;
78using System . Linq ;
89using System . Management . Automation . Internal ;
@@ -276,7 +277,7 @@ private sealed class DefineTypeHelper
276277 internal readonly TypeBuilder _staticHelpersTypeBuilder ;
277278 private readonly Dictionary < string , PropertyMemberAst > _definedProperties ;
278279 private readonly Dictionary < string , List < Tuple < FunctionMemberAst , Type [ ] > > > _definedMethods ;
279- private HashSet < Tuple < string , Type > > _abstractProperties ;
280+ private Dictionary < Tuple < string , Type > , PropertyInfo > _abstractProperties ;
280281 internal readonly List < ( string fieldName , IParameterMetadataProvider bodyAst , bool isStatic ) > _fieldsToInitForMemberFunctions ;
281282 private bool _baseClassHasDefaultCtor ;
282283
@@ -444,11 +445,11 @@ private Type GetBaseTypes(Parser parser, TypeDefinitionAst typeDefinitionAst, ou
444445 return baseClass ?? typeof ( object ) ;
445446 }
446447
447- private bool ShouldImplementProperty ( string name , Type type )
448+ private bool ShouldImplementProperty ( string name , Type type , [ NotNullWhen ( true ) ] out PropertyInfo interfaceProperty )
448449 {
449450 if ( _abstractProperties == null )
450451 {
451- _abstractProperties = new HashSet < Tuple < string , Type > > ( ) ;
452+ _abstractProperties = new Dictionary < Tuple < string , Type > , PropertyInfo > ( ) ;
452453 var allInterfaces = new HashSet < Type > ( ) ;
453454
454455 // TypeBuilder.GetInterfaces() returns only the interfaces that was explicitly passed to its constructor.
@@ -467,7 +468,7 @@ private bool ShouldImplementProperty(string name, Type type)
467468 {
468469 foreach ( var property in interfaceType . GetProperties ( ) )
469470 {
470- _abstractProperties . Add ( Tuple . Create ( property . Name , property . PropertyType ) ) ;
471+ _abstractProperties . Add ( Tuple . Create ( property . Name , property . PropertyType ) , property ) ;
471472 }
472473 }
473474
@@ -477,13 +478,13 @@ private bool ShouldImplementProperty(string name, Type type)
477478 {
478479 if ( property . GetAccessors ( ) . Any ( m => m . IsAbstract ) )
479480 {
480- _abstractProperties . Add ( Tuple . Create ( property . Name , property . PropertyType ) ) ;
481+ _abstractProperties . Add ( Tuple . Create ( property . Name , property . PropertyType ) , property ) ;
481482 }
482483 }
483484 }
484485 }
485486
486- return _abstractProperties . Contains ( Tuple . Create ( name , type ) ) ;
487+ return _abstractProperties . TryGetValue ( Tuple . Create ( name , type ) , out interfaceProperty ) ;
487488 }
488489
489490 public void DefineMembers ( )
@@ -629,9 +630,19 @@ private PropertyBuilder EmitPropertyIl(PropertyMemberAst propertyMemberAst, Type
629630 // The property set and property get methods require a special set of attributes.
630631 var getSetAttributes = Reflection . MethodAttributes . SpecialName | Reflection . MethodAttributes . HideBySig ;
631632 getSetAttributes |= propertyMemberAst . IsPublic ? Reflection . MethodAttributes . Public : Reflection . MethodAttributes . Private ;
632- if ( ShouldImplementProperty ( propertyMemberAst . Name , type ) )
633+ MethodInfo implementingGetter = null ;
634+ MethodInfo implementingSetter = null ;
635+ if ( ShouldImplementProperty ( propertyMemberAst . Name , type , out PropertyInfo interfaceProperty ) )
633636 {
634- getSetAttributes |= Reflection . MethodAttributes . Virtual ;
637+ if ( propertyMemberAst . IsStatic )
638+ {
639+ implementingGetter = interfaceProperty . GetGetMethod ( ) ;
640+ implementingSetter = interfaceProperty . GetSetMethod ( ) ;
641+ }
642+ else
643+ {
644+ getSetAttributes |= Reflection . MethodAttributes . Virtual ;
645+ }
635646 }
636647
637648 if ( propertyMemberAst . IsStatic )
@@ -677,6 +688,11 @@ private PropertyBuilder EmitPropertyIl(PropertyMemberAst propertyMemberAst, Type
677688 getIlGen . Emit ( OpCodes . Ret ) ;
678689 }
679690
691+ if ( implementingGetter != null )
692+ {
693+ _typeBuilder . DefineMethodOverride ( getMethod , implementingGetter ) ;
694+ }
695+
680696 // Define the "set" accessor method.
681697 MethodBuilder setMethod = _typeBuilder . DefineMethod ( string . Concat ( "set_" , propertyMemberAst . Name ) , getSetAttributes , null , new Type [ ] { type } ) ;
682698 ILGenerator setIlGen = setMethod . GetILGenerator ( ) ;
@@ -710,6 +726,11 @@ private PropertyBuilder EmitPropertyIl(PropertyMemberAst propertyMemberAst, Type
710726
711727 setIlGen . Emit ( OpCodes . Ret ) ;
712728
729+ if ( implementingSetter != null )
730+ {
731+ _typeBuilder . DefineMethodOverride ( setMethod , implementingSetter ) ;
732+ }
733+
713734 // Map the two methods created above to our PropertyBuilder to
714735 // their corresponding behaviors, "get" and "set" respectively.
715736 property . SetGetMethod ( getMethod ) ;
0 commit comments