mprobst created this revision. mprobst added a reviewer: krasimir. This change adds some rudimentary support for conditional types. Specifically it avoids breaking before `extends` and `infer` keywords, which are subject to Automatic Semicolon Insertion, so breaking before them creates incorrect syntax.
The actual formatting of the type expression is odd, but there is as of yet no clear idea on how to format these. See https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#conditional-types. Repository: rC Clang https://reviews.llvm.org/D52536 Files: lib/Format/FormatToken.h lib/Format/TokenAnnotator.cpp unittests/Format/FormatTestJS.cpp Index: unittests/Format/FormatTestJS.cpp =================================================================== --- unittests/Format/FormatTestJS.cpp +++ unittests/Format/FormatTestJS.cpp @@ -2308,5 +2308,12 @@ verifyFormat("callFoo(/*spaceAfterParameterNamingComment=*/ 1);"); } +TEST_F(FormatTestJS, ConditionalTypes) { + verifyFormat("type UnionToIntersection<U> =\n" + " (U extends any ? (k: U) => void :\n" + " never) extends((k: infer I) => void) ? I " + ": never;"); +} + } // end namespace tooling } // end namespace clang Index: lib/Format/TokenAnnotator.cpp =================================================================== --- lib/Format/TokenAnnotator.cpp +++ lib/Format/TokenAnnotator.cpp @@ -3088,6 +3088,12 @@ return Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None; if (Right.is(Keywords.kw_as)) return false; // must not break before as in 'x as type' casts + if (Right.isOneOf(Keywords.kw_extends, Keywords.kw_infer)) { + // extends and infer can appear as keywords in conditional types: + // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#conditional-types + // do not break before them, as the expressions are subject to ASI. + return false; + } if (Left.is(Keywords.kw_as)) return true; if (Left.is(TT_JsNonNullAssertion)) Index: lib/Format/FormatToken.h =================================================================== --- lib/Format/FormatToken.h +++ lib/Format/FormatToken.h @@ -680,6 +680,7 @@ kw_function = &IdentTable.get("function"); kw_get = &IdentTable.get("get"); kw_import = &IdentTable.get("import"); + kw_infer = &IdentTable.get("infer"); kw_is = &IdentTable.get("is"); kw_let = &IdentTable.get("let"); kw_module = &IdentTable.get("module"); @@ -751,6 +752,7 @@ IdentifierInfo *kw_function; IdentifierInfo *kw_get; IdentifierInfo *kw_import; + IdentifierInfo *kw_infer; IdentifierInfo *kw_is; IdentifierInfo *kw_let; IdentifierInfo *kw_module;
Index: unittests/Format/FormatTestJS.cpp =================================================================== --- unittests/Format/FormatTestJS.cpp +++ unittests/Format/FormatTestJS.cpp @@ -2308,5 +2308,12 @@ verifyFormat("callFoo(/*spaceAfterParameterNamingComment=*/ 1);"); } +TEST_F(FormatTestJS, ConditionalTypes) { + verifyFormat("type UnionToIntersection<U> =\n" + " (U extends any ? (k: U) => void :\n" + " never) extends((k: infer I) => void) ? I " + ": never;"); +} + } // end namespace tooling } // end namespace clang Index: lib/Format/TokenAnnotator.cpp =================================================================== --- lib/Format/TokenAnnotator.cpp +++ lib/Format/TokenAnnotator.cpp @@ -3088,6 +3088,12 @@ return Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None; if (Right.is(Keywords.kw_as)) return false; // must not break before as in 'x as type' casts + if (Right.isOneOf(Keywords.kw_extends, Keywords.kw_infer)) { + // extends and infer can appear as keywords in conditional types: + // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#conditional-types + // do not break before them, as the expressions are subject to ASI. + return false; + } if (Left.is(Keywords.kw_as)) return true; if (Left.is(TT_JsNonNullAssertion)) Index: lib/Format/FormatToken.h =================================================================== --- lib/Format/FormatToken.h +++ lib/Format/FormatToken.h @@ -680,6 +680,7 @@ kw_function = &IdentTable.get("function"); kw_get = &IdentTable.get("get"); kw_import = &IdentTable.get("import"); + kw_infer = &IdentTable.get("infer"); kw_is = &IdentTable.get("is"); kw_let = &IdentTable.get("let"); kw_module = &IdentTable.get("module"); @@ -751,6 +752,7 @@ IdentifierInfo *kw_function; IdentifierInfo *kw_get; IdentifierInfo *kw_import; + IdentifierInfo *kw_infer; IdentifierInfo *kw_is; IdentifierInfo *kw_let; IdentifierInfo *kw_module;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits