Skip to content

Compiler: Rework IntermediateToken and LazyIntermediateToken #12032

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

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

DustinCampbell
Copy link
Member

@DustinCampbell DustinCampbell commented Jul 14, 2025

This change refactors IntermediateToken and LazyIntermediateToken in the IR nodes. The key goals are:

  1. Provide IntermediateNodeFactory.CSharpToken(...) and IntermediateNodeFactory.HtmlToken(...) methods for constructing tokens. Later, these factory methods will make it easier to user interpolated string handlers to avoid allocating strings when creating tokens.
  2. Remind the Kind and TokenKind properties from IntermediateToken. Instead, introduce CSharpIntermediateToken and HtmlIntermediateToken types. This avoids using LINQ to filter by IsCSharp and IsHtml.
  3. Consolidate IntermediateToken and LazyIntermediateToken. Now, any token can have static or lazy content.

The commit history is solid, so it might be preferrable to review commit-by-commit.


CR Build: https://dev.azure.com/dnceng/internal/_build/results?buildId=2749969&view=results
Test Insertion: https://dev.azure.com/devdiv/DevDiv/_git/VS/pullrequest/651521
Toolset Run: https://dev.azure.com/dnceng/internal/_build/results?buildId=2749970&view=results

Add `IntermediateNodeFactory` static class with factory methods for creating CSharp and Html `IntermediateTokens`.
Basic clean up:

- Enable nullability
- Use constructors rather than property setters

Note: The uses of the ! operator will be cleaned up in a later commit.
Introduce a `LazyContent` helper class that can be used to define content that is computed lazily. Use this helper class to allow `IntermediateToken` to directly support lazy content and remove `LazyIntermediateToken`.

NOTE: There are some slight shenanigans to avoid updating test base lines due to `LazyIntermediateToken` being removed.
Make `IntermediateToken` abstract and add strongly-typed `CSharpIntermediateToken` and `HtmlIntermediateToken`.
Update each reference to these properties with type tests for CSharpIntermediateToken or HtmlIntermediateToken.
@DustinCampbell DustinCampbell requested review from a team as code owners July 14, 2025 23:24
{
public override IntermediateNodeCollection Children => IntermediateNodeCollection.ReadOnly;
public bool IsLazy { get; }
Copy link
Contributor

Choose a reason for hiding this comment

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

public bool IsLazy { get; }

Is this only used by tests?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, but it avoids a huge update to the test baselines. I wanted to prove that all tests pass with this change without updating any test baselines.

Copy link
Contributor

Choose a reason for hiding this comment

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

If we keep it in to avoid the baseline, could we at least avoid the backing field?

return;
}

// If it's a C# expression, we have to wrap it in parenthesize, otherwise things like ternary
Copy link
Contributor

Choose a reason for hiding this comment

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

parenthesize

nit: parenthesis

Copy link
Contributor

Choose a reason for hiding this comment

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

actually, I was wrong, it's parentheses. 😄

Copy link
Contributor

@ToddGrun ToddGrun left a comment

Choose a reason for hiding this comment

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

:shipit:

@ToddGrun
Copy link
Contributor

Love it!

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.

3 participants