mprobst created this revision.
mprobst added a reviewer: djasper.
mprobst added a subscriber: cfe-commits.
Herald added a subscriber: klimek.

See TypeScript grammar for tokens following 'declare':
https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#A.10

Additional minor change:
clang-format: [JS] Prevent ASI before const.


https://reviews.llvm.org/D26274

Files:
  lib/Format/FormatToken.h
  lib/Format/TokenAnnotator.cpp
  lib/Format/UnwrappedLineParser.cpp
  unittests/Format/FormatTestJS.cpp

Index: unittests/Format/FormatTestJS.cpp
===================================================================
--- unittests/Format/FormatTestJS.cpp
+++ unittests/Format/FormatTestJS.cpp
@@ -349,6 +349,37 @@
                "}\n");
 }
 
+TEST_F(FormatTestJS, NamespacesMayNotWrap) {
+  verifyFormat("declare namespace foobarbaz {\n"
+               "}\n", getGoogleJSStyleWithColumns(18));
+  verifyFormat("declare module foobarbaz {\n"
+               "}\n", getGoogleJSStyleWithColumns(15));
+  verifyFormat("namespace foobarbaz {\n"
+               "}\n", getGoogleJSStyleWithColumns(10));
+  verifyFormat("module foobarbaz {\n"
+               "}\n", getGoogleJSStyleWithColumns(7));
+}
+
+TEST_F(FormatTestJS, AmbientDeclarations) {
+  FormatStyle NineCols = getGoogleJSStyleWithColumns(9);
+  verifyFormat(
+      "declare class\n"
+      "    X {}",
+      NineCols);
+  verifyFormat(
+      "declare function\n"
+      "x();",  // TODO(martinprobst): should ideally be indented.
+      NineCols);
+  verifyFormat(
+      "declare enum X {\n"
+      "}",
+      NineCols);
+  verifyFormat(
+      "declare let\n"
+      "    x: number;",
+      NineCols);
+}
+
 TEST_F(FormatTestJS, FormatsFreestandingFunctions) {
   verifyFormat("function outer1(a, b) {\n"
                "  function inner1(a, b) {\n"
Index: lib/Format/UnwrappedLineParser.cpp
===================================================================
--- lib/Format/UnwrappedLineParser.cpp
+++ lib/Format/UnwrappedLineParser.cpp
@@ -669,14 +669,14 @@
   // 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, Keywords.kw_as,
-                              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,
-                              Keywords.kw_abstract, Keywords.kw_extends,
-                              Keywords.kw_implements, Keywords.kw_instanceof,
-                              Keywords.kw_interface, Keywords.kw_throws));
+          !FormatTok->isOneOf(
+              Keywords.kw_in, Keywords.kw_of, Keywords.kw_as, 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, tok::kw_const,
+              Keywords.kw_abstract, Keywords.kw_extends, Keywords.kw_implements,
+              Keywords.kw_instanceof, Keywords.kw_interface,
+              Keywords.kw_throws));
 }
 
 static bool mustBeJSIdentOrValue(const AdditionalKeywords &Keywords,
Index: lib/Format/TokenAnnotator.cpp
===================================================================
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -2420,10 +2420,10 @@
   } else if (Style.Language == FormatStyle::LK_JavaScript) {
     const FormatToken *NonComment = Right.getPreviousNonComment();
     if (Left.isOneOf(tok::kw_return, tok::kw_continue, tok::kw_break,
-                     tok::kw_throw) ||
+                     tok::kw_throw, Keywords.kw_module) ||
         (NonComment &&
          NonComment->isOneOf(tok::kw_return, tok::kw_continue, tok::kw_break,
-                             tok::kw_throw)))
+                             tok::kw_throw, Keywords.kw_module)))
       return false; // Otherwise a semicolon is inserted.
     if (Left.is(TT_JsFatArrow) && Right.is(tok::l_brace))
       return false;
@@ -2437,6 +2437,18 @@
       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 (Left.is(Keywords.kw_declare) &&
+        Right.isOneOf(Keywords.kw_module, tok::kw_namespace,
+                      Keywords.kw_function, tok::kw_class, tok::kw_enum,
+                      Keywords.kw_interface, Keywords.kw_type, Keywords.kw_var,
+                      Keywords.kw_let, tok::kw_const))
+      // See grammar for 'declare' statements at:
+      // https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#A.10
+      return false;
+    if (Left.isOneOf(Keywords.kw_module, tok::kw_namespace) &&
+        Right.isOneOf(tok::identifier, tok::string_literal)) {
+      return false; // must not break in "module foo { ...}"
+    }
   }
 
   if (Left.is(tok::at))
Index: lib/Format/FormatToken.h
===================================================================
--- lib/Format/FormatToken.h
+++ lib/Format/FormatToken.h
@@ -580,12 +580,14 @@
     kw_as = &IdentTable.get("as");
     kw_async = &IdentTable.get("async");
     kw_await = &IdentTable.get("await");
+    kw_declare = &IdentTable.get("declare");
     kw_finally = &IdentTable.get("finally");
     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_module = &IdentTable.get("module");
     kw_type = &IdentTable.get("type");
     kw_var = &IdentTable.get("var");
     kw_yield = &IdentTable.get("yield");
@@ -632,12 +634,14 @@
   IdentifierInfo *kw_as;
   IdentifierInfo *kw_async;
   IdentifierInfo *kw_await;
+  IdentifierInfo *kw_declare;
   IdentifierInfo *kw_finally;
   IdentifierInfo *kw_from;
   IdentifierInfo *kw_function;
   IdentifierInfo *kw_import;
   IdentifierInfo *kw_is;
   IdentifierInfo *kw_let;
+  IdentifierInfo *kw_module;
   IdentifierInfo *kw_type;
   IdentifierInfo *kw_var;
   IdentifierInfo *kw_yield;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to