Skip to content
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

Prepare partial properties feature for merge #73773

Merged

Conversation

RikkiGibson
Copy link
Contributor

@RikkiGibson RikkiGibson commented May 29, 2024

#73090
Introduces several links to tracking issue #73772
VS test insertion: https://dev.azure.com/devdiv/DevDiv/_git/VS/pullrequest/554460
Baseline insertion for comparison: https://dev.azure.com/devdiv/DevDiv/_git/VS/pullrequest/554589

Related spec change: dotnet/csharplang#8169

@dotnet-issue-labeler dotnet-issue-labeler bot added Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead labels May 29, 2024
@RikkiGibson RikkiGibson changed the base branch from main to features/partial-properties May 30, 2024 01:17
@RikkiGibson RikkiGibson force-pushed the partial-properties-10 branch from f242061 to f546237 Compare May 30, 2024 01:18
@RikkiGibson RikkiGibson changed the title Partial properties 10 Prepare partial properties feature for merge May 30, 2024
@RikkiGibson RikkiGibson marked this pull request as ready for review May 30, 2024 21:19
@RikkiGibson RikkiGibson requested review from a team as code owners May 30, 2024 21:19
Comment on lines +1108 to +1111
// The property is responsible for completion of the backing field
// NB: when the **field keyword feature** is implemented, it's possible that synthesized field symbols will also be merged or shared between partial property parts.
// If we do that then this check should possibly be moved, and asserts adjusted accordingly.
_ = BackingField?.GetAttributes();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@cston This comment and the below assert are likely relevant for the field keyword feature.

Comment on lines +177 to +180
Debug.Assert(PartialDefinitionPart is null
// We might still get here when asking for the attributes on a backing field.
// This is an error scenario (requires using a property initializer and field-targeted attributes on partial property implementation part).
|| this.BackingField is not null);
Copy link
Contributor Author

@RikkiGibson RikkiGibson May 30, 2024

Choose a reason for hiding this comment

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

@cston I was anticipating that perhaps the synthesized BackingField symbol will be shared between partial property parts, or otherwise the two field symbols will reference each other similarly as the associated partial property symbols. But, this work won't happen until field keyword feature is implemented, and how specifically it will be done is TBD.

Currently, a different backing field symbol can be created for each partial property part, which is used only for error recovery (e.g. when an initializer is used on the property.)

string s => $@"""{s}""",
_ => obj.ToString()
};
itemInspector = new Func<T, string>(obj => (obj != null) ? obj.ToString() : "<null>");
Copy link
Contributor Author

@RikkiGibson RikkiGibson May 30, 2024

Choose a reason for hiding this comment

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

Reverted to main version

@RikkiGibson RikkiGibson requested review from jcouv and Cosifne May 30, 2024 21:23
@RikkiGibson
Copy link
Contributor Author

IDE layer changes are comment-only @Cosifne. These comments are also enumerated in #73772.

@RikkiGibson

This comment was marked as resolved.

@jcouv jcouv self-assigned this May 31, 2024
Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

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

Compiler changes LGTM Thanks (iteration 9)

/// Test copying custom modifiers in/on parameters/return types.
/// </summary>
[Fact]
public void TestPartialMethodOverrideCombinations()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't see any similar test to this already so figured we might as well have it.

partial class Derived : PropertyCustomModifierCombinations
{
public override partial int[] Property11 { get; set; }
public override partial int[] Property11 { get => new int[0]; set { } }
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Had to change the test away from using [] due to #73804.

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

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

LGTM Thanks (iteration 10)

@RikkiGibson RikkiGibson requested a review from cston May 31, 2024 17:33
[Fact]
public void NullableDifference_Analysis()
{
// Nullable annotations from the *definition* part parameters are used when analyzing implementations.
Copy link
Member

Choose a reason for hiding this comment

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

definition part parameters are used when analyzing implementations.

Is this statement correct? If we used the definition part parameters for analyzing the implementation, why are reporting warnings // 3 and // 4?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're right, I'll adjust the comment and the spec PR. Don't know how I got mixed up on this.

// (10,27): error CS8050: Only auto-implemented properties can have initializers.
// public partial string P3 { get => ""; set { } } = "d";
Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "P3").WithLocation(10, 27));
}
Copy link
Member

@cston cston May 31, 2024

Choose a reason for hiding this comment

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

}

Are we binding the initializers in these error cases? Consider adding a test such as:

partial string P4 { get; set; } = nameof(Unknown);
partial string P4 { get => ""; set { } }
``` #Closed

@cston
Copy link
Member

cston commented May 31, 2024

                public partial int this[int p2] { get => p2; set { } }

Consider using p2 in the set accessor as well: set { _ = p2; }. #Closed


Refers to: src/Compilers/CSharp/Test/Symbol/Symbols/PartialPropertiesTests.cs:4589 in 63e1536. [](commit_id = 63e1536, deletion_comment = False)

{
var indexer = module.GlobalNamespace.GetMember<NamedTypeSymbol>("C").Indexers.Single();
Assert.Equal("p1", indexer.Parameters.Single().Name);
}
}
Copy link
Member

Choose a reason for hiding this comment

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

}

Would it make sense to test which parameter names are in scope? For instance:

class A : System.Attribute
{
    public A(object x, object y) { }
}
partial class C
{
    public partial int this[int p1] { [param: A(nameof(p1), nameof(p2))] set; }
    public partial int this[int p2] { [param: A(nameof(p1), nameof(p2))] set { } }
}

Cosifne and others added 2 commits May 31, 2024 11:44
…lMethodCompletionProvider.cs

Co-authored-by: Rikki Gibson <rigibson@microsoft.com>
…uageService.cs

Co-authored-by: Rikki Gibson <rigibson@microsoft.com>
Diagnostic(ErrorCode.ERR_NameNotInContext, "p2").WithArguments("p2").WithLocation(9, 18),
// (14,29): error CS0103: The name 'p1' does not exist in the current context
// [param: Attr(nameof(p1))] // 3
Diagnostic(ErrorCode.ERR_NameNotInContext, "p1").WithArguments("p1").WithLocation(14, 29),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I know why this is happening. The implementation part owns binding attributes on parameters.

https://github.com/dotnet/csharplang/blob/main/proposals/csharp-11.0/extended-nameof-scope.md doesn't appear to spec what should happen here.

I am hesitant to even spec the behavior here (which is already shipped for methods).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants