Skip to content

feat(ast)!: Add computed property to TSEnumMember and TSEnumMemberName::TemplateString #10092

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

Merged
merged 11 commits into from
Apr 9, 2025

Conversation

leaysgur
Copy link
Member

@leaysgur leaysgur commented Mar 28, 2025

Fixes #10088

Copy link

graphite-app bot commented Mar 28, 2025

How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • 0-merge - adds this PR to the back of the merge queue
  • hotfix - for urgent hot fixes, skip the queue and merge this PR next

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

@github-actions github-actions bot added A-parser Area - Parser A-ast Area - AST A-transformer Area - Transformer / Transpiler A-codegen Area - Code Generation A-prettier A-isolated-declarations Isolated Declarations C-enhancement Category - New feature or request labels Mar 28, 2025
Copy link

codspeed-hq bot commented Mar 28, 2025

CodSpeed Instrumentation Performance Report

Merging #10092 will not alter performance

Comparing fix/issue-10088 (fa97b6c) with main (e000f60)

Summary

✅ 36 untouched benchmarks

@leaysgur leaysgur marked this pull request as draft March 28, 2025 05:50
@leaysgur

This comment was marked as resolved.

@leaysgur leaysgur marked this pull request as ready for review March 30, 2025 12:44
@Boshen Boshen removed the A-prettier label Mar 30, 2025
@overlookmotel
Copy link
Contributor

overlookmotel commented Apr 3, 2025

Thanks for this.

Since we know for sure that the template string must have no expressions and only 1 quasi in this case, I wonder if we should add a specific type for it?

pub enum TSEnumMemberName<'a> {
    Identifier(Box<'a, IdentifierName<'a>>) = 0,
    String(Box<'a, StringLiteral<'a>>) = 1,
    Template(Box<'a, SimpleTemplateLiteral<'a>>) = 2,
}

/// A template literal with no expressions and only 1 quasi.
/// Basically a copy of `StringLiteral`, but with backtick quotes.
pub struct SimpleTemplateLiteral<'a> {
    span: Span,
    #[estree(via = StringLiteralValue)]
    pub value: Atom<'a>,
    #[content_eq(skip)]
    pub raw: Option<Atom<'a>>,
    #[builder(default)]
    #[estree(skip)]
    pub lone_surrogates: bool,
}

Personally I think that'd be preferable as, generally speaking, I think it's ideal for the AST to statically be unable to represent syntax which is illegal.

But @Boshen what do you think?


Additionally, instead of a computed property, we could choose to represent whether the property is computed or not with extra enum variants:

pub enum TSEnumMemberName<'a> {
    Identifier(Box<'a, IdentifierName<'a>>) = 0,
    String(Box<'a, StringLiteral<'a>>) = 1,
    Template(Box<'a, SimpleTemplateLiteral<'a>>) = 2,
    ComputedString(Box<'a, StringLiteral<'a>>) = 3,
    ComputedTemplate(Box<'a, SimpleTemplateLiteral<'a>>) = 4,
}

Again, the rationale is that this makes it impossible to represent an illegal syntax in AST:

enum Foo {
    // Illegal syntax - identifiers cannot be computed
    [x] = 1,
}

(there is no ComputedIdentifier variant)

This also makes TSEnumMember 8 bytes smaller than adding a computed: bool property.

@leaysgur
Copy link
Member Author

leaysgur commented Apr 3, 2025

Thanks for the review~!

I too prefer that idea because it is explicit.
But for computed property, it seems to be present in other AST nodes already, so which is better...?

Let's wait for the Boshen's decision. 🙏🏻

@overlookmotel
Copy link
Contributor

One other thing: Doesn't codegen need to wrap in [...] when computed: true to preserve the original syntax?

Otherwise this:

export enum X {
  [`A`] = 123,
}

is printed as:

export enum X {
  `A` = 123,
}

...which is invalid syntax.

@overlookmotel
Copy link
Contributor

@Boshen Could you please give your opinion on #10092 (comment)? Personally, I like the tighter constraint that a SimpleTemplateLiteral would give. But I know you're not keen to add more AST types.

@Dunqing
Copy link
Member

Dunqing commented Apr 9, 2025

I think adding a computed field is good, which is also compatible with typescript-eslint.

@overlookmotel
Copy link
Contributor

Rebased on main to fix merge conflicts. I'm going to merge this when CI passes.


I realized my idea of a SimpleTemplateLiteral is not good. The problem is that visitors for TemplateLiteral need to visit this node, and they won't if it's a different type.

I do think my other suggestion of removing the computed field and replacing with additional enum variants on TSEnumMemberName is good though:

pub enum TSEnumMemberName<'a> {
    Identifier(Box<'a, IdentifierName<'a>>) = 0,
    String(Box<'a, StringLiteral<'a>>) = 1,
    Template(Box<'a, SimpleTemplateLiteral<'a>>) = 2,
    ComputedString(Box<'a, StringLiteral<'a>>) = 3,
    ComputedTemplate(Box<'a, SimpleTemplateLiteral<'a>>) = 4,
}

I'll open an issue for making that change. But let's get this merged in meantime!

@overlookmotel overlookmotel merged commit 521de23 into main Apr 9, 2025
29 checks passed
@overlookmotel overlookmotel deleted the fix/issue-10088 branch April 9, 2025 11:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ast Area - AST A-codegen Area - Code Generation A-isolated-declarations Isolated Declarations A-parser Area - Parser A-transformer Area - Transformer / Transpiler C-enhancement Category - New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ast: Missing computed in TSEnumMember and TemplateElement pattern
4 participants