Skip to content

Commit 8c4874e

Browse files
committed
more alignment
1 parent 7fcbe1f commit 8c4874e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+3408
-639
lines changed

crates/oxc_angular_compiler/src/ir/enums.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,17 +250,30 @@ pub enum ExpressionKind {
250250
LiteralArray,
251251
/// Literal map (object) with IR expression values.
252252
LiteralMap,
253+
/// Logical NOT expression (!expr).
254+
Not,
255+
/// Unary operator expression (+expr or -expr).
256+
Unary,
257+
/// Typeof expression (typeof expr).
258+
Typeof,
259+
/// Void expression (void expr).
260+
Void,
253261
}
254262

255263
/// Flags for semantic variables.
256-
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
264+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
257265
pub struct VariableFlags(u8);
258266

259267
impl VariableFlags {
260268
/// No flags.
261269
pub const NONE: Self = Self(0b0000);
262270
/// Always inline this variable.
263271
pub const ALWAYS_INLINE: Self = Self(0b0001);
272+
273+
/// Check if a flag is set.
274+
pub fn contains(self, other: Self) -> bool {
275+
(self.0 & other.0) == other.0
276+
}
264277
}
265278

266279
/// Kinds of semantic variables.

crates/oxc_angular_compiler/src/ir/expression.rs

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,18 @@ pub enum IrExpression<'a> {
162162
/// Literal map (object) with IR expression values.
163163
/// Used to preserve pipe bindings inside object literals during ingest.
164164
LiteralMap(Box<'a, IrLiteralMapExpr<'a>>),
165+
/// Logical NOT expression (!expr).
166+
/// Used to preserve pipe bindings inside negation expressions during ingest.
167+
Not(Box<'a, NotExpr<'a>>),
168+
/// Unary operator expression (+expr or -expr).
169+
/// Used to preserve pipe bindings inside unary expressions during ingest.
170+
Unary(Box<'a, UnaryExpr<'a>>),
171+
/// Typeof expression (typeof expr).
172+
/// Used to preserve pipe bindings inside typeof expressions during ingest.
173+
Typeof(Box<'a, TypeofExpr<'a>>),
174+
/// Void expression (void expr).
175+
/// Used to preserve pipe bindings inside void expressions during ingest.
176+
Void(Box<'a, VoidExpr<'a>>),
165177
}
166178

167179
impl<'a> IrExpression<'a> {
@@ -222,6 +234,14 @@ impl<'a> IrExpression<'a> {
222234
IrExpression::LiteralArray(_) => ExpressionKind::LiteralArray,
223235
// LiteralMap is an object literal with IR expression values
224236
IrExpression::LiteralMap(_) => ExpressionKind::LiteralMap,
237+
// Not is a logical NOT expression
238+
IrExpression::Not(_) => ExpressionKind::Not,
239+
// Unary is a unary operator expression (+/-)
240+
IrExpression::Unary(_) => ExpressionKind::Unary,
241+
// Typeof is a typeof expression
242+
IrExpression::Typeof(_) => ExpressionKind::Typeof,
243+
// Void is a void expression
244+
IrExpression::Void(_) => ExpressionKind::Void,
225245
}
226246
}
227247
}
@@ -656,6 +676,35 @@ impl<'a> IrExpression<'a> {
656676
allocator,
657677
))
658678
}
679+
IrExpression::Not(e) => IrExpression::Not(Box::new_in(
680+
NotExpr {
681+
expr: Box::new_in(e.expr.clone_in(allocator), allocator),
682+
source_span: e.source_span,
683+
},
684+
allocator,
685+
)),
686+
IrExpression::Unary(e) => IrExpression::Unary(Box::new_in(
687+
UnaryExpr {
688+
operator: e.operator,
689+
expr: Box::new_in(e.expr.clone_in(allocator), allocator),
690+
source_span: e.source_span,
691+
},
692+
allocator,
693+
)),
694+
IrExpression::Typeof(e) => IrExpression::Typeof(Box::new_in(
695+
TypeofExpr {
696+
expr: Box::new_in(e.expr.clone_in(allocator), allocator),
697+
source_span: e.source_span,
698+
},
699+
allocator,
700+
)),
701+
IrExpression::Void(e) => IrExpression::Void(Box::new_in(
702+
VoidExpr {
703+
expr: Box::new_in(e.expr.clone_in(allocator), allocator),
704+
source_span: e.source_span,
705+
},
706+
allocator,
707+
)),
659708
}
660709
}
661710
}
@@ -1238,6 +1287,61 @@ pub enum IrBinaryOperator {
12381287
NullishCoalesceAssignment,
12391288
}
12401289

