Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 23 additions & 4 deletions src/System.Management.Automation/engine/parser/PSType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ private class DefineTypeHelper
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;

Expand Down Expand Up @@ -436,15 +437,33 @@ private Type GetBaseTypes(Parser parser, TypeDefinitionAst typeDefinitionAst, ou

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())
{
foreach (var parentInterface in interfaceType.GetInterfaces())
{
allInterfaces.Add(parentInterface);
}

allInterfaces.Add(interfaceType);
}

foreach (var interfaceType in allInterfaces)
{
return true;
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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}
Expand Down