Bug 1020587 - Update pretty-fast to latest upstream. r=me
authorNick Fitzgerald <fitzgen@mozilla.com>
Wed, 04 Jun 2014 14:03:00 -0400
changeset 207267 e157171a4df1bd8e28efc425da03436fa73f333b
parent 207266 31db3f3b1107fb0549b26ffb94ddaa17f55fa365
child 207268 17f0049099028179eb9243851fd7d38e684443d9
push id494
push userraliiev@mozilla.com
push dateMon, 25 Aug 2014 18:42:16 +0000
treeherdermozilla-release@a3cc3e46b571 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersme
bugs1020587
milestone32.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1020587 - Update pretty-fast to latest upstream. r=me
toolkit/devtools/pretty-fast/pretty-fast.js
toolkit/devtools/pretty-fast/tests/unit/test.js
--- a/toolkit/devtools/pretty-fast/pretty-fast.js
+++ b/toolkit/devtools/pretty-fast/pretty-fast.js
@@ -1,8 +1,9 @@
+/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2; fill-column: 80 -*- */
 /*
  * Copyright 2013 Mozilla Foundation and contributors
  * Licensed under the New BSD license. See LICENSE.md or:
  * http://opensource.org/licenses/BSD-2-Clause
  */
 (function (root, factory) {
   if (typeof define === 'function' && define.amd) {
     define(factory);
@@ -319,33 +320,34 @@
         return true;
       }
       if (ltt == ";") {
         return true;
       }
 
       var ltk = lastToken.type.keyword;
       if (ltk != null) {
-        if (ltk == "break" || ltk == "continue") {
+        if (ltk == "break" || ltk == "continue" || ltk == "return") {
           return token.type.type != ";";
         }
         if (ltk != "debugger"
             && ltk != "null"
             && ltk != "true"
             && ltk != "false"
             && ltk != "this"
             && ltk != "default") {
           return true;
         }
       }
 
       if (ltt == ")" && (token.type.type != ")"
                          && token.type.type != "]"
                          && token.type.type != ";"
-                         && token.type.type != ",")) {
+                         && token.type.type != ","
+                         && token.type.type != ".")) {
         return true;
       }
     }
 
     if (token.type.isAssign) {
       return true;
     }
     if (token.type.binop != null) {
@@ -552,16 +554,17 @@
   function belongsOnStack(token) {
     var ttt = token.type.type;
     var ttk = token.type.keyword;
     return ttt == "{"
       || ttt == "("
       || ttt == "["
       || ttt == "?"
       || ttk == "do"
+      || ttk == "switch"
       || ttk == "case"
       || ttk == "default";
   }
 
   /**
    * Returns true if the given token should cause us to pop the stack.
    */
   function shouldStackPop(token, stack) {
@@ -584,17 +587,19 @@
       || (tokenType == "]" && stack[stack.length - 1] == "[\n")
   }
 
   /**
    * Returns true if the given token should cause us to increment the indent
    * level.
    */
   function incrementsIndent(token) {
-    return token.type.type == "{" || token.isArrayLiteral;
+    return token.type.type == "{"
+      || token.isArrayLiteral
+      || token.type.keyword == "switch";
   }
 
   /**
    * Add a comment to the pretty printed code.
    *
    * @param Function write
    *        The function to write pretty printed code to the result SourceNode.
    * @param Number indentLevel
@@ -719,16 +724,17 @@
     // Strings that go on the stack:
     //
     //   - "{"
     //   - "("
     //   - "["
     //   - "[\n"
     //   - "do"
     //   - "?"
+    //   - "switch"
     //   - "case"
     //   - "default"
     //
     // The difference between "[" and "[\n" is that "[\n" is used when we are
     // treating "[" and "]" tokens as line delimiters and should increment and
     // decrement the indent level when we find them.
     var stack = [];
 
@@ -751,17 +757,18 @@
       locations: true,
       sourceFile: options.url,
       onComment: function (block, text, start, end, startLoc, endLoc) {
         if (lastToken) {
           commentQueue.push({
             block: block,
             text: text,
             line: startLoc.line,
-            column: startLoc.column
+            column: startLoc.column,
+            trailing: lastToken.endLoc.line == startLoc.line
           });
         } else {
           addComment(write, indentLevel, options, block, text, startLoc.line,
                      startLoc.column);
           addedNewline = true;
         }
       }
     });
@@ -786,25 +793,36 @@
           stack.push("[\n");
         } else {
           stack.push(ttt || ttk);
         }
       }
 
       if (decrementsIndent(ttt, stack)) {
         indentLevel--;
+        if (ttt == "}"
+            && stack.length > 1
+            && stack[stack.length - 2] == "switch") {
+          indentLevel--;
+        }
       }
 
       prependWhiteSpace(token, lastToken, addedNewline, write, options,
                         indentLevel, stack);
       addToken(token, write, options);
-      addedNewline = appendNewline(token, write, stack);
+      if (commentQueue.length == 0 || !commentQueue[0].trailing) {
+        addedNewline = appendNewline(token, write, stack);
+      }
 
       if (shouldStackPop(token, stack)) {
         stack.pop();
+        if (token == "}" && stack.length
+            && stack[stack.length - 1] == "switch") {
+          stack.pop();
+        }
       }
 
       if (incrementsIndent(token)) {
         indentLevel++;
       }
 
       // Acorn's tokenizer re-uses tokens, so we have to copy the last token on
       // every iteration. We follow acorn's lead here, and reuse the lastToken
@@ -820,23 +838,27 @@
       lastToken.endLoc.line = token.endLoc.line;
       lastToken.endLoc.column = token.endLoc.column;
       lastToken.type = token.type;
       lastToken.value = token.value;
       lastToken.isArrayLiteral = token.isArrayLiteral;
 
       // Apply all the comments that have been queued up.
       if (commentQueue.length) {
-        if (!addedNewline) {
+        if (!addedNewline && !commentQueue[0].trailing) {
           write("\n");
         }
+        if (commentQueue[0].trailing) {
+          write(" ");
+        }
         for (var i = 0, n = commentQueue.length; i < n; i++) {
           var comment = commentQueue[i];
-          addComment(write, indentLevel, options, comment.block, comment.text,
-                     comment.line, comment.column);
+          var commentIndentLevel = commentQueue[i].trailing ? 0 : indentLevel;
+          addComment(write, commentIndentLevel, options, comment.block,
+                     comment.text, comment.line, comment.column);
         }
         addedNewline = true;
         commentQueue.splice(0, commentQueue.length);
       }
     }
 
     return result.toStringWithSourceMap({ file: options.url });
   };
--- a/toolkit/devtools/pretty-fast/tests/unit/test.js
+++ b/toolkit/devtools/pretty-fast/tests/unit/test.js
@@ -1,8 +1,12 @@
+/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2; fill-column: 80 -*- */
+
+"use strict";
+
 /*
  * Copyright 2013 Mozilla Foundation and contributors
  * Licensed under the New BSD license. See LICENSE.md or:
  * http://opensource.org/licenses/BSD-2-Clause
  */
 var prettyFast = this.prettyFast || require("./pretty-fast");
 
 var testCases = [
@@ -341,21 +345,21 @@ var testCases = [
     input: "bar?baz:bang;",
     output: "bar ? baz : bang;\n"
   },
 
   {
     name: "Switch statements",
     input: "switch(x){case a:foo();break;default:bar()}",
     output: "switch (x) {\n" +
-            "case a:\n" +
-            "  foo();\n" +
-            "  break;\n" +
-            "default:\n" +
-            "  bar()\n" +
+            "  case a:\n" +
+            "    foo();\n" +
+            "    break;\n" +
+            "  default:\n" +
+            "    bar()\n" +
             "}\n"
   },
 
   {
     name: "Multiple single line comments",
     input: "function f() {\n" +
            "  // a\n" +
            "  // b\n" +
@@ -476,16 +480,54 @@ var testCases = [
   },
 
   {
     name: "Escaping null character in strings",
     input: "'\\0'\n",
     output: "'\\0'\n"
   },
 
+  {
+    name: "Bug 977082 - space between grouping operator and dot notation",
+    input: "JSON.stringify(3).length;\n" +
+           "([1,2,3]).length;\n" +
+           "(new Date()).toLocaleString();\n",
+    output: "JSON.stringify(3).length;\n" +
+            "([1,\n" +
+            "2,\n" +
+            "3]).length;\n" +
+            "(new Date()).toLocaleString();\n"
+  },
+
+  {
+    name: "Bug 975477 don't move end of line comments to next line",
+    input: "switch (request.action) {\n" +
+           "  case 'show': //$NON-NLS-0$\n" +
+           "    if (localStorage.hideicon !== 'true') { //$NON-NLS-0$\n" +
+           "      chrome.pageAction.show(sender.tab.id);\n" +
+           "    }\n" +
+           "    break;\n" +
+           "  default:\n" +
+           "    console.warn('unknown request'); //$NON-NLS-0$\n" +
+           "    // don't respond if you don't understand the message.\n" +
+           "    return;\n" +
+           "}\n",
+    output: "switch (request.action) {\n" +
+            "  case 'show': //$NON-NLS-0$\n" +
+            "    if (localStorage.hideicon !== 'true') { //$NON-NLS-0$\n" +
+            "      chrome.pageAction.show(sender.tab.id);\n" +
+            "    }\n" +
+            "    break;\n" +
+            "  default:\n" +
+            "    console.warn('unknown request'); //$NON-NLS-0$\n" +
+            "    // don't respond if you don't understand the message.\n" +
+            "    return;\n" +
+            "}\n"
+  }
+
 ];
 
 var sourceMap = this.sourceMap || require("source-map");
 
 function run_test() {
   testCases.forEach(function (test) {
     console.log(test.name);