Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/oxc_angular_compiler/angular
Submodule angular updated 177 files
Original file line number Diff line number Diff line change
Expand Up @@ -760,15 +760,29 @@ pub fn collect_element_consts(job: &mut ComponentCompilationJob<'_>) {
// Second pass (2b): Assign const indices in collected order
// This is where we actually call add_const, matching Angular's getConstIndex call order
let mut element_const_indices: FxHashMap<XrefId, u32> = FxHashMap::default();
let mut projection_attrs: FxHashMap<XrefId, OutputExpression<'_>> = FxHashMap::default();
let mut projection_attrs: FxHashMap<XrefId, Ident<'_>> = FxHashMap::default();

for xref_item in &xrefs_to_assign {
match xref_item {
XrefToAssign::Projection(xref) => {
if let Some(attrs) = all_element_attrs.get(xref) {
if !attrs.is_empty() {
let attr_array = serialize_attributes_to_array_expr(allocator, attrs);
projection_attrs.insert(*xref, attr_array);
// Angular v22 (rc.3+) pools projection attributes into the
// shared const pool (`_cN`) instead of emitting them inline,
// matching `getConstLiteral(attrArray, true)` in Angular's
// const_collection.ts (angular/angular@2891f7e). This phase
// runs after `generate_projection_def`, so the projectionDef
// and ngContentSelectors consts are pooled first and the
// projection attrs land at the next `_cN`, as in the goldens.
let pooled = job.pool.get_const_literal(attr_array, true);
Comment thread
brandonroberts marked this conversation as resolved.
let pooled_name = match pooled {
OutputExpression::ReadVar(rv) => rv.name.clone(),
_ => unreachable!(
"ConstantPool::get_const_literal must return OutputExpression::ReadVar"
),
};
projection_attrs.insert(*xref, pooled_name);
}
}
}
Expand All @@ -794,8 +808,17 @@ pub fn collect_element_consts(job: &mut ComponentCompilationJob<'_>) {
for op in view.create.iter_mut() {
match op {
CreateOp::Projection(proj) => {
if let Some(attrs) = projection_attrs.remove(&proj.xref) {
proj.attributes = Some(attrs);
// It's possible for multiple projection ops to reference the same xref
// (e.g. across conditional branches). Avoid consuming the pooled attrs so
// every matching projection op receives the same const reference.
if let Some(pooled_name) = projection_attrs.get(&proj.xref) {
proj.attributes = Some(OutputExpression::ReadVar(Box::new_in(
crate::output::ast::ReadVarExpr {
name: pooled_name.clone(),
source_span: None,
},
allocator,
)));
}
}
CreateOp::ElementStart(elem) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ source: crates/oxc_angular_compiler/tests/integration_test.rs
expression: js
---
const _c0 = ["*"];
const _c1 = ["[select]","'[slot=expanded-content]'"];
function TestComponent_Template(rf,ctx) {
if ((rf & 1)) {
i0.ɵɵprojectionDef();
i0.ɵɵprojection(0,0,["[select]","'[slot=expanded-content]'"]);
i0.ɵɵprojection(0,0,_c1);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ source: crates/oxc_angular_compiler/tests/integration_test.rs
expression: js
---
const _c0 = ["*"];
const _c1 = ["ngProjectAs","bit-label",5,["bit-label"]];
function TestComponent_Template(rf,ctx) {
if ((rf & 1)) {
i0.ɵɵprojectionDef();
i0.ɵɵprojection(0,0,["ngProjectAs","bit-label",5,["bit-label"]]);
i0.ɵɵprojection(0,0,_c1);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ source: crates/oxc_angular_compiler/tests/integration_test.rs
expression: js
---
const _c0 = ["*"];
const _c1 = ["ngProjectAs","[card-content]",5,["","card-content",""]];
function TestComponent_Template(rf,ctx) {
if ((rf & 1)) {
i0.ɵɵprojectionDef();
i0.ɵɵprojection(0,0,["ngProjectAs","[card-content]",5,["","card-content",""]]);
i0.ɵɵprojection(0,0,_c1);
}
}
Loading