-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Readonly members syntax and symbol API #32888
Readonly members syntax and symbol API #32888
Conversation
While somewhat nonsensical from an API design point of view, I would think that any method (including property That is, it is entirely possible for a So, I believe the end-result should be that:
Additionally, given that a |
I think you're right @tannergooding. It's probably not uncommon for a struct setter to modify an object contained in a struct field, without violating the |
This is explicitly an error. The type of That being said any invocation on That being said (part 2) we didn't do this for |
All members types: operators, constructors, etc ... 😄 Even though |
Great. This is even better.
That would be great, but I understand the limitations around "breaking" changes for the existing |
src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbol.cs
Show resolved
Hide resolved
8721918
to
e0fd8a2
Compare
Not looking deeply into this, but this commit message seems super strange: Why would a ReadOnlyKeyword be attached to the ArrowExpression? That seems like a super bizarre place to put it. |
src/Compilers/CSharp/Portable/Generated/Syntax.xml.Internal.Generated.cs
Outdated
Show resolved
Hide resolved
3af5d21
to
c3daaae
Compare
@dotnet/roslyn-compiler This PR is ready for review. |
FYI @sharwell the release mode integration tests failed. Retrying. |
@@ -410,7 +410,12 @@ private DeclarationModifiers MakeModifiers(AccessorDeclarationSyntax syntax, Loc | |||
const DeclarationModifiers defaultAccess = DeclarationModifiers.None; | |||
|
|||
// Check that the set of modifiers is allowed | |||
const DeclarationModifiers allowedModifiers = DeclarationModifiers.AccessibilityMask; | |||
DeclarationModifiers allowedModifiers = DeclarationModifiers.AccessibilityMask; |
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 need to check that the parent property this accessor belongs to isn't readonly?
For access modifiers it's an error when you specify an accessor modifier that isn't more restrictive https://sharplab.io/#v2:D4AQDABCCMDcCwAoEBmKAmCBhCBvJEhBhUaMkAysYfoiYQJADmApgC4J30QOoQDO7TvQC+SEUA==
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.
It seems like that would be consistent with the behavior for visibility modifiers.
Do you propose giving a similar error for this case?
struct S
{
readonly string P
{
readonly get;
}
}
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.
Yeah, that's what I was thinking. Should we be giving an error in that case? I don't really have an opinion one way or the other, but it seems like it would be consistent if we did.
In reply to: 260932737 [](ancestors = 260932737)
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 went ahead and made it an error to provide readonly on an accessor for a property marked readonly.
I believe no because the accessors will "inherit" the In reply to: 468014549 [](ancestors = 468014549) Refers to: src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbol.cs:938 in 7da2c02. [](commit_id = 7da2c02, deletion_comment = False) |
src/Compilers/CSharp/Test/Semantic/Semantics/ReadOnlyStructsTests.cs
Outdated
Show resolved
Hide resolved
@@ -451,6 +456,11 @@ private void CheckModifiers(Location location, bool hasBody, bool isAutoProperty | |||
{ | |||
diagnostics.Add(AccessCheck.GetProtectedMemberInSealedTypeError(ContainingType), location, this); | |||
} | |||
else if (IsStatic && IsReadOnly && !_property.HasReadOnlyModifier) |
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.
&& !_property.HasReadOnlyModifier [](start = 44, length = 33)
Is this check 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.
In this scenario: static readonly int P { get; set; }
this check allows us to give a diagnostic only on the property and not on the accessors, which inherit their modifiers from the property. (is there a better term to use than "inherit"?)
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.
Is there a better pattern to use to prevent redundant diagnostics?
@@ -627,6 +627,8 @@ internal bool IsNew | |||
get { return (_modifiers & DeclarationModifiers.New) != 0; } | |||
} | |||
|
|||
internal bool HasReadOnlyModifier => (_modifiers & DeclarationModifiers.ReadOnly) != 0; |
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.
This might have to become public API at some point, so we'll have to look at naming. IsReadOnly means something else on properties.
@dotnet/roslyn-compiler could I get a second review please? |
@RikkiGibson is it also on you to do the IDE side of things? If so, are you intending to do that through another set of PRs? |
Yeah, that will happen in separate PRs. |
// (9,9): error CS1609: Modifiers cannot be placed on event accessor declarations | ||
// readonly remove {} | ||
Diagnostic(ErrorCode.ERR_NoModifiersOnAccessor, "readonly").WithLocation(9, 9)); | ||
} |
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.
Should add a test or PROTOTYPE about ensuring this only works when C# 8.0 or greater is enabled.
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.
Done. I will probably have a PR specifically about ensuring feature checks occur appropriately in all scenarios (basically wherever the readonly
modifier can be added).
Modified syntax checks and added symbol API to support the readonly members feature. See dotnet/csharplang#1710.
I outlined how I think the entire development of this feature breaks down in #32911. Would also appreciate feedback on that.