1290+
/// Unary operators for IR expressions.
1291+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1292+
pub enum IrUnaryOperator {
1293+
/// Unary plus (+)
1294+
Plus,
1295+
/// Unary minus (-)
1296+
Minus,
1297+
}
1298+
1299+
/// Logical NOT expression (!expr).
1300+
///
1301+
/// Used to preserve pipe bindings inside negation expressions like `!(x | async)`.
1302+
#[derive(Debug)]
1303+
pub struct NotExpr<'a> {
1304+
/// The operand expression.
1305+
pub expr: Box<'a, IrExpression<'a>>,
1306+
/// Source span.
1307+
pub source_span: Option<Span>,
1308+
}
1309+
1310+
/// Unary operator expression (+expr or -expr).
1311+
///
1312+
/// Used to preserve pipe bindings inside unary expressions like `+(x | pipe)`.
1313+
#[derive(Debug)]
1314+
pub struct UnaryExpr<'a> {
1315+
/// The unary operator.
1316+
pub operator: IrUnaryOperator,
1317+
/// The operand expression.
1318+
pub expr: Box<'a, IrExpression<'a>>,
1319+
/// Source span.
1320+
pub source_span: Option<Span>,
1321+
}
1322+
1323+
/// Typeof expression (typeof expr).
1324+
///
1325+
/// Used to preserve pipe bindings inside typeof expressions.
1326+
#[derive(Debug)]
1327+
pub struct TypeofExpr<'a> {
1328+
/// The operand expression.
1329+
pub expr: Box<'a, IrExpression<'a>>,
1330+
/// Source span.
1331+
pub source_span: Option<Span>,
1332+
}
1333+
1334+
/// Void expression (void expr).
1335+
///
1336+
/// Used to preserve pipe bindings inside void expressions.
1337+
#[derive(Debug)]
1338+
pub struct VoidExpr<'a> {
1339+
/// The operand expression.
1340+
pub expr: Box<'a, IrExpression<'a>>,
1341+
/// Source span.
1342+
pub source_span: Option<Span>,
1343+
}
1344+
12411345
// ============================================================================
12421346
// Expression Transformation
12431347
// ============================================================================
@@ -1372,6 +1476,18 @@ pub fn transform_expressions_in_expression<'a, F>(
13721476
transform_expressions_in_expression(&mut e.true_expr, transform, flags);
13731477
transform_expressions_in_expression(&mut e.false_expr, transform, flags);
13741478
}
1479+
IrExpression::Not(e) => {
1480+
transform_expressions_in_expression(&mut e.expr, transform, flags);
1481+
}
1482+
IrExpression::Unary(e) => {
1483+
transform_expressions_in_expression(&mut e.expr, transform, flags);
1484+
}
1485+
IrExpression::Typeof(e) => {
1486+
transform_expressions_in_expression(&mut e.expr, transform, flags);
1487+
}
1488+
IrExpression::Void(e) => {
1489+
transform_expressions_in_expression(&mut e.expr, transform, flags);
1490+
}
13751491
// These expressions have no internal expressions
13761492
IrExpression::LexicalRead(_)
13771493
| IrExpression::Reference(_)
@@ -1525,6 +1641,18 @@ pub fn visit_expressions_in_expression<'a, F>(
15251641
visit_expressions_in_expression(&e.true_expr, visitor, flags);
15261642
visit_expressions_in_expression(&e.false_expr, visitor, flags);
15271643
}
1644+
IrExpression::Not(e) => {
1645+
visit_expressions_in_expression(&e.expr, visitor, flags);
1646+
}
1647+
IrExpression::Unary(e) => {
1648+
visit_expressions_in_expression(&e.expr, visitor, flags);
1649+
}
1650+
IrExpression::Typeof(e) => {
1651+
visit_expressions_in_expression(&e.expr, visitor, flags);
1652+
}
1653+
IrExpression::Void(e) => {
1654+
visit_expressions_in_expression(&e.expr, visitor, flags);
1655+
}
15281656
// These expressions have no internal expressions
15291657
IrExpression::LexicalRead(_)
15301658
| IrExpression::Reference(_)
@@ -2504,6 +2632,18 @@ pub fn vars_used_by_ir_expression(expr: &IrExpression<'_>) -> u32 {
25042632
+ vars_used_by_ir_expression(&ternary.false_expr)
25052633
}
25062634

