Skip to content

Commit 8bb6930

Browse files
ashh640claude
authored andcommitted
1 parent b3d139a commit 8bb6930

2 files changed

Lines changed: 93 additions & 32 deletions

File tree

crates/oxc_angular_compiler/src/component/transform.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -882,8 +882,7 @@ fn extract_all_jit_member_decorators(
882882
use oxc_ast::ast::{ClassElement, MethodDefinitionKind, PropertyKey};
883883

884884
let mut angular_members: std::vec::Vec<JitMemberDecorator> = std::vec::Vec::new();
885-
let mut non_angular_members: std::vec::Vec<JitNonAngularMemberDecorator> =
886-
std::vec::Vec::new();
885+
let mut non_angular_members: std::vec::Vec<JitNonAngularMemberDecorator> = std::vec::Vec::new();
887886

888887
for element in &class.body.body {
889888
let (member_name, is_static, is_property, decorators) = match element {

crates/oxc_angular_compiler/tests/integration_test.rs

Lines changed: 92 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6537,14 +6537,17 @@ export class TodoState {
65376537

65386538
// No raw decorators should remain anywhere
65396539
assert!(
6540-
!result.code.contains("@State") && !result.code.contains("@Injectable")
6541-
&& !result.code.contains("@Selector") && !result.code.contains("@Action"),
6540+
!result.code.contains("@State")
6541+
&& !result.code.contains("@Injectable")
6542+
&& !result.code.contains("@Selector")
6543+
&& !result.code.contains("@Action"),
65426544
"No raw decorator syntax should remain in output. Got:\n{}",
65436545
result.code
65446546
);
65456547

65466548
// Member __decorate calls should come before class __decorate
6547-
let selector_decorate = result.code.find("__decorate([Selector()], TodoState, \"todos\"").unwrap();
6549+
let selector_decorate =
6550+
result.code.find("__decorate([Selector()], TodoState, \"todos\"").unwrap();
65486551
let class_decorate = result.code.find("TodoState = __decorate(").unwrap();
65496552
assert!(
65506553
selector_decorate < class_decorate,
@@ -6631,8 +6634,10 @@ export class FieldDirective {
66316634

66326635
// No raw decorators should remain
66336636
assert!(
6634-
!result.code.contains("@Required") && !result.code.contains("@Input")
6635-
&& !result.code.contains("@Throttle") && !result.code.contains("@Output"),
6637+
!result.code.contains("@Required")
6638+
&& !result.code.contains("@Input")
6639+
&& !result.code.contains("@Throttle")
6640+
&& !result.code.contains("@Output"),
66366641
"No raw decorator syntax should remain. Got:\n{}",
66376642
result.code
66386643
);
@@ -6656,17 +6661,23 @@ export class FieldDirective {
66566661

66576662
// Non-Angular decorators should be lowered via __decorate()
66586663
assert!(
6659-
result.code.contains("__decorate([Required()], FieldDirective.prototype, \"value\", void 0)"),
6664+
result
6665+
.code
6666+
.contains("__decorate([Required()], FieldDirective.prototype, \"value\", void 0)"),
66606667
"Non-Angular property decorator should use __decorate with void 0. Got:\n{}",
66616668
result.code
66626669
);
66636670
assert!(
6664-
result.code.contains("__decorate([Throttle(300)], FieldDirective.prototype, \"valueChange\", void 0)"),
6671+
result.code.contains(
6672+
"__decorate([Throttle(300)], FieldDirective.prototype, \"valueChange\", void 0)"
6673+
),
66656674
"Non-Angular property decorator should use __decorate with void 0. Got:\n{}",
66666675
result.code
66676676
);
66686677
assert!(
6669-
result.code.contains("__decorate([Throttle(100)], FieldDirective.prototype, \"onChange\", null)"),
6678+
result
6679+
.code
6680+
.contains("__decorate([Throttle(100)], FieldDirective.prototype, \"onChange\", null)"),
66706681
"Non-Angular method decorator should use __decorate with null. Got:\n{}",
66716682
result.code
66726683
);
@@ -6704,14 +6715,18 @@ export class MyService {
67046715

67056716
// Multiple decorators on method should be in single __decorate call, in source order
67066717
assert!(
6707-
result.code.contains("__decorate([Log(), Memoize()], MyService.prototype, \"compute\", null)"),
6718+
result
6719+
.code
6720+
.contains("__decorate([Log(), Memoize()], MyService.prototype, \"compute\", null)"),
67086721
"Multiple method decorators should be in one __decorate call. Got:\n{}",
67096722
result.code
67106723
);
67116724

67126725
// Multiple decorators on property should also be in single __decorate call
67136726
assert!(
6714-
result.code.contains("__decorate([Validate(), Log()], MyService.prototype, \"name\", void 0)"),
6727+
result
6728+
.code
6729+
.contains("__decorate([Validate(), Log()], MyService.prototype, \"name\", void 0)"),
67156730
"Multiple property decorators should be in one __decorate call. Got:\n{}",
67166731
result.code
67176732
);
@@ -6770,7 +6785,8 @@ export class FooService {
67706785

67716786
// No raw decorators
67726787
assert!(
6773-
!result.code.contains("@Component") && !result.code.contains("@Injectable")
6788+
!result.code.contains("@Component")
6789+
&& !result.code.contains("@Injectable")
67746790
&& !result.code.contains("@Logger"),
67756791
"No raw decorator syntax should remain. Got:\n{}",
67766792
result.code
@@ -6859,7 +6875,9 @@ class InternalService {
68596875

68606876
// Member decorator should be lowered
68616877
assert!(
6862-
result.code.contains("__decorate([Singleton()], InternalService.prototype, \"getInstance\", null)"),
6878+
result.code.contains(
6879+
"__decorate([Singleton()], InternalService.prototype, \"getInstance\", null)"
6880+
),
68636881
"Member decorator should be lowered. Got:\n{}",
68646882
result.code
68656883
);
@@ -6949,7 +6967,8 @@ export class FieldDirective {
69496967

69506968
// No raw decorators
69516969
assert!(
6952-
!result.code.contains("@Validate") && !result.code.contains("@Input")
6970+
!result.code.contains("@Validate")
6971+
&& !result.code.contains("@Input")
69536972
&& !result.code.contains("@Transform"),
69546973
"No raw decorator syntax should remain. Got:\n{}",
69556974
result.code
@@ -6962,7 +6981,9 @@ export class FieldDirective {
69626981
result.code
69636982
);
69646983
assert!(
6965-
result.code.contains("__decorate([Transform()], FieldDirective.prototype, \"computed\", null)"),
6984+
result
6985+
.code
6986+
.contains("__decorate([Transform()], FieldDirective.prototype, \"computed\", null)"),
69666987
"Getter decorator should use null (accessor). Got:\n{}",
69676988
result.code
69686989
);
@@ -7006,7 +7027,8 @@ export class TestService {
70067027

70077028
// No raw decorators should remain
70087029
assert!(
7009-
!result.code.contains("@Config") && !result.code.contains("@Injectable")
7030+
!result.code.contains("@Config")
7031+
&& !result.code.contains("@Injectable")
70107032
&& !result.code.contains("@Transform"),
70117033
"No raw decorator syntax should remain. Got:\n{}",
70127034
result.code
@@ -7077,7 +7099,9 @@ export class MyService {
70777099

70787100
// @Inject and @Optional should NOT appear in __decorate calls for members
70797101
// They are Angular decorators and should not be treated as non-Angular
7080-
let member_decorate_calls: Vec<&str> = result.code.lines()
7102+
let member_decorate_calls: Vec<&str> = result
7103+
.code
7104+
.lines()
70817105
.filter(|l| l.contains("__decorate(") && l.contains(".prototype"))
70827106
.collect();
70837107
for call in &member_decorate_calls {
@@ -7167,8 +7191,10 @@ class AnimalsState {
71677191

71687192
// No raw decorators
71697193
assert!(
7170-
!result.code.contains("@State") && !result.code.contains("@Injectable")
7171-
&& !result.code.contains("@Selector") && !result.code.contains("@Action"),
7194+
!result.code.contains("@State")
7195+
&& !result.code.contains("@Injectable")
7196+
&& !result.code.contains("@Selector")
7197+
&& !result.code.contains("@Action"),
71727198
"No raw decorator syntax should remain. Got:\n{}",
71737199
result.code
71747200
);
@@ -7374,30 +7400,66 @@ class MyService {
73747400
// myContent: [{ type: ContentChild, args: ['content',] }]
73757401
// };
73767402

7377-
assert!(result.code.contains("propDecorators"), "Should have propDecorators. Got:\n{}", result.code);
7403+
assert!(
7404+
result.code.contains("propDecorators"),
7405+
"Should have propDecorators. Got:\n{}",
7406+
result.code
7407+
);
73787408
assert!(result.code.contains("type: Input"), "propDecorators: Input. Got:\n{}", result.code);
73797409
assert!(result.code.contains("type: Output"), "propDecorators: Output. Got:\n{}", result.code);
7380-
assert!(result.code.contains("type: ViewChild, args: ['ref']"), "propDecorators: ViewChild. Got:\n{}", result.code);
7381-
assert!(result.code.contains("type: HostBinding, args: ['class.active']"), "propDecorators: HostBinding. Got:\n{}", result.code);
7382-
assert!(result.code.contains("type: HostListener, args: ['click', ['$event']]"), "propDecorators: HostListener. Got:\n{}", result.code);
7383-
assert!(result.code.contains("type: ContentChild, args: ['content']"), "propDecorators: ContentChild. Got:\n{}", result.code);
7410+
assert!(
7411+
result.code.contains("type: ViewChild, args: ['ref']"),
7412+
"propDecorators: ViewChild. Got:\n{}",
7413+
result.code
7414+
);
7415+
assert!(
7416+
result.code.contains("type: HostBinding, args: ['class.active']"),
7417+
"propDecorators: HostBinding. Got:\n{}",
7418+
result.code
7419+
);
7420+
assert!(
7421+
result.code.contains("type: HostListener, args: ['click', ['$event']]"),
7422+
"propDecorators: HostListener. Got:\n{}",
7423+
result.code
7424+
);
7425+
assert!(
7426+
result.code.contains("type: ContentChild, args: ['content']"),
7427+
"propDecorators: ContentChild. Got:\n{}",
7428+
result.code
7429+
);
73847430

73857431
// Angular reference: ctorParameters should contain constructor param types and decorators
73867432
// From full-compiled-output.js:
73877433
// static ctorParameters = () => [
73887434
// { type: String, decorators: [{ type: Inject, args: ['TOKEN',] }] },
73897435
// { type: undefined, decorators: [{ type: Optional }] }
73907436
// ];
7391-
assert!(result.code.contains("ctorParameters"), "Should have ctorParameters. Got:\n{}", result.code);
7392-
assert!(result.code.contains("type: Inject, args: ['TOKEN']"), "ctorParameters: Inject. Got:\n{}", result.code);
7393-
assert!(result.code.contains("type: Optional"), "ctorParameters: Optional. Got:\n{}", result.code);
7437+
assert!(
7438+
result.code.contains("ctorParameters"),
7439+
"Should have ctorParameters. Got:\n{}",
7440+
result.code
7441+
);
7442+
assert!(
7443+
result.code.contains("type: Inject, args: ['TOKEN']"),
7444+
"ctorParameters: Inject. Got:\n{}",
7445+
result.code
7446+
);
7447+
assert!(
7448+
result.code.contains("type: Optional"),
7449+
"ctorParameters: Optional. Got:\n{}",
7450+
result.code
7451+
);
73947452

73957453
// No raw Angular decorators should remain
73967454
assert!(
7397-
!result.code.contains("@Input") && !result.code.contains("@Output")
7398-
&& !result.code.contains("@ViewChild") && !result.code.contains("@HostBinding")
7399-
&& !result.code.contains("@HostListener") && !result.code.contains("@ContentChild")
7400-
&& !result.code.contains("@Inject") && !result.code.contains("@Optional"),
7455+
!result.code.contains("@Input")
7456+
&& !result.code.contains("@Output")
7457+
&& !result.code.contains("@ViewChild")
7458+
&& !result.code.contains("@HostBinding")
7459+
&& !result.code.contains("@HostListener")
7460+
&& !result.code.contains("@ContentChild")
7461+
&& !result.code.contains("@Inject")
7462+
&& !result.code.contains("@Optional"),
74017463
"No raw Angular decorator syntax should remain. Got:\n{}",
74027464
result.code
74037465
);

0 commit comments

Comments
 (0)