r222637 - clang-format: [JS] Support Closure's module statements.

Daniel Jasper djasper at google.com
Sun Nov 23 08:46:28 PST 2014


Author: djasper
Date: Sun Nov 23 10:46:28 2014
New Revision: 222637

URL: http://llvm.org/viewvc/llvm-project?rev=222637&view=rev
Log:
clang-format: [JS] Support Closure's module statements.

These are like import statements and should not be line-wrapped. Minor
restructuring of the handling of other import statements.

Modified:
    cfe/trunk/lib/Format/ContinuationIndenter.cpp
    cfe/trunk/lib/Format/Format.cpp
    cfe/trunk/lib/Format/TokenAnnotator.cpp
    cfe/trunk/lib/Format/TokenAnnotator.h
    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=222637&r1=222636&r2=222637&view=diff
==============================================================================
--- cfe/trunk/lib/Format/ContinuationIndenter.cpp (original)
+++ cfe/trunk/lib/Format/ContinuationIndenter.cpp Sun Nov 23 10:46:28 2014
@@ -986,8 +986,9 @@ unsigned ContinuationIndenter::breakProt
   if (Current.Type != TT_BlockComment && Current.IsMultiline)
     return addMultilineToken(Current, State);
 
-  // Don't break implicit string literals.
-  if (Current.Type == TT_ImplicitStringLiteral)
+  // Don't break implicit string literals or import statements.
+  if (Current.Type == TT_ImplicitStringLiteral ||
+      State.Line->Type == LT_ImportStatement)
     return 0;
 
   if (!Current.isStringLiteral() && !Current.is(tok::comment))

Modified: cfe/trunk/lib/Format/Format.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=222637&r1=222636&r2=222637&view=diff
==============================================================================
--- cfe/trunk/lib/Format/Format.cpp (original)
+++ cfe/trunk/lib/Format/Format.cpp Sun Nov 23 10:46:28 2014
@@ -951,7 +951,8 @@ public:
             ColumnLimit = getColumnLimit(TheLine.InPPDirective);
         }
 
-        if (TheLine.Last->TotalLength + Indent <= ColumnLimit) {
+        if (TheLine.Last->TotalLength + Indent <= ColumnLimit ||
+            TheLine.Type == LT_ImportStatement) {
           LineState State = Indenter->getInitialState(Indent, &TheLine, DryRun);
           while (State.NextToken) {
             formatChildren(State, /*Newline=*/false, /*DryRun=*/false, Penalty);

Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=222637&r1=222636&r2=222637&view=diff
==============================================================================
--- cfe/trunk/lib/Format/TokenAnnotator.cpp (original)
+++ cfe/trunk/lib/Format/TokenAnnotator.cpp Sun Nov 23 10:46:28 2014
@@ -33,8 +33,8 @@ class AnnotatingParser {
 public:
   AnnotatingParser(const FormatStyle &Style, AnnotatedLine &Line,
                    const AdditionalKeywords &Keywords)
-      : Style(Style), Line(Line), CurrentToken(Line.First),
-        KeywordVirtualFound(false), AutoFound(false), Keywords(Keywords) {
+      : Style(Style), Line(Line), CurrentToken(Line.First), AutoFound(false),
+        Keywords(Keywords) {
     Contexts.push_back(Context(tok::unknown, 1, /*IsExpression=*/false));
     resetTokenMetadata(CurrentToken);
   }
@@ -536,14 +536,6 @@ private:
           CurrentToken->Type = TT_ImplicitStringLiteral;
         next();
       }
-    } else {
-      while (CurrentToken) {
-        if (CurrentToken->isNot(tok::comment))
-          // Mark these tokens as "implicit" string literals, so that
-          // they are not split or line-wrapped.
-          CurrentToken->Type = TT_ImplicitStringLiteral;
-        next();
-      }
     }
   }
 
@@ -570,23 +562,25 @@ private:
     }
   }
 
