Skip to content

WIP: Write back ByRef parameterized property arguments through the setter - #10

Draft
GrahamTheCoder wants to merge 1 commit into
masterfrom
claude/fix-909-parameterized-property-byref
Draft

GrahamTheCoder wants to merge 1 commit into
masterfrom
claude/fix-909-parameterized-property-byref

Conversation

@GrahamTheCoder

Copy link
Copy Markdown
Owner

Fixes icsharpcode#909

Work in progress. This PR only contains the failing repro test, because work stopped early at the usage limit.

Finding

For a parameterized property, ArgumentConverter.HoistByRefDeclaration uses the converted getter call get_Qr(1, 2) as the write-back target (AdditionalAssignment). The result is get_Qr(1, 2) = arg;, which fails with CS0131. The property's arguments are also evaluated twice: get_Qr(Idx(), 2) … get_Qr(Idx(), 2) = arg. VB evaluates them only once. Roslyn's UseTwiceRewriter copies everything except literals, constants and Me into temps, and copies the receiver too when it's a reference-type lvalue.

The C# indexer path (ElementAccessExpression) already moves the container into tmp, but it still evaluates index arguments twice: tmp[Idx()]. The same goes for a plain property receiver with side effects: GetC().Number runs GetC() twice.

Done

Next steps

  1. In HoistByRefDeclaration, check whether the VB argument's operation is an IPropertyReferenceOperation with arguments that isn't the default property. If so, build the write-back as set_X(args..., value) using Property.SetMethod.Name. Generalise AdditionalAssignment into a write-back node that can produce an invocation statement.
  2. Copy into temps any index argument that isn't a constant or a local/parameter written inside the invocation. Apply the same to element-access indexes and to receivers that aren't stable. Treat fields as stable so that the output for the issue matches its expected output exactly. That is a slight deviation from VB, which also copies fields: it only matters if the callee reassigns that field. Needs a reviewer decision.
  3. Add a conversion test in ByRefTests.cs for the issue's shape (expected Db.set_Qr(CourseBuffer, 21, argkeyValue);). Also test a C#-visible indexer and a VB default property.
  4. Run the full suite against the baseline.

Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

VB -> C#: Property Getter is used instead of Setter for ref argument

2 participants