Skip to content
This repository has been archived by the owner on Aug 31, 2023. It is now read-only.

Commit

Permalink
feat(rome_js_parser): support property init in ambient context
Browse files Browse the repository at this point in the history
  • Loading branch information
Conaclos committed Feb 20, 2023
1 parent e88b826 commit 40f982f
Show file tree
Hide file tree
Showing 21 changed files with 869 additions and 126 deletions.
8 changes: 8 additions & 0 deletions crates/rome_js_factory/src/generated/node_factory.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion crates/rome_js_factory/src/generated/syntax_factory.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 33 additions & 9 deletions crates/rome_js_formatter/src/utils/assignment_like.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,8 +334,9 @@ impl AnyJsAssignmentLike {
// SAFETY: Calling `unwrap` here is safe because we check `has_only_left_hand_side` variant at the beginning of the `layout` function
n.value().unwrap().into()
}
AnyJsAssignmentLike::TsPropertySignatureClassMember(_) => {
unreachable!("TsPropertySignatureClassMember doesn't have any right side. If you're here, `has_only_left_hand_side` hasn't been called")
AnyJsAssignmentLike::TsPropertySignatureClassMember(n) => {
// SAFETY: Calling `unwrap` here is safe because we check `has_only_left_hand_side` variant at the beginning of the `layout` function
n.value().unwrap().into()
}
};

Expand Down Expand Up @@ -458,6 +459,7 @@ impl AnyJsAssignmentLike {
modifiers,
name,
property_annotation,
value: _,
semicolon_token: _,
} = property_signature_class_member.as_fields();

Expand Down Expand Up @@ -505,8 +507,13 @@ impl AnyJsAssignmentLike {
}
Ok(())
}
// this variant doesn't have any operator
AnyJsAssignmentLike::TsPropertySignatureClassMember(_) => Ok(()),
AnyJsAssignmentLike::TsPropertySignatureClassMember(property_class_member) => {
if let Some(initializer) = property_class_member.value() {
let eq_token = initializer.eq_token()?;
write!(f, [space(), eq_token.format()])?
}
Ok(())
}
}
}

Expand Down Expand Up @@ -572,8 +579,21 @@ impl AnyJsAssignmentLike {
}
Ok(())
}
// this variant doesn't have any right part
AnyJsAssignmentLike::TsPropertySignatureClassMember(_) => Ok(()),
AnyJsAssignmentLike::TsPropertySignatureClassMember(property_class_member) => {
if let Some(initializer) = property_class_member.value() {
let expression = initializer.expression()?;
write!(
f,
[
space(),
format_leading_comments(initializer.syntax()),
with_assignment_layout(&expression, Some(layout)),
format_trailing_comments(initializer.syntax())
]
)?;
}
Ok(())
}
}
}

