[Pkg-javascript-commits] [node-recast] 01/04: Imported Upstream version 0.11.11

Julien Puydt julien.puydt at laposte.net
Thu Aug 11 04:11:21 UTC 2016


This is an automated email from the git hooks/post-receive script.

jpuydt-guest pushed a commit to branch master
in repository node-recast.

commit e678b89bba13094a049edd9beaf4e05181bc2403
Author: Julien Puydt <julien.puydt at laposte.net>
Date:   Thu Aug 11 06:02:33 2016 +0200

    Imported Upstream version 0.11.11
---
 .editorconfig       |   1 -
 .travis.yml         |   2 +
 lib/fast-path.js    |  13 +++-
 lib/options.js      |  11 +++
 lib/printer.js      |  60 +++++++++++++--
 lib/util.js         |  17 ++++-
 package.json        |   8 +-
 test/babylon.js     |  55 ++++++++++++++
 test/es6tests.js    |  12 +--
 test/jsx.js         |   4 -
 test/parens.js      |   7 ++
 test/printer.js     | 207 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 test/type-syntax.js |   3 +-
 13 files changed, 368 insertions(+), 32 deletions(-)

diff --git a/.editorconfig b/.editorconfig
index 9541a24..70bfb79 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,3 +1,2 @@
 [*.js]
 indent_style = space
-indent_size = 4
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 10219ea..dc44815 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,7 @@
 language: node_js
 node_js:
+  - "6.0"
+  - "5.0"
   - "4.0"
   - "iojs"
   - "0.12"
diff --git a/lib/fast-path.js b/lib/fast-path.js
index 4f6ab77..255bd2a 100644
--- a/lib/fast-path.js
+++ b/lib/fast-path.js
@@ -192,8 +192,8 @@ FPp.needsParens = function(assumeExpressionContext) {
         return false;
     }
 
