@@ -18,7 +18,7 @@ use rustc_hash::FxHashMap;
1818use super :: cross_file_elision:: CrossFileAnalyzer ;
1919use super :: decorator:: {
2020 collect_constructor_decorator_spans, collect_member_decorator_spans,
21- collect_uninitialized_field_spans , extract_component_metadata, find_component_decorator_span,
21+ extract_component_metadata, find_component_decorator_span,
2222} ;
2323use super :: definition:: { const_value_to_expression, generate_component_definitions} ;
2424use super :: import_elision:: { ImportElisionAnalyzer , filter_imports} ;
@@ -121,28 +121,6 @@ pub struct TransformOptions {
121121 /// Contains property bindings, attribute bindings, and event listeners.
122122 pub host : Option < HostMetadataInput > ,
123123
124- /// Use ES2022 class field semantics for static field emission.
125- ///
126- /// When `true` (default), emits static fields inside the class body:
127- /// ```js
128- /// class MyComponent {
129- /// static ɵfac = ...;
130- /// static ɵcmp = ...;
131- /// }
132- /// ```
133- ///
134- /// When `false`, emits static fields as external property assignments:
135- /// ```js
136- /// class MyComponent { }
137- /// MyComponent.ɵfac = ...;
138- /// MyComponent.ɵcmp = ...;
139- /// ```
140- ///
141- /// This corresponds to TypeScript's `useDefineForClassFields` compiler option.
142- /// Projects targeting older browsers or using `useDefineForClassFields: false`
143- /// should set this to `false` for compatibility.
144- pub use_define_for_class_fields : bool ,
145-
146124 /// Enable cross-file import elision analysis.
147125 ///
148126 /// When true, resolves imports to source files to check if exports are type-only.
@@ -225,7 +203,6 @@ impl Default for TransformOptions {
225203 change_detection : None ,
226204 preserve_whitespaces : None ,
227205 host : None ,
228- use_define_for_class_fields : true , // ES2022 style by default
229206 // Cross-file elision options (feature-gated)
230207 #[ cfg( feature = "cross_file_elision" ) ]
231208 cross_file_elision : false ,
@@ -755,23 +732,12 @@ pub fn transform_angular_file(
755732 // Order: ɵfac BEFORE ɵcmp (Angular convention).
756733 // External declarations (child view functions, constants) go BEFORE the class.
757734 // Note: The /*@__PURE__*/ annotation is already included in cmp_js by the emitter.
758- let property_assignments = if options. use_define_for_class_fields {
759- // ES2022 style: static fields INSIDE the class body
760- format ! (
761- "static ɵfac = {};\n static ɵcmp = {};" ,
762- compilation_result. fac_js,
763- compilation_result. cmp_js
764- )
765- } else {
766- // ES5 style: external property assignments AFTER the class
767- format ! (
768- "{}.ɵfac = {};\n {}.ɵcmp = {};" ,
769- class_name,
770- compilation_result. fac_js,
771- class_name,
772- compilation_result. cmp_js
773- )
774- } ;
735+ // ES2022 style: static fields INSIDE the class body
736+ let property_assignments = format ! (
737+ "static ɵfac = {};\n static ɵcmp = {};" ,
738+ compilation_result. fac_js,
739+ compilation_result. cmp_js
740+ ) ;
775741
776742 // External declarations and HMR code go after the class
777743 let mut external_decls = compilation_result. declarations_js . clone ( ) ;
@@ -840,23 +806,12 @@ pub fn transform_angular_file(
840806 let emitter = JsEmitter :: new ( ) ;
841807 let class_name = directive_metadata. name . to_string ( ) ;
842808 // Order: ɵfac BEFORE ɵdir (Angular convention)
843- let property_assignments = if options. use_define_for_class_fields {
844- // ES2022 style: static fields INSIDE the class body
845- format ! (
846- "static ɵfac = {};\n static ɵdir = {};" ,
847- emitter. emit_expression( & definitions. fac_definition) ,
848- emitter. emit_expression( & definitions. dir_definition)
849- )
850- } else {
851- // ES5 style: external property assignments AFTER the class
852- format ! (
853- "{}.ɵfac = {};\n {}.ɵdir = {};" ,
854- class_name,
855- emitter. emit_expression( & definitions. fac_definition) ,
856- class_name,
857- emitter. emit_expression( & definitions. dir_definition)
858- )
859- } ;
809+ // ES2022 style: static fields INSIDE the class body
810+ let property_assignments = format ! (
811+ "static ɵfac = {};\n static ɵdir = {};" ,
812+ emitter. emit_expression( & definitions. fac_definition) ,
813+ emitter. emit_expression( & definitions. dir_definition)
814+ ) ;
860815
861816 // Track definitions by class name (position is recalculated later)
862817 class_definitions. insert ( class_name, ( property_assignments, String :: new ( ) ) ) ;
@@ -888,23 +843,12 @@ pub fn transform_angular_file(
888843 // Emit both ɵfac and ɵprov definitions.
889844 // IMPORTANT: ɵfac must come BEFORE ɵprov because ɵprov's factory
890845 // property references MyClass.ɵfac, which must already be defined.
891- let property_assignments = if options. use_define_for_class_fields {
892- // ES2022 style: static fields INSIDE the class body
893- format ! (
894- "static ɵfac = {};\n static ɵprov = {};" ,
895- emitter. emit_expression( & definition. fac_definition) ,
896- emitter. emit_expression( & definition. prov_definition)
897- )
898- } else {
899- // ES5 style: external property assignments AFTER the class
900- format ! (
901- "{}.ɵfac = {};\n {}.ɵprov = {};" ,
902- class_name,
903- emitter. emit_expression( & definition. fac_definition) ,
904- class_name,
905- emitter. emit_expression( & definition. prov_definition)
906- )
907- } ;
846+ // ES2022 style: static fields INSIDE the class body
847+ let property_assignments = format ! (
848+ "static ɵfac = {};\n static ɵprov = {};" ,
849+ emitter. emit_expression( & definition. fac_definition) ,
850+ emitter. emit_expression( & definition. prov_definition)
851+ ) ;
908852
909853 // Track definitions by class name (position is recalculated later)
910854 class_definitions. insert ( class_name, ( property_assignments, String :: new ( ) ) ) ;
@@ -933,23 +877,12 @@ pub fn transform_angular_file(
933877 let emitter = JsEmitter :: new ( ) ;
934878 let class_name = pipe_metadata. class_name . to_string ( ) ;
935879 // Order: ɵfac BEFORE ɵpipe (Angular convention)
936- let property_assignments = if options. use_define_for_class_fields {
937- // ES2022 style: static fields INSIDE the class body
938- format ! (
939- "static ɵfac = {};\n static ɵpipe = {};" ,
940- emitter. emit_expression( & definition. fac_definition) ,
941- emitter. emit_expression( & definition. pipe_definition)
942- )
943- } else {
944- // ES5 style: external property assignments AFTER the class
945- format ! (
946- "{}.ɵfac = {};\n {}.ɵpipe = {};" ,
947- class_name,
948- emitter. emit_expression( & definition. fac_definition) ,
949- class_name,
950- emitter. emit_expression( & definition. pipe_definition)
951- )
952- } ;
880+ // ES2022 style: static fields INSIDE the class body
881+ let property_assignments = format ! (
882+ "static ɵfac = {};\n static ɵpipe = {};" ,
883+ emitter. emit_expression( & definition. fac_definition) ,
884+ emitter. emit_expression( & definition. pipe_definition)
885+ ) ;
953886
954887 // Track definitions by class name (position is recalculated later)
955888 class_definitions. insert ( class_name, ( property_assignments, String :: new ( ) ) ) ;
@@ -980,26 +913,13 @@ pub fn transform_angular_file(
980913
981914 // Generate static field definitions
982915 // Order: ɵfac BEFORE ɵmod BEFORE ɵinj (Angular convention)
983- let property_assignments = if options. use_define_for_class_fields {
984- // ES2022 style: static fields INSIDE the class body
985- format ! (
986- "static ɵfac = {};\n static ɵmod = {};\n static ɵinj = {};" ,
987- emitter. emit_expression( & definition. fac_definition) ,
988- emitter. emit_expression( & definition. mod_definition) ,
989- emitter. emit_expression( & definition. inj_definition)
990- )
991- } else {
992- // ES5 style: external property assignments AFTER the class
993- format ! (
994- "{}.ɵfac = {};\n {}.ɵmod = {};\n {}.ɵinj = {};" ,
995- class_name,
996- emitter. emit_expression( & definition. fac_definition) ,
997- class_name,
998- emitter. emit_expression( & definition. mod_definition) ,
999- class_name,
1000- emitter. emit_expression( & definition. inj_definition)
1001- )
1002- } ;
916+ // ES2022 style: static fields INSIDE the class body
917+ let property_assignments = format ! (
918+ "static ɵfac = {};\n static ɵmod = {};\n static ɵinj = {};" ,
919+ emitter. emit_expression( & definition. fac_definition) ,
920+ emitter. emit_expression( & definition. mod_definition) ,
921+ emitter. emit_expression( & definition. inj_definition)
922+ ) ;
1003923
1004924 // Collect any side-effect statements as external declarations
1005925 let mut external_decls = String :: new ( ) ;
@@ -1019,27 +939,6 @@ pub fn transform_angular_file(
1019939 }
1020940 }
1021941
1022- // Collect uninitialized field spans from ALL classes (including non-Angular-decorated ones).
1023- // TypeScript strips field declarations like `name: string;` (without initializers) because
1024- // they're type-only annotations with no runtime effect.
1025- for stmt in & parser_ret. program . body {
1026- let class = match stmt {
1027- Statement :: ClassDeclaration ( class) => Some ( class. as_ref ( ) ) ,
1028- Statement :: ExportDefaultDeclaration ( export) => match & export. declaration {
1029- ExportDefaultDeclarationKind :: ClassDeclaration ( class) => Some ( class. as_ref ( ) ) ,
1030- _ => None ,
1031- } ,
1032- Statement :: ExportNamedDeclaration ( export) => match & export. declaration {
1033- Some ( Declaration :: ClassDeclaration ( class) ) => Some ( class. as_ref ( ) ) ,
1034- _ => None ,
1035- } ,
1036- _ => None ,
1037- } ;
1038- if let Some ( class) = class {
1039- collect_uninitialized_field_spans ( class, & mut decorator_spans_to_remove) ;
1040- }
1041- }
1042-
1043942 // 5. Generate output code by modifying the original source
1044943 // We use string manipulation instead of oxc_codegen to preserve
1045944 // the original code structure and avoid decorator placement issues.
@@ -1070,9 +969,6 @@ pub fn transform_angular_file(
1070969 _ => None ,
1071970 } ;
1072971 if let Some ( class) = class {
1073- // Collect uninitialized field spans for ALL classes (TypeScript stripping)
1074- collect_uninitialized_field_spans ( class, & mut new_decorator_spans) ;
1075-
1076972 // Check for component, directive, injectable, pipe, or ngmodule decorators
1077973 // and collect associated parameter/member decorator spans
1078974 if let Some ( span) = find_component_decorator_span ( class) {
@@ -1228,30 +1124,16 @@ pub fn transform_angular_file(
12281124
12291125 for ( class_name, class_start, class_body_end) in class_positions {
12301126 if let Some ( ( property_assignments, external_decls) ) = class_definitions. get ( & class_name) {
1231- if options. use_define_for_class_fields {
1232- // ES2022 style: Property assignments go INSIDE the class body as static fields
1233- // class_body_end points right after the `}`, so we insert at position - 1 (before the `}`)
1234- let insert_pos = ( class_body_end - 1 ) as usize ;
1127+ // ES2022 style: Property assignments go INSIDE the class body as static fields
1128+ // class_body_end points right after the `}`, so we insert at position - 1 (before the `}`)
1129+ let insert_pos = ( class_body_end - 1 ) as usize ;
12351130
1236- // Build the insertion string: static fields go inside the class body
1237- let insertion = format ! ( "\n {}\n " , property_assignments) ;
1131+ // Build the insertion string: static fields go inside the class body
1132+ let insertion = format ! ( "\n {}\n " , property_assignments) ;
12381133
1239- // Insert static fields before the closing brace
1240- if insert_pos <= final_code. len ( ) {
1241- final_code. insert_str ( insert_pos, & insertion) ;
1242- }
1243- } else {
1244- // ES5 style: Property assignments go AFTER the class as external assignments
1245- // class_body_end points right after the `}`, so we insert there
1246- let insert_pos = class_body_end as usize ;
1247-
1248- // Build the insertion string: external assignments after the class
1249- let insertion = format ! ( "\n {}" , property_assignments) ;
1250-
1251- // Insert after the class closing brace
1252- if insert_pos <= final_code. len ( ) {
1253- final_code. insert_str ( insert_pos, & insertion) ;
1254- }
1134+ // Insert static fields before the closing brace
1135+ if insert_pos <= final_code. len ( ) {
1136+ final_code. insert_str ( insert_pos, & insertion) ;
12551137 }
12561138
12571139 // External declarations (constants, child views) go BEFORE the class
0 commit comments