Skip to content

Commit 0631dcc

Browse files
committed
pass more tests
1 parent ceceb2a commit 0631dcc

23 files changed

Lines changed: 3782 additions & 374 deletions

crates/oxc_angular_compiler/src/ast/html.rs

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,34 @@ use oxc_span::{Atom, Span};
88

99
use super::expression::AngularExpression;
1010

11+
// ============================================================================
12+
// Token Types (ported from Angular's ml_parser/tokens.ts)
13+
// ============================================================================
14+
15+
/// Token types for text and attribute value tokens.
16+
/// These are used to preserve the original token structure for transforms.
17+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18+
pub enum InterpolatedTokenType {
19+
/// Plain text: parts = [text]
20+
Text,
21+
/// Interpolation: parts = [startMarker, expression, endMarker]
22+
Interpolation,
23+
/// Encoded entity: parts = [decoded, encoded]
24+
EncodedEntity,
25+
}
26+
27+
/// A token within interpolated text or attribute values.
28+
/// Preserves the original lexer tokens for transforms like whitespace removal.
29+
#[derive(Debug)]
30+
pub struct InterpolatedToken<'a> {
31+
/// The token type.
32+
pub token_type: InterpolatedTokenType,
33+
/// The token parts (structure depends on token type).
34+
pub parts: Vec<'a, Atom<'a>>,
35+
/// The source span.
36+
pub span: Span,
37+
}
38+
1139
/// An HTML AST node.
1240
#[derive(Debug)]
1341
pub enum HtmlNode<'a> {
@@ -34,10 +62,16 @@ pub enum HtmlNode<'a> {
3462
/// A text node in the HTML AST.
3563
#[derive(Debug)]
3664
pub struct HtmlText<'a> {
37-
/// The text value.
65+
/// The decoded text value (entities resolved, interpolations joined).
3866
pub value: Atom<'a>,
39-
/// The source span.
67+
/// The source span (after stripping leading trivia).
4068
pub span: Span,
69+
/// The full start offset before stripping leading trivia (for source maps).
70+
/// If None, there was no leading trivia stripped.
71+
pub full_start: Option<u32>,
72+
/// The original tokens (text, interpolation, encoded entity).
73+
/// Used by transforms like whitespace removal.
74+
pub tokens: Vec<'a, InterpolatedToken<'a>>,
4175
}
4276

4377
/// An element node in the HTML AST.
@@ -83,14 +117,17 @@ pub struct HtmlDirective<'a> {
83117
pub struct HtmlAttribute<'a> {
84118
/// The attribute name.
85119
pub name: Atom<'a>,
86-
/// The attribute value (may be empty).
120+
/// The decoded attribute value (entities resolved, interpolations joined).
87121
pub value: Atom<'a>,
88122
/// The source span.
89123
pub span: Span,
90124
/// The name span.
91125
pub name_span: Span,
92126
/// The value span (if value exists).
93127
pub value_span: Option<Span>,
128+
/// The original value tokens (text, interpolation, encoded entity).
129+
/// Used by transforms. None for valueless attributes.
130+
pub value_tokens: Option<Vec<'a, InterpolatedToken<'a>>>,
94131
}
95132

96133
/// A comment node in the HTML AST.
@@ -438,7 +475,12 @@ mod tests {
438475
fn test_traverse_all() {
439476
let allocator = Allocator::default();
440477

441-
let text = HtmlText { value: Atom::from("Hello"), span: Span::default() };
478+
let text = HtmlText {
479+
value: Atom::from("Hello"),
480+
span: Span::default(),
481+
full_start: None,
482+
tokens: Vec::new_in(&allocator),
483+
};
442484

443485
let mut nodes = Vec::new_in(&allocator);
444486
nodes.push(HtmlNode::Text(Box::new_in(text, &allocator)));

crates/oxc_angular_compiler/src/i18n/parser.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ fn extract_placeholder_name(expression: &str) -> Option<String> {
467467
mod tests {
468468
use super::*;
469469
use crate::ast::html::HtmlText;
470-
use oxc_allocator::{Allocator, Box};
470+
use oxc_allocator::{Allocator, Box, Vec as AllocVec};
471471
use oxc_span::Atom;
472472

473473
#[test]
@@ -489,7 +489,12 @@ mod tests {
489489
let allocator = Allocator::default();
490490
let factory = create_i18n_message_factory(false, false);
491491

492-
let text = HtmlText { value: Atom::from("Hello {{name}}!"), span: Span::default() };
492+
let text = HtmlText {
493+
value: Atom::from("Hello {{name}}!"),
494+
span: Span::default(),
495+
full_start: None,
496+
tokens: AllocVec::new_in(&allocator),
497+
};
493498

494499
let nodes = vec![HtmlNode::Text(Box::new_in(text, &allocator))];
495500
let message = factory.create_message(&nodes, None, None, None, None);
@@ -514,7 +519,12 @@ mod tests {
514519
let allocator = Allocator::default();
515520
let factory = create_i18n_message_factory(false, false);
516521

517-
let text = HtmlText { value: Atom::from("Hello World"), span: Span::default() };
522+
let text = HtmlText {
523+
value: Atom::from("Hello World"),
524+
span: Span::default(),
525+
full_start: None,
526+
tokens: AllocVec::new_in(&allocator),
527+
};
518528

519529
let nodes = vec![HtmlNode::Text(Box::new_in(text, &allocator))];
520530
let message = factory.create_message(&nodes, None, None, None, None);
@@ -529,7 +539,12 @@ mod tests {
529539
let allocator = Allocator::default();
530540
let factory = create_i18n_message_factory(false, false);
531541

532-
let text = HtmlText { value: Atom::from("{{greeting}} {{name}}!"), span: Span::default() };
542+
let text = HtmlText {
543+
value: Atom::from("{{greeting}} {{name}}!"),
544+
span: Span::default(),
545+
full_start: None,
546+
tokens: AllocVec::new_in(&allocator),
547+
};
533548

534549
let nodes = vec![HtmlNode::Text(Box::new_in(text, &allocator))];
535550
let message = factory.create_message(&nodes, None, None, None, None);

0 commit comments

Comments
 (0)