mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Flatten interface hierarchy when generating properties that implement interface properties (#8382)
`TypeBuilder.GetInterfaces()` returns only the interfaces that was explicitly passed to its constructor, so we need to flatten the interface hierarchy in order to properly support inherited interfaces.
This commit is contained in:
committed by
Dongbo Wang
parent
c14d5dd67f
commit
0a570211df
@@ -272,6 +272,7 @@ namespace System.Management.Automation.Language
|
||||
internal readonly TypeBuilder _staticHelpersTypeBuilder;
|
||||
private readonly Dictionary<string, PropertyMemberAst> _definedProperties;
|
||||
private readonly Dictionary<string, List<Tuple<FunctionMemberAst, Type[]>>> _definedMethods;
|
||||
private HashSet<Tuple<string, Type>> _interfaceProperties;
|
||||
internal readonly List<(string fieldName, IParameterMetadataProvider bodyAst, bool isStatic)> _fieldsToInitForMemberFunctions;
|
||||
private bool _baseClassHasDefaultCtor;
|
||||
|
||||
@@ -442,15 +443,33 @@ namespace System.Management.Automation.Language
|
||||
|
||||
private bool ShouldImplementProperty(string name, Type type)
|
||||
{
|
||||
foreach (var interfaceType in _typeBuilder.GetInterfaces())
|
||||
if (_interfaceProperties == null)
|
||||
{
|
||||
if (interfaceType.GetProperty(name, type) != null)
|
||||
_interfaceProperties = new HashSet<Tuple<string, Type>>();
|
||||
var allInterfaces = new HashSet<Type>();
|
||||
|
||||
// TypeBuilder.GetInterfaces() returns only the interfaces that was explicitly passed to its constructor.
|
||||
// During compilation the interface hierarchy is flattened, so we only need to resolve one level of ancestral interfaces.
|
||||
foreach (var interfaceType in _typeBuilder.GetInterfaces())
|
||||
{
|
||||
return true;
|
||||
foreach (var parentInterface in interfaceType.GetInterfaces())
|
||||
{
|
||||
allInterfaces.Add(parentInterface);
|
||||
}
|
||||
|
||||
allInterfaces.Add(interfaceType);
|
||||
}
|
||||
|
||||
foreach (var interfaceType in allInterfaces)
|
||||
{
|
||||
foreach (var property in interfaceType.GetProperties())
|
||||
{
|
||||
_interfaceProperties.Add(Tuple.Create(property.Name, property.PropertyType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return _interfaceProperties.Contains(Tuple.Create(name, type));
|
||||
}
|
||||
|
||||
public void DefineMembers()
|
||||
|
||||
@@ -71,6 +71,15 @@ Describe 'Classes inheritance syntax' -Tags "CI" {
|
||||
$getter.Attributes -band [System.Reflection.MethodAttributes]::Virtual |Should -Be ([System.Reflection.MethodAttributes]::Virtual)
|
||||
}
|
||||
|
||||
It 'can implement inherited .NET interface properties' {
|
||||
Add-Type -TypeDefinition 'public interface IParent { int ParentInteger { get; set; } }
|
||||
public interface IChild : IParent { int ChildInteger { get; set; } }'
|
||||
$C1 = Invoke-Expression 'class ClassWithInheritedInterfaces : IChild { [int]$ParentInteger; [int]$ChildInteger } [ClassWithInheritedInterfaces]'
|
||||
$getter = $C1.GetMember('get_ParentInteger')
|
||||
$getter.ReturnType.FullName | Should -Be System.Int32
|
||||
$getter.Attributes -band [System.Reflection.MethodAttributes]::Virtual |Should -Be ([System.Reflection.MethodAttributes]::Virtual)
|
||||
}
|
||||
|
||||
It 'allows use of defined later type as a property type' {
|
||||
class A { static [B]$b }
|
||||
class B : A {}
|
||||
|
||||
Reference in New Issue
Block a user