Skip to content

[http-client-csharp] Add ArgumentExpression for ref/out argument support#10845

Open
JonathanCrd wants to merge 8 commits into
microsoft:mainfrom
JonathanCrd:joncarde/argument-expression-8399
Open

[http-client-csharp] Add ArgumentExpression for ref/out argument support#10845
JonathanCrd wants to merge 8 commits into
microsoft:mainfrom
JonathanCrd:joncarde/argument-expression-8399

Conversation

@JonathanCrd

@JonathanCrd JonathanCrd commented May 30, 2026

Copy link
Copy Markdown
Member

Summary

Add a new ArgumentExpression class that wraps a ValueExpression with optional ref/out modifiers, cleanly separating argument-passing semantics from variable reference semantics.

Closes #8399

Changes

  • New ArgumentExpression class — wraps a ValueExpression with IsRef/IsOut, Write() visitor support via Accept(), and Update()
  • Simplified VariableExpression — removed IsRef/IsOut properties; now a pure variable reference (with backward-compatible shims)
  • Simplified ParameterProvider — removed dual _asVariable/_asArgument caching pattern; added GetArgumentExpression()
  • Updated AsArgument() — now returns ValueExpression (an ArgumentExpression) instead of VariableExpression
  • Added VisitArgumentExpression to LibraryVisitor
  • Updated call sites: ClientProvider, MrwSerializationTypeDefinition, JsonPatchSnippets, ScmModelProvider
  • Added tests: ArgumentExpressionTests (8 tests covering ref, out, update, and ParameterProvider integration) and ExpressionVisitorTests

@microsoft-github-policy-service microsoft-github-policy-service Bot added the emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp label May 30, 2026
@pkg-pr-new

pkg-pr-new Bot commented May 30, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@typespec/http-client-csharp@10845

commit: 68dfa53

@github-actions

Copy link
Copy Markdown
Contributor

No changes needing a change description found.

@JonathanCrd JonathanCrd force-pushed the joncarde/argument-expression-8399 branch from c34da4a to 30e4276 Compare June 2, 2026 22:09
@azure-sdk-automation

azure-sdk-automation Bot commented Jun 2, 2026

Copy link
Copy Markdown

You can try these changes here

🛝 Playground 🌐 Website 🛝 VSCode Extension

@JonathanCrd JonathanCrd force-pushed the joncarde/argument-expression-8399 branch from 30e4276 to 56c20d4 Compare June 2, 2026 23:14
@JonathanCrd JonathanCrd self-assigned this Jun 16, 2026
JonathanCrd and others added 5 commits June 16, 2026 16:08
… support

Add a new ArgumentExpression class that wraps a ValueExpression with
optional ref/out modifiers, separating argument-passing semantics from
variable reference semantics.

Changes:
- Create ArgumentExpression to handle ref/out keywords in argument context
- Remove IsRef/IsOut from VariableExpression (now a pure variable reference)
- Simplify ParameterProvider by removing the dual _asVariable/_asArgument pattern
- Update AsArgument() to return ArgumentExpression wrapping the variable
- Update call sites: ClientProvider, MrwSerializationTypeDefinition,
  JsonPatchSnippets, ScmModelProvider
- Add VisitArgumentExpression to LibraryVisitor
- Add comprehensive ArgumentExpressionTests

Closes microsoft#8399

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Restore the legacy VariableExpression ref/out constructor and add regression tests for ArgumentExpression visitor handling.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The pnpm setup:min step in RegenCheck CI fails on Linux runners
where NodeTool resolves Node.js 24.x to v24.14.1, which does not
satisfy the which@7.0.0 engine requirement (^24.15.0). Temporarily
relax engine-strict during workspace setup to unblock CI while the
runner images are updated.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Mark VariableExpression.IsRef/IsOut and legacy constructor as
  [Obsolete] to guide callers toward ArgumentExpression
- Replace ByRef() with ArgumentExpression in MrwSerializationTypeDefinition
  for method argument semantics (ref return in ScmModelProvider is correct)
- Fix dead ternary in ExpressionVisitorTests assertion
- Keep redundant 2-param VariableExpression(type, name) constructor since
  it is part of the public API surface and used widely

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@JonathanCrd JonathanCrd force-pushed the joncarde/argument-expression-8399 branch from e7255fb to 29c8aa5 Compare June 16, 2026 23:32
JonathanCrd and others added 2 commits June 16, 2026 16:57
@typespec/http-client-csharp is not in the chronus workspace.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@JonathanCrd JonathanCrd changed the title [WIP] feat(http-client-csharp): add ArgumentExpression for ref/out argument support [http-client-csharp] Add ArgumentExpression for ref/out argument support Jun 17, 2026
@JonathanCrd JonathanCrd marked this pull request as ready for review June 17, 2026 07:04
public record VariableExpression(CSharpType Type, CodeWriterDeclaration Declaration) : ValueExpression
{
[Obsolete("Use ArgumentExpression for ref/out argument semantics.")]
public bool IsRef { get; private set; }

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.

Should we swap out all the usages rather than marking obsolete?

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.

Addressed in e2b push (68dfa53) — removed the obsolete IsRef/IsOut properties and the legacy (type, name, isRef, isOut) constructor entirely, plus the isRef/isOut parameters on Update. VariableExpression is now a pure variable reference and all ref/out usages flow through ArgumentExpression.

}

var cachedClientFieldVar = new VariableExpression(subClient.Type, subClient._clientCachingField.Declaration, IsRef: true);
var cachedClientFieldVar = new ArgumentExpression(new VariableExpression(subClient.Type, subClient._clientCachingField.Declaration), IsRef: true);

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.

I think we should have some sort of AsArgument snippet to make the code more readable and intuitive.

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.

Done — added a ValueExpression.AsArgument(isRef, isOut) snippet and updated this call site to new VariableExpression(...).AsArgument(isRef: true). Also applied it in JsonPatchSnippets.

if (hookMethod == null)
{
// Fall back: no method found, use previous behavior (first known arg, ref variable, no options)
return [knownArguments[0].Argument, ByRef(refVariable)];

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.

Should ByRef be updated to return an ArgumentExpression?

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.

Yes — ByRef now returns new ArgumentExpression(expression, IsRef: true) and the call sites here use ByRef(refVariable). (Also added an ArgumentExpression case to UpdateProtocolMethodInvocation so ref/out args are still unwrapped, since they're no longer KeywordExpression.)

- Remove obsolete IsRef/IsOut shims and legacy constructor from VariableExpression
- Update ByRef snippet to return an ArgumentExpression
- Add ValueExpression.AsArgument snippet for readable ref/out argument wrapping
- Use ByRef/AsArgument at call sites (ClientProvider, MrwSerializationTypeDefinition, JsonPatchSnippets)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp eng

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add better support for ArgumentExpression vs VariableExpression

2 participants