summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Jasper <djasper@google.com>2016-03-22 14:32:20 +0000
committerDaniel Jasper <djasper@google.com>2016-03-22 14:32:20 +0000
commit8fc7a1e9920668acca038eeee3afdcd682bba352 (patch)
treedd8827c618415c17baaf99782f5c7de09b871352
parent0f17d0da4a9c3da0e2488eab1aee63adfaf8504f (diff)
downloadbcm5719-llvm-8fc7a1e9920668acca038eeee3afdcd682bba352.tar.gz
bcm5719-llvm-8fc7a1e9920668acca038eeee3afdcd682bba352.zip
clang-format: [JS] do not wrap ES6 imports/exports.
"import ... from '...';" and "export ... from '...';" should be treated the same as goog.require/provide/module/forwardDeclare calls. Patch by Martin Probst. llvm-svn: 264055
-rw-r--r--clang/lib/Format/FormatToken.h2
-rw-r--r--clang/lib/Format/TokenAnnotator.cpp26
-rw-r--r--clang/unittests/Format/FormatTestJS.cpp32
3 files changed, 38 insertions, 22 deletions
diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h
index 64d236bfb37..f15c9e998e6 100644
--- a/clang/lib/Format/FormatToken.h
+++ b/clang/lib/Format/FormatToken.h
@@ -537,6 +537,7 @@ struct AdditionalKeywords {
kw_finally = &IdentTable.get("finally");
kw_function = &IdentTable.get("function");
+ kw_from = &IdentTable.get("from");
kw_import = &IdentTable.get("import");
kw_is = &IdentTable.get("is");
kw_let = &IdentTable.get("let");
@@ -583,6 +584,7 @@ struct AdditionalKeywords {
// JavaScript keywords.
IdentifierInfo *kw_finally;
IdentifierInfo *kw_function;
+ IdentifierInfo *kw_from;
IdentifierInfo *kw_import;
IdentifierInfo *kw_is;
IdentifierInfo *kw_let;
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 69b703d03c1..b57faaad8bb 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -764,13 +764,30 @@ public:
return LT_ImportStatement;
}
+ // import {...} from '...';
+ if (Style.Language == FormatStyle::LK_JavaScript &&
+ CurrentToken->is(Keywords.kw_import))
+ return LT_ImportStatement;
+
bool KeywordVirtualFound = false;
bool ImportStatement = false;
while (CurrentToken) {
if (CurrentToken->is(tok::kw_virtual))
KeywordVirtualFound = true;
- if (isImportStatement(*CurrentToken))
- ImportStatement = true;
+ if (Style.Language == FormatStyle::LK_JavaScript) {
+ // export {...} from '...';
+ // An export followed by "from 'some string';" is a re-export from
+ // another module identified by a URI and is treated as a
+ // LT_ImportStatement (i.e. prevent wraps on it for long URIs).
+ // Just "export {...};" or "export class ..." should not be treated as
+ // an import in this sense.
+ if (Line.First->is(tok::kw_export) &&
+ CurrentToken->is(Keywords.kw_from) && CurrentToken->Next &&
+ CurrentToken->Next->isStringLiteral())
+ ImportStatement = true;
+ if (isClosureImportStatement(*CurrentToken))
+ ImportStatement = true;
+ }
if (!consumeToken())
return LT_Invalid;
}
@@ -790,11 +807,10 @@ public:
}
private:
- bool isImportStatement(const FormatToken &Tok) {
+ bool isClosureImportStatement(const FormatToken &Tok) {
// FIXME: Closure-library specific stuff should not be hard-coded but be
// configurable.
- return Style.Language == FormatStyle::LK_JavaScript &&
- Tok.TokenText == "goog" && Tok.Next && Tok.Next->is(tok::period) &&
+ return Tok.TokenText == "goog" && Tok.Next && Tok.Next->is(tok::period) &&
Tok.Next->Next && (Tok.Next->Next->TokenText == "module" ||
Tok.Next->Next->TokenText == "provide" ||
Tok.Next->Next->TokenText == "require" ||
diff --git a/clang/unittests/Format/FormatTestJS.cpp b/clang/unittests/Format/FormatTestJS.cpp
index c39667613c0..73f3afbaf09 100644
--- a/clang/unittests/Format/FormatTestJS.cpp
+++ b/clang/unittests/Format/FormatTestJS.cpp
@@ -942,21 +942,10 @@ TEST_F(FormatTestJS, Modules) {
verifyFormat("import SomeThing from 'some/module.js';");
verifyFormat("import {X, Y} from 'some/module.js';");
verifyFormat("import a, {X, Y} from 'some/module.js';");
- verifyFormat("import {\n"
- " VeryLongImportsAreAnnoying,\n"
- " VeryLongImportsAreAnnoying,\n"
- " VeryLongImportsAreAnnoying,\n"
- " VeryLongImportsAreAnnoying\n"
+ verifyFormat("import {VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying,"
+ " VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying"
"} from 'some/module.js';");
- verifyFormat("import {\n"
- " X,\n"
- " Y,\n"
- "} from 'some/module.js';");
- verifyFormat("import {\n"
- " X,\n"
- " Y,\n"
- "} from\n 'some/long/module.js';",
- getGoogleJSStyleWithColumns(20));
+ verifyFormat("import {X, Y,} from 'some/module.js';");
verifyFormat("import {X as myLocalX, Y as myLocalY} from 'some/module.js';");
verifyFormat("import * as lib from 'some/module.js';");
verifyFormat("var x = {import: 1};\nx.import = 2;");
@@ -970,10 +959,19 @@ TEST_F(FormatTestJS, Modules) {
verifyFormat("export const x = 12;");
verifyFormat("export default class X {}");
verifyFormat("export {X, Y} from 'some/module.js';");
+ verifyFormat("export {X, Y,} from 'some/module.js';");
+ verifyFormat("export {SomeVeryLongExport as X, "
+ "SomeOtherVeryLongExport as Y} from 'some/module.js';");
+ // export without 'from' is wrapped.
+ verifyFormat("export let someRatherLongVariableName =\n"
+ " someSurprisinglyLongVariable + someOtherRatherLongVar;");
+ // ... but not if from is just an identifier.
verifyFormat("export {\n"
- " X,\n"
- " Y,\n"
- "} from 'some/module.js';");
+ " from as from,\n"
+ " someSurprisinglyLongVariable\n"
+ " as from\n"
+ "};",
+ getGoogleJSStyleWithColumns(20));
verifyFormat("export class C {\n"
" x: number;\n"
" y: string;\n"
OpenPOWER on IntegriCloud