-  void parsePreprocessorDirective() {
+  LineType parsePreprocessorDirective() {
+    LineType Type = LT_PreprocessorDirective;
     next();
     if (!CurrentToken)
-      return;
+      return Type;
     if (CurrentToken->Tok.is(tok::numeric_constant)) {
       CurrentToken->SpacesRequiredBefore = 1;
-      return;
+      return Type;
     }
     // Hashes in the middle of a line can lead to any strange token
     // sequence.
     if (!CurrentToken->Tok.getIdentifierInfo())
-      return;
+      return Type;
     switch (CurrentToken->Tok.getIdentifierInfo()->getPPKeywordID()) {
     case tok::pp_include:
     case tok::pp_import:
       next();
       parseIncludeDirective();
+      Type = LT_ImportStatement;
       break;
     case tok::pp_error:
     case tok::pp_warning:
@@ -605,13 +599,13 @@ private:
     }
     while (CurrentToken)
       next();
+    return Type;
   }
 
 public:
   LineType parseLine() {
     if (CurrentToken->is(tok::hash)) {
-      parsePreprocessorDirective();
-      return LT_PreprocessorDirective;
+      return parsePreprocessorDirective();
     }
 
     // Directly allow to 'import <string-literal>' to support protocol buffer
@@ -622,24 +616,30 @@ public:
         CurrentToken->Next) {
       next();
       parseIncludeDirective();
-      return LT_Other;
+      return LT_ImportStatement;
     }
 
     // If this line starts and ends in '<' and '>', respectively, it is likely
     // part of "#define <a/b.h>".
     if (CurrentToken->is(tok::less) && Line.Last->is(tok::greater)) {
       parseIncludeDirective();
-      return LT_Other;
+      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 (!consumeToken())
         return LT_Invalid;
     }
     if (KeywordVirtualFound)
       return LT_VirtualFunctionDecl;
+    if (ImportStatement)
+      return LT_ImportStatement;
 
     if (Line.First->Type == TT_ObjCMethodSpecifier) {
       if (Contexts.back().FirstObjCSelectorName)
@@ -652,6 +652,16 @@ public:
   }
 
 private:
+  bool IsImportStatement(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) &&
+           Tok.Next->Next && (Tok.Next->Next->TokenText == "module" ||
+                              Tok.Next->Next->TokenText == "require" ||
+                              Tok.Next->Next->TokenText == "provide");
+  }
+
   void resetTokenMetadata(FormatToken *Token) {
     if (!Token)
       return;
@@ -1066,7 +1076,6 @@ private:
   const FormatStyle &Style;
   AnnotatedLine &Line;
   FormatToken *CurrentToken;
-  bool KeywordVirtualFound;
   bool AutoFound;
   const AdditionalKeywords &Keywords;
 };

Modified: cfe/trunk/lib/Format/TokenAnnotator.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.h?rev=222637&r1=222636&r2=222637&view=diff
==============================================================================
--- cfe/trunk/lib/Format/TokenAnnotator.h (original)
+++ cfe/trunk/lib/Format/TokenAnnotator.h Sun Nov 23 10:46:28 2014
@@ -27,12 +27,13 @@ namespace format {
 
 enum LineType {
   LT_Invalid,
-  LT_Other,
-  LT_PreprocessorDirective,
-  LT_VirtualFunctionDecl,
+  LT_ImportStatement,
   LT_ObjCDecl, // An @interface, @implementation, or @protocol line.
   LT_ObjCMethodDecl,
-  LT_ObjCProperty // An @property line.
+  LT_ObjCProperty, // An @property line.
+  LT_Other,
+  LT_PreprocessorDirective,
+  LT_VirtualFunctionDecl
 };
 
 class AnnotatedLine {

Modified: cfe/trunk/lib/Format/UnwrappedLineParser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.cpp?rev=222637&r1=222636&r2=222637&view=diff
==============================================================================
--- cfe/trunk/lib/Format/UnwrappedLineParser.cpp (original)
+++ cfe/trunk/lib/Format/UnwrappedLineParser.cpp Sun Nov 23 10:46:28 2014
@@ -418,6 +418,8 @@ void UnwrappedLineParser::parseBlock(boo
 }
 
 static bool IsGoogScope(const UnwrappedLine &Line) {
+  // FIXME: Closure-library specific stuff should not be hard-coded but be
+  // configurable.
   if (Line.Tokens.size() < 4)
     return false;
   auto I = Line.Tokens.begin();

Modified: cfe/trunk/unittests/Format/FormatTestJS.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestJS.cpp?rev=222637&r1=222636&r2=222637&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTestJS.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTestJS.cpp Sun Nov 23 10:46:28 2014
@@ -158,6 +158,17 @@ TEST_F(FormatTestJS, GoogScopes) {
                "});  // goog.scope");
 }
 
+TEST_F(FormatTestJS, GoogModules) {
+  verifyFormat("goog.module('this.is.really.absurdly.long');",
+               getGoogleJSStyleWithColumns(40));
+  verifyFormat("goog.require('this.is.really.absurdly.long');",
+               getGoogleJSStyleWithColumns(40));
+  verifyFormat("goog.provide('this.is.really.absurdly.long');",
+               getGoogleJSStyleWithColumns(40));
+  verifyFormat("var long = goog.require('this.is.really.absurdly.long');",
+               getGoogleJSStyleWithColumns(40));
+}
+
 TEST_F(FormatTestJS, FormatsFreestandingFunctions) {
   verifyFormat("function outer1(a, b) {\n"
                "  function inner1(a, b) { return a; }\n"





More information about the cfe-commits mailing list