Skip to content

Support field-targeted attributes on auto-properties (7.3)#22664

Merged
jcouv merged 9 commits into
dotnet:features/compilerfrom
jcouv:field-attribute
Nov 13, 2017
Merged

Support field-targeted attributes on auto-properties (7.3)#22664
jcouv merged 9 commits into
dotnet:features/compilerfrom
jcouv:field-attribute

Conversation

@jcouv
Copy link
Copy Markdown
Member

@jcouv jcouv commented Oct 11, 2017

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.

[Serializable]
public class Foo {
    [field: NonSerialized]
    public string MySecret { get; set; }
}

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 field target doesn't exist in VB (only assembly and module are supported as explicit targets).

Fixes #22512
Implements dotnet/csharplang#42
Spec https://github.com/dotnet/csharplang/blob/master/proposals/auto-prop-field-attrs.md

@jcouv jcouv added this to the 15.later milestone Oct 11, 2017
@jcouv jcouv self-assigned this Oct 11, 2017
@jcouv jcouv changed the title Support field-targeted attributes on auto-properties (post dev15.5) Support field-targeted attributes on auto-properties (15.later) Oct 11, 2017
@jcouv jcouv added the PR For Personal Review Only The PR doesn’t require anyone other than the developer to review it. label Oct 12, 2017
@jcouv jcouv force-pushed the field-attribute branch 4 times, most recently from 76b1da1 to 65062f6 Compare October 13, 2017 19:18
@jcouv jcouv removed the PR For Personal Review Only The PR doesn’t require anyone other than the developer to review it. label Oct 13, 2017
@jcouv jcouv changed the base branch from master to post-dev15.5-contrib October 13, 2017 21:51
@jcouv jcouv force-pushed the field-attribute branch 3 times, most recently from ab1986f to c6050c0 Compare October 15, 2017 20:08
@jcouv jcouv added the PR For Personal Review Only The PR doesn’t require anyone other than the developer to review it. label Oct 27, 2017
@jcouv jcouv force-pushed the field-attribute branch 2 times, most recently from 905d79e to 891f24b Compare October 28, 2017 00:22
@jcouv jcouv removed the PR For Personal Review Only The PR doesn’t require anyone other than the developer to review it. label Oct 28, 2017
@jcouv jcouv changed the title Support field-targeted attributes on auto-properties (15.later) Support field-targeted attributes on auto-properties (7.3) Oct 30, 2017
Copy link
Copy Markdown
Member Author

@jcouv jcouv Oct 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 This is a warning (rather than an error) since such code currently produces a warning.
[field: SomeAttribute] public int prop { get; set; } #Resolved

@jcouv
Copy link
Copy Markdown
Member Author

jcouv commented Oct 30, 2017

@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.
This PR will need to be retargeted to the appropriate branch for 7.3 (once we know what branch that is). #Resolved

@jcouv jcouv changed the base branch from post-dev15.5-contrib to features/compiler October 30, 2017 18:48
private void CheckForFieldTargetedAttribute(bool isAutoProperty, BasePropertyDeclarationSyntax syntax, DiagnosticBag diagnostics)
{
var languageVersion = this.DeclaringCompilation.LanguageVersion;
if (!isAutoProperty || languageVersion.AllowAttributesOnBackingFields())
Copy link
Copy Markdown
Contributor

@cston cston Oct 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider having the caller check _isAutoProperty and remove the parameter. #Resolved


/// <summary>
/// C# language version 7.3
/// </summary>
Copy link
Copy Markdown
Contributor

@AlekseyTs AlekseyTs Oct 31, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Copy Markdown
Contributor

@AlekseyTs AlekseyTs Oct 31, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Member Author

@jcouv jcouv Nov 1, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Member Author

@jcouv jcouv Nov 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That worked out better indeed. Thanks Aleksey #Resolved

Copy link
Copy Markdown
Contributor

@AlekseyTs AlekseyTs Nov 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Contributor

@AlekseyTs AlekseyTs Nov 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Contributor

@AlekseyTs AlekseyTs Nov 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// (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

Copy link
Copy Markdown
Contributor

@AlekseyTs AlekseyTs Nov 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// TODO [](start = 16, length = 7)

TODO? #Closed

@AlekseyTs
Copy link
Copy Markdown
Contributor

AlekseyTs commented Nov 7, 2017

Done with review pass (iteration 3). #Closed

@AlekseyTs
Copy link
Copy Markdown
Contributor

AlekseyTs commented Nov 7, 2017

It looks like there are some test failures. #Resolved

@jcouv
Copy link
Copy Markdown
Member Author

jcouv commented Nov 7, 2017

That's expected (two tests related to language version). I didn't want to rebase mid-review.


In reply to: 342641726 [](ancestors = 342641726)

Copy link
Copy Markdown
Contributor

@AlekseyTs AlekseyTs Nov 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It turns out this can be reached (InteractiveSessionTests.ScriptMemberAccessFromNestedClass). I'll restore the original code.

Copy link
Copy Markdown
Contributor

@AlekseyTs AlekseyTs Nov 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AssertEx.SetEqual(fieldAttributesExpected, GetAttributeStrings(field1.GetAttributes())); [](start = 20, length = 88)

Is the attribute converted to a constant value on the field? #Closed

Copy link
Copy Markdown
Contributor

@AlekseyTs AlekseyTs Nov 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assert.Empty(GetAttributeStrings(field3.GetAttributes())); [](start = 20, length = 58)

Is the attribute converted to a constant value on the field? #Closed

Copy link
Copy Markdown
Contributor

@AlekseyTs AlekseyTs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (iteration 5) with minor comments.

@jcouv
Copy link
Copy Markdown
Member Author

jcouv commented Nov 8, 2017

Awesome. Thanks!
@dotnet/roslyn-compiler for a second review

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the method returns a non-null value in all cases.

@jcouv
Copy link
Copy Markdown
Member Author

jcouv commented Nov 13, 2017

test ubuntu_14_debug_prtest please

@jcouv jcouv merged commit 3d2101e into dotnet:features/compiler Nov 13, 2017
@jcouv jcouv deleted the field-attribute branch November 13, 2017 21:24
@jcouv jcouv modified the milestones: 15.6, 15.7 Jan 9, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants