Skip to content

Commit b3d8203

Browse files
xcb3dElior Nguyen
andauthored
feat(json): Implement json-parse-with-source proposal (ES2026) (boa-dev#4873)
Related: https://github.com/tc39/proposal-json-parse-with-source It changes the following: - Implement `JSON.rawJSON(text)`: creates frozen raw JSON objects with `[[IsRawJSON]]` internal slot and a `rawJSON` property. Validates input is a valid JSON primitive (not object/array), rejects empty and whitespace-padded strings. - Implement `JSON.isRawJSON(value)`: checks for the `[[IsRawJSON]]` internal slot. - Update `JSON.stringify` to serialize raw JSON objects by outputting their `rawJSON` property value directly. - Implement `JSON.parse` reviver `context.source`: the reviver function now receives a third `context` argument. For primitive JSON values, `context` contains a [source](cci:1://file:///d:/boa/core/engine/src/builtins/json/mod.rs:188:0-193:1) property with the original source text (e.g., `"1.1e1"` instead of `"11"`). For objects/arrays, `context` is an empty object. A value-matching guard ensures [source](cci:1://file:///d:/boa/core/engine/src/builtins/json/mod.rs:188:0-193:1) is omitted when the reviver forward-modifies values during iteration. - Add a `JsonNode` source tree builder that parses JSON to extract byte-accurate source text spans for all primitive values. - Remove `"json-parse-with-source"` from ignored features in [test262_config.toml](cci:7://file:///d:/boa/test262_config.toml:0:0-0:0). **Test262 Results: 165/165 (100% conformance)** | Suite | Pass | Total | |-------|------|-------| | `JSON.parse` | 77 | 77 | | `JSON.stringify` | 66 | 66 | | `JSON.rawJSON` | 10 | 10 | | `JSON.isRawJSON` | 6 | 6 | --------- Co-authored-by: Elior Nguyen <anhtunguyendev@wavenet.com.tw>
1 parent 6bd8334 commit b3d8203

File tree

4 files changed

+397
-35
lines changed

4 files changed

+397
-35
lines changed

core/ast/src/expression/literal/mod.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub use object::{ObjectLiteral, ObjectMethodDefinition, PropertyDefinition};
1717
pub use template::{TemplateElement, TemplateLiteral};
1818

1919
use crate::{
20-
Span, Spanned,
20+
LinearSpan, LinearSpanIgnoreEq, Span, Spanned,
2121
visitor::{VisitWith, Visitor, VisitorMut},
2222
};
2323
use boa_interner::{Interner, Sym, ToInternedString};
@@ -41,6 +41,7 @@ use super::Expression;
4141
pub struct Literal {
4242
kind: LiteralKind,
4343
span: Span,
44+
linear_span: LinearSpanIgnoreEq,
4445
}
4546

4647
impl Literal {
@@ -51,6 +52,22 @@ impl Literal {
5152
Self {
5253
kind: kind.into(),
5354
span,
55+
linear_span: LinearSpanIgnoreEq(LinearSpan::default()),
56+
}
57+
}
58+
59+
/// Create a new [`Literal`] with a [`LinearSpan`] for source text tracking.
60+
#[inline]
61+
#[must_use]
62+
pub fn with_linear_span<T: Into<LiteralKind>>(
63+
kind: T,
64+
span: Span,
65+
linear_span: LinearSpan,
66+
) -> Self {
67+
Self {
68+
kind: kind.into(),
69+
span,
70+
linear_span: LinearSpanIgnoreEq(linear_span),
5471
}
5572
}
5673

@@ -68,6 +85,13 @@ impl Literal {
6885
&mut self.kind
6986
}
7087

88+
/// Get the [`LinearSpan`] of this literal in the source text.
89+
#[inline]
90+
#[must_use]
91+
pub const fn linear_span(&self) -> LinearSpan {
92+
self.linear_span.0
93+
}
94+
7195
/// Get position of the node.
7296
#[inline]
7397
#[must_use]

0 commit comments

Comments
 (0)