Skip to content

Conversation

@AlekseyTs
Copy link
Contributor

@AlekseyTs AlekseyTs commented Feb 13, 2025

Relates to test plan #76130

@AlekseyTs AlekseyTs added Area-Compilers Feature - Extension Everything The extension everything feature labels Feb 13, 2025
@AlekseyTs AlekseyTs requested a review from a team as a code owner February 13, 2025 04:20
@ghost ghost added the untriaged Issues and PRs which have not yet been triaged by a lead label Feb 13, 2025
@AlekseyTs AlekseyTs requested review from jcouv and jjonescz February 13, 2025 14:54
@AlekseyTs
Copy link
Contributor Author

@jcouv, @jjonescz, @dotnet/roslyn-compiler Please review

{
if (method is { IsStatic: false, ContainingType: SourceNamedTypeSymbol { IsExtension: true, ExtensionParameter: { } parameter } })
{
return new WithParametersBinder([parameter], resultBinder);
Copy link
Member

@jjonescz jjonescz Feb 14, 2025

Choose a reason for hiding this comment

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

Should the doc comment of WithParametersBinder be updated to mention this scenario?

    /// <summary>
    /// Binder used to place the parameters of a method, property, indexer, or delegate
    /// in scope when binding &lt;param&gt; tags inside of XML documentation comments
    /// and `nameof` in certain attribute positions.
    /// </summary>
``` #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should the doc comment of WithParametersBinder be updated to mention this scenario?

Mentioned this in a PROTOTYPE comment

method = method ?? GetMethodSymbol(methodDecl, resultBinder);
isIteratorBody = method.IsIterator;
resultBinder = WithExtensionReceiverParameterBinderIfNecessary(resultBinder, method);
resultBinder = new InMethodBinder(method, resultBinder);
Copy link
Member

@jjonescz jjonescz Feb 14, 2025

Choose a reason for hiding this comment

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

Wouldn't it be better to update InMethodBinder to handle extension receiver? #Resolved

Copy link
Contributor Author

@AlekseyTs AlekseyTs Feb 14, 2025

Choose a reason for hiding this comment

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

Wouldn't it be better to update InMethodBinder to handle extension receiver?

It depends. For example, whether we consider method parameters and receiver parameters in the same scope and what are the shadowing rules might affect the decision. My goal in this PR is to quickly enable test scenarios for implementation methods. I'll add a prototype comment.


bool haveExtraParameter = sourceMethod.ParameterCount != implementationMethod.ParameterCount;
if (haveExtraParameter)
{
Copy link
Member

@jjonescz jjonescz Feb 14, 2025

Choose a reason for hiding this comment

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

Consider asserting that implementationMethod.ParameterCount - 1 == sourceMethod.ParameterCount #Resolved

@AlekseyTs AlekseyTs requested review from a team as code owners February 14, 2025 15:19
@dotnet-policy-service dotnet-policy-service bot added VSCode Needs UX Triage Needs API Review Needs to be reviewed by the API review council labels Feb 14, 2025
@dotnet-policy-service
Copy link
Contributor

This PR modifies public API files. Please follow the instructions at https://github.com/dotnet/roslyn/blob/main/docs/contributing/API%20Review%20Process.md for ensuring all public APIs are reviewed before merging.

@AlekseyTs
Copy link
Contributor Author

AlekseyTs commented Feb 14, 2025

I had to rebase because, for some reason, GitHub was including all commits from #77216 into this PR as well (despite the fact that that PR was already merged). Sorry for any inconvenience that that might cause. #Closed

AddSynthesizedTypeMembersIfNecessary(builder, declaredMembersAndInitializers, diagnostics);
AddSynthesizedConstructorsIfNecessary(builder, declaredMembersAndInitializers, diagnostics);

if (TypeKind == TypeKind.Class)
Copy link
Member

@jcouv jcouv Feb 14, 2025

Choose a reason for hiding this comment

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

nit: consider tightening this check to only top-level non-generic static classes #Closed

public override MethodKind MethodKind => MethodKind.Ordinary;
public override bool IsImplicitlyDeclared => true;

internal override bool HasSpecialName => true;
Copy link
Member

@jcouv jcouv Feb 14, 2025

Choose a reason for hiding this comment

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

Did we have a motivating scenario for this? I thought we wanted to hold off on marking as special name until a scenario was identified #Closed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We are generating a special name for this method, that is enough motivation in my mind (like we do for property accessors an the like). The flag doesn't cause any harm to anyone, but it can be used to quickly filter methods in metadata.

get
{
return _originalMethod.ParameterCount +
(_originalMethod.IsStatic || _originalMethod.ContainingType is not SourceNamedTypeSymbol { ExtensionParameter: { } } ? 0 : 1);
Copy link
Member

@jcouv jcouv Feb 14, 2025

Choose a reason for hiding this comment

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

Would it be better to not create an implementation method in the first place when the ExtensionParameter is faulty? #Closed

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 do not know. So far that didn't cause an problems.

return localFunctions.SelectAsArray(static (l, map) => (MethodSymbol)map[l], _symbolMap);
}

[return: NotNullIfNotNull("symbol")]
Copy link
Member

@jcouv jcouv Feb 14, 2025

Choose a reason for hiding this comment

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

"symbol"

nameof(symbol)? #Closed

@jcouv
Copy link
Member

jcouv commented Feb 14, 2025

""".Replace("[mscorlib]", ExecutionConditionUtil.IsMonoOrCoreClr ? "[netstandard]" : "[mscorlib]"));

I don't mind this approach, but consider moving this to VerifyTypeIL helper at top of the file instead of repeating. #Resolved


Refers to: src/Compilers/CSharp/Test/Emit3/Semantics/ExtensionTests.cs:2989 in d358e8f. [](commit_id = d358e8f, deletion_comment = False)

@jcouv
Copy link
Member

jcouv commented Feb 14, 2025

public void Implementation_InstanceMethod_08_WithLocalFunction_Generic()

Consider testing with generic local function too #Resolved


Refers to: src/Compilers/CSharp/Test/Emit3/Semantics/ExtensionTests.cs:3688 in d358e8f. [](commit_id = d358e8f, deletion_comment = False)

@AlekseyTs
Copy link
Contributor Author

""".Replace("[mscorlib]", ExecutionConditionUtil.IsMonoOrCoreClr ? "[netstandard]" : "[mscorlib]"));

I do not want to be required to provide a base line with specific references. For example, I might use base line from core CLR run, then the helper wouldn't work


In reply to: 2660273404


Refers to: src/Compilers/CSharp/Test/Emit3/Semantics/ExtensionTests.cs:2989 in d358e8f. [](commit_id = d358e8f, deletion_comment = False)

@jcouv
Copy link
Member

jcouv commented Feb 14, 2025

extension(object _)

I noticed you use _ as the receiver parameter name in static scenarios. Is there a reason we can't just omit the name? #Resolved


Refers to: src/Compilers/CSharp/Test/Emit3/Semantics/ExtensionTests.cs:4547 in d358e8f. [](commit_id = d358e8f, deletion_comment = False)

{
ILBuilder builder = new ILBuilder(_moduleBeingBuiltOpt, new LocalSlotManager(slotAllocator: null), OptimizationLevel.Release, areLocalsZeroed: false);

// throw null;
Copy link
Member

@jcouv jcouv Feb 14, 2025

Choose a reason for hiding this comment

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

nit: consider expanding the comment to provide more context "// Emit methods in extensions as skeletons:" #Closed

@jcouv
Copy link
Member

jcouv commented Feb 14, 2025

    var verifier = CompileAndVerify(comp).VerifyDiagnostics();

Should we leave PROTOTYPE markers to execute these tests once we're able to emit call sites? #Resolved


Refers to: src/Compilers/CSharp/Test/Emit3/Semantics/ExtensionTests.cs:4735 in d358e8f. [](commit_id = d358e8f, deletion_comment = False)


internal sealed override bool HasAsyncMethodBuilderAttribute(out TypeSymbol? builderArgument)
{
// PROTOTYPE(roles): Test this code path
Copy link
Member

@jcouv jcouv Feb 14, 2025

Choose a reason for hiding this comment

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

roles

nit: Is this intentional? #Closed

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.

Done with review pass (iteration 3)

@jcouv jcouv self-assigned this Feb 14, 2025
@AlekseyTs
Copy link
Contributor Author

extension(object _)

Is there a reason we can't just omit the name?

It is my intent to use a name in these tests.


In reply to: 2660289257


Refers to: src/Compilers/CSharp/Test/Emit3/Semantics/ExtensionTests.cs:4547 in d358e8f. [](commit_id = d358e8f, deletion_comment = False)

@AlekseyTs
Copy link
Contributor Author

    var verifier = CompileAndVerify(comp).VerifyDiagnostics();

We don't have to and I intend to port end-to-end tests from roles branch. I think they will cover execution of interesting scenarios


In reply to: 2660301916


Refers to: src/Compilers/CSharp/Test/Emit3/Semantics/ExtensionTests.cs:4735 in d358e8f. [](commit_id = d358e8f, deletion_comment = False)

@AlekseyTs AlekseyTs requested a review from jcouv February 14, 2025 23:00
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 4)

@AlekseyTs AlekseyTs merged commit 7981391 into dotnet:features/extensions Feb 18, 2025
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area-Compilers Feature - Extension Everything The extension everything feature Needs API Review Needs to be reviewed by the API review council Needs UX Triage untriaged Issues and PRs which have not yet been triaged by a lead VSCode

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants