From: Martin Probst Date: Tue, 8 Aug 2017 15:00:58 +0000 (+0000) Subject: clang-format: [JS] fix union type spacing in object & array types. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3efad662a1b054b090ea1259b0b6e6b613db2651;p=clang clang-format: [JS] fix union type spacing in object & array types. Summary: Previously, clang-format would insert whitespace in union types nested in object and array types, as it wouldn't recognize those as a type operator: const x: {foo: number | null}; const x: [number | null]; While this is correct for actual binary operators, clang-format should not insert whitespace into union and intersection types to mark those: const x: {foo: number|null}; const x: [number|null]; This change propagates that the context is not an expression by inspecting the preceding token and marking as non-expression if it was a type colon. Reviewers: djasper Subscribers: klimek Differential Revision: https://reviews.llvm.org/D36136 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@310367 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp index 7ea34d49be..37583cdb8f 100644 --- a/lib/Format/TokenAnnotator.cpp +++ b/lib/Format/TokenAnnotator.cpp @@ -372,6 +372,10 @@ private: ScopedContextCreator ContextCreator(*this, tok::l_square, BindingIncrease); Contexts.back().IsExpression = true; + if (Style.Language == FormatStyle::LK_JavaScript && Parent && + Parent->is(TT_JsTypeColon)) + Contexts.back().IsExpression = false; + Contexts.back().ColonIsObjCMethodExpr = StartsObjCMethodExpr; while (CurrentToken) { @@ -439,6 +443,9 @@ private: Contexts.back().ColonIsDictLiteral = true; if (Left->BlockKind == BK_BracedInit) Contexts.back().IsExpression = true; + if (Style.Language == FormatStyle::LK_JavaScript && Left->Previous && + Left->Previous->is(TT_JsTypeColon)) + Contexts.back().IsExpression = false; while (CurrentToken) { if (CurrentToken->is(tok::r_brace)) { @@ -531,6 +538,8 @@ private: !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) || Contexts.back().ContextKind == tok::l_paren || // function params Contexts.back().ContextKind == tok::l_square || // array type + (!Contexts.back().IsExpression && + Contexts.back().ContextKind == tok::l_brace) || // object type (Contexts.size() == 1 && Line.MustBeDeclaration)) { // method/property declaration Contexts.back().IsExpression = false; diff --git a/unittests/Format/FormatTestJS.cpp b/unittests/Format/FormatTestJS.cpp index 12ff750a8f..033c024e5a 100644 --- a/unittests/Format/FormatTestJS.cpp +++ b/unittests/Format/FormatTestJS.cpp @@ -1363,6 +1363,18 @@ TEST_F(FormatTestJS, UnionIntersectionTypes) { "};"); } +TEST_F(FormatTestJS, UnionIntersectionTypesInObjectType) { + verifyFormat("let x: {x: number|null} = {x: number | null};"); + verifyFormat("let nested: {x: {y: number|null}};"); + verifyFormat("let mixed: {x: [number|null, {w: number}]};"); + verifyFormat("class X {\n" + " contructor(x: {\n" + " a: a|null,\n" + " b: b|null,\n" + " }) {}\n" + "}"); +} + TEST_F(FormatTestJS, ClassDeclarations) { verifyFormat("class C {\n x: string = 12;\n}"); verifyFormat("class C {\n x(): string => 12;\n}");