This repository has been archived by the owner on Aug 31, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 660
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(rome_js_formatter): EcmaScript @decorators #4252
- Loading branch information
1 parent
6abe553
commit ff02317
Showing
61 changed files
with
2,374 additions
and
1,462 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
use crate::prelude::*; | ||
use crate::utils::sort_modifiers_by_precedence; | ||
use crate::{AsFormat, IntoFormat}; | ||
use rome_formatter::{format_args, write}; | ||
use rome_js_syntax::JsSyntaxKind::JS_DECORATOR; | ||
use rome_js_syntax::{JsLanguage, Modifiers}; | ||
use rome_rowan::{AstNode, AstNodeList, NodeOrToken}; | ||
|
||
pub(crate) struct FormatModifiers<List> { | ||
pub(crate) list: List, | ||
} | ||
|
||
impl<List> FormatModifiers<List> { | ||
pub(crate) fn from(list: List) -> Self { | ||
Self { list } | ||
} | ||
} | ||
|
||
impl<List, Node> Format<JsFormatContext> for FormatModifiers<List> | ||
where | ||
Node: AstNode<Language = JsLanguage> + AsFormat<JsFormatContext> + IntoFormat<JsFormatContext>, | ||
List: AstNodeList<Language = JsLanguage, Node = Node>, | ||
Modifiers: for<'a> From<&'a Node>, | ||
{ | ||
fn fmt(&self, f: &mut Formatter<JsFormatContext>) -> FormatResult<()> { | ||
let modifiers = sort_modifiers_by_precedence(&self.list); | ||
let should_expand = should_expand_decorators(&self.list); | ||
|
||
// need to use peek the iterator to check if the current node is a decorator and don't advance the iterator | ||
let mut iter = modifiers.into_iter().peekable(); | ||
let decorators = format_once(|f| { | ||
let mut join = f.join_nodes_with_soft_line(); | ||
|
||
// join only decorators here | ||
while let Some(node) = iter.peek() { | ||
// check if the current node is a decorator | ||
match node.syntax().kind() { | ||
JS_DECORATOR => { | ||
join.entry(node.syntax(), &node.format()); | ||
// advance the iterator | ||
iter.next(); | ||
} | ||
_ => { | ||
// if we encounter a non-decorator we break out of the loop | ||
break; | ||
} | ||
} | ||
} | ||
|
||
join.finish() | ||
}); | ||
|
||
write!( | ||
f, | ||
[group(&format_args![decorators, soft_line_break_or_space()]) | ||
.should_expand(should_expand)] | ||
)?; | ||
|
||
// join the rest of the modifiers | ||
f.join_with(&space()).entries(iter.formatted()).finish() | ||
} | ||
} | ||
|
||
/// This function expands decorators enclosing a group if there is a newline between decorators or after the last decorator. | ||
fn should_expand_decorators<List, Node>(list: &List) -> bool | ||
where | ||
Node: AstNode<Language = JsLanguage>, | ||
List: AstNodeList<Language = JsLanguage, Node = Node>, | ||
{ | ||
// we need to skip the first node because we look for newlines between decorators or after the last decorator | ||
for node in list.iter().skip(1) { | ||
match node.syntax().kind() { | ||
JS_DECORATOR => { | ||
if node.syntax().has_leading_newline() { | ||
return true; | ||
} | ||
} | ||
_ => { | ||
// if we encounter a non-decorator with a leading newline after a decorator and the next modifier | ||
return node.syntax().has_leading_newline(); | ||
} | ||
} | ||
} | ||
|
||
// if we encounter a non-decorator with a leading newline after a decorator and the next node or token | ||
list.syntax_list() | ||
.node() | ||
.next_sibling_or_token() | ||
.map_or(false, |node| match node { | ||
NodeOrToken::Node(node) => node.has_leading_newline(), | ||
NodeOrToken::Token(token) => token.has_leading_newline(), | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.