Skip to content
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

Make raw field on literal AST types optional, or remove them #7254

Open
overlookmotel opened this issue Nov 12, 2024 · 0 comments
Open

Make raw field on literal AST types optional, or remove them #7254

overlookmotel opened this issue Nov 12, 2024 · 0 comments
Assignees
Labels
C-bug Category - Bug

Comments

@overlookmotel
Copy link
Collaborator

The problem

#7211 brought up a problem. Most of our literal types (NumericLiteral etc) have raw field.

This makes sense when the AST has come from the parser, but little sense when the node is generated (e.g. in transformer), because the node has no "raw" representation.

Having to provide "0" here feels like a hack to me, for example:

pub fn number_0(self) -> Expression<'a> {
self.expression_numeric_literal(Span::default(), 0.0, "0", NumberBase::Decimal)
}

The exception is StringLiteral which doesn't have a raw field. This feels like an omission - if the other literal types have a raw field, it should have one too. But adding one would be a pain, as there are a lot of places we generate strings in transformer etc.

Prior art

Babel's types have the raw field under extra which is optional:

export interface StringLiteral extends BaseNode {
  type: "StringLiteral";
  value: string;
}

interface BaseNode {
  type: Node["type"];
  // ...
  extra?: Record<string, unknown>;
}

StringLiteral BaseNode

Acorn's types also have the raw field as optional:

export interface Literal extends Node {
  type: "Literal"
  value?: string | boolean | null | number | RegExp | bigint
  raw?: string
  regex?: {
    pattern: string
    flags: string
  }
  bigint?: string
}

source

Possible solutions

I can see 2 options:

Make raw fields optional

  • Change raw field on NumericLiteral etc to Option<&'a str>.
  • Add a raw: Option<&'a str> field to StringLiteral.

Remove all raw fields

Where an AST node has a non-empty span, the raw value can be obtained by slicing source text. So remove all the raw fields, and use methods to get raw value where required:

impl NumericLiteral {
    pub fn raw<'a>(&self, source_text: &'a str) -> Option<&'a str> {
        if self.span.start == 0 && self.span.end == 0 {
            None
        } else {
            Some(&source_text[self.span.start..self.span.end])
        }
    }
}

(as suggested in #5522)

Which?

Personally I prefer the 2nd. I don't think the raw fields are used much, so they're bloating the AST for little value. The methods to get raw value from Span are pretty trivial and cheap.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category - Bug
Projects
None yet
Development

No branches or pull requests

2 participants