oxc-project / oxc-project/backlog
AST: Remove `raw` field from `BigIntLiteral`
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"withraw: Some("256n");- binary
rawwithbase: Hex; - a transformed value with stale raw digits;
rawwithout a trailingn;- 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
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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