forked from OSchip/llvm-project
clang-format: [JS] allow breaking after non-null assertions.
Summary: Previously clang-format would not break after any !. However in TypeScript, ! can be used as a post fix operator for non-nullability: x.foo()!.bar()!; With this change, clang-format will wrap after the ! if it is likely a post-fix non null operator. Reviewers: djasper Subscribers: klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D30705 llvm-svn: 297606
This commit is contained in:
parent
b98ab89ebb
commit
22b8d26924
|
@ -54,6 +54,7 @@ namespace format {
|
|||
TYPE(JavaAnnotation) \
|
||||
TYPE(JsComputedPropertyName) \
|
||||
TYPE(JsFatArrow) \
|
||||
TYPE(JsNonNullAssertion) \
|
||||
TYPE(JsTypeColon) \
|
||||
TYPE(JsTypeOperator) \
|
||||
TYPE(JsTypeOptionalQuestion) \
|
||||
|
|
|
@ -1030,6 +1030,23 @@ private:
|
|||
// The token type is already known.
|
||||
return;
|
||||
|
||||
if (Style.Language == FormatStyle::LK_JavaScript) {
|
||||
if (Current.is(tok::exclaim)) {
|
||||
if (Current.Previous &&
|
||||
(Current.Previous->isOneOf(tok::identifier, tok::r_paren,
|
||||
tok::r_square, tok::r_brace) ||
|
||||
Current.Previous->Tok.isLiteral())) {
|
||||
Current.Type = TT_JsNonNullAssertion;
|
||||
return;
|
||||
}
|
||||
if (Current.Next &&
|
||||
Current.Next->isOneOf(TT_BinaryOperator, Keywords.kw_as)) {
|
||||
Current.Type = TT_JsNonNullAssertion;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Line.MightBeFunctionDecl can only be true after the parentheses of a
|
||||
// function declaration have been found. In this case, 'Current' is a
|
||||
// trailing token of this declaration and thus cannot be a name.
|
||||
|
@ -2284,12 +2301,9 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
|
|||
// locations that should have whitespace following are identified by the
|
||||
// above set of follower tokens.
|
||||
return false;
|
||||
// Postfix non-null assertion operator, as in `foo!.bar()`.
|
||||
if (Right.is(tok::exclaim) && (Left.isOneOf(tok::identifier, tok::r_paren,
|
||||
tok::r_square, tok::r_brace) ||
|
||||
Left.Tok.isLiteral()))
|
||||
if (Right.is(TT_JsNonNullAssertion))
|
||||
return false;
|
||||
if (Left.is(tok::exclaim) && Right.is(Keywords.kw_as))
|
||||
if (Left.is(TT_JsNonNullAssertion) && Right.is(Keywords.kw_as))
|
||||
return true; // "x! as string"
|
||||
} else if (Style.Language == FormatStyle::LK_Java) {
|
||||
if (Left.is(tok::r_square) && Right.is(tok::l_brace))
|
||||
|
@ -2545,6 +2559,8 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
|
|||
return false; // must not break before as in 'x as type' casts
|
||||
if (Left.is(Keywords.kw_as))
|
||||
return true;
|
||||
if (Left.is(TT_JsNonNullAssertion))
|
||||
return true;
|
||||
if (Left.is(Keywords.kw_declare) &&
|
||||
Right.isOneOf(Keywords.kw_module, tok::kw_namespace,
|
||||
Keywords.kw_function, tok::kw_class, tok::kw_enum,
|
||||
|
|
|
@ -1714,6 +1714,12 @@ TEST_F(FormatTestJS, NonNullAssertionOperator) {
|
|||
verifyFormat("let x = (foo)!;\n");
|
||||
verifyFormat("let x = foo! - 1;\n");
|
||||
verifyFormat("let x = {foo: 1}!;\n");
|
||||
verifyFormat(
|
||||
"let x = hello.foo()!\n"
|
||||
" .foo()!\n"
|
||||
" .foo()!\n"
|
||||
" .foo()!;\n",
|
||||
getGoogleJSStyleWithColumns(20));
|
||||
}
|
||||
|
||||
TEST_F(FormatTestJS, Conditional) {
|
||||
|
|
Loading…
Reference in New Issue