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(JavaAnnotation) \
|
||||||
TYPE(JsComputedPropertyName) \
|
TYPE(JsComputedPropertyName) \
|
||||||
TYPE(JsFatArrow) \
|
TYPE(JsFatArrow) \
|
||||||
|
TYPE(JsNonNullAssertion) \
|
||||||
TYPE(JsTypeColon) \
|
TYPE(JsTypeColon) \
|
||||||
TYPE(JsTypeOperator) \
|
TYPE(JsTypeOperator) \
|
||||||
TYPE(JsTypeOptionalQuestion) \
|
TYPE(JsTypeOptionalQuestion) \
|
||||||
|
|
|
@ -1030,6 +1030,23 @@ private:
|
||||||
// The token type is already known.
|
// The token type is already known.
|
||||||
return;
|
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
|
// Line.MightBeFunctionDecl can only be true after the parentheses of a
|
||||||
// function declaration have been found. In this case, 'Current' is a
|
// function declaration have been found. In this case, 'Current' is a
|
||||||
// trailing token of this declaration and thus cannot be a name.
|
// 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
|
// locations that should have whitespace following are identified by the
|
||||||
// above set of follower tokens.
|
// above set of follower tokens.
|
||||||
return false;
|
return false;
|
||||||
// Postfix non-null assertion operator, as in `foo!.bar()`.
|
if (Right.is(TT_JsNonNullAssertion))
|
||||||
if (Right.is(tok::exclaim) && (Left.isOneOf(tok::identifier, tok::r_paren,
|
|
||||||
tok::r_square, tok::r_brace) ||
|
|
||||||
Left.Tok.isLiteral()))
|
|
||||||
return false;
|
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"
|
return true; // "x! as string"
|
||||||
} else if (Style.Language == FormatStyle::LK_Java) {
|
} else if (Style.Language == FormatStyle::LK_Java) {
|
||||||
if (Left.is(tok::r_square) && Right.is(tok::l_brace))
|
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
|
return false; // must not break before as in 'x as type' casts
|
||||||
if (Left.is(Keywords.kw_as))
|
if (Left.is(Keywords.kw_as))
|
||||||
return true;
|
return true;
|
||||||
|
if (Left.is(TT_JsNonNullAssertion))
|
||||||
|
return true;
|
||||||
if (Left.is(Keywords.kw_declare) &&
|
if (Left.is(Keywords.kw_declare) &&
|
||||||
Right.isOneOf(Keywords.kw_module, tok::kw_namespace,
|
Right.isOneOf(Keywords.kw_module, tok::kw_namespace,
|
||||||
Keywords.kw_function, tok::kw_class, tok::kw_enum,
|
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)!;\n");
|
||||||
verifyFormat("let x = foo! - 1;\n");
|
verifyFormat("let x = foo! - 1;\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) {
|
TEST_F(FormatTestJS, Conditional) {
|
||||||
|
|
Loading…
Reference in New Issue