From: Daniel Jasper Date: Wed, 18 Feb 2015 17:09:53 +0000 (+0000) Subject: clang-format: [JS] Support type annotations. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3cf42560c61412439bc2ab8785e5f7814b001678;p=clang clang-format: [JS] Support type annotations. This patch adds support for type annotations that follow TypeScript's, Flow's, and AtScript's syntax style. Patch by Martin Probst, thank you. Review: http://reviews.llvm.org/D7721 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@229700 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Format/FormatToken.h b/lib/Format/FormatToken.h index 4692c20d75..41988bf590 100644 --- a/lib/Format/FormatToken.h +++ b/lib/Format/FormatToken.h @@ -48,6 +48,7 @@ enum TokenType { TT_InheritanceColon, TT_InlineASMColon, TT_JavaAnnotation, + TT_JsTypeColon, TT_LambdaArrow, TT_LambdaLSquare, TT_LeadingJavaAnnotation, diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp index dc48d86551..8db48ff1ed 100644 --- a/lib/Format/TokenAnnotator.cpp +++ b/lib/Format/TokenAnnotator.cpp @@ -408,10 +408,7 @@ private: if (!Tok->Previous) return false; // Colons from ?: are handled in parseConditional(). - if (Tok->Previous->is(tok::r_paren) && Contexts.size() == 1 && - Line.First->isNot(tok::kw_case)) { - Tok->Type = TT_CtorInitializerColon; - } else if (Contexts.back().ColonIsDictLiteral) { + if (Contexts.back().ColonIsDictLiteral) { Tok->Type = TT_DictLiteral; } else if (Contexts.back().ColonIsObjCMethodExpr || Line.First->is(TT_ObjCMethodSpecifier)) { @@ -424,19 +421,28 @@ private: if (!Contexts.back().FirstObjCSelectorName) Contexts.back().FirstObjCSelectorName = Tok->Previous; } else if (Contexts.back().ColonIsForRangeExpr) { - Tok->Type = TT_RangeBasedForLoopColon; + Tok->Type = Style.Language == FormatStyle::LK_JavaScript + ? TT_JsTypeColon + : TT_RangeBasedForLoopColon; } else if (CurrentToken && CurrentToken->is(tok::numeric_constant)) { Tok->Type = TT_BitFieldColon; } else if (Contexts.size() == 1 && !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) { - Tok->Type = TT_InheritanceColon; + if (Style.Language == FormatStyle::LK_JavaScript) + Tok->Type = TT_JsTypeColon; + else if (Tok->Previous->is(tok::r_paren)) + Tok->Type = TT_CtorInitializerColon; + else + Tok->Type = TT_InheritanceColon; } else if (Tok->Previous->is(tok::identifier) && Tok->Next && Tok->Next->isOneOf(tok::r_paren, tok::comma)) { // This handles a special macro in ObjC code where selectors including // the colon are passed as macro arguments. Tok->Type = TT_ObjCMethodExpr; } else if (Contexts.back().ContextKind == tok::l_paren) { - Tok->Type = TT_InlineASMColon; + Tok->Type = Style.Language == FormatStyle::LK_JavaScript + ? TT_JsTypeColon + : TT_InlineASMColon; } break; case tok::kw_if: @@ -1748,6 +1754,8 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, } else if (Style.Language == FormatStyle::LK_JavaScript) { if (Left.is(Keywords.kw_var)) return true; + if (Right.is(TT_JsTypeColon)) + return false; } else if (Style.Language == FormatStyle::LK_Java) { if (Left.is(tok::r_square) && Right.is(tok::l_brace)) return true; diff --git a/unittests/Format/FormatTestJS.cpp b/unittests/Format/FormatTestJS.cpp index 780b02f746..d5ce580f24 100644 --- a/unittests/Format/FormatTestJS.cpp +++ b/unittests/Format/FormatTestJS.cpp @@ -490,5 +490,15 @@ TEST_F(FormatTestJS, RegexLiteralExamples) { verifyFormat("var regex = search.match(/(?:\?|&)times=([^?&]+)/i);"); } +TEST_F(FormatTestJS, TypeAnnotations) { + verifyFormat("var x: string;"); + verifyFormat("function x(): string {\n return 'x';\n}"); + verifyFormat("function x(y: string): string {\n return 'x';\n}"); + verifyFormat("for (var y: string in x) {\n x();\n}"); + verifyFormat("((a: string, b: number): string => a + b);"); + verifyFormat("var x: (y: number) => string;"); + verifyFormat("var x: P string>;"); +} + } // end namespace tooling } // end namespace clang