-    // Only expressions need parentheses.
-    if (!n.Expression.check(node)) {
+    // Only statements don't need parentheses.
+    if (n.Statement.check(node)) {
         return false;
     }
 
@@ -252,6 +252,9 @@ FPp.needsParens = function(assumeExpressionContext) {
 
     case "SequenceExpression":
         switch (parent.type) {
+        case "ReturnStatement":
+            return false;
+
         case "ForStatement":
             // Although parentheses wouldn't hurt around sequence
             // expressions in the head of for loops, traditional style
@@ -286,6 +289,10 @@ FPp.needsParens = function(assumeExpressionContext) {
             return false;
         }
 
+    case "IntersectionTypeAnnotation":
+    case "UnionTypeAnnotation":
+        return parent.type === "NullableTypeAnnotation";
+
     case "Literal":
         return parent.type === "MemberExpression"
             && isNumber.check(node.value)
@@ -371,7 +378,7 @@ var PRECEDENCE = {};
  ["<", ">", "<=", ">=", "in", "instanceof"],
  [">>", "<<", ">>>"],
  ["+", "-"],
- ["*", "/", "%"]
+ ["*", "/", "%", "**"]
 ].forEach(function(tier, i) {
     tier.forEach(function(op) {
         PRECEDENCE[op] = i;
diff --git a/lib/options.js b/lib/options.js
index 10f4520..2e71d08 100644
--- a/lib/options.js
+++ b/lib/options.js
@@ -64,6 +64,15 @@ var defaults = {
     // array expressions, functions calls and function definitions pass true
     // for this option.
     trailingComma: false,
+
+    // If you want parenthesis to wrap single-argument arrow function parameter
+    // lists, pass true for this option.
+    arrowParensAlways: false,
+
+    // There are 2 supported syntaxes (`,` and `;`) in Flow Object Types;
+    // The use of commas is in line with the more popular style and matches
+    // how objects are defined in JS, making it a bit more natural to write.
+    flowObjectCommas: true,
 }, hasOwn = defaults.hasOwnProperty;
 
 // Copy options and fill in default values.
@@ -91,5 +100,7 @@ exports.normalize = function(options) {
         tolerant: get("tolerant"),
         quote: get("quote"),
         trailingComma: get("trailingComma"),
+        arrowParensAlways: get("arrowParensAlways"),
+        flowObjectCommas: get("flowObjectCommas"),
     };
 };
diff --git a/lib/printer.js b/lib/printer.js
index e44ef0f..23e5738 100644
--- a/lib/printer.js
+++ b/lib/printer.js
@@ -294,6 +294,7 @@ function genericPrintNoParens(path, options, print) {
 
     case "SpreadElement":
     case "SpreadElementPattern":
+    case "RestProperty": // Babel 6 for ObjectPattern
     case "SpreadProperty":
     case "SpreadPropertyPattern":
     case "RestElement":
@@ -333,17 +334,20 @@ function genericPrintNoParens(path, options, print) {
             parts.push("async ");
 
         if (
+            !options.arrowParensAlways &&
             n.params.length === 1 &&
             !n.rest &&
             n.params[0].type === 'Identifier' &&
-            !n.params[0].typeAnnotation
+            !n.params[0].typeAnnotation &&
+            !n.returnType
         ) {
             parts.push(path.call(print, "params", 0));
         } else {
             parts.push(
                 "(",
                 printFunctionParams(path, options, print),
-                ")"
+                ")",
+                path.call(print, "returnType")
             );
         }
 
@@ -351,6 +355,7 @@ function genericPrintNoParens(path, options, print) {
 
         return concat(parts);
 
+    case "ClassMethod": // Babel 6
     case "MethodDefinition":
         if (n.static) {
             parts.push("static ");
@@ -562,7 +567,7 @@ function genericPrintNoParens(path, options, print) {
     case "ObjectTypeAnnotation":
         var allowBreak = false;
         var isTypeAnnotation = n.type === "ObjectTypeAnnotation";
-        var separator = isTypeAnnotation ? ';' : ',';
+        var separator = options.flowObjectCommas ? "," : (isTypeAnnotation ? ";" : ",");
         var fields = [];
 
         if (isTypeAnnotation) {
@@ -603,7 +608,7 @@ function genericPrintNoParens(path, options, print) {
                     allowBreak = !multiLine;
                 } else if (len !== 1 && isTypeAnnotation) {
                     parts.push(separator);
-                } else if (options.trailingComma) {
+                } else if (!oneLine && options.trailingComma) {
                     parts.push(separator);
                 }
                 i++;
@@ -621,6 +626,8 @@ function genericPrintNoParens(path, options, print) {
             path.call(print, "pattern")
         ]);
 
+    case "ObjectProperty": // Babel 6
+    case "ObjectMethod": // Babel 6
     case "Property": // Non-standard AST node type.
         if (n.method || n.kind === "get" || n.kind === "set") {
             return printMethod(path, options, print);
@@ -691,6 +698,11 @@ function genericPrintNoParens(path, options, print) {
     case "Super":
         return fromString("super");
 
+    case "BooleanLiteral": // Babel 6 Literal split
+    case "RegExpLiteral": // Babel 6 Literal split
+    case "NumericLiteral": // Babel 6 Literal split
+    case "StringLiteral": // Babel 6 Literal split
+    case "NullLiteral": // Babel 6 Literal split
     case "Literal":
         if (typeof n.value !== "string")
             return fromString(n.value, options);
@@ -1003,7 +1015,11 @@ function genericPrintNoParens(path, options, print) {
 
                 if (namedTypes.Literal.check(child) &&
                     typeof child.value === "string") {
-                    return child.value;
+                    if (/\S/.test(child.value)) {
+                        return child.value.replace(/^\s+|\s+$/g, "");
+                    } else if (/\n/.test(child.value)) {
+                        return "\n";
+                    }
                 }
 
                 return print(childPath);
@@ -1193,6 +1209,9 @@ function genericPrintNoParens(path, options, print) {
 
         return fromString("");
 
+    case "ExistsTypeAnnotation":
+        return fromString("*", options);
+
     case "AnyTypeAnnotation":
         return fromString("any", options);
 
@@ -1360,6 +1379,7 @@ function genericPrintNoParens(path, options, print) {
     case "ObjectTypeProperty":
         return concat([
             path.call(print, "key"),
+            n.optional ? "?" : "",
             ": ",
             path.call(print, "value")
         ]);
@@ -1408,6 +1428,28 @@ function genericPrintNoParens(path, options, print) {
             fromString(", ").join(path.map(print, "params")),
             ">"
         ]);
+    case "TypeParameter":
+        switch (n.variance) {
+            case 'plus':
+                parts.push('+');
+                break;
+            case 'minus':
+                parts.push('-');
+                break;
+            default:
+        }
+
+        parts.push(path.call(print, 'name'));
+
+        if (n.bound) {
+            parts.push(path.call(print, 'bound'));
+        }
+
+        if (n['default']) {
+            parts.push('=', path.call(print, 'default'));
+        }
+
+        return concat(parts);
 
     case "TypeofTypeAnnotation":
         return concat([
@@ -1421,6 +1463,9 @@ function genericPrintNoParens(path, options, print) {
     case "VoidTypeAnnotation":
         return fromString("void", options);
 
+    case "NullTypeAnnotation":
+        return fromString("null", options);
+
     // Unhandled types below. If encountered, nodes of these types should
     // be either left alone or desugared into AST types that are fully
     // supported by the pretty-printer.
@@ -1724,7 +1769,10 @@ function printExportDeclaration(path, options, print) {
 
     var lines = concat(parts);
 
-    if (lastNonSpaceCharacter(lines) !== ";") {
+    if (lastNonSpaceCharacter(lines) !== ";" &&
+        ! (decl.declaration &&
+           (decl.declaration.type === "FunctionDeclaration" ||
+            decl.declaration.type === "ClassDeclaration"))) {
         lines = concat([lines, ";"]);
     }
 
diff --git a/lib/util.js b/lib/util.js
index f78cdaa..ae6e69d 100644
--- a/lib/util.js
+++ b/lib/util.js
@@ -111,7 +111,7 @@ util.getTrueLoc = function(node, lines) {
   // If the node is an export declaration and its .declaration has any
   // decorators, their locations might contribute to the true start/end
   // positions of the export declaration node.
-  if (util.isExportDeclaration(node) &&
+  if (node.declaration && util.isExportDeclaration(node) &&
       node.declaration.decorators) {
     node.declaration.decorators.forEach(include);
   }
@@ -195,6 +195,21 @@ util.fixFaultyLocations = function(node, lines) {
       // because their .id fields are ignored anyway.
       node.value.id = null;
     }
+
+  } else if (node.type === "ObjectTypeProperty") {
+    var loc = node.loc;
+    var end = loc && loc.end;
+    if (end) {
+      end = copyPos(end);
+      if (lines.prevPos(end) &&
+          lines.charAt(end) === ",") {
+        // Some parsers accidentally include trailing commas in the
+        // .loc.end information for ObjectTypeProperty nodes.
+        if ((end = lines.skipSpaces(end, true, true))) {
+          loc.end = end;
+        }
+      }
+    }
   }
 };
 
diff --git a/package.json b/package.json
index b87bb3b..3d84659 100644
--- a/package.json
+++ b/package.json
@@ -12,7 +12,7 @@
     "parsing",
     "pretty-printing"
   ],
-  "version": "0.11.4",
+  "version": "0.11.11",
   "homepage": "http://github.com/benjamn/recast",
   "repository": {
     "type": "git",
@@ -28,15 +28,15 @@
     "fs": false
   },
   "dependencies": {
-    "ast-types": "0.8.16",
+    "ast-types": "0.8.18",
     "esprima": "~2.7.1",
     "private": "~0.1.5",
     "source-map": "~0.5.0"
   },
   "devDependencies": {
-    "babylon": "~6.4.2",
+    "babylon": "~6.8.0",
     "esprima-fb": "^15001.1001.0-dev-harmony-fb",
-    "mocha": "~2.2.5"
+    "mocha": "~3.0.1"
   },
   "engines": {
     "node": ">= 0.8"
diff --git a/test/babylon.js b/test/babylon.js
index 319474e..2fa96db 100644
--- a/test/babylon.js
+++ b/test/babylon.js
@@ -161,4 +161,59 @@ describe("decorators", function () {
       ['import x from "x";'].concat(code.split(eol)).join(eol)
     );
   });
+
+  it("should not print delimiters with type annotations", function () {
+    var code = [
+      'type X = {',
+      '  a: number,',
+      '  b: number,',
+      '};',
+    ].join('\n');
+
+    var parseOptions = {
+      parser: {
+        parse: function (source) {
+          return babylon.parse(source, {plugins: ['flow']});
+        }
+      },
+    };
+
+    var ast = recast.parse(code, parseOptions)
+    var root = new recast.types.NodePath(ast);
+
+    root.get('program', 'body', 0, 'right', 'properties', 0).prune();
+
+    assert.strictEqual(
+      recast.print(ast).code,
+      "type X = {b: number};"
+    );
+  });
+
+  function parseExpression(code) {
+    return recast.parse(code, parseOptions).program.body[0].expression;
+  }
+
+  it("should parenthesize ** operator arguments when lower precedence", function () {
+    var ast = recast.parse('a ** b;', parseOptions);
+
+    ast.program.body[0].expression.left = parseExpression('x + y');
+    ast.program.body[0].expression.right = parseExpression('x || y');
+
+    assert.strictEqual(
+      recast.print(ast).code,
+      '(x + y) ** (x || y);'
+    );
+  });
+
+  it("should parenthesize ** operator arguments as needed when same precedence", function () {
+    var ast = recast.parse('a ** b;', parseOptions);
+
+    ast.program.body[0].expression.left = parseExpression('x * y');
+    ast.program.body[0].expression.right = parseExpression('x / y');
+
+    assert.strictEqual(
+      recast.print(ast).code,
+      'x * y ** (x / y);'
+    );
+  });
 });
diff --git a/test/es6tests.js b/test/es6tests.js
index 87af3a2..70e4535 100644
--- a/test/es6tests.js
+++ b/test/es6tests.js
@@ -105,10 +105,10 @@ describe("import/export syntax", function() {
         check("export default {};");
         check("export default [];");
         check("export default foo;");
-        check("export default function () {};");
-        check("export default class {};");
-        check("export default function foo () {};");
-        check("export default class foo {};");
+        check("export default function () {}");
+        check("export default class {}");
+        check("export default function foo () {}");
+        check("export default class foo {}");
 
         // variables exports
         check("export var foo = 1;");
@@ -117,8 +117,8 @@ describe("import/export syntax", function() {
         check("export let foo = 2;");
         check("export let bar;"); // lazy initialization
         check("export const foo = 3;");
-        check("export function foo () {};");
-        check("export class foo {};");
+        check("export function foo () {}");
+        check("export class foo {}");
 
         // named exports
         check("export {foo};");
diff --git a/test/jsx.js b/test/jsx.js
index 5569b48..ea1c511 100644
--- a/test/jsx.js
+++ b/test/jsx.js
@@ -47,8 +47,4 @@ describe("JSX Compatability", function() {
   it("should parse and print namespaced elements", function() {
     check("<Foo.Bar />");
   });
-
-  it('should parse and print string literal children with leading and trailing whitespace', function () {
-    check("<div>Hello, {name} and {name2}.</div>");
-  });
 });
diff --git a/test/parens.js b/test/parens.js
index 5fd5211..2c36074 100644
--- a/test/parens.js
+++ b/test/parens.js
@@ -184,6 +184,13 @@ describe("parens", function() {
         assert.strictEqual(objReprint, objCode);
     });
 
+    it("don't parenthesize return statements with sequence expressions", function() {
+        var objCode = "function foo() { return 1, 2; }";
+        var objAst = parse(objCode);
+        var objReprint = printer.print(objAst).code;
+        assert.strictEqual(objReprint, objCode);
+    });
+
     it("NegatedLoopCondition", function() {
         var ast = parse([
             "for (var i = 0; i < 10; ++i) {",
diff --git a/test/printer.js b/test/printer.js
index 90528fc..ac34c2e 100644
--- a/test/printer.js
+++ b/test/printer.js
@@ -538,12 +538,6 @@ describe("printer", function() {
         ast = parse(code);
 
         assert.strictEqual(printer.print(ast).code, code);
-        assert.strictEqual(printer.printGenerically(ast).code, code + ";");
-
-        code = "export function foo() {};";
-        ast = parse(code);
-
-        assert.strictEqual(printer.print(ast).code, code);
         assert.strictEqual(printer.printGenerically(ast).code, code);
     });
 
@@ -956,6 +950,26 @@ describe("printer", function() {
         assert.strictEqual(pretty, code);
     });
 
+    it("adds parenthesis around single arrow function arg when options.arrowParensAlways is true", function() {
+      var code = "(a) => {};";
+
+      var fn = b.arrowFunctionExpression(
+          [b.identifier('a')],
+          b.blockStatement([]),
+          false
+      );
+
+      var ast = b.program([
+          b.expressionStatement(fn)
+      ]);
+
+      var printer = new Printer({
+        arrowParensAlways: true
+      });
+      var pretty = printer.printGenerically(ast).code;
+      assert.strictEqual(pretty, code);
+    });
+
     it("adds parenthesis around async arrow functions with args", function() {
         var code = "async () => {};";
 
@@ -1015,6 +1029,73 @@ describe("printer", function() {
         assert.strictEqual(pretty, code);
     });
 
+    it("adds parenthesis around arrow functions with single arg and a return type", function() {
+        var code = "(a): void => {};";
+
+        var arg = b.identifier('a');
+
+        var fn = b.arrowFunctionExpression(
+            [arg],
+            b.blockStatement([]),
+            false
+        );
+
+        fn.returnType = b.typeAnnotation(
+            b.voidTypeAnnotation()
+        );
+
+        var ast = b.program([
+            b.expressionStatement(fn)
+        ]);
+
+        var printer = new Printer();
+        var pretty = printer.printGenerically(ast).code;
+        assert.strictEqual(pretty, code);
+    });
+
+    it("prints class property initializers with type annotations correctly", function() {
+        var code = [
+            "class A {",
+            "  foo = (a: b): void => {};",
+            "}",
+        ].join(eol);
+
+        var arg = b.identifier('a');
+        arg.typeAnnotation = b.typeAnnotation(
+            b.genericTypeAnnotation(b.identifier('b'), null)
+        );
+
+        var fn = b.arrowFunctionExpression(
+            [arg],
+            b.blockStatement([]),
+            false
+        );
+        fn.returnType = b.typeAnnotation(
+            b.voidTypeAnnotation()
+        );
+
+        var ast = b.program([
+            b.classDeclaration(
+                b.identifier('A'),
+                b.classBody([
+                    b.classProperty(
+                        b.identifier('foo'),
+                        fn,
+                        null,
+                        false
+                    )
+                ])
+            )
+        ]);
+
+        var printer = new Printer({
+            tabWidth: 2
+        });
+
+        var pretty = printer.printGenerically(ast).code;
+        assert.strictEqual(pretty, code);
+    });
+
     it("prints ClassProperty correctly", function() {
         var code = [
             "class A {",
@@ -1271,4 +1352,118 @@ describe("printer", function() {
 
         assert.strictEqual(actual, expected);
     });
+
+    it("prints commas for flow object types by default", function() {
+        var code = [
+            "type MyType = {",
+            "    message: string,",
+            "    isAwesome: boolean,",
+            "};"
+        ].join(eol);
+
+        var ast = b.typeAlias(
+            b.identifier("MyType"),
+            null,
+            b.objectTypeAnnotation([
+                b.objectTypeProperty(
+                    b.identifier("message"),
+                    b.stringTypeAnnotation(),
+                    false
+                ),
+                b.objectTypeProperty(
+                    b.identifier("isAwesome"),
+                    b.booleanTypeAnnotation(),
+                    false
+                )
+            ])
+        );
+
+        var printer = new Printer();
+        var pretty = printer.printGenerically(ast).code;
+        assert.strictEqual(pretty, code);
+    });
+
+    it("shouldn't print a trailing comma for single-line flow object types", function() {
+        var code1 = "type MyType = {message: string};";
+        var code2 = "type MyType = {[key: string]: string};";
+
+        var ast1 = b.typeAlias(
+            b.identifier("MyType"),
+            null,
+            b.objectTypeAnnotation([
+                b.objectTypeProperty(
+                    b.identifier("message"),
+                    b.stringTypeAnnotation(),
+                    false
+                )
+            ])
+        );
+
+        var ast2 = b.typeAlias(
+            b.identifier("MyType"),
+            null,
+            b.objectTypeAnnotation([], [
+                b.objectTypeIndexer(
+                    b.identifier('key'),
+                    b.stringTypeAnnotation(),
+                    b.stringTypeAnnotation(),
+                    false
+                )
+            ])
+        );
+
+        var printer = new Printer({trailingComma: true});
+        var pretty1 = printer.printGenerically(ast1).code;
+        var pretty2 = printer.printGenerically(ast2).code;
+        assert.strictEqual(pretty1, code1);
+        assert.strictEqual(pretty2, code2);
+    });
+
+    it("prints semicolons for flow object types when options.flowObjectCommas is falsy", function() {
+        var code = [
+            "type MyType = {",
+            "    message: string;",
+            "    isAwesome: boolean;",
+            "};"
+        ].join(eol);
+
+        var ast = b.typeAlias(
+            b.identifier("MyType"),
+            null,
+            b.objectTypeAnnotation([
+                b.objectTypeProperty(
+                    b.identifier("message"),
+                    b.stringTypeAnnotation(),
+                    false
+                ),
+                b.objectTypeProperty(
+                    b.identifier("isAwesome"),
+                    b.booleanTypeAnnotation(),
+                    false
+                )
+            ])
+        );
+
+        var printer = new Printer({ flowObjectCommas: false });
+        var pretty = printer.printGenerically(ast).code;
+        assert.strictEqual(pretty, code);
+    });
+
+    it("prints parens for nullable union/intersection types", function() {
+        var code = "type MyType = ?(string | number);";
+
+        var ast = b.typeAlias(
+            b.identifier("MyType"),
+            null,
+            b.nullableTypeAnnotation(
+                b.unionTypeAnnotation(
+                    [b.stringTypeAnnotation(), b.numberTypeAnnotation()]
+                )
+            )
+        );
+
+        var printer = new Printer({});
+        var pretty = printer.printGenerically(ast).code;
+        assert.strictEqual(pretty, code);
+    });
 });
diff --git a/test/type-syntax.js b/test/type-syntax.js
index 87e9fdd..cf2fc2f 100644
--- a/test/type-syntax.js
+++ b/test/type-syntax.js
@@ -7,7 +7,7 @@ var b = types.builders;
 var eol = require("os").EOL;
 
 describe("type syntax", function() {
-  var printer = new Printer({ tabWidth: 2, quote: 'single' });
+  var printer = new Printer({ tabWidth: 2, quote: 'single', flowObjectCommas: false });
   var parseOptions = {
     parser: require("esprima-fb")
   };
@@ -50,6 +50,7 @@ describe("type syntax", function() {
     // Type aliases
     check("type A = B;");
     check("type A = B.C;");
+    check("type A = {optionalNumber?: number};")
 
     // Generic
     check("var a: Array<Foo>;");

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-recast.git



More information about the Pkg-javascript-commits mailing list