r267368 - clang-format: [JS] generator and async functions.
Martin Probst via cfe-commits
cfe-commits at lists.llvm.org
Sun Apr 24 15:05:09 PDT 2016
Author: mprobst
Date: Sun Apr 24 17:05:09 2016
New Revision: 267368
URL: http://llvm.org/viewvc/llvm-project?rev=267368&view=rev
Log:
clang-format: [JS] generator and async functions.
For generators, see:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_generators
async functions are not quite in the spec yet, but stage 3 and already widely used:
http://tc39.github.io/ecmascript-asyncawait/
Reviewers: djasper
Subscribers: klimek
Differential Revision: http://reviews.llvm.org/D19204
Modified:
cfe/trunk/lib/Format/ContinuationIndenter.cpp
cfe/trunk/lib/Format/FormatToken.h
cfe/trunk/lib/Format/TokenAnnotator.cpp
cfe/trunk/lib/Format/UnwrappedLineParser.cpp
cfe/trunk/unittests/Format/FormatTestJS.cpp
Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=267368&r1=267367&r2=267368&view=diff
==============================================================================
--- cfe/trunk/lib/Format/ContinuationIndenter.cpp (original)
+++ cfe/trunk/lib/Format/ContinuationIndenter.cpp Sun Apr 24 17:05:09 2016
@@ -479,7 +479,7 @@ unsigned ContinuationIndenter::addTokenO
// is common and should be formatted like a free-standing function.
if (Style.Language != FormatStyle::LK_JavaScript ||
Current.NestingLevel != 0 || !PreviousNonComment->is(tok::equal) ||
- !Current.is(Keywords.kw_function))
+ !Current.isOneOf(Keywords.kw_async, Keywords.kw_function))
State.Stack.back().NestedBlockIndent = State.Column;
if (NextNonComment->isMemberAccess()) {
Modified: cfe/trunk/lib/Format/FormatToken.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatToken.h?rev=267368&r1=267367&r2=267368&view=diff
==============================================================================
--- cfe/trunk/lib/Format/FormatToken.h (original)
+++ cfe/trunk/lib/Format/FormatToken.h Sun Apr 24 17:05:09 2016
@@ -535,13 +535,16 @@ struct AdditionalKeywords {
kw_NS_ENUM = &IdentTable.get("NS_ENUM");
kw_NS_OPTIONS = &IdentTable.get("NS_OPTIONS");
+ kw_async = &IdentTable.get("async");
+ kw_await = &IdentTable.get("await");
kw_finally = &IdentTable.get("finally");
- kw_function = &IdentTable.get("function");
kw_from = &IdentTable.get("from");
+ kw_function = &IdentTable.get("function");
kw_import = &IdentTable.get("import");
kw_is = &IdentTable.get("is");
kw_let = &IdentTable.get("let");
kw_var = &IdentTable.get("var");
+ kw_yield = &IdentTable.get("yield");
kw_abstract = &IdentTable.get("abstract");
kw_assert = &IdentTable.get("assert");
@@ -582,13 +585,16 @@ struct AdditionalKeywords {
IdentifierInfo *kw___except;
// JavaScript keywords.
+ IdentifierInfo *kw_async;
+ IdentifierInfo *kw_await;
IdentifierInfo *kw_finally;
- IdentifierInfo *kw_function;
IdentifierInfo *kw_from;
+ IdentifierInfo *kw_function;
IdentifierInfo *kw_import;
IdentifierInfo *kw_is;
IdentifierInfo *kw_let;
IdentifierInfo *kw_var;
+ IdentifierInfo *kw_yield;
// Java keywords.
IdentifierInfo *kw_abstract;
Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=267368&r1=267367&r2=267368&view=diff
==============================================================================
--- cfe/trunk/lib/Format/TokenAnnotator.cpp (original)
+++ cfe/trunk/lib/Format/TokenAnnotator.cpp Sun Apr 24 17:05:09 2016
@@ -2078,6 +2078,9 @@ bool TokenAnnotator::spaceRequiredBefore
} else if (Style.Language == FormatStyle::LK_JavaScript) {
if (Left.is(TT_JsFatArrow))
return true;
+ if (Right.is(tok::star) &&
+ Left.isOneOf(Keywords.kw_function, Keywords.kw_yield))
+ return false;
if (Left.isOneOf(Keywords.kw_let, Keywords.kw_var, Keywords.kw_in,
Keywords.kw_of) &&
(!Left.Previous || !Left.Previous->is(tok::period)))
Modified: cfe/trunk/lib/Format/UnwrappedLineParser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.cpp?rev=267368&r1=267367&r2=267368&view=diff
==============================================================================
--- cfe/trunk/lib/Format/UnwrappedLineParser.cpp (original)
+++ cfe/trunk/lib/Format/UnwrappedLineParser.cpp Sun Apr 24 17:05:09 2016
@@ -668,7 +668,8 @@ static bool mustBeJSIdent(const Addition
// FIXME: This returns true for C/C++ keywords like 'struct'.
return FormatTok->is(tok::identifier) &&
(FormatTok->Tok.getIdentifierInfo() == nullptr ||
- !FormatTok->isOneOf(Keywords.kw_in, Keywords.kw_of,
+ !FormatTok->isOneOf(Keywords.kw_in, Keywords.kw_of, Keywords.kw_async,
+ Keywords.kw_await, Keywords.kw_yield,
Keywords.kw_finally, Keywords.kw_function,
Keywords.kw_import, Keywords.kw_is,
Keywords.kw_let, Keywords.kw_var,
@@ -687,7 +688,7 @@ static bool mustBeJSIdentOrValue(const A
static bool isJSDeclOrStmt(const AdditionalKeywords &Keywords,
const FormatToken *FormatTok) {
return FormatTok->isOneOf(
- tok::kw_return,
+ tok::kw_return, Keywords.kw_yield,
// conditionals
tok::kw_if, tok::kw_else,
// loops
@@ -698,7 +699,9 @@ static bool isJSDeclOrStmt(const Additio
tok::kw_throw, tok::kw_try, tok::kw_catch, Keywords.kw_finally,
// declaration
tok::kw_const, tok::kw_class, Keywords.kw_var, Keywords.kw_let,
- Keywords.kw_function);
+ Keywords.kw_async, Keywords.kw_function,
+ // import/export
+ Keywords.kw_import, tok::kw_export);
}
// readTokenWithJavaScriptASI reads the next token and terminates the current
@@ -1003,7 +1006,8 @@ void UnwrappedLineParser::parseStructura
// Parse function literal unless 'function' is the first token in a line
// in which case this should be treated as a free-standing function.
if (Style.Language == FormatStyle::LK_JavaScript &&
- FormatTok->is(Keywords.kw_function) && Line->Tokens.size() > 0) {
+ FormatTok->isOneOf(Keywords.kw_async, Keywords.kw_function) &&
+ Line->Tokens.size() > 0) {
tryToParseJSFunction();
break;
}
@@ -1189,8 +1193,16 @@ bool UnwrappedLineParser::tryToParseLamb
}
void UnwrappedLineParser::tryToParseJSFunction() {
+ assert(FormatTok->isOneOf(Keywords.kw_async, Keywords.kw_function));
+ if (FormatTok->is(Keywords.kw_async))
+ nextToken();
+ // Consume "function".
nextToken();
+ // Consume * (generator function).
+ if (FormatTok->is(tok::star))
+ nextToken();
+
// Consume function name.
if (FormatTok->is(tok::identifier))
nextToken();
@@ -1235,7 +1247,7 @@ bool UnwrappedLineParser::parseBracedLis
// replace this by using parseAssigmentExpression() inside.
do {
if (Style.Language == FormatStyle::LK_JavaScript) {
- if (FormatTok->is(Keywords.kw_function)) {
+ if (FormatTok->isOneOf(Keywords.kw_async, Keywords.kw_function)) {
tryToParseJSFunction();
continue;
}
@@ -1333,7 +1345,7 @@ void UnwrappedLineParser::parseParens()
break;
case tok::identifier:
if (Style.Language == FormatStyle::LK_JavaScript &&
- FormatTok->is(Keywords.kw_function))
+ FormatTok->isOneOf(Keywords.kw_async, Keywords.kw_function))
tryToParseJSFunction();
else
nextToken();
@@ -1904,8 +1916,11 @@ void UnwrappedLineParser::parseJavaScrip
if (FormatTok->is(tok::kw_default))
nextToken();
- // Consume "function" and "default function", so that these get parsed as
- // free-standing JS functions, i.e. do not require a trailing semicolon.
+ // Consume "async function", "function" and "default function", so that these
+ // get parsed as free-standing JS functions, i.e. do not require a trailing
+ // semicolon.
+ if (FormatTok->is(Keywords.kw_async))
+ nextToken();
if (FormatTok->is(Keywords.kw_function)) {
nextToken();
return;
Modified: cfe/trunk/unittests/Format/FormatTestJS.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestJS.cpp?rev=267368&r1=267367&r2=267368&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTestJS.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTestJS.cpp Sun Apr 24 17:05:09 2016
@@ -320,6 +320,40 @@ TEST_F(FormatTestJS, FormatsFreestanding
verifyFormat("function f() {}");
}
+TEST_F(FormatTestJS, GeneratorFunctions) {
+ verifyFormat("function* f() {\n"
+ " let x = 1;\n"
+ " yield x;\n"
+ " yield* something();\n"
+ "}");
+ verifyFormat("function*\n"
+ " f() {\n"
+ "}",
+ getGoogleJSStyleWithColumns(8));
+ verifyFormat("export function* f() {\n"
+ " yield 1;\n"
+ "}\n");
+ verifyFormat("class X {\n"
+ " * generatorMethod() { yield x; }\n"
+ "}");
+}
+
+TEST_F(FormatTestJS, AsyncFunctions) {
+ verifyFormat("async function f() {\n"
+ " let x = 1;\n"
+ " return fetch(x);\n"
+ "}");
+ verifyFormat("async function* f() {\n"
+ " yield fetch(x);\n"
+ "}");
+ verifyFormat("export async function f() {\n"
+ " return fetch(x);\n"
+ "}");
+ verifyFormat("class X {\n"
+ " async asyncMethod() { return fetch(1); }\n"
+ "}");
+}
+
TEST_F(FormatTestJS, ArrayLiterals) {
verifyFormat("var aaaaa: List<SomeThing> =\n"
" [new SomeThingAAAAAAAAAAAA(), new SomeThingBBBBBBBBB()];");
More information about the cfe-commits
mailing list