New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix PowerShell class to support deriving from an abstract class with abstract properties #21331
Conversation
…abstract properties
|
This PR has Quantification details
Why proper sizing of changes matters
Optimal pull request sizes drive a better predictable PR flow as they strike a
What can I do to optimize my changes
How to interpret the change counts in git diff output
Was this comment helpful? 👍 :ok_hand: :thumbsdown: (Email) |
|
@jborean93 Will do a review later today or tomorrow. Thanks for the reminder! |
| @@ -628,3 +628,33 @@ class Derived : Base | |||
| $sb.Invoke() | Should -Be 200 | |||
| } | |||
| } | |||
|
|
|||
| Describe 'Base type has abstract properties' -Tags "CI" { | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we have validation which ensures that an error is produced if the abstract property is not defined? is it needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. I will add one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A test for the error case was added.
|
|
||
| if (_typeBuilder.BaseType.IsAbstract) | ||
| { | ||
| foreach (var property in _typeBuilder.BaseType.GetProperties()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this will need to include BindingFlags.NonPublic as protected members should still be found right? Likewise GetAccessors below likely needs nonPublic: true.
Then a check like
accessor.IsFamilyOrAssembly || accessor.IsFamily || assessor.IsPublicInterfaces may also actually need that check too since C# 8 added the ability to mark members as protected. Though that wouldn't be fixing a regression so likely fine to leave out of this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But we don't create properties or methods with the "protected" (family) modifier, and we don't have a keyword in PowerShell language to declare a property as protected, we only create public (by default or with the hidden keyword) or static (static keyword) members. So, even if we check for protected abstract properties here, the public property we are going to create later won't be considered as an implementation of the protected property.
When a base type (MyBase) has a protected abstract property Name, the class definition class MySub : MyBase { [string]$Name } will fail on 7.2 and 7.3 as well today (see the screenshots below). So, I think we just don't support deriving from a class that has protected abstract properties/methods.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah alright if it failed before then good enough for me!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
|
This PR has Quantification details
Why proper sizing of changes matters
Optimal pull request sizes drive a better predictable PR flow as they strike a
What can I do to optimize my changes
How to interpret the change counts in git diff output
Was this comment helpful? 👍 :ok_hand: :thumbsdown: (Email) |
|
📣 Hey @daxian-dbw, how did we do? We would love to hear your feedback with the link below! 🗣️ 🔗 https://aka.ms/PSRepoFeedback |
…abstract properties (PowerShell#21331)




PR Summary
Fix PowerShell class to support deriving from an abstract class with abstract properties.
The fix is to detect that we are deriving from an abstract base type, and the property is an implementation of an abstract property from that base type.
PR Context
The following PowerShell class stops working in PowerShell v7.4.1, because .NET 8 enforces stricter validation on the dynamically emitted IL code. Previously, for a property that is supposed to be the implementation of an abstract property in base type, we don't set the
Reflection.MethodAttributes.Virtualattribute when creating the property. That actually makes the created property have nothing to do with the abstract property in base type. Prior to .NET 8, the IL emitting library doesn't detect this error even though the abstract property is not implemented. However, starting from .NET 8, it detects the issue and throw exception in this case.Running the following PowerShell class will result in an error in v7.4.1
PR Checklist
.h,.cpp,.cs,.ps1and.psm1files have the correct copyright headerWIP:or[ WIP ]to the beginning of the title (theWIPbot will keep its status check atPendingwhile the prefix is present) and remove the prefix when the PR is ready.