oxc-project / oxc-project/backlog

AST: Remove `raw` field from `BigIntLiteral`

Open
#231 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
No language data
Stars
7
Forks
0
PR merge metrics
No merged PRs in 30d

Description

Summary

Remove BigIntLiteral::raw from the Rust AST.

Keep the normalized decimal value as semantic state. Original radix prefixes, separators, digit case, and the trailing n remain available from source text and span for parser-origin nodes.

Motivation

These literals have the same mathematical value:

255n
0xffn
0xFFn
0b1111_1111n

Oxc stores normalized value, optional raw, and base separately. The AST can therefore represent impossible combinations:

  • value: "255" with raw: Some("256n");
  • binary raw with base: Hex;
  • a transformed value with stale raw digits;
  • raw without a trailing n;
  • a parser-origin node with no raw spelling.

Arithmetic and semantic consumers need only the normalized value. Lexical lint rules have source text available and can inspect the token through its span. Codegen already prints the normalized value followed by n, so raw is not required for valid output.

The field is skipped by content equality and primarily serves source-oriented consumers. Source text should be the authority for that information.

Current AST Shape

pub struct BigIntLiteral<'a> {
    pub node_id: Cell<NodeId>,
    pub span: Span,
    #[estree(via = BigIntLiteralValue)]
    pub value: Str<'a>,
    #[content_eq(skip)]
    #[estree(json_safe, from_span)]
    pub raw: Option<Str<'a>>,
    #[content_eq(skip)]
    #[estree(skip)]
    pub base: BigintBase,
}

value is decimal and contains no numeric separators. raw records the original token, including prefix, separators, digit case, and suffix.

Proposed AST Shape

Before the base-removal follow-up:

pub struct BigIntLiteral<'a> {
    pub node_id: Cell<NodeId>,
    pub span: Span,
    #[estree(via = BigIntLiteralValue)]
    pub value: Str<'a>,
    #[content_eq(skip)]
    #[estree(skip)]
    pub base: BigintBase,
}

After the related base-removal issue, retain only node_id, span, and normalized value.

Lexical consumers should call a checked source-range helper. AST-only consumers should use value; codegen appends n and handles a synthetic negative value according to expression precedence.

ESTree serialization can derive public raw data from source context for parsed nodes. A synthetic-node fallback should be generated from value rather than stored on the AST.

Syntax Mapping

Source form Current representation Proposed representation
255n value: "255", decimal raw/base value: "255", base retained temporarily; raw from source
0xffn value: "255", hex raw/base Same semantic value; prefix and digit case from source
1_000n value: "1000", raw with separator value: "1000"; separator rules inspect source
Synthetic bigint Normalized value and usually raw: None Normalized value; printer emits <value>n

Guaranteed Invariants

  • A bigint has one semantic value in normalized decimal form.
  • Raw token text cannot contradict the semantic value.
  • Parser-origin spelling has one authority: source text plus span.
  • Synthetic bigints are printable without optional source metadata.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating the Rust AST definition of BigIntLiteral and all consumers of raw, value, and base, then trace parser-origin and synthetic bigint handling. The change is done when raw is removed without breaking source-based lexical access, ESTree serialization, or code generation, and the stated normalized-value invariants hold.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.