Support field-targeted attributes on auto-properties (7.3)#22664
Conversation
c33b872 to
24d780c
Compare
76b1da1 to
65062f6
Compare
65062f6 to
f50a8d3
Compare
ab1986f to
c6050c0
Compare
905d79e to
891f24b
Compare
There was a problem hiding this comment.
📝 This is a warning (rather than an error) since such code currently produces a warning.
[field: SomeAttribute] public int prop { get; set; } #Resolved
891f24b to
b0d6259
Compare
|
@AlekseyTs @dotnet/roslyn-compiler This PR is ready for review. The first commit adds support for attributes on backing fields. The second commit adds LangVersion 7.3. |
| private void CheckForFieldTargetedAttribute(bool isAutoProperty, BasePropertyDeclarationSyntax syntax, DiagnosticBag diagnostics) | ||
| { | ||
| var languageVersion = this.DeclaringCompilation.LanguageVersion; | ||
| if (!isAutoProperty || languageVersion.AllowAttributesOnBackingFields()) |
There was a problem hiding this comment.
Consider having the caller check _isAutoProperty and remove the parameter. #Resolved
|
|
||
| /// <summary> | ||
| /// C# language version 7.3 | ||
| /// </summary> |
There was a problem hiding this comment.
CSharp7_3 = 703 [](start = 8, length = 15)
CSharp7_3 = 703 [](start = 8, length = 15)
It is probably worth separating addition of a language version into its own PR. #Closed
| } | ||
| } | ||
|
|
||
| internal virtual Location ErrorLocation => throw ExceptionUtilities.Unreachable; |
There was a problem hiding this comment.
internal virtual Location ErrorLocation => throw ExceptionUtilities.Unreachable; [](start = 8, length = 80)
In general, we prefer abstract API to virtual APIs with default implementation that throws. Perhaps this API can be moved to specific derived type?
| AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDebuggerBrowsableNeverAttribute()); | ||
| } | ||
|
|
||
| internal sealed override bool IsNotSerialized |
There was a problem hiding this comment.
IsNotSerialized [](start = 38, length = 15)
IsNotSerialized [](start = 38, length = 15)
It feels like a lot of code duplicated here, I think we should find a way to share it instead. Perhaps we should stop inheriting from SynthesizedFieldSymbolBase and introduce a new base class, from which SourceFieldSymbol and SynthesizedBackingFieldSymbol can inherit. #Closed
There was a problem hiding this comment.
If we do that, then we'll end up duplicating some logic related to synthesized symbols.
I can give a try and see how it looks... #Resolved
There was a problem hiding this comment.
That worked out better indeed. Thanks Aleksey #Resolved
There was a problem hiding this comment.
SynthesizedFieldSymbolBase.AddSynthesizedFieldAttributes(ref attributes, this, suppressDynamicAttribute: false); [](start = 12, length = 112)
It feels like, if we move SourceFieldSymbol.AddSynthesizedAttributes to the new base, we wouldn't have to add this call. #Closed
There was a problem hiding this comment.
AddSynthesizedFieldAttributes [](start = 29, length = 29)
It feels like, if we move SourceFieldSymbol.AddSynthesizedAttributes to the new base, we wouldn't have to make any changes in this file. #Closed
There was a problem hiding this comment.
// (7,16): error CS0625: 'Test.P': instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute [](start = 16, length = 135)
Is this message missing 'in' - "instance field in type marked ..."? #Closed
There was a problem hiding this comment.
// TODO [](start = 16, length = 7)
TODO? #Closed
|
Done with review pass (iteration 3). #Closed |
|
It looks like there are some test failures. #Resolved |
|
That's expected (two tests related to language version). I didn't want to rebase mid-review. In reply to: 342641726 [](ancestors = 342641726) |
There was a problem hiding this comment.
if (!this.ContainingType.IsImplicitlyDeclared) [](start = 12, length = 46)
I do not think this condition can ever be true. Consider replacing the if with assert. #Closed
There was a problem hiding this comment.
It turns out this can be reached (InteractiveSessionTests.ScriptMemberAccessFromNestedClass). I'll restore the original code.
There was a problem hiding this comment.
AssertEx.SetEqual(fieldAttributesExpected, GetAttributeStrings(field1.GetAttributes())); [](start = 20, length = 88)
Is the attribute converted to a constant value on the field? #Closed
There was a problem hiding this comment.
Assert.Empty(GetAttributeStrings(field3.GetAttributes())); [](start = 20, length = 58)
Is the attribute converted to a constant value on the field? #Closed
AlekseyTs
left a comment
There was a problem hiding this comment.
LGTM (iteration 5) with minor comments.
|
Awesome. Thanks! |
There was a problem hiding this comment.
Looks like the method returns a non-null value in all cases.
6baae7c to
d468b14
Compare
|
test ubuntu_14_debug_prtest please |
This is a small feature for C# 7.3.
In the following example, the field-targeted attribute is applied to the backing field instead of the property itself.
This used to be a warning:
warning CS0657: 'field' is not a valid attribute location for this declaration. Valid attribute locations for this declaration are 'property'. All attributes in this block will be ignored.📝 The two failing tests are expected, as this PR needs be be rebased to get the new LanguageVersion.
📝 No VB change. The
fieldtarget doesn't exist in VB (onlyassemblyandmoduleare supported as explicit targets).Fixes #22512
Implements dotnet/csharplang#42
Spec https://github.com/dotnet/csharplang/blob/master/proposals/auto-prop-field-attrs.md