2635+
// Not expression: vars used by inner expression
2636+
IrExpression::Not(not) => vars_used_by_ir_expression(&not.expr),
2637+
2638+
// Unary expression: vars used by inner expression
2639+
IrExpression::Unary(unary) => vars_used_by_ir_expression(&unary.expr),
2640+
2641+
// Typeof expression: vars used by inner expression
2642+
IrExpression::Typeof(typeof_expr) => vars_used_by_ir_expression(&typeof_expr.expr),
2643+
2644+
// Void expression: vars used by inner expression
2645+
IrExpression::Void(void_expr) => vars_used_by_ir_expression(&void_expr.expr),
2646+
25072647
// All other expressions don't directly consume variable slots
25082648
IrExpression::LexicalRead(_)
25092649
| IrExpression::Reference(_)

crates/oxc_angular_compiler/src/parser/html/lexer.rs

Lines changed: 47 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1759,27 +1759,32 @@ impl<'a> HtmlLexer<'a> {
17591759
self.skip_whitespace();
17601760

17611761
if close_tag_name == tag_name && self.peek() == '>' {
1762-
// Found the closing tag - emit any accumulated content first
1762+
// Found the closing tag - emit any accumulated content first (if non-empty)
17631763
if consume_entities {
1764-
// Emit remaining text (may be empty)
1765-
let text = &self.input[text_start as usize..saved_index as usize];
1766-
let normalized = normalize_line_endings(text);
1767-
self.tokens.push(HtmlToken::with_part(
1768-
token_type,
1769-
&normalized,
1770-
text_start,
1771-
saved_index,
1772-
));
1764+
// Only emit text token if there is actual content
1765+
if text_start < saved_index {
1766+
let text = &self.input[text_start as usize..saved_index as usize];
1767+
let normalized = normalize_line_endings(text);
1768+
self.tokens.push(HtmlToken::with_part(
1769+
token_type,
1770+
&normalized,
1771+
text_start,
1772+
saved_index,
1773+
));
1774+
}
17731775
} else {
1774-
// For raw text, emit the whole content
1775-
let content = &self.input[content_start as usize..saved_index as usize];
1776-
let normalized = normalize_line_endings(content);
1777-
self.tokens.push(HtmlToken::with_part(
1778-
token_type,
1779-
&normalized,
1780-
content_start,
1781-
saved_index,
1782-
));
1776+
// For raw text, only emit if there is actual content
1777+
if content_start < saved_index {
1778+
let content =
1779+
&self.input[content_start as usize..saved_index as usize];
1780+
let normalized = normalize_line_endings(content);
1781+
self.tokens.push(HtmlToken::with_part(
1782+
token_type,
1783+
&normalized,
1784+
content_start,
1785+
saved_index,
1786+
));
1787+
}
17831788
}
17841789

17851790
// Emit the closing tag
@@ -1801,17 +1806,19 @@ impl<'a> HtmlLexer<'a> {
18011806
}
18021807

18031808
if self.peek() == chars::EOF {
1804-
// End of input - emit what we have
1809+
// End of input - emit what we have (if non-empty)
18051810
if consume_entities {
1806-
let text = &self.input[text_start as usize..self.index as usize];
1807-
let normalized = normalize_line_endings(text);
1808-
self.tokens.push(HtmlToken::with_part(
1809-
token_type,
1810-
&normalized,
1811-
text_start,
1812-
self.index,
1813-
));
1814-
} else {
1811+
if text_start < self.index {
1812+
let text = &self.input[text_start as usize..self.index as usize];
1813+
let normalized = normalize_line_endings(text);
1814+
self.tokens.push(HtmlToken::with_part(
1815+
token_type,
1816+
&normalized,
1817+
text_start,
1818+
self.index,
1819+
));
1820+
}
1821+
} else if content_start < self.index {
18151822
let content = &self.input[content_start as usize..self.index as usize];
18161823
let normalized = normalize_line_endings(content);
18171824
self.tokens.push(HtmlToken::with_part(
@@ -1826,15 +1833,17 @@ impl<'a> HtmlLexer<'a> {
18261833

18271834
// Handle entities for escapable raw text
18281835
if consume_entities && self.peek() == '&' {
1829-
// Emit any accumulated text before entity (may be empty)
1830-
let text = &self.input[text_start as usize..self.index as usize];
1831-
let normalized = normalize_line_endings(text);
1832-
self.tokens.push(HtmlToken::with_part(
1833-
token_type,
1834-
&normalized,
1835-
text_start,
1836-
self.index,
1837-
));
1836+
// Emit any accumulated text before entity (if non-empty)
1837+
if text_start < self.index {
1838+
let text = &self.input[text_start as usize..self.index as usize];
1839+
let normalized = normalize_line_endings(text);
1840+
self.tokens.push(HtmlToken::with_part(
1841+
token_type,
1842+
&normalized,
1843+
text_start,
1844+
self.index,
1845+
));
1846+
}
18381847

18391848
// Try to scan entity
18401849
if self.scan_entity() {

crates/oxc_angular_compiler/src/pipeline/emit.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,6 +1123,60 @@ fn convert_pure_function_body<'a>(
11231123
allocator,
11241124
))
11251125
}
1126+
1127+
// Not expression: convert operand and wrap in NOT
1128+
IrExpression::Not(not_expr) => {
1129+
let inner = convert_pure_function_body(allocator, &not_expr.expr, params);
1130+
OutputExpression::Not(Box::new_in(
1131+
crate::output::ast::NotExpr {
1132+
condition: Box::new_in(inner, allocator),
1133+
source_span: None,
1134+
},
1135+
allocator,
1136+
))
1137+
}
1138+
1139+
// Unary expression: convert operand and wrap in unary operator
1140+
IrExpression::Unary(unary) => {
1141+
let inner = convert_pure_function_body(allocator, &unary.expr, params);
1142+
let operator = match unary.operator {
1143+
crate::ir::expression::IrUnaryOperator::Plus => UnaryOperator::Plus,
1144+
crate::ir::expression::IrUnaryOperator::Minus => UnaryOperator::Minus,
1145+
};
1146+
OutputExpression::UnaryOperator(Box::new_in(
1147+
UnaryOperatorExpr {
1148+
operator,
1149+
expr: Box::new_in(inner, allocator),
1150+
parens: false,
1151+
source_span: None,
1152+
},
1153+
allocator,
1154+
))
1155+
}
1156+
1157+
// Typeof expression: convert operand and wrap in typeof
1158+
IrExpression::Typeof(typeof_expr) => {
1159+
let inner = convert_pure_function_body(allocator, &typeof_expr.expr, params);
1160+
OutputExpression::Typeof(Box::new_in(
1161+
crate::output::ast::TypeofExpr {
1162+
expr: Box::new_in(inner, allocator),
1163+
source_span: None,
1164+
},
1165+
allocator,
1166+
))
1167+
}
1168+
1169+
// Void expression: convert operand and wrap in void
1170+
IrExpression::Void(void_expr) => {
1171+
let inner = convert_pure_function_body(allocator, &void_expr.expr, params);
1172+
OutputExpression::Void(Box::new_in(
1173+
crate::output::ast::VoidExpr {
1174+
expr: Box::new_in(inner, allocator),
1175+
source_span: None,
1176+
},
1177+
allocator,
1178+
))
1179+
}
11261180
}
11271181
}
11281182

0 commit comments

Comments
 (0)