Expand All @@ -583,12 +603,14 @@ impl AnyJsAssignmentLike {
AnyJsAssignmentLike::JsVariableDeclarator(variable_declarator) => {
variable_declarator.initializer()
}
AnyJsAssignmentLike::TsPropertySignatureClassMember(class_member) => {
class_member.value()
}

AnyJsAssignmentLike::JsPropertyObjectMember(_)
| AnyJsAssignmentLike::JsAssignmentExpression(_)
| AnyJsAssignmentLike::JsObjectAssignmentPatternProperty(_)
| AnyJsAssignmentLike::TsTypeAliasDeclaration(_)
| AnyJsAssignmentLike::TsPropertySignatureClassMember(_) => {
| AnyJsAssignmentLike::TsTypeAliasDeclaration(_) => {
unreachable!("These variants have no initializer")
}
};
Expand Down Expand Up @@ -698,8 +720,10 @@ impl AnyJsAssignmentLike {
declarator.initializer().is_none()
} else if let AnyJsAssignmentLike::JsPropertyClassMember(class_member) = self {
class_member.value().is_none()
} else if let AnyJsAssignmentLike::TsPropertySignatureClassMember(class_member) = self {
class_member.value().is_none()
} else {
matches!(self, AnyJsAssignmentLike::TsPropertySignatureClassMember(_))
false
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
declare class A {
readonly prop = "value"


}
class A {
declare readonly prop = "value__value__value__value__value__value__value__value__value__value__value__"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
source: crates/rome_formatter_test/src/snapshot_builder.rs
assertion_line: 212
info: ts/class/readonly_ambient_property.ts
---

# Input

```ts
declare class A {
readonly prop = "value"


}
class A {
declare readonly prop = "value__value__value__value__value__value__value__value__value__value__value__"
}
```


=============================

# Outputs

## Output 1

-----
Indent style: Tab
Line width: 80
Quote style: Double Quotes
Quote properties: As needed
Trailing comma: All
Semicolons: Always
-----

```ts
declare class A {
readonly prop = "value";
}
class A {
declare readonly prop = "value__value__value__value__value__value__value__value__value__value__value__";
}
```

# Lines exceeding max width of 80 characters
```
5: declare readonly prop = "value__value__value__value__value__value__value__value__value__value__value__";
```


34 changes: 26 additions & 8 deletions crates/rome_js_parser/src/syntax/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -901,7 +901,7 @@ fn parse_property_class_member_body(
member_marker: Marker,
modifiers: &ClassMemberModifiers,
) -> CompletedMarker {
parse_ts_property_annotation(p, modifiers).ok();
let annotation = parse_ts_property_annotation(p, modifiers).ok();

// test class_await_property_initializer
// // SCRIPT
Expand Down Expand Up @@ -945,13 +945,31 @@ fn parse_property_class_member_body(
initializer.range(p),
));
} else if modifiers.has(ModifierKind::Declare) || p.state().in_ambient_context() {
// test_err ts ts_property_initializer_ambient_context
// declare class A { prop = "test" }
// class B { declare prop = "test" }
p.error(p.err_builder(
"Initializers are not allowed in ambient contexts.",
initializer.range(p),
));
// test ts ts_readonly_property_initializer_ambient_context
// declare class A { readonly prop = "test"; }
// class B { declare readonly prop = "test"; }
// declare class A { private readonly prop = "test"; }
// class B { declare private readonly prop = "test"; }
// declare class A { static readonly prop = "test"; }
// class B { declare static readonly prop = "test"; }

if !modifiers.has(ModifierKind::Readonly) {
// test_err ts ts_property_initializer_ambient_context
// declare class A { prop = "test"; }
// class B { declare prop = "test"; }
p.error(p.err_builder(
"In ambient contexts, properties with initializers need to be readonly.",
initializer.range(p),
));
} else if let Some(annotation) = annotation {
// test_err ts ts_annotated_property_initializer_ambient_context
// declare class T { readonly b: string = "test"; }
// class T { declare readonly b: string = "test"; }
p.error(p.err_builder(
"In ambient contexts, properties cannot have both a type annotation and an initializer.",
initializer.range(p),
).detail(annotation.range(p), "The type annotation is here:"));
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ JsModule {
value: IDENT@118..123 "prop" [] [Whitespace(" ")],
},
property_annotation: missing (optional),
value: missing (optional),
semicolon_token: missing (optional),
},
],
Expand Down Expand Up @@ -182,6 +183,7 @@ JsModule {
0: IDENT@118..123 "prop" [] [Whitespace(" ")]
2: (empty)
3: (empty)
4: (empty)
8: R_CURLY@123..124 "}" [] []
3: EOF@124..125 "" [Newline("\n")] []
--
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,28 @@ JsModule {
implements_clause: missing (optional),
l_curly_token: L_CURLY@17..18 "{" [] [],
members: JsClassMemberList [
JsBogusMember {
items: [
TsPropertySignatureModifierList [
TsAbstractModifier {
modifier_token: ABSTRACT_KW@18..32 "abstract" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")],
},
],
JsLiteralMemberName {
value: IDENT@32..36 "name" [] [],
TsPropertySignatureClassMember {
modifiers: TsPropertySignatureModifierList [
TsAbstractModifier {
modifier_token: ABSTRACT_KW@18..32 "abstract" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")],
},
TsTypeAnnotation {
colon_token: COLON@36..38 ":" [] [Whitespace(" ")],
ty: TsStringType {
string_token: STRING_KW@38..45 "string" [] [Whitespace(" ")],
},
],
name: JsLiteralMemberName {
value: IDENT@32..36 "name" [] [],
},
property_annotation: TsTypeAnnotation {
colon_token: COLON@36..38 ":" [] [Whitespace(" ")],
ty: TsStringType {
string_token: STRING_KW@38..45 "string" [] [Whitespace(" ")],
},
JsInitializerClause {
eq_token: EQ@45..47 "=" [] [Whitespace(" ")],
expression: JsStringLiteralExpression {
value_token: JS_STRING_LITERAL@47..49 "\"\"" [] [],
},
},
value: JsInitializerClause {
eq_token: EQ@45..47 "=" [] [Whitespace(" ")],
expression: JsStringLiteralExpression {
value_token: JS_STRING_LITERAL@47..49 "\"\"" [] [],
},
SEMICOLON@49..50 ";" [] [],
],
},
semicolon_token: SEMICOLON@49..50 ";" [] [],
},
],
r_curly_token: R_CURLY@50..52 "}" [Newline("\n")] [],
Expand All @@ -59,7 +57,7 @@ JsModule {
5: (empty)
6: L_CURLY@17..18 "{" [] []
7: JS_CLASS_MEMBER_LIST@18..50
0: JS_BOGUS_MEMBER@18..50
0: TS_PROPERTY_SIGNATURE_CLASS_MEMBER@18..50
0: TS_PROPERTY_SIGNATURE_MODIFIER_LIST@18..32
0: TS_ABSTRACT_MODIFIER@18..32
0: ABSTRACT_KW@18..32 "abstract" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")]
Expand Down

0 comments on commit 40f982f

Please sign in to comment.