[Pkg-javascript-commits] [acorn] 01/19: Import 0.12.0 by hand in upstream branch

Julien Puydt julien.puydt at laposte.net
Fri Nov 25 08:13:24 UTC 2016


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

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

commit 937788adae044fa23a392f7ce49c1372625796d5
Author: Julien Puydt <julien.puydt at laposte.net>
Date:   Tue Nov 15 17:49:47 2016 +0100

    Import 0.12.0 by hand in upstream branch
---
 .gitignore            |    2 +
 .npmignore            |    3 +
 README.md             |   19 +-
 acorn.js              |  878 ++++++++-----
 acorn_loose.js        |  274 ++--
 bin/acorn             |   22 +-
 package.json          |    4 +-
 test/driver.js        |    5 +-
 test/tests-harmony.js | 3387 +++++++++++++++++++++++++++++--------------------
 test/tests.js         |  176 ++-
 util/walk.js          |   20 +-
 11 files changed, 2896 insertions(+), 1894 deletions(-)

diff --git a/.gitignore b/.gitignore
index 7a9d2aa..66cc69a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
 /node_modules
 /.tern-port
+/acorn_csp.js
+/local
diff --git a/.npmignore b/.npmignore
new file mode 100644
index 0000000..ecba291
--- /dev/null
+++ b/.npmignore
@@ -0,0 +1,3 @@
+/.tern-port
+/test
+/local
diff --git a/README.md b/README.md
index 58627b0..0b0d841 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,8 @@
 # Acorn
 
 [![Build Status](https://travis-ci.org/marijnh/acorn.svg?branch=master)](https://travis-ci.org/marijnh/acorn)
+[![NPM version](https://img.shields.io/npm/v/acorn.svg)](https://www.npmjs.org/package/acorn)  
+[Author funding status: ![maintainer happiness](https://marijnhaverbeke.nl/fund/status_s.png)](https://marijnhaverbeke.nl/fund/)
 
 A tiny, fast JavaScript parser, written completely in JavaScript.
 
@@ -72,6 +74,10 @@ object referring to that same position.
   declarations can only appear at a program's top level. Setting this
   option to `true` allows them anywhere where a statement is allowed.
 
+- **allowHashBang**: When this is enabled (off by default), if the
+  code starts with the characters `#!` (as in a shellscript), the
+  first line will be treated as a comment.
+
 - **locations**: When `true`, each node has a `loc` object attached
   with `start` and `end` subobjects, each of which contains the
   one-based line and zero-based column numbers in `{line, column}`
@@ -158,6 +164,17 @@ token, and returns a `{start, end, type, value}` object (with added
 `loc` property when the `locations` option is enabled and `range`
 property when the `ranges` option is enabled).
 
+In ES6 environment, returned result can be used as any other protocol-compliant iterable:
+
+```javascript
+for (let token of acorn.tokenize(str)) {
+  // iterate over the tokens
+}
+
+// transform code to array of tokens:
+var tokens = [...acorn.tokenize(str)];
+```
+
 **tokTypes** holds an object mapping names to the token type objects
 that end up in the `type` properties of tokens.
 
@@ -215,7 +232,7 @@ but never raises an error, and will do its best to parse syntactically
 invalid code in as meaningful a way as it can. It'll insert identifier
 nodes with name `"✖"` as placeholders in places where it can't make
 sense of the input. Depends on `acorn.js`, because it uses the same
-tokenizer. The loose parser does not support ECMAScript 6 syntax yet.
+tokenizer.
 
 ### util/walk.js ###
 
diff --git a/acorn.js b/acorn.js
index d8ae3cc..542844c 100644
--- a/acorn.js
+++ b/acorn.js
@@ -28,7 +28,7 @@
 })(this, function(exports) {
   "use strict";
 
-  exports.version = "0.11.0";
+  exports.version = "0.12.0";
 
   // The main exported interface (under `self.acorn` when in the
   // browser) is a `parse` function that takes a code string and
@@ -74,6 +74,9 @@
     // When enabled, import/export statements are not constrained to
     // appearing at the top of the program.
     allowImportExportEverywhere: false,
+    // When enabled, hashbang directive in the beginning of file
+    // is allowed and treated as a line comment.
+    allowHashBang: false,
     // When `locations` is on, `loc` properties holding objects with
     // `start` and `end` properties in `{line, column}` form (with
     // line being 1-based and column 0-based) will be attached to the
@@ -197,9 +200,6 @@
     if (options.locations) {
       this.loc = new SourceLocation();
       this.loc.end = tokEndLoc;
-      // TODO: remove in next major release
-      this.startLoc = tokStartLoc;
-      this.endLoc = tokEndLoc;
     }
     if (options.ranges)
       this.range = [tokStart, tokEnd];
@@ -220,12 +220,12 @@
     initTokenState();
     skipSpace();
 
-    function getToken(forceRegexp) {
+    function getToken() {
       lastEnd = tokEnd;
-      readToken(forceRegexp);
+      readToken();
       return new Token();
     }
-    getToken.jumpTo = function(pos, reAllowed) {
+    getToken.jumpTo = function(pos, exprAllowed) {
       tokPos = pos;
       if (options.locations) {
         tokCurLine = 1;
@@ -236,12 +236,23 @@
           tokLineStart = match.index + match[0].length;
         }
       }
-      tokRegexpAllowed = reAllowed;
+      tokExprAllowed = !!exprAllowed;
       skipSpace();
     };
-    getToken.noRegexp = function() {
-      tokRegexpAllowed = false;
-    };
+    getToken.current = function() { return new Token(); };
+    if (typeof Symbol !== 'undefined') {
+      getToken[Symbol.iterator] = function () {
+        return {
+          next: function () {
+            var token = getToken();
+            return {
+              done: token.type === _eof,
+              value: token
+            };
+          }
+        };
+      };
+    }
     getToken.options = options;
     return getToken;
   };
@@ -274,12 +285,13 @@
 
   // Internal state for the tokenizer. To distinguish between division
   // operators and regular expressions, it remembers whether the last
-  // token was one that is allowed to be followed by an expression.
-  // (If it is, a slash is probably a regexp, if it isn't it's a
-  // division operator. See the `parseStatement` function for a
-  // caveat.)
+  // token was one that is allowed to be followed by an expression. In
+  // some cases, notably after ')' or '}' tokens, the situation
+  // depends on the context before the matching opening bracket, so
+  // tokContext keeps a stack of information about current bracketed
+  // forms.
 
-  var tokRegexpAllowed;
+  var tokContext, tokExprAllowed;
 
   // When `options.locations` is true, these are used to keep
   // track of the current line, and know when a new line has been
@@ -300,22 +312,10 @@
 
   var inFunction, inGenerator, labels, strict;
 
-  // This counter is used for checking that arrow expressions did
-  // not contain nested parentheses in argument list.
-
-  var metParenL;
-
-  // This is used by the tokenizer to track the template strings it is
-  // inside, and count the amount of open braces seen inside them, to
-  // be able to switch back to a template token when the } to match ${
-  // is encountered. It will hold an array of integers.
-
-  var templates;
-
   function initParserState() {
     lastStart = lastEnd = tokPos;
     if (options.locations) lastEndLoc = curPosition();
-    inFunction = inGenerator = strict = false;
+    inFunction = inGenerator = false;
     labels = [];
     skipSpace();
     readToken();
@@ -413,8 +413,9 @@
   var _braceR = {type: "}"}, _parenL = {type: "(", beforeExpr: true}, _parenR = {type: ")"};
   var _comma = {type: ",", beforeExpr: true}, _semi = {type: ";", beforeExpr: true};
   var _colon = {type: ":", beforeExpr: true}, _dot = {type: "."}, _question = {type: "?", beforeExpr: true};
-  var _arrow = {type: "=>", beforeExpr: true}, _template = {type: "template"}, _templateContinued = {type: "templateContinued"};
-  var _ellipsis = {type: "...", prefix: true, beforeExpr: true};
+  var _arrow = {type: "=>", beforeExpr: true}, _template = {type: "template"};
+  var _ellipsis = {type: "...", beforeExpr: true};
+  var _backQuote = {type: "`"}, _dollarBraceL = {type: "${", beforeExpr: true};
 
   // Operators. These carry several kinds of properties to help the
   // parser use them properly (the presence of these properties is
@@ -456,8 +457,8 @@
                       parenL: _parenL, parenR: _parenR, comma: _comma, semi: _semi, colon: _colon,
                       dot: _dot, ellipsis: _ellipsis, question: _question, slash: _slash, eq: _eq,
                       name: _name, eof: _eof, num: _num, regexp: _regexp, string: _string,
-                      arrow: _arrow, template: _template, templateContinued: _templateContinued, star: _star,
-                      assign: _assign};
+                      arrow: _arrow, template: _template, star: _star, assign: _assign,
+                      backQuote: _backQuote, dollarBraceL: _dollarBraceL};
   for (var kw in keywordTypes) exports.tokTypes["_" + kw] = keywordTypes[kw];
 
   // This is a trick taken from Esprima. It turns out that, on
@@ -595,7 +596,7 @@
 
   Position.prototype.offset = function(n) {
     return new Position(this.line, this.column + n);
-  }
+  };
 
   function curPosition() {
     return new Position(tokCurLine, tokPos - tokLineStart);
@@ -612,25 +613,95 @@
       tokCurLine = 1;
       tokPos = tokLineStart = 0;
     }
-    tokRegexpAllowed = true;
-    metParenL = 0;
-    templates = [];
+    tokType = _eof;
+    tokContext = [b_stat];
+    tokExprAllowed = true;
+    strict = false;
+    if (tokPos === 0 && options.allowHashBang && input.slice(0, 2) === '#!') {
+      skipLineComment(2);
+    }
+  }
+
+  // The algorithm used to determine whether a regexp can appear at a
+  // given point in the program is loosely based on sweet.js' approach.
+  // See https://github.com/mozilla/sweet.js/wiki/design
+
+  var b_stat = {token: "{", isExpr: false}, b_expr = {token: "{", isExpr: true}, b_tmpl = {token: "${", isExpr: true};
+  var p_stat = {token: "(", isExpr: false}, p_expr = {token: "(", isExpr: true};
+  var q_tmpl = {token: "`", isExpr: true}, f_expr = {token: "function", isExpr: true};
+
+  function curTokContext() {
+    return tokContext[tokContext.length - 1];
+  }
+
+  function braceIsBlock(prevType) {
+    var parent;
+    if (prevType === _colon && (parent = curTokContext()).token == "{")
+      return !parent.isExpr;
+    if (prevType === _return)
+      return newline.test(input.slice(lastEnd, tokStart));
+    if (prevType === _else || prevType === _semi || prevType === _eof)
+      return true;
+    if (prevType == _braceL)
+      return curTokContext() === b_stat;
+    return !tokExprAllowed;
   }
 
   // Called at the end of every token. Sets `tokEnd`, `tokVal`, and
-  // `tokRegexpAllowed`, and skips the space after the token, so that
-  // the next one's `tokStart` will point at the right position.
+  // maintains `tokContext` and `tokExprAllowed`, and skips the space
+  // after the token, so that the next one's `tokStart` will point at
+  // the right position.
 
-  function finishToken(type, val, shouldSkipSpace) {
+  function finishToken(type, val) {
     tokEnd = tokPos;
     if (options.locations) tokEndLoc = curPosition();
+    var prevType = tokType, preserveSpace = false;
     tokType = type;
-    if (shouldSkipSpace !== false) skipSpace();
     tokVal = val;
-    tokRegexpAllowed = type.beforeExpr;
-    if (options.onToken) {
-      options.onToken(new Token());
+
+    // Update context info
+    if (type === _parenR || type === _braceR) {
+      var out = tokContext.pop();
+      if (out === b_tmpl) {
+        preserveSpace = true;
+      } else if (out === b_stat && curTokContext() === f_expr) {
+        tokContext.pop();
+        tokExprAllowed = false;
+      } else {
+        tokExprAllowed = !(out && out.isExpr);
+      }
+    } else if (type === _braceL) {
+      tokContext.push(braceIsBlock(prevType) ? b_stat : b_expr);
+      tokExprAllowed = true;
+    } else if (type === _dollarBraceL) {
+      tokContext.push(b_tmpl);
+      tokExprAllowed = true;
+    } else if (type == _parenL) {
+      var statementParens = prevType === _if || prevType === _for || prevType === _with || prevType === _while;
+      tokContext.push(statementParens ? p_stat : p_expr);
+      tokExprAllowed = true;
+    } else if (type == _incDec) {
+      // tokExprAllowed stays unchanged
+    } else if (type.keyword && prevType == _dot) {
+      tokExprAllowed = false;
+    } else if (type == _function) {
+      if (curTokContext() !== b_stat) {
+        tokContext.push(f_expr);
+      }
+      tokExprAllowed = false;
+    } else if (type === _backQuote) {
+      if (curTokContext() === q_tmpl) {
+        tokContext.pop();
+      } else {
+        tokContext.push(q_tmpl);
+        preserveSpace = true;
+      }
+      tokExprAllowed = false;
+    } else {
+      tokExprAllowed = type.beforeExpr;
     }
+
+    if (!preserveSpace) skipSpace();
   }
 
   function skipBlockComment() {
@@ -716,9 +787,6 @@
   //
   // All in the name of speed.
   //
-  // The `forceRegexp` parameter is used in the one case where the
-  // `tokRegexpAllowed` trick does not work. See `parseStatement`.
-
   function readToken_dot() {
     var next = input.charCodeAt(tokPos + 1);
     if (next >= 48 && next <= 57) return readNumber(true);
@@ -734,7 +802,7 @@
 
   function readToken_slash() { // '/'
     var next = input.charCodeAt(tokPos + 1);
-    if (tokRegexpAllowed) {++tokPos; return readRegexp();}
+    if (tokExprAllowed) {++tokPos; return readRegexp();}
     if (next === 61) return finishOp(_assign, 2);
     return finishOp(_slash, 1);
   }
@@ -818,23 +886,17 @@
     case 44: ++tokPos; return finishToken(_comma);
     case 91: ++tokPos; return finishToken(_bracketL);
     case 93: ++tokPos; return finishToken(_bracketR);
-    case 123:
-      ++tokPos;
-      if (templates.length) ++templates[templates.length - 1];
-      return finishToken(_braceL);
-    case 125:
-      ++tokPos;
-      if (templates.length && --templates[templates.length - 1] === 0)
-        return readTemplateString(_templateContinued);
-      else
-        return finishToken(_braceR);
+    case 123: ++tokPos; return finishToken(_braceL);
+    case 125: ++tokPos; return finishToken(_braceR);
     case 58: ++tokPos; return finishToken(_colon);
     case 63: ++tokPos; return finishToken(_question);
 
     case 96: // '`'
       if (options.ecmaVersion >= 6) {
         ++tokPos;
-        return readTemplateString(_template);
+        return finishToken(_backQuote);
+      } else {
+        return false;
       }
 
     case 48: // '0'
@@ -886,13 +948,15 @@
     return false;
   }
 
-  function readToken(forceRegexp) {
-    if (!forceRegexp) tokStart = tokPos;
-    else tokPos = tokStart + 1;
+  function readToken() {
+    tokStart = tokPos;
     if (options.locations) tokStartLoc = curPosition();
-    if (forceRegexp) return readRegexp();
     if (tokPos >= inputLen) return finishToken(_eof);
 
+    if (curTokContext() === q_tmpl) {
+      return readTmplToken();
+    }
+
     var code = input.charCodeAt(tokPos);
 
     // Identifier or keyword. '\uXXXX' sequences are allowed in
@@ -1056,55 +1120,64 @@
   }
 
   function readString(quote) {
-    ++tokPos;
-    var out = "";
+    var out = "", chunkStart = ++tokPos;
     for (;;) {
       if (tokPos >= inputLen) raise(tokStart, "Unterminated string constant");
       var ch = input.charCodeAt(tokPos);
-      if (ch === quote) {
-        ++tokPos;
-        return finishToken(_string, out);
-      }
+      if (ch === quote) break;
       if (ch === 92) { // '\'
+        out += input.slice(chunkStart, tokPos);
         out += readEscapedChar();
+        chunkStart = tokPos;
       } else {
+        if (isNewLine(ch)) raise(tokStart, "Unterminated string constant");
         ++tokPos;
-        if (newline.test(String.fromCharCode(ch))) {
-          raise(tokStart, "Unterminated string constant");
-        }
-        out += String.fromCharCode(ch); // '\'
       }
     }
+    out += input.slice(chunkStart, tokPos++);
+    return finishToken(_string, out);
   }
 
-  function readTemplateString(type) {
-    if (type == _templateContinued) templates.pop();
-    var out = "", start = tokPos;;
+  // Reads template string tokens.
+
+  function readTmplToken() {
+    var out = "", chunkStart = tokPos;
     for (;;) {
       if (tokPos >= inputLen) raise(tokStart, "Unterminated template");
-      var ch = input.charAt(tokPos);
-      if (ch === "`" || ch === "$" && input.charCodeAt(tokPos + 1) === 123) { // '`', '${'
-        var raw = input.slice(start, tokPos);
-        ++tokPos;
-        if (ch == "$") { ++tokPos; templates.push(1); }
-        return finishToken(type, {cooked: out, raw: raw});
+      var ch = input.charCodeAt(tokPos);
+      if (ch === 96 || ch === 36 && input.charCodeAt(tokPos + 1) === 123) { // '`', '${'
+        if (tokPos === tokStart && tokType === _template) {
+          if (ch === 36) {
+            tokPos += 2;
+            return finishToken(_dollarBraceL);
+          } else {
+            ++tokPos;
+            return finishToken(_backQuote);
+          }
+        }
+        out += input.slice(chunkStart, tokPos);
+        return finishToken(_template, out);
       }
-
-      if (ch === "\\") { // '\'
+      if (ch === 92) { // '\'
+        out += input.slice(chunkStart, tokPos);
         out += readEscapedChar();
-      } else {
+        chunkStart = tokPos;
+      } else if (isNewLine(ch)) {
+        out += input.slice(chunkStart, tokPos);
         ++tokPos;
-        if (newline.test(ch)) {
-          if (ch === "\r" && input.charCodeAt(tokPos) === 10) {
-            ++tokPos;
-            ch = "\n";
-          }
-          if (options.locations) {
-            ++tokCurLine;
-            tokLineStart = tokPos;
-          }
+        if (ch === 13 && input.charCodeAt(tokPos) === 10) {
+          ++tokPos;
+          out += "\n";
+        } else {
+          out += String.fromCharCode(ch);
         }
-        out += ch;
+        if (options.locations) {
+          ++tokCurLine;
+          tokLineStart = tokPos;
+        }
+        chunkStart = tokPos;
+      } else {
+        ++tokPos;
       }
     }
   }
@@ -1159,20 +1232,19 @@
   // Read an identifier, and return it as a string. Sets `containsEsc`
   // to whether the word contained a '\u' escape.
   //
-  // Only builds up the word character-by-character when it actually
-  // containeds an escape, as a micro-optimization.
+  // Incrementally adds only escaped chars, adding other chunks as-is
+  // as a micro-optimization.
 
   function readWord1() {
     containsEsc = false;
-    var word, first = true, start = tokPos;
-    for (;;) {
+    var word = "", first = true, chunkStart = tokPos;
+    while (tokPos < inputLen) {
       var ch = input.charCodeAt(tokPos);
       if (isIdentifierChar(ch)) {
-        if (containsEsc) word += input.charAt(tokPos);
         ++tokPos;
       } else if (ch === 92) { // "\"
-        if (!containsEsc) word = input.slice(start, tokPos);
         containsEsc = true;
+        word += input.slice(chunkStart, tokPos);
         if (input.charCodeAt(++tokPos) != 117) // "u"
           raise(tokPos, "Expecting Unicode escape sequence \\uXXXX");
         ++tokPos;
@@ -1182,12 +1254,13 @@
         if (!(first ? isIdentifierStart(esc) : isIdentifierChar(esc)))
           raise(tokPos - 4, "Invalid Unicode escape");
         word += escStr;
+        chunkStart = tokPos;
       } else {
         break;
       }
       first = false;
     }
-    return containsEsc ? word : input.slice(start, tokPos);
+    return word + input.slice(chunkStart, tokPos);
   }
 
   // Read an identifier or keyword token. Will check for reserved
@@ -1226,17 +1299,21 @@
   // Continue to the next token.
 
   function next() {
+    if (options.onToken)
+      options.onToken(new Token());
+
     lastStart = tokStart;
     lastEnd = tokEnd;
     lastEndLoc = tokEndLoc;
     readToken();
   }
 
-  // Enter strict mode. Re-reads the next token to please pedantic
-  // tests ("use strict"; 010; -- should fail).
+  // Enter strict mode. Re-reads the next number or string to
+  // please pedantic tests ("use strict"; 010; -- should fail).
 
   function setStrict(strct) {
     strict = strct;
+    if (tokType !== _num && tokType !== _string) return;
     tokPos = tokStart;
     if (options.locations) {
       while (tokPos < tokLineStart) {
@@ -1311,6 +1388,8 @@
     return node;
   }
 
+  // Finish node at given position
+
   function finishNodeAt(node, type, pos) {
     if (options.locations) { node.loc.end = pos[1]; pos = pos[0]; }
     node.type = type;
@@ -1339,6 +1418,24 @@
     }
   }
 
+  // Tests whether parsed token is a contextual keyword.
+
+  function isContextual(name) {
+    return tokType === _name && tokVal === name;
+  }
+
+  // Consumes contextual keyword if possible.
+
+  function eatContextual(name) {
+    return tokVal === name && eat(_name);
+  }
+
+  // Asserts that following token is given contextual keyword.
+
+  function expectContextual(name) {
+    if (!eatContextual(name)) unexpected();
+  }
+
   // Test whether a semicolon can be inserted at the current position.
 
   function canInsertSemicolon() {
@@ -1371,53 +1468,139 @@
   function has(obj, propName) {
     return Object.prototype.hasOwnProperty.call(obj, propName);
   }
+
   // Convert existing expression atom to assignable pattern
   // if possible.
 
-  function toAssignable(node, allowSpread, checkType) {
+  function toAssignable(node, isBinding) {
     if (options.ecmaVersion >= 6 && node) {
       switch (node.type) {
         case "Identifier":
-        case "MemberExpression":
+        case "ObjectPattern":
+        case "ArrayPattern":
+        case "AssignmentPattern":
           break;
 
         case "ObjectExpression":
           node.type = "ObjectPattern";
           for (var i = 0; i < node.properties.length; i++) {
             var prop = node.properties[i];
-            if (prop.kind !== "init") unexpected(prop.key.start);
-            toAssignable(prop.value, false, checkType);
+            if (prop.kind !== "init") raise(prop.key.start, "Object pattern can't contain getter or setter");
+            toAssignable(prop.value, isBinding);
           }
           break;
 
         case "ArrayExpression":
           node.type = "ArrayPattern";
-          for (var i = 0, lastI = node.elements.length - 1; i <= lastI; i++) {
-            toAssignable(node.elements[i], i === lastI, checkType);
-          }
+          toAssignableList(node.elements, isBinding);
           break;
 
-        case "SpreadElement":
-          if (allowSpread) {
-            toAssignable(node.argument, false, checkType);
-            checkSpreadAssign(node.argument);
+        case "AssignmentExpression":
+          if (node.operator === "=") {
+            node.type = "AssignmentPattern";
           } else {
-            unexpected(node.start);
+            raise(node.left.end, "Only '=' operator can be used for specifying default value.");
           }
           break;
 
+        case "MemberExpression":
+          if (!isBinding) break;
+
         default:
-          if (checkType) unexpected(node.start);
+          raise(node.start, "Assigning to rvalue");
       }
     }
     return node;
   }
 
-  // Checks if node can be assignable spread argument.
+  // Convert list of expression atoms to binding list.
+
+  function toAssignableList(exprList, isBinding) {
+    if (exprList.length) {
+      for (var i = 0; i < exprList.length - 1; i++) {
+        toAssignable(exprList[i], isBinding);
+      }
+      var last = exprList[exprList.length - 1];
+      switch (last.type) {
+        case "RestElement":
+          break;
+        case "SpreadElement":
+          last.type = "RestElement";
+          var arg = last.argument;
+          toAssignable(arg, isBinding);
+          if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern")
+            unexpected(arg.start);
+          break;
+        default:
+          toAssignable(last, isBinding);
+      }
+    }
+    return exprList;
+  }
+
+  // Parses spread element.
+
+  function parseSpread(refShorthandDefaultPos) {
+    var node = startNode();
+    next();
+    node.argument = parseMaybeAssign(refShorthandDefaultPos);
+    return finishNode(node, "SpreadElement");
+  }
+
+  function parseRest() {
+    var node = startNode();
+    next();
+    node.argument = tokType === _name || tokType === _bracketL ? parseBindingAtom() : unexpected();
+    return finishNode(node, "RestElement");
+  }
+
+  // Parses lvalue (assignable) atom.
+
+  function parseBindingAtom() {
+    if (options.ecmaVersion < 6) return parseIdent();
+    switch (tokType) {
+      case _name:
+        return parseIdent();
+
+      case _bracketL:
+        var node = startNode();
+        next();
+        node.elements = parseBindingList(_bracketR, true);
+        return finishNode(node, "ArrayPattern");
+
+      case _braceL:
+        return parseObj(true);
+
+      default:
+        unexpected();
+    }
+  }
+
+  function parseBindingList(close, allowEmpty) {
+    var elts = [], first = true;
+    while (!eat(close)) {
+      first ? first = false : expect(_comma);
+      if (tokType === _ellipsis) {
+        elts.push(parseRest());
+        expect(close);
+        break;
+      }
+      elts.push(allowEmpty && tokType === _comma ? null : parseMaybeDefault());
+    }
+    return elts;
+  }
 
-  function checkSpreadAssign(node) {
-    if (node.type !== "Identifier" && node.type !== "ArrayPattern")
-      unexpected(node.start);
+  // Parses assignment pattern around given atom if possible.
+
+  function parseMaybeDefault(startPos, left) {
+    startPos = startPos || storeCurrentPos();
+    left = left || parseBindingAtom();
+    if (!eat(_eq)) return left;
+    var node = startNodeAt(startPos);
+    node.operator = "=";
+    node.left = left;
+    node.right = parseMaybeAssign();
+    return finishNode(node, "AssignmentPattern");
   }
 
   // Verify that argument names are not repeated, and it does not
@@ -1444,6 +1627,9 @@
           if (elem) checkFunctionParam(elem, nameHash);
         }
         break;
+
+      case "RestElement":
+        return checkFunctionParam(param.argument, nameHash);
     }
   }
 
@@ -1483,14 +1669,12 @@
     switch (expr.type) {
       case "Identifier":
         if (strict && (isStrictBadIdWord(expr.name) || isStrictReservedWord(expr.name)))
-          raise(expr.start, isBinding
-            ? "Binding " + expr.name + " in strict mode"
-            : "Assigning to " + expr.name + " in strict mode"
-          );
+          raise(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode");
         break;
 
       case "MemberExpression":
-        if (!isBinding) break;
+        if (isBinding) raise(expr.start, "Binding to member expression");
+        break;
 
       case "ObjectPattern":
         for (var i = 0; i < expr.properties.length; i++)
@@ -1504,7 +1688,12 @@
         }
         break;
 
-      case "SpreadElement":
+      case "AssignmentPattern":
+        checkLVal(expr.left);
+        break;
+
+      case "RestElement":
+        checkLVal(expr.argument);
         break;
 
       default:
@@ -1523,15 +1712,13 @@
     var first = true;
     if (!node.body) node.body = [];
     while (tokType !== _eof) {
-      var stmt = parseStatement(true);
+      var stmt = parseStatement(true, true);
       node.body.push(stmt);
       if (first && isUseStrict(stmt)) setStrict(true);
       first = false;
     }
 
-    lastStart = tokStart;
-    lastEnd = tokEnd;
-    lastEndLoc = tokEndLoc;
+    next();
     return finishNode(node, "Program");
   }
 
@@ -1544,10 +1731,7 @@
   // `if (foo) /blah/.exec(foo);`, where looking at the previous token
   // does not help.
 
-  function parseStatement(topLevel) {
-    if (tokType === _slash || tokType === _assign && tokVal == "/=")
-      readToken(true);
-
+  function parseStatement(declaration, topLevel) {
     var starttype = tokType, node = startNode();
 
     // Most types of statements are recognized by the keyword they
@@ -1559,14 +1743,19 @@
     case _debugger: return parseDebuggerStatement(node);
     case _do: return parseDoStatement(node);
     case _for: return parseForStatement(node);
-    case _function: return parseFunctionStatement(node);
-    case _class: return parseClass(node, true);
+    case _function:
+      if (!declaration && options.ecmaVersion >= 6) unexpected();
+      return parseFunctionStatement(node);
+    case _class:
+      if (!declaration) unexpected();
+      return parseClass(node, true);
     case _if: return parseIfStatement(node);
     case _return: return parseReturnStatement(node);
     case _switch: return parseSwitchStatement(node);
     case _throw: return parseThrowStatement(node);
     case _try: return parseTryStatement(node);
-    case _var: case _let: case _const: return parseVarStatement(node, starttype.keyword);
+    case _let: case _const: if (!declaration) unexpected(); // NOTE: falls through to _var
+    case _var: return parseVarStatement(node, starttype.keyword);
     case _while: return parseWhileStatement(node);
     case _with: return parseWithStatement(node);
     case _braceL: return parseBlock(); // no point creating a function for this
@@ -1622,7 +1811,7 @@
   function parseDoStatement(node) {
     next();
     labels.push(loopLabel);
-    node.body = parseStatement();
+    node.body = parseStatement(false);
     labels.pop();
     expect(_while);
     node.test = parseParenExpression();
@@ -1651,15 +1840,19 @@
       next();
       parseVar(init, true, varKind);
       finishNode(init, "VariableDeclaration");
-      if ((tokType === _in || (options.ecmaVersion >= 6 && tokType === _name && tokVal === "of")) && init.declarations.length === 1 &&
+      if ((tokType === _in || (options.ecmaVersion >= 6 && isContextual("of"))) && init.declarations.length === 1 &&
           !(isLet && init.declarations[0].init))
         return parseForIn(node, init);
       return parseFor(node, init);
     }
-    var init = parseExpression(false, true);
-    if (tokType === _in || (options.ecmaVersion >= 6 && tokType === _name && tokVal === "of")) {
+    var refShorthandDefaultPos = {start: 0};
+    var init = parseExpression(true, refShorthandDefaultPos);
+    if (tokType === _in || (options.ecmaVersion >= 6 && isContextual("of"))) {
+      toAssignable(init);
       checkLVal(init);
       return parseForIn(node, init);
+    } else if (refShorthandDefaultPos.start) {
+      unexpected(refShorthandDefaultPos.start);
     }
     return parseFor(node, init);
   }
@@ -1672,8 +1865,8 @@
   function parseIfStatement(node) {
     next();
     node.test = parseParenExpression();
-    node.consequent = parseStatement();
-    node.alternate = eat(_else) ? parseStatement() : null;
+    node.consequent = parseStatement(false);
+    node.alternate = eat(_else) ? parseStatement(false) : null;
     return finishNode(node, "IfStatement");
   }
 
@@ -1717,7 +1910,7 @@
         expect(_colon);
       } else {
         if (!cur) unexpected();
-        cur.consequent.push(parseStatement());
+        cur.consequent.push(parseStatement(true));
       }
     }
     if (cur) finishNode(cur, "SwitchCase");
@@ -1743,9 +1936,8 @@
       var clause = startNode();
       next();
       expect(_parenL);
-      clause.param = parseIdent();
-      if (strict && isStrictBadIdWord(clause.param.name))
-        raise(clause.param.start, "Binding " + clause.param.name + " in strict mode");
+      clause.param = parseBindingAtom();
+      checkLVal(clause.param, true);
       expect(_parenR);
       clause.guard = null;
       clause.body = parseBlock();
@@ -1769,7 +1961,7 @@
     next();
     node.test = parseParenExpression();
     labels.push(loopLabel);
-    node.body = parseStatement();
+    node.body = parseStatement(false);
     labels.pop();
     return finishNode(node, "WhileStatement");
   }
@@ -1778,7 +1970,7 @@
     if (strict) raise(tokStart, "'with' in strict mode");
     next();
     node.object = parseParenExpression();
-    node.body = parseStatement();
+    node.body = parseStatement(false);
     return finishNode(node, "WithStatement");
   }
 
@@ -1792,7 +1984,7 @@
       if (labels[i].name === maybeName) raise(expr.start, "Label '" + maybeName + "' is already declared");
     var kind = tokType.isLoop ? "loop" : tokType === _switch ? "switch" : null;
     labels.push({name: maybeName, kind: kind});
-    node.body = parseStatement();
+    node.body = parseStatement(true);
     labels.pop();
     node.label = expr;
     return finishNode(node, "LabeledStatement");
@@ -1823,7 +2015,7 @@
     node.body = [];
     expect(_braceL);
     while (!eat(_braceR)) {
-      var stmt = parseStatement();
+      var stmt = parseStatement(true);
       node.body.push(stmt);
       if (first && allowStrict && isUseStrict(stmt)) {
         oldStrict = strict;
@@ -1846,7 +2038,7 @@
     expect(_semi);
     node.update = tokType === _parenR ? null : parseExpression();
     expect(_parenR);
-    node.body = parseStatement();
+    node.body = parseStatement(false);
     labels.pop();
     return finishNode(node, "ForStatement");
   }
@@ -1860,7 +2052,7 @@
     node.left = init;
     node.right = parseExpression();
     expect(_parenR);
-    node.body = parseStatement();
+    node.body = parseStatement(false);
     labels.pop();
     return finishNode(node, type);
   }
@@ -1872,9 +2064,9 @@
     node.kind = kind;
     for (;;) {
       var decl = startNode();
-      decl.id = options.ecmaVersion >= 6 ? toAssignable(parseExprAtom()) : parseIdent();
+      decl.id = parseBindingAtom();
       checkLVal(decl.id, true);
-      decl.init = eat(_eq) ? parseExpression(true, noIn) : (kind === _const.keyword ? unexpected() : null);
+      decl.init = eat(_eq) ? parseMaybeAssign(noIn) : (kind === _const.keyword ? unexpected() : null);
       node.declarations.push(finishNode(decl, "VariableDeclarator"));
       if (!eat(_comma)) break;
     }
@@ -1889,17 +2081,20 @@
   // and, *if* the syntactic construct they handle is present, wrap
   // the AST node that the inner parser gave them in another node.
 
-  // Parse a full expression. The arguments are used to forbid comma
-  // sequences (in argument lists, array literals, or object literals)
-  // or the `in` operator (in for loops initalization expressions).
+  // Parse a full expression. The optional arguments are used to
+  // forbid the `in` operator (in for loops initalization expressions)
+  // and provide reference for storing '=' operator inside shorthand
+  // property assignment in contexts where both object expression
+  // and object pattern might appear (so it's possible to raise
+  // delayed syntax error at correct position).
 
-  function parseExpression(noComma, noIn) {
+  function parseExpression(noIn, refShorthandDefaultPos) {
     var start = storeCurrentPos();
-    var expr = parseMaybeAssign(noIn);
-    if (!noComma && tokType === _comma) {
+    var expr = parseMaybeAssign(noIn, refShorthandDefaultPos);
+    if (tokType === _comma) {
       var node = startNodeAt(start);
       node.expressions = [expr];
-      while (eat(_comma)) node.expressions.push(parseMaybeAssign(noIn));
+      while (eat(_comma)) node.expressions.push(parseMaybeAssign(noIn, refShorthandDefaultPos));
       return finishNode(node, "SequenceExpression");
     }
     return expr;
@@ -1908,32 +2103,43 @@
   // Parse an assignment expression. This includes applications of
   // operators like `+=`.
 
-  function parseMaybeAssign(noIn) {
+  function parseMaybeAssign(noIn, refShorthandDefaultPos) {
+    var failOnShorthandAssign;
+    if (!refShorthandDefaultPos) {
+      refShorthandDefaultPos = {start: 0};
+      failOnShorthandAssign = true;
+    } else {
+      failOnShorthandAssign = false;
+    }
     var start = storeCurrentPos();
-    var left = parseMaybeConditional(noIn);
+    var left = parseMaybeConditional(noIn, refShorthandDefaultPos);
     if (tokType.isAssign) {
       var node = startNodeAt(start);
       node.operator = tokVal;
       node.left = tokType === _eq ? toAssignable(left) : left;
+      refShorthandDefaultPos.start = 0; // reset because shorthand default was used correctly
       checkLVal(left);
       next();
       node.right = parseMaybeAssign(noIn);
       return finishNode(node, "AssignmentExpression");
+    } else if (failOnShorthandAssign && refShorthandDefaultPos.start) {
+      unexpected(refShorthandDefaultPos.start);
     }
     return left;
   }
 
   // Parse a ternary conditional (`?:`) operator.
 
-  function parseMaybeConditional(noIn) {
+  function parseMaybeConditional(noIn, refShorthandDefaultPos) {
     var start = storeCurrentPos();
-    var expr = parseExprOps(noIn);
+    var expr = parseExprOps(noIn, refShorthandDefaultPos);
+    if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
     if (eat(_question)) {
       var node = startNodeAt(start);
       node.test = expr;
-      node.consequent = parseExpression(true);
+      node.consequent = parseMaybeAssign();
       expect(_colon);
-      node.alternate = parseExpression(true, noIn);
+      node.alternate = parseMaybeAssign(noIn);
       return finishNode(node, "ConditionalExpression");
     }
     return expr;
@@ -1941,9 +2147,11 @@
 
   // Start the precedence parser.
 
-  function parseExprOps(noIn) {
+  function parseExprOps(noIn, refShorthandDefaultPos) {
     var start = storeCurrentPos();
-    return parseExprOp(parseMaybeUnary(), start, -1, noIn);
+    var expr = parseMaybeUnary(refShorthandDefaultPos);
+    if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
+    return parseExprOp(expr, start, -1, noIn);
   }
 
   // Parse binary operators with the operator precedence parsing
@@ -1972,27 +2180,23 @@
 
   // Parse unary operators, both prefix and postfix.
 
-  function parseMaybeUnary() {
+  function parseMaybeUnary(refShorthandDefaultPos) {
     if (tokType.prefix) {
-      var node = startNode(), update = tokType.isUpdate, nodeType;
-      if (tokType === _ellipsis) {
-        nodeType = "SpreadElement";
-      } else {
-        nodeType = update ? "UpdateExpression" : "UnaryExpression";
-        node.operator = tokVal;
-        node.prefix = true;
-      }
-      tokRegexpAllowed = true;
+      var node = startNode(), update = tokType.isUpdate;
+      node.operator = tokVal;
+      node.prefix = true;
       next();
       node.argument = parseMaybeUnary();
+      if (refShorthandDefaultPos && refShorthandDefaultPos.start) unexpected(refShorthandDefaultPos.start);
       if (update) checkLVal(node.argument);
       else if (strict && node.operator === "delete" &&
                node.argument.type === "Identifier")
         raise(node.start, "Deleting local variable in strict mode");
-      return finishNode(node, nodeType);
+      return finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
     }
     var start = storeCurrentPos();
-    var expr = parseExprSubscripts();
+    var expr = parseExprSubscripts(refShorthandDefaultPos);
+    if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
     while (tokType.postfix && !canInsertSemicolon()) {
       var node = startNodeAt(start);
       node.operator = tokVal;
@@ -2007,9 +2211,11 @@
 
   // Parse call, dot, and `[]`-subscript expressions.
 
-  function parseExprSubscripts() {
+  function parseExprSubscripts(refShorthandDefaultPos) {
     var start = storeCurrentPos();
-    return parseSubscripts(parseExprAtom(), start);
+    var expr = parseExprAtom(refShorthandDefaultPos);
+    if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
+    return parseSubscripts(expr, start);
   }
 
   function parseSubscripts(base, start, noCalls) {
@@ -2031,7 +2237,7 @@
       node.callee = base;
       node.arguments = parseExprList(_parenR, false);
       return parseSubscripts(finishNode(node, "CallExpression"), start, noCalls);
-    } else if (tokType === _template) {
+    } else if (tokType === _backQuote) {
       var node = startNodeAt(start);
       node.tag = base;
       node.quasi = parseTemplate();
@@ -2044,7 +2250,7 @@
   // `new`, or an expression wrapped in punctuation like `()`, `[]`,
   // or `{}`.
 
-  function parseExprAtom() {
+  function parseExprAtom(refShorthandDefaultPos) {
     switch (tokType) {
     case _this:
       var node = startNode();
@@ -2057,7 +2263,7 @@
     case _name:
       var start = storeCurrentPos();
       var id = parseIdent(tokType !== _name);
-      if (eat(_arrow)) {
+      if (!canInsertSemicolon() && eat(_arrow)) {
         return parseArrowExpression(startNodeAt(start), [id]);
       }
       return id;
@@ -2085,42 +2291,7 @@
       return finishNode(node, "Literal");
 
     case _parenL:
-      var start = storeCurrentPos();
-      var val, exprList;
-      next();
-      // check whether this is generator comprehension or regular expression
-      if (options.ecmaVersion >= 7 && tokType === _for) {
-        val = parseComprehension(startNodeAt(start), true);
-      } else {
-        var oldParenL = ++metParenL;
-        if (tokType !== _parenR) {
-          val = parseExpression();
-          exprList = val.type === "SequenceExpression" ? val.expressions : [val];
-        } else {
-          exprList = [];
-        }
-        expect(_parenR);
-        // if '=>' follows '(...)', convert contents to arguments
-        if (metParenL === oldParenL && eat(_arrow)) {
-          val = parseArrowExpression(startNodeAt(start), exprList);
-        } else {
-          // forbid '()' before everything but '=>'
-          if (!val) unexpected(lastStart);
-          // forbid '...' in sequence expressions
-          if (options.ecmaVersion >= 6) {
-            for (var i = 0; i < exprList.length; i++) {
-              if (exprList[i].type === "SpreadElement") unexpected();
-            }
-          }
-
-          if (options.preserveParens) {
-            var par = startNodeAt(start);
-            par.expression = val;
-            val = finishNode(par, "ParenthesizedExpression");
-          }
-        }
-      }
-      return val;
+      return parseParenAndDistinguishExpression();
 
     case _bracketL:
       var node = startNode();
@@ -2129,11 +2300,11 @@
       if (options.ecmaVersion >= 7 && tokType === _for) {
         return parseComprehension(node, false);
       }
-      node.elements = parseExprList(_bracketR, true, true);
+      node.elements = parseExprList(_bracketR, true, true, refShorthandDefaultPos);
       return finishNode(node, "ArrayExpression");
 
     case _braceL:
-      return parseObj();
+      return parseObj(false, refShorthandDefaultPos);
 
     case _function:
       var node = startNode();
@@ -2146,7 +2317,7 @@
     case _new:
       return parseNew();
 
-    case _template:
+    case _backQuote:
       return parseTemplate();
 
     default:
@@ -2154,6 +2325,62 @@
     }
   }
 
+  function parseParenAndDistinguishExpression() {
+    var start = storeCurrentPos(), val;
+    if (options.ecmaVersion >= 6) {
+      next();
+
+      if (options.ecmaVersion >= 7 && tokType === _for) {
+        return parseComprehension(startNodeAt(start), true);
+      }
+
+      var innerStart = storeCurrentPos(), exprList = [], first = true;
+      var refShorthandDefaultPos = {start: 0}, spreadStart, innerParenStart;
+      while (tokType !== _parenR) {
+        first ? first = false : expect(_comma);
+        if (tokType === _ellipsis) {
+          spreadStart = tokStart;
+          exprList.push(parseRest());
+          break;
+        } else {
+          if (tokType === _parenL && !innerParenStart) {
+            innerParenStart = tokStart;
+          }
+          exprList.push(parseMaybeAssign(false, refShorthandDefaultPos));
+        }
+      }
+      var innerEnd = storeCurrentPos();
+      expect(_parenR);
+
+      if (!canInsertSemicolon() && eat(_arrow)) {
+        if (innerParenStart) unexpected(innerParenStart);
+        return parseArrowExpression(startNodeAt(start), exprList);
+      }
+
+      if (!exprList.length) unexpected(lastStart);
+      if (spreadStart) unexpected(spreadStart);
+      if (refShorthandDefaultPos.start) unexpected(refShorthandDefaultPos.start);
+
+      if (exprList.length > 1) {
+        val = startNodeAt(innerStart);
+        val.expressions = exprList;
+        finishNodeAt(val, "SequenceExpression", innerEnd);
+      } else {
+        val = exprList[0];
+      }
+    } else {
+      val = parseParenExpression();
+    }
+
+    if (options.preserveParens) {
+      var par = startNodeAt(start);
+      par.expression = val;
+      return finishNode(par, "ParenthesizedExpression");
+    } else {
+      return val;
+    }
+  }
+
   // New's precedence is slightly tricky. It must allow its argument
   // to be a `[]` or dot subscript expression, but not a call — at
   // least, not without wrapping it in parentheses. Thus, it uses the
@@ -2171,30 +2398,35 @@
   // Parse template expression.
 
   function parseTemplateElement() {
-    var elem = startNodeAt(options.locations ? [tokStart + 1, tokStartLoc.offset(1)] : tokStart + 1);
-    elem.value = tokVal;
-    elem.tail = input.charCodeAt(tokEnd - 1) !== 123; // '{'
+    var elem = startNode();
+    elem.value = {
+      raw: input.slice(tokStart, tokEnd),
+      cooked: tokVal
+    };
     next();
-    var endOff = elem.tail ? 1 : 2;
-    return finishNodeAt(elem, "TemplateElement", options.locations ? [lastEnd - endOff, lastEndLoc.offset(-endOff)] : lastEnd - endOff);
+    elem.tail = tokType === _backQuote;
+    return finishNode(elem, "TemplateElement");
   }
 
   function parseTemplate() {
     var node = startNode();
+    next();
     node.expressions = [];
     var curElt = parseTemplateElement();
     node.quasis = [curElt];
     while (!curElt.tail) {
+      expect(_dollarBraceL);
       node.expressions.push(parseExpression());
-      if (tokType !== _templateContinued) unexpected();
+      expect(_braceR);
       node.quasis.push(curElt = parseTemplateElement());
     }
+    next();
     return finishNode(node, "TemplateLiteral");
   }
 
-  // Parse an object literal.
+  // Parse an object literal or binding pattern.
 
-  function parseObj() {
+  function parseObj(isPattern, refShorthandDefaultPos) {
     var node = startNode(), first = true, propHash = {};
     node.properties = [];
     next();
@@ -2204,36 +2436,51 @@
         if (options.allowTrailingCommas && eat(_braceR)) break;
       } else first = false;
 
-      var prop = startNode(), isGenerator;
+      var prop = startNode(), isGenerator, start;
       if (options.ecmaVersion >= 6) {
         prop.method = false;
         prop.shorthand = false;
-        isGenerator = eat(_star);
+        if (isPattern || refShorthandDefaultPos) {
+          start = storeCurrentPos();
+        }
+        if (!isPattern) {
+          isGenerator = eat(_star);
+        }
       }
       parsePropertyName(prop);
       if (eat(_colon)) {
-        prop.value = parseExpression(true);
+        prop.value = isPattern ? parseMaybeDefault() : parseMaybeAssign(false, refShorthandDefaultPos);
         prop.kind = "init";
       } else if (options.ecmaVersion >= 6 && tokType === _parenL) {
+        if (isPattern) unexpected();
         prop.kind = "init";
         prop.method = true;
         prop.value = parseMethod(isGenerator);
       } else if (options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" &&
-                 (prop.key.name === "get" || prop.key.name === "set")) {
-        if (isGenerator) unexpected();
+                 (prop.key.name === "get" || prop.key.name === "set") &&
+                 (tokType != _comma && tokType != _braceR)) {
+        if (isGenerator || isPattern) unexpected();
         prop.kind = prop.key.name;
         parsePropertyName(prop);
         prop.value = parseMethod(false);
       } else if (options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
         prop.kind = "init";
-        prop.value = prop.key;
+        if (isPattern) {
+          prop.value = parseMaybeDefault(start, prop.key);
+        } else if (tokType === _eq && refShorthandDefaultPos) {
+          if (!refShorthandDefaultPos.start)
+            refShorthandDefaultPos.start = tokStart;
+          prop.value = parseMaybeDefault(start, prop.key);
+        } else {
+          prop.value = prop.key;
+        }
         prop.shorthand = true;
       } else unexpected();
 
       checkPropClash(prop, propHash);
       node.properties.push(finishNode(prop, "Property"));
     }
-    return finishNode(node, "ObjectExpression");
+    return finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression");
   }
 
   function parsePropertyName(prop) {
@@ -2254,11 +2501,9 @@
 
   function initFunction(node) {
     node.id = null;
-    node.params = [];
     if (options.ecmaVersion >= 6) {
-      node.defaults = [];
-      node.rest = null;
       node.generator = false;
+      node.expression = false;
     }
   }
 
@@ -2273,7 +2518,8 @@
     if (isStatement || tokType === _name) {
       node.id = parseIdent();
     }
-    parseFunctionParams(node);
+    expect(_parenL);
+    node.params = parseBindingList(_parenR, false);
     parseFunctionBody(node, allowExpressionBody);
     return finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression");
   }
@@ -2283,7 +2529,8 @@
   function parseMethod(isGenerator) {
     var node = startNode();
     initFunction(node);
-    parseFunctionParams(node);
+    expect(_parenL);
+    node.params = parseBindingList(_parenR, false);
     var allowExpressionBody;
     if (options.ecmaVersion >= 6) {
       node.generator = isGenerator;
@@ -2299,76 +2546,18 @@
 
   function parseArrowExpression(node, params) {
     initFunction(node);
-
-    var defaults = node.defaults, hasDefaults = false;
-
-    for (var i = 0, lastI = params.length - 1; i <= lastI; i++) {
-      var param = params[i];
-
-      if (param.type === "AssignmentExpression" && param.operator === "=") {
-        hasDefaults = true;
-        params[i] = param.left;
-        defaults.push(param.right);
-      } else {
-        toAssignable(param, i === lastI, true);
-        defaults.push(null);
-        if (param.type === "SpreadElement") {
-          params.length--;
-          node.rest = param.argument;
-          break;
-        }
-      }
-    }
-
-    node.params = params;
-    if (!hasDefaults) node.defaults = [];
-
+    node.params = toAssignableList(params, true);
     parseFunctionBody(node, true);
     return finishNode(node, "ArrowFunctionExpression");
   }
 
-  // Parse function parameters.
-
-  function parseFunctionParams(node) {
-    var defaults = [], hasDefaults = false;
-
-    expect(_parenL);
-    for (;;) {
-      if (eat(_parenR)) {
-        break;
-      } else if (options.ecmaVersion >= 6 && eat(_ellipsis)) {
-        node.rest = toAssignable(parseExprAtom(), false, true);
-        checkSpreadAssign(node.rest);
-        expect(_parenR);
-        defaults.push(null);
-        break;
-      } else {
-        node.params.push(options.ecmaVersion >= 6 ? toAssignable(parseExprAtom(), false, true) : parseIdent());
-        if (options.ecmaVersion >= 6) {
-          if (eat(_eq)) {
-            hasDefaults = true;
-            defaults.push(parseExpression(true));
-          } else {
-            defaults.push(null);
-          }
-        }
-        if (!eat(_comma)) {
-          expect(_parenR);
-          break;
-        }
-      }
-    }
-
-    if (hasDefaults) node.defaults = defaults;
-  }
-
   // Parse function body and check parameters.
 
   function parseFunctionBody(node, allowExpression) {
     var isExpression = allowExpression && tokType !== _braceL;
 
     if (isExpression) {
-      node.body = parseExpression(true);
+      node.body = parseMaybeAssign();
       node.expression = true;
     } else {
       // Start a new scope with regard to labels and the `inFunction`
@@ -2389,8 +2578,6 @@
         checkFunctionParam(node.id, {});
       for (var i = 0; i < node.params.length; i++)
         checkFunctionParam(node.params[i], nameHash);
-      if (node.rest)
-        checkFunctionParam(node.rest, nameHash);
     }
   }
 
@@ -2400,20 +2587,24 @@
   function parseClass(node, isStatement) {
     next();
     node.id = tokType === _name ? parseIdent() : isStatement ? unexpected() : null;
-    node.superClass = eat(_extends) ? parseExpression() : null;
+    node.superClass = eat(_extends) ? parseExprSubscripts() : null;
     var classBody = startNode();
     classBody.body = [];
     expect(_braceL);
     while (!eat(_braceR)) {
+      if (eat(_semi)) continue;
       var method = startNode();
-      if (tokType === _name && tokVal === "static") {
-        next();
+      var isGenerator = eat(_star);
+      parsePropertyName(method);
+      if (tokType !== _parenL && !method.computed && method.key.type === "Identifier" &&
+          method.key.name === "static") {
+        if (isGenerator) unexpected();
         method['static'] = true;
+        isGenerator = eat(_star);
+        parsePropertyName(method);
       } else {
         method['static'] = false;
       }
-      var isGenerator = eat(_star);
-      parsePropertyName(method);
       if (tokType !== _parenL && !method.computed && method.key.type === "Identifier" &&
           (method.key.name === "get" || method.key.name === "set")) {
         if (isGenerator) unexpected();
@@ -2424,7 +2615,6 @@
       }
       method.value = parseMethod(isGenerator);
       classBody.body.push(finishNode(method, "MethodDefinition"));
-      eat(_semi);
     }
     node.body = finishNode(classBody, "ClassBody");
     return finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression");
@@ -2436,7 +2626,7 @@
   // nothing in between them to be parsed as `null` (which is needed
   // for array literals).
 
-  function parseExprList(close, allowTrailingComma, allowEmpty) {
+  function parseExprList(close, allowTrailingComma, allowEmpty, refShorthandDefaultPos) {
     var elts = [], first = true;
     while (!eat(close)) {
       if (!first) {
@@ -2444,8 +2634,14 @@
         if (allowTrailingComma && options.allowTrailingCommas && eat(close)) break;
       } else first = false;
 
-      if (allowEmpty && tokType === _comma) elts.push(null);
-      else elts.push(parseExpression(true));
+      if (allowEmpty && tokType === _comma) {
+        elts.push(null);
+      } else {
+        if (tokType === _ellipsis)
+          elts.push(parseSpread(refShorthandDefaultPos));
+        else
+          elts.push(parseMaybeAssign(false, refShorthandDefaultPos));
+      }
     }
     return elts;
   }
@@ -2470,7 +2666,6 @@
     } else {
       unexpected();
     }
-    tokRegexpAllowed = false;
     next();
     return finishNode(node, "Identifier");
   }
@@ -2481,14 +2676,21 @@
     next();
     // export var|const|let|function|class ...;
     if (tokType === _var || tokType === _const || tokType === _let || tokType === _function || tokType === _class) {
-      node.declaration = parseStatement();
+      node.declaration = parseStatement(true);
       node['default'] = false;
       node.specifiers = null;
       node.source = null;
     } else
     // export default ...;
     if (eat(_default)) {
-      node.declaration = parseExpression(true);
+      var expr = parseMaybeAssign();
+      if (expr.id) {
+        switch (expr.type) {
+          case "FunctionExpression": expr.type = "FunctionDeclaration"; break;
+          case "ClassExpression": expr.type = "ClassDeclaration"; break;
+        }
+      }
+      node.declaration = expr;
       node['default'] = true;
       node.specifiers = null;
       node.source = null;
@@ -2500,8 +2702,7 @@
       node.declaration = null;
       node['default'] = false;
       node.specifiers = parseExportSpecifiers();
-      if (tokType === _name && tokVal === "from") {
-        next();
+      if (eatContextual("from")) {
         node.source = tokType === _string ? parseExprAtom() : unexpected();
       } else {
         if (isBatch) unexpected();
@@ -2532,12 +2733,7 @@
 
         var node = startNode();
         node.id = parseIdent(tokType === _default);
-        if (tokType === _name && tokVal === "as") {
-          next();
-          node.name = parseIdent(true);
-        } else {
-          node.name = null;
-        }
+        node.name = eatContextual("as") ? parseIdent(true) : null;
         nodes.push(finishNode(node, "ExportSpecifier"));
       }
     }
@@ -2555,8 +2751,7 @@
       node.kind = "";
     } else {
       node.specifiers = parseImportSpecifiers();
-      if (tokType !== _name || tokVal !== "from") unexpected();
-      next();
+      expectContextual("from");
       node.source = tokType === _string ? parseExprAtom() : unexpected();
     }
     semicolon();
@@ -2580,8 +2775,7 @@
     if (tokType === _star) {
       var node = startNode();
       next();
-      if (tokType !== _name || tokVal !== "as") unexpected();
-      next();
+      expectContextual("as");
       node.name = parseIdent();
       checkLVal(node.name, true);
       nodes.push(finishNode(node, "ImportBatchSpecifier"));
@@ -2596,12 +2790,7 @@
 
       var node = startNode();
       node.id = parseIdent(true);
-      if (tokType === _name && tokVal === "as") {
-        next();
-        node.name = parseIdent();
-      } else {
-        node.name = null;
-      }
+      node.name = eatContextual("as") ? parseIdent() : null;
       checkLVal(node.name || node.id, true);
       node['default'] = false;
       nodes.push(finishNode(node, "ImportSpecifier"));
@@ -2619,7 +2808,7 @@
       node.argument = null;
     } else {
       node.delegate = eat(_star);
-      node.argument = parseExpression(true);
+      node.argument = parseMaybeAssign();
     }
     return finishNode(node, "YieldExpression");
   }
@@ -2632,13 +2821,9 @@
       var block = startNode();
       next();
       expect(_parenL);
-      block.left = toAssignable(parseExprAtom());
+      block.left = parseBindingAtom();
       checkLVal(block.left, true);
-      if (tokType !== _name || tokVal !== "of") unexpected();
-      next();
-      // `of` property is here for compatibility with Esprima's AST
-      // which also supports deprecated [for (... in ...) expr]
-      block.of = true;
+      expectContextual("of");
       block.right = parseExpression();
       expect(_parenR);
       node.blocks.push(finishNode(block, "ComprehensionBlock"));
@@ -2649,5 +2834,4 @@
     node.generator = isGenerator;
     return finishNode(node, "ComprehensionExpression");
   }
-
 });
diff --git a/acorn_loose.js b/acorn_loose.js
index 97a3df6..5136c44 100644
--- a/acorn_loose.js
+++ b/acorn_loose.js
@@ -45,7 +45,6 @@
   exports.parse_dammit = function(inpt, opts) {
     if (!opts) opts = {};
     input = String(inpt);
-    if (/^#!.*/.test(input)) input = "//" + input.slice(2);
     fetchToken = acorn.tokenize(input, opts);
     options = fetchToken.options;
     sourceFile = options.sourceFile || null;
@@ -59,14 +58,14 @@
   var lastEnd, token = {start: 0, end: 0}, ahead = [];
   var curLineStart, nextLineStart, curIndent, lastEndLoc, sourceFile;
 
-  function next(forceRegexp) {
+  function next() {
     lastEnd = token.end;
     if (options.locations)
-      lastEndLoc = token.endLoc;
-    if (forceRegexp)
-      ahead.length = 0;
+      lastEndLoc = token.loc && token.loc.end;
 
-    token = ahead.shift() || readToken(forceRegexp);
+    token = ahead.shift() || readToken();
+    if (options.onToken)
+      options.onToken(token);
 
     if (token.start >= nextLineStart) {
       while (token.start >= nextLineStart) {
@@ -77,11 +76,11 @@
     }
   }
 
-  function readToken(forceRegexp) {
+  function readToken() {
     for (;;) {
       try {
-        var tok = fetchToken(forceRegexp);
-        if (tok.type === tt.dot && input.substr(tok.end, 1) === '.') {
+        var tok = fetchToken();
+        if (tok.type === tt.dot && input.substr(tok.end, 1) === '.' && options.ecmaVersion >= 6) {
           tok = fetchToken();
           tok.start--;
           tok.type = tt.ellipsis;
@@ -102,8 +101,10 @@
             replace = {start: e.pos, end: pos, type: tt.regexp, value: re};
           } else if (/template/.test(msg)) {
             replace = {start: e.pos, end: pos,
-                       type: input.charAt(e.pos) == "`" ? tt.template : tt.templateContinued,
-                       value: input.slice(e.pos + 1, pos)};
+                       type: tt.template,
+                       value: input.slice(e.pos, pos)};
+          } else if (/comment/.test(msg)) {
+            replace = fetchToken.current();
           } else {
             replace = false;
           }
@@ -126,8 +127,8 @@
         if (replace === true) replace = {start: pos, end: pos, type: tt.name, value: "✖"};
         if (replace) {
           if (options.locations) {
-            replace.startLoc = acorn.getLineInfo(input, replace.start);
-            replace.endLoc = acorn.getLineInfo(input, replace.end);
+            replace.loc = new SourceLocation(acorn.getLineInfo(input, replace.start));
+            replace.loc.end = acorn.getLineInfo(input, replace.end);
           }
           return replace;
         }
@@ -209,7 +210,7 @@
   Node.prototype = acorn.Node.prototype;
 
   function SourceLocation(start) {
-    this.start = start || token.startLoc || {line: 1, column: 0};
+    this.start = start || token.loc.start || {line: 1, column: 0};
     this.end = null;
     if (sourceFile !== null) this.source = sourceFile;
   }
@@ -226,7 +227,7 @@
   }
 
   function storeCurrentPos() {
-    return options.locations ? [token.start, token.startLoc] : token.start;
+    return options.locations ? [token.start, token.loc.start] : token.start;
   }
 
   function startNodeAt(pos) {
@@ -234,13 +235,14 @@
     if (options.locations) {
       node = new Node(pos[0]);
       node.loc = new SourceLocation(pos[1]);
+      pos = pos[0];
     } else {
       node = new Node(pos);
     }
     if (options.directSourceFile)
       node.sourceFile = options.directSourceFile;
     if (options.ranges)
-      node.range = [pos[0], 0];
+      node.range = [pos, 0];
     return node;
   }
 
@@ -254,14 +256,6 @@
     return node;
   }
 
-  function finishNodeAt(node, type, pos) {
-    if (options.locations) { node.loc.end = pos[1]; pos = pos[0]; }
-    node.type = type;
-    node.end = pos;
-    if (options.ranges) node.range[1] = pos;
-    return node;
-  }
-
   function dummyIdent() {
     var dummy = startNode();
     dummy.name = "✖";
@@ -278,9 +272,18 @@
     }
   }
 
+  function isContextual(name) {
+    return token.type === tt.name && token.value === name;
+  }
+
+  function eatContextual(name) {
+    return token.value === name && eat(tt.name);
+  }
+
   function canInsertSemicolon() {
     return (token.type === tt.eof || token.type === tt.braceR || newline.test(input.slice(lastEnd, token.start)));
   }
+
   function semicolon() {
     return eat(tt.semi);
   }
@@ -304,7 +307,8 @@
       case "MemberExpression":
       case "ObjectPattern":
       case "ArrayPattern":
-      case "SpreadElement":
+      case "RestElement":
+      case "AssignmentPattern":
         return expr;
 
       default:
@@ -317,14 +321,11 @@
     node.body = [];
     while (token.type !== tt.eof) node.body.push(parseStatement());
     lastEnd = token.end;
-    lastEndLoc = token.endLoc;
+    lastEndLoc = token.loc && token.loc.end;
     return finishNode(node, "Program");
   }
 
   function parseStatement() {
-    if (token.type === tt.slash || token.type === tt.assign && token.value === "/=")
-      next(true);
-
     var starttype = token.type, node = startNode();
 
     switch (starttype) {
@@ -358,14 +359,14 @@
       if (token.type === tt.semi) return parseFor(node, null);
       if (token.type === tt._var || token.type === tt._let) {
         var init = parseVar(true);
-        if (init.declarations.length === 1 && (token.type === tt._in || token.type === tt.name && token.value === "of")) {
+        if (init.declarations.length === 1 && (token.type === tt._in || isContextual("of"))) {
           return parseForIn(node, init);
         }
         return parseFor(node, init);
       }
-      var init = parseExpression(false, true);
-      if (token.type === tt._in || token.type === tt.name && token.value === "of") {
-        return parseForIn(node, checkLVal(init));
+      var init = parseExpression(true);
+      if (token.type === tt._in || isContextual("of")) {
+        return parseForIn(node, toAssignable(init));
       }
       return parseFor(node, init);
 
@@ -432,7 +433,7 @@
         var clause = startNode();
         next();
         expect(tt.parenL);
-        clause.param = parseIdent();
+        clause.param = toAssignable(parseExprAtom());
         expect(tt.parenR);
         clause.guard = null;
         clause.body = parseBlock();
@@ -536,7 +537,7 @@
     do {
       var decl = startNode();
       decl.id = options.ecmaVersion >= 6 ? toAssignable(parseExprAtom()) : parseIdent();
-      decl.init = eat(tt.eq) ? parseExpression(true, noIn) : null;
+      decl.init = eat(tt.eq) ? parseMaybeAssign(noIn) : null;
       node.declarations.push(finishNode(decl, "VariableDeclarator"));
     } while (eat(tt.comma));
     if (!node.declarations.length) {
@@ -548,10 +549,10 @@
     return finishNode(node, "VariableDeclaration");
   }
 
-  function parseExpression(noComma, noIn) {
+  function parseExpression(noIn) {
     var start = storeCurrentPos();
     var expr = parseMaybeAssign(noIn);
-    if (!noComma && token.type === tt.comma) {
+    if (token.type === tt.comma) {
       var node = startNodeAt(start);
       node.expressions = [expr];
       while (eat(tt.comma)) node.expressions.push(parseMaybeAssign(noIn));
@@ -589,8 +590,8 @@
     if (eat(tt.question)) {
       var node = startNodeAt(start);
       node.test = expr;
-      node.consequent = parseExpression(true);
-      node.alternate = expect(tt.colon) ? parseExpression(true, noIn) : dummyIdent();
+      node.consequent = parseMaybeAssign();
+      node.alternate = expect(tt.colon) ? parseMaybeAssign(noIn) : dummyIdent();
       return finishNode(node, "ConditionalExpression");
     }
     return expr;
@@ -626,20 +627,18 @@
 
   function parseMaybeUnary(noIn) {
     if (token.type.prefix) {
-      var node = startNode(), update = token.type.isUpdate, nodeType;
-      if (token.type === tt.ellipsis) {
-        nodeType = "SpreadElement";
-      } else {
-        nodeType = update ? "UpdateExpression" : "UnaryExpression";
-        node.operator = token.value;
-        node.prefix = true;
-      }
+      var node = startNode(), update = token.type.isUpdate;
       node.operator = token.value;
       node.prefix = true;
       next();
       node.argument = parseMaybeUnary(noIn);
       if (update) node.argument = checkLVal(node.argument);
-      return finishNode(node, nodeType);
+      return finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
+    } else if (token.type === tt.ellipsis) {
+      var node = startNode();
+      next();
+      node.argument = parseMaybeUnary(noIn);
+      return finishNode(node, "SpreadElement");
     }
     var start = storeCurrentPos();
     var expr = parseExprSubscripts();
@@ -693,7 +692,7 @@
         node.callee = base;
         node.arguments = parseExprList(tt.parenR);
         base = finishNode(node, "CallExpression");
-      } else if (token.type == tt.template) {
+      } else if (token.type == tt.backQuote) {
         var node = startNodeAt(start);
         node.tag = base;
         node.quasi = parseTemplate();
@@ -782,11 +781,11 @@
         node.argument = null;
       } else {
         node.delegate = eat(tt.star);
-        node.argument = parseExpression(true);
+        node.argument = parseMaybeAssign();
       }
       return finishNode(node, "YieldExpression");
 
-    case tt.template:
+    case tt.backQuote:
       return parseTemplate();
 
     default:
@@ -809,36 +808,35 @@
   }
 
   function parseTemplateElement() {
-    var elem = startNodeAt(options.locations ? [token.start + 1, token.startLoc.offset(1)] : token.start + 1);
-    elem.value = token.value;
-    elem.tail = input.charCodeAt(token.end - 1) !== 123; // '{'
-    var endOff = elem.tail ? 1 : 2;
-    var endPos = options.locations ? [token.end - endOff, token.endLoc.offset(-endOff)] : token.end - endOff;
+    var elem = startNode();
+    elem.value = {
+      raw: input.slice(token.start, token.end),
+      cooked: token.value
+    };
     next();
-    return finishNodeAt(elem, "TemplateElement", endPos);
+    elem.tail = token.type === tt.backQuote;
+    return finishNode(elem, "TemplateElement");
   }
 
   function parseTemplate() {
     var node = startNode();
+    next();
     node.expressions = [];
     var curElt = parseTemplateElement();
     node.quasis = [curElt];
     while (!curElt.tail) {
-      var next = parseExpression();
-      if (isDummy(next)) {
-        node.quasis[node.quasis.length - 1].tail = true;
-        break;
-      }
-      node.expressions.push(next);
-      if (token.type === tt.templateContinued) {
-        node.quasis.push(curElt = parseTemplateElement());
+      next();
+      node.expressions.push(parseExpression());
+      if (expect(tt.braceR)) {
+        curElt = parseTemplateElement();
       } else {
         curElt = startNode();
-        curElt.value = {cooked: "", raw: ""};
+        curElt.value = {cooked: '', raw: ''};
         curElt.tail = true;
-        node.quasis.push(curElt);
       }
+      node.quasis.push(curElt);
     }
+    expect(tt.backQuote);
     return finishNode(node, "TemplateLiteral");
   }
 
@@ -848,6 +846,7 @@
       next();
       if (token.type === tt.name) node.id = parseIdent();
       else if (isStatement) node.id = dummyIdent();
+      else node.id = null;
       node.superClass = eat(tt._extends) ? parseExpression() : null;
       node.body = startNode();
       node.body.body = [];
@@ -859,21 +858,33 @@
     eat(tt.braceL);
     if (curIndent + 1 < indent) { indent = curIndent; line = curLineStart; }
     while (!closes(tt.braceR, indent, line)) {
-      var prop = startNode(), isGenerator;
+      if (isClass && semicolon()) continue;
+      var prop = startNode(), isGenerator, start;
       if (options.ecmaVersion >= 6) {
         if (isClass) {
-          if (prop['static'] = (token.type === tt.name && token.value === "static")) next();
+          prop['static'] = false;
         } else {
+          start = storeCurrentPos();
           prop.method = false;
           prop.shorthand = false;
         }
         isGenerator = eat(tt.star);
       }
       parsePropertyName(prop);
-      if (isDummy(prop.key)) { if (isDummy(parseExpression(true))) next(); eat(tt.comma); continue; }
+      if (isDummy(prop.key)) { if (isDummy(parseMaybeAssign())) next(); eat(tt.comma); continue; }
+      if (isClass) {
+        if (prop.key.type === "Identifier" && !prop.computed && prop.key.name === "static" &&
+            (token.type != tt.parenL && token.type != tt.braceL)) {
+          prop['static'] = true;
+          isGenerator = eat(tt.star);
+          parsePropertyName(prop);
+        } else {
+          prop['static'] = false;
+        }
+      }
       if (!isClass && eat(tt.colon)) {
         prop.kind = "init";
-        prop.value = parseExpression(true);
+        prop.value = parseMaybeAssign();
       } else if (options.ecmaVersion >= 6 && (token.type === tt.parenL || token.type === tt.braceL)) {
         if (isClass) {
           prop.kind = "";
@@ -883,7 +894,8 @@
         }
         prop.value = parseMethod(isGenerator);
       } else if (options.ecmaVersion >= 5 && prop.key.type === "Identifier" &&
-                 (prop.key.name === "get" || prop.key.name === "set")) {
+                 !prop.computed && (prop.key.name === "get" || prop.key.name === "set") &&
+                 (token.type != tt.comma && token.type != tt.braceR)) {
         prop.kind = prop.key.name;
         parsePropertyName(prop);
         prop.value = parseMethod(false);
@@ -892,13 +904,24 @@
         prop.value = parseMethod(isGenerator);
       } else {
         prop.kind = "init";
-        prop.value = options.ecmaVersion >= 6 ? prop.key : dummyIdent();
+        if (options.ecmaVersion >= 6) {
+          if (eat(tt.eq)) {
+            var assign = startNodeAt(start);
+            assign.operator = "=";
+            assign.left = prop.key;
+            assign.right = parseMaybeAssign();
+            prop.value = finishNode(assign, "AssignmentExpression");
+          } else {
+            prop.value = prop.key;
+          }
+        } else {
+          prop.value = dummyIdent();
+        }
         prop.shorthand = true;
       }
 
       if (isClass) {
         node.body.body.push(finishNode(prop, "MethodDefinition"));
-        semicolon();
       } else {
         node.properties.push(finishNode(prop, "Property"));
         eat(tt.comma);
@@ -909,7 +932,7 @@
       // If there is no closing brace, make the node span to the start
       // of the next token (this is useful for Tern)
       lastEnd = token.start;
-      if (options.locations) lastEndLoc = token.startLoc;
+      if (options.locations) lastEndLoc = token.loc.start;
     }
     if (isClass) {
       semicolon();
@@ -942,7 +965,6 @@
   function parseIdent() {
     var node = startNode();
     node.name = token.type === tt.name ? token.value : token.type.keyword;
-    fetchToken.noRegexp();
     next();
     return finishNode(node, "Identifier");
   }
@@ -951,8 +973,6 @@
     node.id = null;
     node.params = [];
     if (options.ecmaVersion >= 6) {
-      node.defaults = [];
-      node.rest = null;
       node.generator = false;
       node.expression = false;
     }
@@ -968,53 +988,39 @@
           node.type = "ObjectPattern";
           var props = node.properties;
           for (var i = 0; i < props.length; i++) {
-            props[i].value = toAssignable(props[i].value);
+            toAssignable(props[i].value);
           }
           break;
 
         case "ArrayExpression":
           node.type = "ArrayPattern";
-          var elms = node.elements;
-          for (var i = 0; i < elms.length; i++) {
-            elms[i] = toAssignable(elms[i]);
-          }
+          toAssignableList(node.elements);
           break;
 
         case "SpreadElement":
+          node.type = "RestElement";
           node.argument = toAssignable(node.argument);
           break;
+
+        case "AssignmentExpression":
+          node.type = "AssignmentPattern";
+          break;
       }
     }
     return checkLVal(node);
   }
 
-  function parseFunctionParams(node, params) {
-    var defaults = [], hasDefaults = false;
-
-    if (!params) {
-      pushCx();
-      params = parseExprList(tt.parenR);
-    }
-    for (var i = 0; i < params.length; i++) {
-      var param = params[i], defValue = null;
-      if (param.type === "AssignmentExpression") {
-        defValue = param.right;
-        param = param.left;
-      }
-      param = toAssignable(param);
-      if (param.type === "SpreadElement") {
-        param = param.argument;
-        if (i === params.length - 1) {
-          node.rest = param;
-          continue;
-        }
-      }
-      node.params.push(param);
-      defaults.push(defValue);
-      if (defValue) hasDefaults = true;
+  function toAssignableList(exprList) {
+    for (var i = 0; i < exprList.length; i++) {
+      toAssignable(exprList[i]);
     }
+    return exprList;
+  }
 
-    if (hasDefaults) node.defaults = defaults;
+  function parseFunctionParams(params) {
+    pushCx();
+    params = parseExprList(tt.parenR);
+    return toAssignableList(params);
   }
 
   function parseFunction(node, isStatement) {
@@ -1024,7 +1030,7 @@
     }
     if (token.type === tt.name) node.id = parseIdent();
     else if (isStatement) node.id = dummyIdent();
-    parseFunctionParams(node);
+    node.params = parseFunctionParams();
     node.body = parseBlock();
     return finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression");
   }
@@ -1032,18 +1038,18 @@
   function parseMethod(isGenerator) {
     var node = startNode();
     initFunction(node);
-    parseFunctionParams(node);
+    node.params = parseFunctionParams();
     node.generator = isGenerator || false;
     node.expression = options.ecmaVersion >= 6 && token.type !== tt.braceL;
-    node.body = node.expression ? parseExpression(true) : parseBlock();
+    node.body = node.expression ? parseMaybeAssign() : parseBlock();
     return finishNode(node, "FunctionExpression");
   }
 
   function parseArrowExpression(node, params) {
     initFunction(node);
-    parseFunctionParams(node, params);
+    node.params = toAssignableList(params);
     node.expression = token.type !== tt.braceL;
-    node.body = node.expression ? parseExpression(true) : parseBlock();
+    node.body = node.expression ? parseMaybeAssign() : parseBlock();
     return finishNode(node, "ArrowFunctionExpression");
   }
 
@@ -1053,7 +1059,14 @@
     node['default'] = eat(tt._default);
     node.specifiers = node.source = null;
     if (node['default']) {
-      node.declaration = parseExpression();
+      var expr = parseMaybeAssign();
+      if (expr.id) {
+        switch (expr.type) {
+          case "FunctionExpression": expr.type = "FunctionDeclaration"; break;
+          case "ClassExpression": expr.type = "ClassDeclaration"; break;
+        }
+      }
+      node.declaration = expr;
       semicolon();
     } else if (token.type.keyword) {
       node.declaration = parseStatement();
@@ -1095,10 +1108,7 @@
     if (token.type === tt.star) {
       var elt = startNode();
       next();
-      if (token.type === tt.name && token.value === "as") {
-        next();
-        elt.name = parseIdent();
-      }
+      if (eatContextual("as")) elt.name = parseIdent();
       elts.push(finishNode(elt, prefix + "BatchSpecifier"));
     } else {
       var indent = curIndent, line = curLineStart, continuedLine = nextLineStart;
@@ -1107,22 +1117,13 @@
       if (curLineStart > continuedLine) continuedLine = curLineStart;
       while (!closes(tt.braceR, indent + (curLineStart <= continuedLine ? 1 : 0), line)) {
         var elt = startNode();
-        if (token.type === tt.star) {
-          next();
-          if (token.type === tt.name && token.value === "as") {
-            next();
-            elt.name = parseIdent();
-          }
+        if (eat(tt.star)) {
+          if (eatContextual("as")) elt.name = parseIdent();
           finishNode(elt, prefix + "BatchSpecifier");
         } else {
-          if (token.type === tt.name && token.value === "from") break;
+          if (isContextual("from")) break;
           elt.id = parseIdent();
-          if (token.type === tt.name && token.value === "as") {
-            next();
-            elt.name = parseIdent();
-          } else {
-            elt.name = null;
-          }
+          elt.name = eatContextual("as") ? parseIdent() : null;
           finishNode(elt, prefix + "Specifier");
         }
         elts.push(elt);
@@ -1131,12 +1132,7 @@
       eat(tt.braceR);
       popCx();
     }
-    if (token.type === tt.name && token.value === "from") {
-      next();
-      node.source = parseExprAtom();
-    } else {
-      node.source = null;
-    }
+    node.source = eatContextual("from") ? parseExprAtom() : null;
   }
 
   function parseExprList(close, allowEmpty) {
@@ -1147,7 +1143,7 @@
         elts.push(allowEmpty ? null : dummyIdent());
         continue;
       }
-      var elt = parseExpression(true);
+      var elt = parseMaybeAssign();
       if (isDummy(elt)) {
         if (closes(close, indent, line)) break;
         next();
@@ -1161,7 +1157,7 @@
       // If there is no closing brace, make the node span to the start
       // of the next token (this is useful for Tern)
       lastEnd = token.start;
-      if (options.locations) lastEndLoc = token.startLoc;
+      if (options.locations) lastEndLoc = token.loc.start;
     }
     return elts;
   }
diff --git a/bin/acorn b/bin/acorn
index 2a226da..b80ad29 100755
--- a/bin/acorn
+++ b/bin/acorn
@@ -4,12 +4,12 @@ var path = require("path");
 var fs = require("fs");
 var acorn = require("../acorn.js");
 
-var infile, parsed, options = {}, silent = false, compact = false;
+var infile, parsed, tokens, options = {}, silent = false, compact = false, tokenize = false;
 
 function help(status) {
   var print = (status == 0) ? console.log : console.error;
   print("usage: " + path.basename(process.argv[1]) + " [--ecma3|--ecma5|--ecma6] [--strictSemicolons]");
-  print("        [--locations] [--compact] [--silent] [--help] [--] infile");
+  print("        [--tokenize] [--locations] [--compact] [--silent] [--help] [--] infile");
   process.exit(status);
 }
 
@@ -20,21 +20,35 @@ for (var i = 2; i < process.argv.length; ++i) {
   else if (arg == "--ecma3") options.ecmaVersion = 3;
   else if (arg == "--ecma5") options.ecmaVersion = 5;
   else if (arg == "--ecma6") options.ecmaVersion = 6;
+  else if (arg == "--ecma7") options.ecmaVersion = 7;
   else if (arg == "--strictSemicolons") options.strictSemicolons = true;
   else if (arg == "--locations") options.locations = true;
   else if (arg == "--silent") silent = true;
   else if (arg == "--compact") compact = true;
   else if (arg == "--help") help(0);
+  else if (arg == "--tokenize") tokenize = true;
   else help(1);
 }
 
 try {
   var code = fs.readFileSync(infile, "utf8");
-  parsed = acorn.parse(code, options);
+
+  if (!tokenize)
+    parsed = acorn.parse(code, options);
+  else {
+    var get = acorn.tokenize(code, options);
+    tokens = [];
+    while (true) {
+      var token = get();
+      tokens.push(token);
+      if (token.type.type == "eof")
+        break;
+    }
+  }
 } catch(e) {
   console.log(e.message);
   process.exit(1);
 }
 
 if (!silent)
-  console.log(JSON.stringify(parsed, null, compact ? null : 2));
+  console.log(JSON.stringify(tokenize ? tokens : parsed, null, compact ? null : 2));
diff --git a/package.json b/package.json
index 71298fc..e92e8bf 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
     "description": "ECMAScript parser",
     "homepage": "http://marijnhaverbeke.nl/acorn/",
     "main": "acorn.js",
-    "version": "0.11.0",
+    "version": "0.12.0",
     "engines": {"node": ">=0.4.0"},
     "maintainers": [{"name": "Marijn Haverbeke",
                      "email": "marijnh at gmail.com",
@@ -14,7 +14,7 @@
                   "url": "http://marijnhaverbeke.nl/acorn/LICENSE"}],
     "scripts": {
       "test": "node test/run.js",
-      "prepublish": "bin/without_eval > acorn_csp.js"
+      "prepublish": "node bin/without_eval > acorn_csp.js"
     },
     "bin": {"acorn": "./bin/acorn"},
     "devDependencies": {"regenerate": "~0.6.2",
diff --git a/test/driver.js b/test/driver.js
index c76b8f9..7b7dee8 100644
--- a/test/driver.js
+++ b/test/driver.js
@@ -66,7 +66,7 @@
     }
   };
 
-  function ppJSON(v) { return JSON.stringify(v, null, 2); }
+  function ppJSON(v) { return v instanceof RegExp ? v.toString() : JSON.stringify(v, null, 2); }
   function addPath(str, pt) {
     if (str.charAt(str.length-1) == ")")
       return str.slice(0, str.length-1) + "/" + pt + ")";
@@ -76,6 +76,9 @@
   var misMatch = exports.misMatch = function(exp, act) {
     if (!exp || !act || (typeof exp != "object") || (typeof act != "object")) {
       if (exp !== act) return ppJSON(exp) + " !== " + ppJSON(act);
+    } else if (exp instanceof RegExp || act instanceof RegExp) {
+      var left = ppJSON(exp), right = ppJSON(act);
+      if (left !== right) return left + " !== " + right;
     } else if (exp.splice) {
       if (!act.slice) return ppJSON(exp) + " != " + ppJSON(act);
       if (act.length != exp.length) return "array length mismatch " + exp.length + " != " + act.length;
diff --git a/test/tests-harmony.js b/test/tests-harmony.js
index fbe33be..1b45b38 100644
--- a/test/tests-harmony.js
+++ b/test/tests-harmony.js
@@ -174,7 +174,6 @@ test("function test() {'use strict'; 0o0; }", {
       }
     },
     params: [],
-    defaults: [],
     body: {
       type: "BlockStatement",
       body: [
@@ -216,7 +215,6 @@ test("function test() {'use strict'; 0o0; }", {
         end: {line: 1, column: 37}
       }
     },
-    rest: null,
     generator: false,
     expression: false,
     loc: {
@@ -331,7 +329,6 @@ test("function test() {'use strict'; 0O0; }", {
       }
     },
     params: [],
-    defaults: [],
     body: {
       type: "BlockStatement",
       body: [
@@ -373,7 +370,6 @@ test("function test() {'use strict'; 0O0; }", {
         end: {line: 1, column: 37}
       }
     },
-    rest: null,
     generator: false,
     expression: false,
     loc: {
@@ -1028,8 +1024,6 @@ test("`outer${{x: {y: 10}}}bar${`nested${function(){return 1;}}endnest`}end`",{
                 type: "FunctionExpression",
                 id: null,
                 params: [],
-                defaults: [],
-                rest: null,
                 generator: false,
                 body: {
                   type: "BlockStatement",
@@ -1198,7 +1192,6 @@ test("() => \"test\"", {
       type: "ArrowFunctionExpression",
       id: null,
       params: [],
-      defaults: [],
       body: {
         type: "Literal",
         value: "test",
@@ -1208,7 +1201,6 @@ test("() => \"test\"", {
           end: {line: 1, column: 12}
         }
       },
-      rest: null,
       generator: false,
       expression: true,
       loc: {
@@ -1246,7 +1238,6 @@ test("e => \"test\"", {
           end: {line: 1, column: 1}
         }
       }],
-      defaults: [],
       body: {
         type: "Literal",
         value: "test",
@@ -1256,7 +1247,6 @@ test("e => \"test\"", {
           end: {line: 1, column: 11}
         }
       },
-      rest: null,
       generator: false,
       expression: true,
       loc: {
@@ -1294,7 +1284,6 @@ test("(e) => \"test\"", {
           end: {line: 1, column: 2}
         }
       }],
-      defaults: [],
       body: {
         type: "Literal",
         value: "test",
@@ -1304,7 +1293,6 @@ test("(e) => \"test\"", {
           end: {line: 1, column: 13}
         }
       },
-      rest: null,
       generator: false,
       expression: true,
       loc: {
@@ -1352,7 +1340,6 @@ test("(a, b) => \"test\"", {
           }
         }
       ],
-      defaults: [],
       body: {
         type: "Literal",
         value: "test",
@@ -1362,7 +1349,6 @@ test("(a, b) => \"test\"", {
           end: {line: 1, column: 16}
         }
       },
-      rest: null,
       generator: false,
       expression: true,
       loc: {
@@ -1400,7 +1386,6 @@ test("e => { 42; }", {
           end: {line: 1, column: 1}
         }
       }],
-      defaults: [],
       body: {
         type: "BlockStatement",
         body: [{
@@ -1424,7 +1409,6 @@ test("e => { 42; }", {
           end: {line: 1, column: 12}
         }
       },
-      rest: null,
       generator: false,
       expression: false,
       loc: {
@@ -1462,7 +1446,6 @@ test("e => ({ property: 42 })", {
           end: {line: 1, column: 1}
         }
       }],
-      defaults: [],
       body: {
         type: "ObjectExpression",
         properties: [{
@@ -1498,7 +1481,6 @@ test("e => ({ property: 42 })", {
           end: {line: 1, column: 22}
         }
       },
-      rest: null,
       generator: false,
       expression: true,
       loc: {
@@ -1536,7 +1518,6 @@ test("e => { label: 42 }", {
           end: {line: 1, column: 1}
         }
       }],
-      defaults: [],
       body: {
         type: "BlockStatement",
         body: [{
@@ -1575,7 +1556,6 @@ test("e => { label: 42 }", {
           end: {line: 1, column: 18}
         }
       },
-      rest: null,
       generator: false,
       expression: false,
       loc: {
@@ -1623,7 +1603,6 @@ test("(a, b) => { 42; }", {
           }
         }
       ],
-      defaults: [],
       body: {
         type: "BlockStatement",
         body: [{
@@ -1647,7 +1626,6 @@ test("(a, b) => { 42; }", {
           end: {line: 1, column: 17}
         }
       },
-      rest: null,
       generator: false,
       expression: false,
       loc: {
@@ -1703,7 +1681,6 @@ test("([a, , b]) => 42", {
           end: {line: 1, column: 9}
         }
       }],
-      defaults: [],
       body: {
         type: "Literal",
         value: 42,
@@ -1713,7 +1690,6 @@ test("([a, , b]) => 42", {
           end: {line: 1, column: 16}
         }
       },
-      rest: null,
       generator: false,
       expression: true,
       loc: {
@@ -1736,76 +1712,7 @@ test("([a, , b]) => 42", {
   locations: true
 });
 
-test("([a.a]) => 42", {
-  type: "Program",
-  body: [{
-    type: "ExpressionStatement",
-    expression: {
-      type: "ArrowFunctionExpression",
-      id: null,
-      params: [{
-        type: "ArrayPattern",
-        elements: [{
-          type: "MemberExpression",
-          computed: false,
-          object: {
-            type: "Identifier",
-            name: "a",
-            loc: {
-              start: {line: 1, column: 2},
-              end: {line: 1, column: 3}
-            }
-          },
-          property: {
-            type: "Identifier",
-            name: "a",
-            loc: {
-              start: {line: 1, column: 4},
-              end: {line: 1, column: 5}
-            }
-          },
-          loc: {
-            start: {line: 1, column: 2},
-            end: {line: 1, column: 5}
-          }
-        }],
-        loc: {
-          start: {line: 1, column: 1},
-          end: {line: 1, column: 6}
-        }
-      }],
-      defaults: [],
-      body: {
-        type: "Literal",
-        value: 42,
-        raw: "42",
-        loc: {
-          start: {line: 1, column: 11},
-          end: {line: 1, column: 13}
-        }
-      },
-      rest: null,
-      generator: false,
-      expression: true,
-      loc: {
-        start: {line: 1, column: 0},
-        end: {line: 1, column: 13}
-      }
-    },
-    loc: {
-      start: {line: 1, column: 0},
-      end: {line: 1, column: 13}
-    }
-  }],
-  loc: {
-    start: {line: 1, column: 0},
-    end: {line: 1, column: 13}
-  }
-}, {
-  ecmaVersion: 6,
-  ranges: true,
-  locations: true
-});
+testFail("([a.a]) => 42", "Assigning to rvalue (1:2)", {ecmaVersion: 6});
 
 test("(x=1) => x * x", {
   type: "Program",
@@ -1815,19 +1722,26 @@ test("(x=1) => x * x", {
       type: "ArrowFunctionExpression",
       id: null,
       params: [{
-        type: "Identifier",
-        name: "x",
+        type: "AssignmentPattern",
+        left: {
+          type: "Identifier",
+          name: "x",
+          loc: {
+            start: {line: 1, column: 1},
+            end: {line: 1, column: 2}
+          }
+        },
+        right: {
+          type: "Literal",
+          value: 1,
+          raw: "1",
+          loc: {
+            start: {line: 1, column: 3},
+            end: {line: 1, column: 4}
+          }
+        },
         loc: {
           start: {line: 1, column: 1},
-          end: {line: 1, column: 2}
-        }
-      }],
-      defaults: [{
-        type: "Literal",
-        value: 1,
-        raw: "1",
-        loc: {
-          start: {line: 1, column: 3},
           end: {line: 1, column: 4}
         }
       }],
@@ -1855,7 +1769,6 @@ test("(x=1) => x * x", {
           end: {line: 1, column: 14}
         }
       },
-      rest: null,
       generator: false,
       expression: true,
       loc: {
@@ -1893,7 +1806,6 @@ test("eval => 42", {
           end: {line: 1, column: 4}
         }
       }],
-      defaults: [],
       body: {
         type: "Literal",
         value: 42,
@@ -1903,7 +1815,6 @@ test("eval => 42", {
           end: {line: 1, column: 10}
         }
       },
-      rest: null,
       generator: false,
       expression: true,
       loc: {
@@ -1941,7 +1852,6 @@ test("arguments => 42", {
           end: {line: 1, column: 9}
         }
       }],
-      defaults: [],
       body: {
         type: "Literal",
         value: 42,
@@ -1951,7 +1861,6 @@ test("arguments => 42", {
           end: {line: 1, column: 15}
         }
       },
-      rest: null,
       generator: false,
       expression: true,
       loc: {
@@ -1989,7 +1898,6 @@ test("(a) => 00", {
           end: {line: 1, column: 2}
         }
       }],
-      defaults: [],
       body: {
         type: "Literal",
         value: 0,
@@ -1999,7 +1907,6 @@ test("(a) => 00", {
           end: {line: 1, column: 9}
         }
       },
-      rest: null,
       generator: false,
       expression: true,
       loc: {
@@ -2047,7 +1954,6 @@ test("(eval, a) => 42", {
           }
         }
       ],
-      defaults: [],
       body: {
         type: "Literal",
         value: 42,
@@ -2057,7 +1963,6 @@ test("(eval, a) => 42", {
           end: {line: 1, column: 15}
         }
       },
-      rest: null,
       generator: false,
       expression: true,
       loc: {
@@ -2088,19 +1993,26 @@ test("(eval = 10) => 42", {
       type: "ArrowFunctionExpression",
       id: null,
       params: [{
-        type: "Identifier",
-        name: "eval",
+        type: "AssignmentPattern",
+        left: {
+          type: "Identifier",
+          name: "eval",
+          loc: {
+            start: {line: 1, column: 1},
+            end: {line: 1, column: 5}
+          }
+        },
+        right: {
+          type: "Literal",
+          value: 10,
+          raw: "10",
+          loc: {
+            start: {line: 1, column: 8},
+            end: {line: 1, column: 10}
+          }
+        },
         loc: {
           start: {line: 1, column: 1},
-          end: {line: 1, column: 5}
-        }
-      }],
-      defaults: [{
-        type: "Literal",
-        value: 10,
-        raw: "10",
-        loc: {
-          start: {line: 1, column: 8},
           end: {line: 1, column: 10}
         }
       }],
@@ -2113,7 +2025,6 @@ test("(eval = 10) => 42", {
           end: {line: 1, column: 17}
         }
       },
-      rest: null,
       generator: false,
       expression: true,
       loc: {
@@ -2153,22 +2064,26 @@ test("(eval, a = 10) => 42", {
           }
         },
         {
-          type: "Identifier",
-          name: "a",
+          type: "AssignmentPattern",
+          left: {
+            type: "Identifier",
+            name: "a",
+            loc: {
+              start: {line: 1, column: 7},
+              end: {line: 1, column: 8}
+            }
+          },
+          right: {
+            type: "Literal",
+            value: 10,
+            raw: "10",
+            loc: {
+              start: {line: 1, column: 11},
+              end: {line: 1, column: 13}
+            }
+          },
           loc: {
             start: {line: 1, column: 7},
-            end: {line: 1, column: 8}
-          }
-        }
-      ],
-      defaults: [
-        null,
-        {
-          type: "Literal",
-          value: 10,
-          raw: "10",
-          loc: {
-            start: {line: 1, column: 11},
             end: {line: 1, column: 13}
           }
         }
@@ -2182,7 +2097,6 @@ test("(eval, a = 10) => 42", {
           end: {line: 1, column: 20}
         }
       },
-      rest: null,
       generator: false,
       expression: true,
       loc: {
@@ -2220,7 +2134,6 @@ test("(x => x)", {
           end: {line: 1, column: 2}
         }
       }],
-      defaults: [],
       body: {
         type: "Identifier",
         name: "x",
@@ -2229,7 +2142,6 @@ test("(x => x)", {
           end: {line: 1, column: 7}
         }
       },
-      rest: null,
       generator: false,
       expression: true,
       loc: {
@@ -2267,7 +2179,6 @@ test("x => y => 42", {
           end: {line: 1, column: 1}
         }
       }],
-      defaults: [],
       body: {
         type: "ArrowFunctionExpression",
         id: null,
@@ -2279,7 +2190,6 @@ test("x => y => 42", {
             end: {line: 1, column: 6}
           }
         }],
-        defaults: [],
         body: {
           type: "Literal",
           value: 42,
@@ -2289,7 +2199,6 @@ test("x => y => 42", {
             end: {line: 1, column: 12}
           }
         },
-        rest: null,
         generator: false,
         expression: true,
         loc: {
@@ -2297,7 +2206,6 @@ test("x => y => 42", {
           end: {line: 1, column: 12}
         }
       },
-      rest: null,
       generator: false,
       expression: true,
       loc: {
@@ -2335,7 +2243,6 @@ test("(x) => ((y, z) => (x, y, z))", {
           end: {line: 1, column: 2}
         }
       }],
-      defaults: [],
       body: {
         type: "ArrowFunctionExpression",
         id: null,
@@ -2357,7 +2264,6 @@ test("(x) => ((y, z) => (x, y, z))", {
             }
           }
         ],
-        defaults: [],
         body: {
           type: "SequenceExpression",
           expressions: [
@@ -2391,7 +2297,6 @@ test("(x) => ((y, z) => (x, y, z))", {
             end: {line: 1, column: 26}
           }
         },
-        rest: null,
         generator: false,
         expression: true,
         loc: {
@@ -2399,7 +2304,6 @@ test("(x) => ((y, z) => (x, y, z))", {
           end: {line: 1, column: 27}
         }
       },
-      rest: null,
       generator: false,
       expression: true,
       loc: {
@@ -2440,7 +2344,6 @@ test("foo(() => {})", {
         type: "ArrowFunctionExpression",
         id: null,
         params: [],
-        defaults: [],
         body: {
           type: "BlockStatement",
           body: [],
@@ -2449,7 +2352,6 @@ test("foo(() => {})", {
             end: {line: 1, column: 12}
           }
         },
-        rest: null,
         generator: false,
         expression: false,
         loc: {
@@ -2512,7 +2414,6 @@ test("foo((x, y) => {})", {
             }
           }
         ],
-        defaults: [],
         body: {
           type: "BlockStatement",
           body: [],
@@ -2521,7 +2422,6 @@ test("foo((x, y) => {})", {
             end: {line: 1, column: 16}
           }
         },
-        rest: null,
         generator: false,
         expression: false,
         loc: {
@@ -2586,8 +2486,6 @@ test("(a, a) => 42", {
           name: "a"
         }
       ],
-      defaults: [],
-      rest: null,
       generator: false,
       body: {
         type: "Literal",
@@ -2640,7 +2538,6 @@ test("x = { method() { } }", {
             type: "FunctionExpression",
             id: null,
             params: [],
-            defaults: [],
             body: {
               type: "BlockStatement",
               body: [],
@@ -2649,7 +2546,6 @@ test("x = { method() { } }", {
                 end: {line: 1, column: 18}
               }
             },
-            rest: null,
             generator: false,
             expression: false,
             loc: {
@@ -2729,7 +2625,6 @@ test("x = { method(test) { } }", {
                 end: {line: 1, column: 17}
               }
             }],
-            defaults: [],
             body: {
               type: "BlockStatement",
               body: [],
@@ -2738,7 +2633,6 @@ test("x = { method(test) { } }", {
                 end: {line: 1, column: 22}
               }
             },
-            rest: null,
             generator: false,
             expression: false,
             loc: {
@@ -2812,7 +2706,6 @@ test("x = { 'method'() { } }", {
             type: "FunctionExpression",
             id: null,
             params: [],
-            defaults: [],
             body: {
               type: "BlockStatement",
               body: [],
@@ -2821,7 +2714,6 @@ test("x = { 'method'() { } }", {
                 end: {line: 1, column: 20}
               }
             },
-            rest: null,
             generator: false,
             expression: false,
             loc: {
@@ -2894,7 +2786,6 @@ test("x = { get() { } }", {
             type: "FunctionExpression",
             id: null,
             params: [],
-            defaults: [],
             body: {
               type: "BlockStatement",
               body: [],
@@ -2903,7 +2794,6 @@ test("x = { get() { } }", {
                 end: {line: 1, column: 15}
               }
             },
-            rest: null,
             generator: false,
             expression: false,
             loc: {
@@ -2976,7 +2866,6 @@ test("x = { set() { } }", {
             type: "FunctionExpression",
             id: null,
             params: [],
-            defaults: [],
             body: {
               type: "BlockStatement",
               body: [],
@@ -2985,7 +2874,6 @@ test("x = { set() { } }", {
                 end: {line: 1, column: 15}
               }
             },
-            rest: null,
             generator: false,
             expression: false,
             loc: {
@@ -3058,7 +2946,6 @@ test("x = { method() 42 }", {
             type: "FunctionExpression",
             id: null,
             params: [],
-            defaults: [],
             body: {
               type: "Literal",
               value: 42,
@@ -3068,7 +2955,6 @@ test("x = { method() 42 }", {
                 end: {line: 1, column: 17}
               }
             },
-            rest: null,
             generator: false,
             expression: true,
             loc: {
@@ -3141,7 +3027,6 @@ test("x = { get method() 42 }", {
             type: "FunctionExpression",
             id: null,
             params: [],
-            defaults: [],
             body: {
               type: "Literal",
               value: 42,
@@ -3151,7 +3036,6 @@ test("x = { get method() 42 }", {
                 end: {line: 1, column: 21}
               }
             },
-            rest: null,
             generator: false,
             expression: true,
             loc: {
@@ -3231,7 +3115,6 @@ test("x = { set method(val) v = val }", {
                 end: {line: 1, column: 20}
               }
             }],
-            defaults: [],
             body: {
               type: "AssignmentExpression",
               operator: "=",
@@ -3256,7 +3139,6 @@ test("x = { set method(val) v = val }", {
                 end: {line: 1, column: 29}
               }
             },
-            rest: null,
             generator: false,
             expression: true,
             loc: {
@@ -3328,8 +3210,7 @@ test("[for (x of array) x]", {
         loc: {
           start: {line: 1, column: 1},
           end: {line: 1, column: 17}
-        },
-        of: true
+        }
       }],
       body: {
         type: "Identifier",
@@ -3412,8 +3293,7 @@ test("[for (x of array) for (y of array2) if (x === test) x]", {
           loc: {
             start: {line: 1, column: 1},
             end: {line: 1, column: 17}
-          },
-          of: true
+          }
         },
         {
           type: "ComprehensionBlock",
@@ -3436,8 +3316,7 @@ test("[for (x of array) for (y of array2) if (x === test) x]", {
           loc: {
             start: {line: 1, column: 18},
             end: {line: 1, column: 35}
-          },
-          of: true
+          }
         }
       ],
       body: {
@@ -3521,8 +3400,7 @@ test("(for (x of array) for (y of array2) if (x === test) x)", {
           loc: {
             start: {line: 1, column: 1},
             end: {line: 1, column: 17}
-          },
-          of: true
+          }
         },
         {
           type: "ComprehensionBlock",
@@ -3545,8 +3423,7 @@ test("(for (x of array) for (y of array2) if (x === test) x)", {
           loc: {
             start: {line: 1, column: 18},
             end: {line: 1, column: 35}
-          },
-          of: true
+          }
         }
       ],
       body: {
@@ -3617,8 +3494,7 @@ test("[for ([,x] of array) for ({[start.x]: x, [start.y]: y} of array2) x]", {
           loc: {
             start: {line: 1, column: 1},
             end: {line: 1, column: 20}
-          },
-          of: true
+          }
         },
         {
           type: "ComprehensionBlock",
@@ -3728,8 +3604,7 @@ test("[for ([,x] of array) for ({[start.x]: x, [start.y]: y} of array2) x]", {
           loc: {
             start: {line: 1, column: 21},
             end: {line: 1, column: 65}
-          },
-          of: true
+          }
         }
       ],
       body: {
@@ -4841,7 +4716,6 @@ test("export function parse() { }", {
         }
       },
       params: [],
-      defaults: [],
       body: {
         type: "BlockStatement",
         body: [],
@@ -4850,7 +4724,6 @@ test("export function parse() { }", {
           end: {line: 1, column: 27}
         }
       },
-      rest: null,
       generator: false,
       expression: false,
       loc: {
@@ -4953,6 +4826,110 @@ test("export default 42", {
   locations: true
 });
 
+test("export default function () {}", {
+  type: "Program",
+  range: [0, 29],
+  body: [{
+    type: "ExportDeclaration",
+    range: [0, 29],
+    declaration: {
+      type: "FunctionExpression",
+      range: [15, 29],
+      id: null,
+      generator: false,
+      expression: false,
+      params: [],
+      body: {
+        type: "BlockStatement",
+        range: [27, 29],
+        body: []
+      }
+    },
+    default: true,
+    specifiers: null,
+    source: null
+  }]
+}, {ecmaVersion: 6, ranges: true});
+
+test("export default function f() {}", {
+  type: "Program",
+  range: [0, 30],
+  body: [{
+    type: "ExportDeclaration",
+    range: [0, 30],
+    declaration: {
+      type: "FunctionDeclaration",
+      range: [15, 30],
+      id: {
+        type: "Identifier",
+        range: [24, 25],
+        name: "f"
+      },
+      generator: false,
+      expression: false,
+      params: [],
+      body: {
+        type: "BlockStatement",
+        range: [28, 30],
+        body: []
+      }
+    },
+    default: true,
+    specifiers: null,
+    source: null
+  }]
+}, {ecmaVersion: 6, ranges: true});
+
+test("export default class {}", {
+  type: "Program",
+  range: [0, 23],
+  body: [{
+    type: "ExportDeclaration",
+    range: [0, 23],
+    declaration: {
+      type: "ClassExpression",
+      range: [15, 23],
+      id: null,
+      superClass: null,
+      body: {
+        type: "ClassBody",
+        range: [21, 23],
+        body: []
+      }
+    },
+    default: true,
+    specifiers: null,
+    source: null
+  }]
+}, {ecmaVersion: 6, ranges: true});
+
+test("export default class A {}", {
+  type: "Program",
+  range: [0, 25],
+  body: [{
+    type: "ExportDeclaration",
+    range: [0, 25],
+    declaration: {
+      type: "ClassDeclaration",
+      range: [15, 25],
+      id: {
+        type: "Identifier",
+        range: [21, 22],
+        name: "A"
+      },
+      superClass: null,
+      body: {
+        type: "ClassBody",
+        range: [23, 25],
+        body: []
+      }
+    },
+    default: true,
+    specifiers: null,
+    source: null
+  }]
+}, {ecmaVersion: 6, ranges: true});
+
 testFail("export *", "Unexpected token (1:8)", {ecmaVersion: 6});
 
 test("export * from \"crypto\"", {
@@ -5622,7 +5599,6 @@ test("(function* () { yield v })", {
       type: "FunctionExpression",
       id: null,
       params: [],
-      defaults: [],
       body: {
         type: "BlockStatement",
         body: [{
@@ -5653,7 +5629,6 @@ test("(function* () { yield v })", {
           end: {line: 1, column: 25}
         }
       },
-      rest: null,
       generator: true,
       expression: false,
       loc: {
@@ -5684,7 +5659,6 @@ test("(function* () { yield\nv })", {
       type: "FunctionExpression",
       id: null,
       params: [],
-      defaults: [],
       body: {
         type: "BlockStatement",
         body: [
@@ -5725,7 +5699,6 @@ test("(function* () { yield\nv })", {
           end: {line: 2, column: 3}
         }
       },
-      rest: null,
       generator: true,
       expression: false,
       loc: {
@@ -5756,7 +5729,6 @@ test("(function* () { yield *v })", {
       type: "FunctionExpression",
       id: null,
       params: [],
-      defaults: [],
       body: {
         type: "BlockStatement",
         body: [{
@@ -5787,7 +5759,6 @@ test("(function* () { yield *v })", {
           end: {line: 1, column: 26}
         }
       },
-      rest: null,
       generator: true,
       expression: false,
       loc: {
@@ -5823,7 +5794,6 @@ test("function* test () { yield *v }", {
       }
     },
     params: [],
-    defaults: [],
     body: {
       type: "BlockStatement",
       body: [{
@@ -5854,7 +5824,6 @@ test("function* test () { yield *v }", {
         end: {line: 1, column: 30}
       }
     },
-    rest: null,
     generator: true,
     expression: false,
     loc: {
@@ -5902,7 +5871,6 @@ test("var x = { *test () { yield *v } };", {
             type: "FunctionExpression",
             id: null,
             params: [],
-            defaults: [],
             body: {
               type: "BlockStatement",
               body: [{
@@ -5933,7 +5901,6 @@ test("var x = { *test () { yield *v } };", {
                 end: {line: 1, column: 31}
               }
             },
-            rest: null,
             generator: true,
             expression: false,
             loc: {
@@ -5989,7 +5956,6 @@ test("function* t() {}", {
       }
     },
     params: [],
-    defaults: [],
     body: {
       type: "BlockStatement",
       body: [],
@@ -5998,7 +5964,6 @@ test("function* t() {}", {
         end: {line: 1, column: 16}
       }
     },
-    rest: null,
     generator: true,
     expression: false,
     loc: {
@@ -6024,7 +5989,6 @@ test("(function* () { yield yield 10 })", {
       type: "FunctionExpression",
       id: null,
       params: [],
-      defaults: [],
       body: {
         type: "BlockStatement",
         body: [{
@@ -6064,7 +6028,6 @@ test("(function* () { yield yield 10 })", {
           end: {line: 1, column: 32}
         }
       },
-      rest: null,
       generator: true,
       expression: false,
       loc: {
@@ -6561,7 +6524,6 @@ test("class A {get() {}}", {
           type: "FunctionExpression",
           id: null,
           params: [],
-          defaults: [],
           body: {
             type: "BlockStatement",
             body: [],
@@ -6570,7 +6532,6 @@ test("class A {get() {}}", {
               end: {line: 1, column: 17}
             }
           },
-          rest: null,
           generator: false,
           expression: false,
           loc: {
@@ -6635,7 +6596,6 @@ test("class A { static get() {}}", {
           type: "FunctionExpression",
           id: null,
           params: [],
-          defaults: [],
           body: {
             type: "BlockStatement",
             body: [],
@@ -6644,7 +6604,6 @@ test("class A { static get() {}}", {
               end: {line: 1, column: 25}
             }
           },
-          rest: null,
           generator: false,
           expression: false,
           loc: {
@@ -6716,7 +6675,6 @@ test("class A extends B {get foo() {}}", {
           type: "FunctionExpression",
           id: null,
           params: [],
-          defaults: [],
           body: {
             type: "BlockStatement",
             body: [],
@@ -6725,7 +6683,6 @@ test("class A extends B {get foo() {}}", {
               end: {line: 1, column: 31}
             }
           },
-          rest: null,
           generator: false,
           expression: false,
           loc: {
@@ -6797,7 +6754,6 @@ test("class A extends B { static get foo() {}}", {
           type: "FunctionExpression",
           id: null,
           params: [],
-          defaults: [],
           body: {
             type: "BlockStatement",
             body: [],
@@ -6806,7 +6762,6 @@ test("class A extends B { static get foo() {}}", {
               end: {line: 1, column: 39}
             }
           },
-          rest: null,
           generator: false,
           expression: false,
           loc: {
@@ -6878,7 +6833,6 @@ test("class A {set a(v) {}}", {
               end: {line: 1, column: 16}
             }
           }],
-          defaults: [],
           body: {
             type: "BlockStatement",
             body: [],
@@ -6887,7 +6841,6 @@ test("class A {set a(v) {}}", {
               end: {line: 1, column: 20}
             }
           },
-          rest: null,
           generator: false,
           expression: false,
           loc: {
@@ -6959,7 +6912,6 @@ test("class A { static set a(v) {}}", {
               end: {line: 1, column: 24}
             }
           }],
-          defaults: [],
           body: {
             type: "BlockStatement",
             body: [],
@@ -6968,7 +6920,6 @@ test("class A { static set a(v) {}}", {
               end: {line: 1, column: 28}
             }
           },
-          rest: null,
           generator: false,
           expression: false,
           loc: {
@@ -7040,7 +6991,6 @@ test("class A {set(v) {};}", {
               end: {line: 1, column: 14}
             }
           }],
-          defaults: [],
           body: {
             type: "BlockStatement",
             body: [],
@@ -7049,7 +6999,6 @@ test("class A {set(v) {};}", {
               end: {line: 1, column: 18}
             }
           },
-          rest: null,
           generator: false,
           expression: false,
           loc: {
@@ -7121,7 +7070,6 @@ test("class A { static set(v) {};}", {
               end: {line: 1, column: 22}
             }
           }],
-          defaults: [],
           body: {
             type: "BlockStatement",
             body: [],
@@ -7130,7 +7078,6 @@ test("class A { static set(v) {};}", {
               end: {line: 1, column: 26}
             }
           },
-          rest: null,
           generator: false,
           expression: false,
           loc: {
@@ -7202,7 +7149,6 @@ test("class A {*gen(v) { yield v; }}", {
               end: {line: 1, column: 15}
             }
           }],
-          defaults: [],
           body: {
             type: "BlockStatement",
             body: [{
@@ -7233,7 +7179,6 @@ test("class A {*gen(v) { yield v; }}", {
               end: {line: 1, column: 29}
             }
           },
-          rest: null,
           generator: true,
           expression: false,
           loc: {
@@ -7305,7 +7250,6 @@ test("class A { static *gen(v) { yield v; }}", {
               end: {line: 1, column: 23}
             }
           }],
-          defaults: [],
           body: {
             type: "BlockStatement",
             body: [{
@@ -7336,7 +7280,6 @@ test("class A { static *gen(v) { yield v; }}", {
               end: {line: 1, column: 37}
             }
           },
-          rest: null,
           generator: true,
           expression: false,
           loc: {
@@ -7420,7 +7363,6 @@ test("\"use strict\"; (class A {constructor() { super() }})", {
               type: "FunctionExpression",
               id: null,
               params: [],
-              defaults: [],
               body: {
                 type: "BlockStatement",
                 body: [{
@@ -7451,7 +7393,6 @@ test("\"use strict\"; (class A {constructor() { super() }})", {
                   end: {line: 1, column: 49}
                 }
               },
-              rest: null,
               generator: false,
               expression: false,
               loc: {
@@ -7522,7 +7463,6 @@ test("class A {static foo() {}}", {
           type: "FunctionExpression",
           id: null,
           params: [],
-          defaults: [],
           body: {
             type: "BlockStatement",
             body: [],
@@ -7531,7 +7471,6 @@ test("class A {static foo() {}}", {
               end: {line: 1, column: 24}
             }
           },
-          rest: null,
           generator: false,
           expression: false,
           loc: {
@@ -7597,7 +7536,6 @@ test("class A {foo() {} static bar() {}}", {
             type: "FunctionExpression",
             id: null,
             params: [],
-            defaults: [],
             body: {
               type: "BlockStatement",
               body: [],
@@ -7606,7 +7544,6 @@ test("class A {foo() {} static bar() {}}", {
                 end: {line: 1, column: 17}
               }
             },
-            rest: null,
             generator: false,
             expression: false,
             loc: {
@@ -7636,7 +7573,6 @@ test("class A {foo() {} static bar() {}}", {
             type: "FunctionExpression",
             id: null,
             params: [],
-            defaults: [],
             body: {
               type: "BlockStatement",
               body: [],
@@ -7645,7 +7581,6 @@ test("class A {foo() {} static bar() {}}", {
                 end: {line: 1, column: 33}
               }
             },
-            rest: null,
             generator: false,
             expression: false,
             loc: {
@@ -7730,7 +7665,6 @@ test("\"use strict\"; (class A { static constructor() { super() }})", {
               type: "FunctionExpression",
               id: null,
               params: [],
-              defaults: [],
               body: {
                 type: "BlockStatement",
                 body: [{
@@ -7761,7 +7695,6 @@ test("\"use strict\"; (class A { static constructor() { super() }})", {
                   end: {line: 1, column: 57}
                 }
               },
-              rest: null,
               generator: false,
               expression: false,
               loc: {
@@ -7833,7 +7766,6 @@ test("class A { foo() {} bar() {}}", {
             type: "FunctionExpression",
             id: null,
             params: [],
-            defaults: [],
             body: {
               type: "BlockStatement",
               body: [],
@@ -7842,7 +7774,6 @@ test("class A { foo() {} bar() {}}", {
                 end: {line: 1, column: 18}
               }
             },
-            rest: null,
             generator: false,
             expression: false,
             loc: {
@@ -7872,7 +7803,6 @@ test("class A { foo() {} bar() {}}", {
             type: "FunctionExpression",
             id: null,
             params: [],
-            defaults: [],
             body: {
               type: "BlockStatement",
               body: [],
@@ -7881,7 +7811,6 @@ test("class A { foo() {} bar() {}}", {
                 end: {line: 1, column: 27}
               }
             },
-            rest: null,
             generator: false,
             expression: false,
             loc: {
@@ -7948,7 +7877,6 @@ test("class A { get foo() {} set foo(v) {}}", {
             type: "FunctionExpression",
             id: null,
             params: [],
-            defaults: [],
             body: {
               type: "BlockStatement",
               body: [],
@@ -7957,7 +7885,6 @@ test("class A { get foo() {} set foo(v) {}}", {
                 end: {line: 1, column: 22}
               }
             },
-            rest: null,
             generator: false,
             expression: false,
             loc: {
@@ -7994,7 +7921,6 @@ test("class A { get foo() {} set foo(v) {}}", {
                 end: {line: 1, column: 32}
               }
             }],
-            defaults: [],
             body: {
               type: "BlockStatement",
               body: [],
@@ -8003,7 +7929,6 @@ test("class A { get foo() {} set foo(v) {}}", {
                 end: {line: 1, column: 36}
               }
             },
-            rest: null,
             generator: false,
             expression: false,
             loc: {
@@ -8070,7 +7995,6 @@ test("class A { static get foo() {} get foo() {}}", {
             type: "FunctionExpression",
             id: null,
             params: [],
-            defaults: [],
             body: {
               type: "BlockStatement",
               body: [],
@@ -8079,7 +8003,6 @@ test("class A { static get foo() {} get foo() {}}", {
                 end: {line: 1, column: 29}
               }
             },
-            rest: null,
             generator: false,
             expression: false,
             loc: {
@@ -8109,7 +8032,6 @@ test("class A { static get foo() {} get foo() {}}", {
             type: "FunctionExpression",
             id: null,
             params: [],
-            defaults: [],
             body: {
               type: "BlockStatement",
               body: [],
@@ -8118,7 +8040,6 @@ test("class A { static get foo() {} get foo() {}}", {
                 end: {line: 1, column: 42}
               }
             },
-            rest: null,
             generator: false,
             expression: false,
             loc: {
@@ -8185,7 +8106,6 @@ test("class A { static get foo() {} static get bar() {} }", {
             type: "FunctionExpression",
             id: null,
             params: [],
-            defaults: [],
             body: {
               type: "BlockStatement",
               body: [],
@@ -8194,7 +8114,6 @@ test("class A { static get foo() {} static get bar() {} }", {
                 end: {line: 1, column: 29}
               }
             },
-            rest: null,
             generator: false,
             expression: false,
             loc: {
@@ -8224,7 +8143,6 @@ test("class A { static get foo() {} static get bar() {} }", {
             type: "FunctionExpression",
             id: null,
             params: [],
-            defaults: [],
             body: {
               type: "BlockStatement",
               body: [],
@@ -8233,7 +8151,6 @@ test("class A { static get foo() {} static get bar() {} }", {
                 end: {line: 1, column: 49}
               }
             },
-            rest: null,
             generator: false,
             expression: false,
             loc: {
@@ -8300,7 +8217,6 @@ test("class A { static get foo() {} static set foo(v) {} get foo() {} set foo(v)
             type: "FunctionExpression",
             id: null,
             params: [],
-            defaults: [],
             body: {
               type: "BlockStatement",
               body: [],
@@ -8309,7 +8225,6 @@ test("class A { static get foo() {} static set foo(v) {} get foo() {} set foo(v)
                 end: {line: 1, column: 29}
               }
             },
-            rest: null,
             generator: false,
             expression: false,
             loc: {
@@ -8346,7 +8261,6 @@ test("class A { static get foo() {} static set foo(v) {} get foo() {} set foo(v)
                 end: {line: 1, column: 46}
               }
             }],
-            defaults: [],
             body: {
               type: "BlockStatement",
               body: [],
@@ -8355,7 +8269,6 @@ test("class A { static get foo() {} static set foo(v) {} get foo() {} set foo(v)
                 end: {line: 1, column: 50}
               }
             },
-            rest: null,
             generator: false,
             expression: false,
             loc: {
@@ -8385,7 +8298,6 @@ test("class A { static get foo() {} static set foo(v) {} get foo() {} set foo(v)
             type: "FunctionExpression",
             id: null,
             params: [],
-            defaults: [],
             body: {
               type: "BlockStatement",
               body: [],
@@ -8394,7 +8306,6 @@ test("class A { static get foo() {} static set foo(v) {} get foo() {} set foo(v)
                 end: {line: 1, column: 63}
               }
             },
-            rest: null,
             generator: false,
             expression: false,
             loc: {
@@ -8431,7 +8342,6 @@ test("class A { static get foo() {} static set foo(v) {} get foo() {} set foo(v)
                 end: {line: 1, column: 73}
               }
             }],
-            defaults: [],
             body: {
               type: "BlockStatement",
               body: [],
@@ -8440,7 +8350,6 @@ test("class A { static get foo() {} static set foo(v) {} get foo() {} set foo(v)
                 end: {line: 1, column: 77}
               }
             },
-            rest: null,
             generator: false,
             expression: false,
             loc: {
@@ -8529,8 +8438,6 @@ test("class A { static [foo]() {} }", {
           },
           id: null,
           params: [],
-          defaults: [],
-          rest: null,
           generator: false,
           body: {
             type: "BlockStatement",
@@ -8607,8 +8514,6 @@ test("class A { static get [foo]() {} }", {
           },
           id: null,
           params: [],
-          defaults: [],
-          rest: null,
           generator: false,
           body: {
             type: "BlockStatement",
@@ -8667,7 +8572,6 @@ test("class A { set foo(v) {} get foo() {} }", {
                 end: {line: 1, column: 19}
               }
             }],
-            defaults: [],
             body: {
               type: "BlockStatement",
               body: [],
@@ -8676,7 +8580,6 @@ test("class A { set foo(v) {} get foo() {} }", {
                 end: {line: 1, column: 23}
               }
             },
-            rest: null,
             generator: false,
             expression: false,
             loc: {
@@ -8706,7 +8609,6 @@ test("class A { set foo(v) {} get foo() {} }", {
             type: "FunctionExpression",
             id: null,
             params: [],
-            defaults: [],
             body: {
               type: "BlockStatement",
               body: [],
@@ -8715,7 +8617,6 @@ test("class A { set foo(v) {} get foo() {} }", {
                 end: {line: 1, column: 36}
               }
             },
-            rest: null,
             generator: false,
             expression: false,
             loc: {
@@ -8804,8 +8705,6 @@ test("class A { foo() {} get foo() {} }",{
             },
             id: null,
             params: [],
-            defaults: [],
-            rest: null,
             generator: false,
             body: {
               type: "BlockStatement",
@@ -8843,8 +8742,6 @@ test("class A { foo() {} get foo() {} }",{
             },
             id: null,
             params: [],
-            defaults: [],
-            rest: null,
             generator: false,
             body: {
               type: "BlockStatement",
@@ -8866,27 +8763,63 @@ test("class A { foo() {} get foo() {} }",{
   locations: true
 });
 
-// ES6: Computed Properties
-
-test("({[x]: 10})", {
+test("class Semicolon { ; }", {
   type: "Program",
+  loc: {
+    start: {line: 1, column: 0},
+    end: {line: 1, column: 21}
+  },
   body: [{
-    type: "ExpressionStatement",
-    expression: {
-      type: "ObjectExpression",
-      properties: [{
-        type: "Property",
-        key: {
-          type: "Identifier",
-          name: "x",
-          loc: {
-            start: {line: 1, column: 3},
-            end: {line: 1, column: 4}
-          }
-        },
-        value: {
-          type: "Literal",
-          value: 10,
+    type: "ClassDeclaration",
+    loc: {
+      start: {line: 1, column: 0},
+      end: {line: 1, column: 21}
+    },
+    id: {
+      type: "Identifier",
+      loc: {
+        start: {line: 1, column: 6},
+        end: {line: 1, column: 15}
+      },
+      name: "Semicolon"
+    },
+    superClass: null,
+    body: {
+      type: "ClassBody",
+      loc: {
+        start: {line: 1, column: 16},
+        end: {line: 1, column: 21}
+      },
+      body: []
+    }
+  }]
+}, {
+  ecmaVersion: 6,
+  ranges: true,
+  locations: true
+});
+
+// ES6: Computed Properties
+
+test("({[x]: 10})", {
+  type: "Program",
+  body: [{
+    type: "ExpressionStatement",
+    expression: {
+      type: "ObjectExpression",
+      properties: [{
+        type: "Property",
+        key: {
+          type: "Identifier",
+          name: "x",
+          loc: {
+            start: {line: 1, column: 3},
+            end: {line: 1, column: 4}
+          }
+        },
+        value: {
+          type: "Literal",
+          value: 10,
           raw: "10",
           loc: {
             start: {line: 1, column: 7},
@@ -9014,7 +8947,6 @@ test("({[x]: function() {}})", {
           type: "FunctionExpression",
           id: null,
           params: [],
-          defaults: [],
           body: {
             type: "BlockStatement",
             body: [],
@@ -9023,7 +8955,6 @@ test("({[x]: function() {}})", {
               end: {line: 1, column: 20}
             }
           },
-          rest: null,
           generator: false,
           expression: false,
           loc: {
@@ -9165,7 +9096,6 @@ test("({get [x]() {}, set [x](v) {}})", {
             type: "FunctionExpression",
             id: null,
             params: [],
-            defaults: [],
             body: {
               type: "BlockStatement",
               body: [],
@@ -9174,7 +9104,6 @@ test("({get [x]() {}, set [x](v) {}})", {
                 end: {line: 1, column: 14}
               }
             },
-            rest: null,
             generator: false,
             expression: false,
             loc: {
@@ -9212,7 +9141,6 @@ test("({get [x]() {}, set [x](v) {}})", {
                 end: {line: 1, column: 25}
               }
             }],
-            defaults: [],
             body: {
               type: "BlockStatement",
               body: [],
@@ -9221,7 +9149,6 @@ test("({get [x]() {}, set [x](v) {}})", {
                 end: {line: 1, column: 29}
               }
             },
-            rest: null,
             generator: false,
             expression: false,
             loc: {
@@ -9279,7 +9206,6 @@ test("({[x]() {}})", {
           type: "FunctionExpression",
           id: null,
           params: [],
-          defaults: [],
           body: {
             type: "BlockStatement",
             body: [],
@@ -9288,7 +9214,6 @@ test("({[x]() {}})", {
               end: {line: 1, column: 10}
             }
           },
-          rest: null,
           generator: false,
           expression: false,
           loc: {
@@ -9466,7 +9391,6 @@ test("function f({[x]: y}) {}", {
         end: {line: 1, column: 19}
       }
     }],
-    defaults: [],
     body: {
       type: "BlockStatement",
       body: [],
@@ -9475,7 +9399,6 @@ test("function f({[x]: y}) {}", {
         end: {line: 1, column: 23}
       }
     },
-    rest: null,
     generator: false,
     expression: false,
     loc: {
@@ -9523,7 +9446,6 @@ test("var x = {*[test]() { yield *v; }}", {
             type: "FunctionExpression",
             id: null,
             params: [],
-            defaults: [],
             body: {
               type: "BlockStatement",
               body: [{
@@ -9554,7 +9476,6 @@ test("var x = {*[test]() { yield *v; }}", {
                 end: {line: 1, column: 32}
               }
             },
-            rest: null,
             generator: true,
             expression: false,
             loc: {
@@ -9649,8 +9570,6 @@ test("class A {[x]() {}}", {
           },
           id: null,
           params: [],
-          defaults: [],
-          rest: null,
           generator: false,
           body: {
             type: "BlockStatement",
@@ -9688,33 +9607,40 @@ test("function f([x] = [1]) {}", {
       }
     },
     params: [{
-      type: "ArrayPattern",
-      elements: [{
-        type: "Identifier",
-        name: "x",
+      type: "AssignmentPattern",
+      left: {
+        type: "ArrayPattern",
+        elements: [{
+          type: "Identifier",
+          name: "x",
+          loc: {
+            start: {line: 1, column: 12},
+            end: {line: 1, column: 13}
+          }
+        }],
         loc: {
-          start: {line: 1, column: 12},
-          end: {line: 1, column: 13}
+          start: {line: 1, column: 11},
+          end: {line: 1, column: 14}
         }
-      }],
-      loc: {
-        start: {line: 1, column: 11},
-        end: {line: 1, column: 14}
-      }
-    }],
-    defaults: [{
-      type: "ArrayExpression",
-      elements: [{
-        type: "Literal",
-        value: 1,
-        raw: "1",
+      },
+      right: {
+        type: "ArrayExpression",
+        elements: [{
+          type: "Literal",
+          value: 1,
+          raw: "1",
+          loc: {
+            start: {line: 1, column: 18},
+            end: {line: 1, column: 19}
+          }
+        }],
         loc: {
-          start: {line: 1, column: 18},
-          end: {line: 1, column: 19}
+          start: {line: 1, column: 17},
+          end: {line: 1, column: 20}
         }
-      }],
+      },
       loc: {
-        start: {line: 1, column: 17},
+        start: {line: 1, column: 11},
         end: {line: 1, column: 20}
       }
     }],
@@ -9726,7 +9652,6 @@ test("function f([x] = [1]) {}", {
         end: {line: 1, column: 24}
       }
     },
-    rest: null,
     generator: false,
     expression: false,
     loc: {
@@ -9757,71 +9682,78 @@ test("function f({x} = {x: 10}) {}", {
       }
     },
     params: [{
-      type: "ObjectPattern",
-      properties: [{
-        type: "Property",
-        key: {
-          type: "Identifier",
-          name: "x",
-          loc: {
-            start: {line: 1, column: 12},
-            end: {line: 1, column: 13}
-          }
-        },
-        value: {
-          type: "Identifier",
-          name: "x",
+      type: "AssignmentPattern",
+      left: {
+        type: "ObjectPattern",
+        properties: [{
+          type: "Property",
+          key: {
+            type: "Identifier",
+            name: "x",
+            loc: {
+              start: {line: 1, column: 12},
+              end: {line: 1, column: 13}
+            }
+          },
+          value: {
+            type: "Identifier",
+            name: "x",
+            loc: {
+              start: {line: 1, column: 12},
+              end: {line: 1, column: 13}
+            }
+          },
+          kind: "init",
+          method: false,
+          shorthand: true,
+          computed: false,
           loc: {
             start: {line: 1, column: 12},
             end: {line: 1, column: 13}
           }
-        },
-        kind: "init",
-        method: false,
-        shorthand: true,
-        computed: false,
+        }],
         loc: {
-          start: {line: 1, column: 12},
-          end: {line: 1, column: 13}
+          start: {line: 1, column: 11},
+          end: {line: 1, column: 14}
         }
-      }],
-      loc: {
-        start: {line: 1, column: 11},
-        end: {line: 1, column: 14}
-      }
-    }],
-    defaults: [{
-      type: "ObjectExpression",
-      properties: [{
-        type: "Property",
-        key: {
-          type: "Identifier",
-          name: "x",
+      },
+      right: {
+        type: "ObjectExpression",
+        properties: [{
+          type: "Property",
+          key: {
+            type: "Identifier",
+            name: "x",
+            loc: {
+              start: {line: 1, column: 18},
+              end: {line: 1, column: 19}
+            }
+          },
+          value: {
+            type: "Literal",
+            value: 10,
+            raw: "10",
+            loc: {
+              start: {line: 1, column: 21},
+              end: {line: 1, column: 23}
+            }
+          },
+          kind: "init",
+          method: false,
+          shorthand: false,
+          computed: false,
           loc: {
             start: {line: 1, column: 18},
-            end: {line: 1, column: 19}
-          }
-        },
-        value: {
-          type: "Literal",
-          value: 10,
-          raw: "10",
-          loc: {
-            start: {line: 1, column: 21},
             end: {line: 1, column: 23}
           }
-        },
-        kind: "init",
-        method: false,
-        shorthand: false,
-        computed: false,
+        }],
         loc: {
-          start: {line: 1, column: 18},
-          end: {line: 1, column: 23}
+          start: {line: 1, column: 17},
+          end: {line: 1, column: 24}
         }
-      }],
+      },
       loc: {
-        start: {line: 1, column: 17},
+        start: {line: 1, column: 11},
         end: {line: 1, column: 24}
       }
     }],
@@ -9833,7 +9765,6 @@ test("function f({x} = {x: 10}) {}", {
         end: {line: 1, column: 28}
       }
     },
-    rest: null,
     generator: false,
     expression: false,
     loc: {
@@ -9870,71 +9801,78 @@ test("f = function({x} = {x: 10}) {}", {
         type: "FunctionExpression",
         id: null,
         params: [{
-          type: "ObjectPattern",
-          properties: [{
-            type: "Property",
-            key: {
-              type: "Identifier",
-              name: "x",
-              loc: {
-                start: {line: 1, column: 14},
-                end: {line: 1, column: 15}
-              }
-            },
-            value: {
-              type: "Identifier",
-              name: "x",
+          type: "AssignmentPattern",
+          left: {
+            type: "ObjectPattern",
+            properties: [{
+              type: "Property",
+              key: {
+                type: "Identifier",
+                name: "x",
+                loc: {
+                  start: {line: 1, column: 14},
+                  end: {line: 1, column: 15}
+                }
+              },
+              value: {
+                type: "Identifier",
+                name: "x",
+                loc: {
+                  start: {line: 1, column: 14},
+                  end: {line: 1, column: 15}
+                }
+              },
+              kind: "init",
+              method: false,
+              shorthand: true,
+              computed: false,
               loc: {
                 start: {line: 1, column: 14},
                 end: {line: 1, column: 15}
               }
-            },
-            kind: "init",
-            method: false,
-            shorthand: true,
-            computed: false,
+            }],
             loc: {
-              start: {line: 1, column: 14},
-              end: {line: 1, column: 15}
+              start: {line: 1, column: 13},
+              end: {line: 1, column: 16}
             }
-          }],
-          loc: {
-            start: {line: 1, column: 13},
-            end: {line: 1, column: 16}
-          }
-        }],
-        defaults: [{
-          type: "ObjectExpression",
-          properties: [{
-            type: "Property",
-            key: {
-              type: "Identifier",
-              name: "x",
+          },
+          right: {
+            type: "ObjectExpression",
+            properties: [{
+              type: "Property",
+              key: {
+                type: "Identifier",
+                name: "x",
+                loc: {
+                  start: {line: 1, column: 20},
+                  end: {line: 1, column: 21}
+                }
+              },
+              value: {
+                type: "Literal",
+                value: 10,
+                raw: "10",
+                loc: {
+                  start: {line: 1, column: 23},
+                  end: {line: 1, column: 25}
+                }
+              },
+              kind: "init",
+              method: false,
+              shorthand: false,
+              computed: false,
               loc: {
                 start: {line: 1, column: 20},
-                end: {line: 1, column: 21}
-              }
-            },
-            value: {
-              type: "Literal",
-              value: 10,
-              raw: "10",
-              loc: {
-                start: {line: 1, column: 23},
                 end: {line: 1, column: 25}
               }
-            },
-            kind: "init",
-            method: false,
-            shorthand: false,
-            computed: false,
+            }],
             loc: {
-              start: {line: 1, column: 20},
-              end: {line: 1, column: 25}
+              start: {line: 1, column: 19},
+              end: {line: 1, column: 26}
             }
-          }],
+          },
           loc: {
-            start: {line: 1, column: 19},
+            start: {line: 1, column: 13},
             end: {line: 1, column: 26}
           }
         }],
@@ -9946,7 +9884,6 @@ test("f = function({x} = {x: 10}) {}", {
             end: {line: 1, column: 30}
           }
         },
-        rest: null,
         generator: false,
         expression: false,
         loc: {
@@ -9994,71 +9931,78 @@ test("({f: function({x} = {x: 10}) {}})", {
           type: "FunctionExpression",
           id: null,
           params: [{
-            type: "ObjectPattern",
-            properties: [{
-              type: "Property",
-              key: {
-                type: "Identifier",
-                name: "x",
-                loc: {
-                  start: {line: 1, column: 15},
-                  end: {line: 1, column: 16}
-                }
-              },
-              value: {
-                type: "Identifier",
-                name: "x",
+            type: "AssignmentPattern",
+            left: {
+              type: "ObjectPattern",
+              properties: [{
+                type: "Property",
+                key: {
+                  type: "Identifier",
+                  name: "x",
+                  loc: {
+                    start: {line: 1, column: 15},
+                    end: {line: 1, column: 16}
+                  }
+                },
+                value: {
+                  type: "Identifier",
+                  name: "x",
+                  loc: {
+                    start: {line: 1, column: 15},
+                    end: {line: 1, column: 16}
+                  }
+                },
+                kind: "init",
+                method: false,
+                shorthand: true,
+                computed: false,
                 loc: {
                   start: {line: 1, column: 15},
                   end: {line: 1, column: 16}
                 }
-              },
-              kind: "init",
-              method: false,
-              shorthand: true,
-              computed: false,
+              }],
               loc: {
-                start: {line: 1, column: 15},
-                end: {line: 1, column: 16}
+                start: {line: 1, column: 14},
+                end: {line: 1, column: 17}
               }
-            }],
-            loc: {
-              start: {line: 1, column: 14},
-              end: {line: 1, column: 17}
-            }
-          }],
-          defaults: [{
-            type: "ObjectExpression",
-            properties: [{
-              type: "Property",
-              key: {
-                type: "Identifier",
-                name: "x",
+            },
+            right: {
+              type: "ObjectExpression",
+              properties: [{
+                type: "Property",
+                key: {
+                  type: "Identifier",
+                  name: "x",
+                  loc: {
+                    start: {line: 1, column: 21},
+                    end: {line: 1, column: 22}
+                  }
+                },
+                value: {
+                  type: "Literal",
+                  value: 10,
+                  raw: "10",
+                  loc: {
+                    start: {line: 1, column: 24},
+                    end: {line: 1, column: 26}
+                  }
+                },
+                kind: "init",
+                method: false,
+                shorthand: false,
+                computed: false,
                 loc: {
                   start: {line: 1, column: 21},
-                  end: {line: 1, column: 22}
-                }
-              },
-              value: {
-                type: "Literal",
-                value: 10,
-                raw: "10",
-                loc: {
-                  start: {line: 1, column: 24},
                   end: {line: 1, column: 26}
                 }
-              },
-              kind: "init",
-              method: false,
-              shorthand: false,
-              computed: false,
+              }],
               loc: {
-                start: {line: 1, column: 21},
-                end: {line: 1, column: 26}
+                start: {line: 1, column: 20},
+                end: {line: 1, column: 27}
               }
-            }],
+            },
             loc: {
-              start: {line: 1, column: 20},
+              start: {line: 1, column: 14},
               end: {line: 1, column: 27}
             }
           }],
@@ -10070,7 +10014,6 @@ test("({f: function({x} = {x: 10}) {}})", {
               end: {line: 1, column: 31}
             }
           },
-          rest: null,
           generator: false,
           expression: false,
           loc: {
@@ -10127,71 +10070,78 @@ test("({f({x} = {x: 10}) {}})", {
           type: "FunctionExpression",
           id: null,
           params: [{
-            type: "ObjectPattern",
-            properties: [{
-              type: "Property",
-              key: {
-                type: "Identifier",
-                name: "x",
-                loc: {
-                  start: {line: 1, column: 5},
-                  end: {line: 1, column: 6}
-                }
-              },
-              value: {
-                type: "Identifier",
-                name: "x",
+            type: "AssignmentPattern",
+            left: {
+              type: "ObjectPattern",
+              properties: [{
+                type: "Property",
+                key: {
+                  type: "Identifier",
+                  name: "x",
+                  loc: {
+                    start: {line: 1, column: 5},
+                    end: {line: 1, column: 6}
+                  }
+                },
+                value: {
+                  type: "Identifier",
+                  name: "x",
+                  loc: {
+                    start: {line: 1, column: 5},
+                    end: {line: 1, column: 6}
+                  }
+                },
+                kind: "init",
+                method: false,
+                shorthand: true,
+                computed: false,
                 loc: {
                   start: {line: 1, column: 5},
                   end: {line: 1, column: 6}
                 }
-              },
-              kind: "init",
-              method: false,
-              shorthand: true,
-              computed: false,
+              }],
               loc: {
-                start: {line: 1, column: 5},
-                end: {line: 1, column: 6}
+                start: {line: 1, column: 4},
+                end: {line: 1, column: 7}
               }
-            }],
-            loc: {
-              start: {line: 1, column: 4},
-              end: {line: 1, column: 7}
-            }
-          }],
-          defaults: [{
-            type: "ObjectExpression",
-            properties: [{
-              type: "Property",
-              key: {
-                type: "Identifier",
-                name: "x",
+            },
+            right: {
+              type: "ObjectExpression",
+              properties: [{
+                type: "Property",
+                key: {
+                  type: "Identifier",
+                  name: "x",
+                  loc: {
+                    start: {line: 1, column: 11},
+                    end: {line: 1, column: 12}
+                  }
+                },
+                value: {
+                  type: "Literal",
+                  value: 10,
+                  raw: "10",
+                  loc: {
+                    start: {line: 1, column: 14},
+                    end: {line: 1, column: 16}
+                  }
+                },
+                kind: "init",
+                method: false,
+                shorthand: false,
+                computed: false,
                 loc: {
                   start: {line: 1, column: 11},
-                  end: {line: 1, column: 12}
-                }
-              },
-              value: {
-                type: "Literal",
-                value: 10,
-                raw: "10",
-                loc: {
-                  start: {line: 1, column: 14},
                   end: {line: 1, column: 16}
                 }
-              },
-              kind: "init",
-              method: false,
-              shorthand: false,
-              computed: false,
+              }],
               loc: {
-                start: {line: 1, column: 11},
-                end: {line: 1, column: 16}
+                start: {line: 1, column: 10},
+                end: {line: 1, column: 17}
               }
-            }],
+            },
             loc: {
-              start: {line: 1, column: 10},
+              start: {line: 1, column: 4},
               end: {line: 1, column: 17}
             }
           }],
@@ -10203,7 +10153,6 @@ test("({f({x} = {x: 10}) {}})", {
               end: {line: 1, column: 21}
             }
           },
-          rest: null,
           generator: false,
           expression: false,
           loc: {
@@ -10264,71 +10213,78 @@ test("(class {f({x} = {x: 10}) {}})", {
             type: "FunctionExpression",
             id: null,
             params: [{
-              type: "ObjectPattern",
-              properties: [{
-                type: "Property",
-                key: {
-                  type: "Identifier",
-                  name: "x",
-                  loc: {
-                    start: {line: 1, column: 11},
-                    end: {line: 1, column: 12}
-                  }
-                },
-                value: {
-                  type: "Identifier",
-                  name: "x",
+              type: "AssignmentPattern",
+              left: {
+                type: "ObjectPattern",
+                properties: [{
+                  type: "Property",
+                  key: {
+                    type: "Identifier",
+                    name: "x",
+                    loc: {
+                      start: {line: 1, column: 11},
+                      end: {line: 1, column: 12}
+                    }
+                  },
+                  value: {
+                    type: "Identifier",
+                    name: "x",
+                    loc: {
+                      start: {line: 1, column: 11},
+                      end: {line: 1, column: 12}
+                    }
+                  },
+                  kind: "init",
+                  method: false,
+                  shorthand: true,
+                  computed: false,
                   loc: {
                     start: {line: 1, column: 11},
                     end: {line: 1, column: 12}
                   }
-                },
-                kind: "init",
-                method: false,
-                shorthand: true,
-                computed: false,
+                }],
                 loc: {
-                  start: {line: 1, column: 11},
-                  end: {line: 1, column: 12}
+                  start: {line: 1, column: 10},
+                  end: {line: 1, column: 13}
                 }
-              }],
-              loc: {
-                start: {line: 1, column: 10},
-                end: {line: 1, column: 13}
-              }
-            }],
-            defaults: [{
-              type: "ObjectExpression",
-              properties: [{
-                type: "Property",
-                key: {
-                  type: "Identifier",
-                  name: "x",
+              },
+              right: {
+                type: "ObjectExpression",
+                properties: [{
+                  type: "Property",
+                  key: {
+                    type: "Identifier",
+                    name: "x",
+                    loc: {
+                      start: {line: 1, column: 17},
+                      end: {line: 1, column: 18}
+                    }
+                  },
+                  value: {
+                    type: "Literal",
+                    value: 10,
+                    raw: "10",
+                    loc: {
+                      start: {line: 1, column: 20},
+                      end: {line: 1, column: 22}
+                    }
+                  },
+                  kind: "init",
+                  method: false,
+                  shorthand: false,
+                  computed: false,
                   loc: {
                     start: {line: 1, column: 17},
-                    end: {line: 1, column: 18}
-                  }
-                },
-                value: {
-                  type: "Literal",
-                  value: 10,
-                  raw: "10",
-                  loc: {
-                    start: {line: 1, column: 20},
                     end: {line: 1, column: 22}
                   }
-                },
-                kind: "init",
-                method: false,
-                shorthand: false,
-                computed: false,
+                }],
                 loc: {
-                  start: {line: 1, column: 17},
-                  end: {line: 1, column: 22}
+                  start: {line: 1, column: 16},
+                  end: {line: 1, column: 23}
                 }
-              }],
+              },
               loc: {
-                start: {line: 1, column: 16},
+                start: {line: 1, column: 10},
                 end: {line: 1, column: 23}
               }
             }],
@@ -10340,7 +10296,6 @@ test("(class {f({x} = {x: 10}) {}})", {
                 end: {line: 1, column: 27}
               }
             },
-            rest: null,
             generator: false,
             expression: false,
             loc: {
@@ -10388,71 +10343,78 @@ test("(({x} = {x: 10}) => {})", {
       type: "ArrowFunctionExpression",
       id: null,
       params: [{
-        type: "ObjectPattern",
-        properties: [{
-          type: "Property",
-          key: {
-            type: "Identifier",
-            name: "x",
-            loc: {
-              start: {line: 1, column: 3},
-              end: {line: 1, column: 4}
-            }
-          },
-          value: {
-            type: "Identifier",
-            name: "x",
+        type: "AssignmentPattern",
+        left: {
+          type: "ObjectPattern",
+          properties: [{
+            type: "Property",
+            key: {
+              type: "Identifier",
+              name: "x",
+              loc: {
+                start: {line: 1, column: 3},
+                end: {line: 1, column: 4}
+              }
+            },
+            value: {
+              type: "Identifier",
+              name: "x",
+              loc: {
+                start: {line: 1, column: 3},
+                end: {line: 1, column: 4}
+              }
+            },
+            kind: "init",
+            method: false,
+            shorthand: true,
+            computed: false,
             loc: {
               start: {line: 1, column: 3},
               end: {line: 1, column: 4}
             }
-          },
-          kind: "init",
-          method: false,
-          shorthand: true,
-          computed: false,
+          }],
           loc: {
-            start: {line: 1, column: 3},
-            end: {line: 1, column: 4}
+            start: {line: 1, column: 2},
+            end: {line: 1, column: 5}
           }
-        }],
-        loc: {
-          start: {line: 1, column: 2},
-          end: {line: 1, column: 5}
-        }
-      }],
-      defaults: [{
-        type: "ObjectExpression",
-        properties: [{
-          type: "Property",
-          key: {
-            type: "Identifier",
-            name: "x",
+        },
+        right: {
+          type: "ObjectExpression",
+          properties: [{
+            type: "Property",
+            key: {
+              type: "Identifier",
+              name: "x",
+              loc: {
+                start: {line: 1, column: 9},
+                end: {line: 1, column: 10}
+              }
+            },
+            value: {
+              type: "Literal",
+              value: 10,
+              raw: "10",
+              loc: {
+                start: {line: 1, column: 12},
+                end: {line: 1, column: 14}
+              }
+            },
+            kind: "init",
+            method: false,
+            shorthand: false,
+            computed: false,
             loc: {
               start: {line: 1, column: 9},
-              end: {line: 1, column: 10}
-            }
-          },
-          value: {
-            type: "Literal",
-            value: 10,
-            raw: "10",
-            loc: {
-              start: {line: 1, column: 12},
               end: {line: 1, column: 14}
             }
-          },
-          kind: "init",
-          method: false,
-          shorthand: false,
-          computed: false,
+          }],
           loc: {
-            start: {line: 1, column: 9},
-            end: {line: 1, column: 14}
+            start: {line: 1, column: 8},
+            end: {line: 1, column: 15}
           }
-        }],
+        },
         loc: {
-          start: {line: 1, column: 8},
+          start: {line: 1, column: 2},
           end: {line: 1, column: 15}
         }
       }],
@@ -10464,7 +10426,6 @@ test("(({x} = {x: 10}) => {})", {
           end: {line: 1, column: 22}
         }
       },
-      rest: null,
       generator: false,
       expression: false,
       loc: {
@@ -10506,19 +10467,26 @@ test("x = function(y = 1) {}", {
         type: "FunctionExpression",
         id: null,
         params: [{
-          type: "Identifier",
-          name: "y",
+          type: "AssignmentPattern",
+          left: {
+            type: "Identifier",
+            name: "y",
+            loc: {
+              start: {line: 1, column: 13},
+              end: {line: 1, column: 14}
+            }
+          },
+          right: {
+            type: "Literal",
+            value: 1,
+            raw: "1",
+            loc: {
+              start: {line: 1, column: 17},
+              end: {line: 1, column: 18}
+            }
+          },
           loc: {
             start: {line: 1, column: 13},
-            end: {line: 1, column: 14}
-          }
-        }],
-        defaults: [{
-          type: "Literal",
-          value: 1,
-          raw: "1",
-          loc: {
-            start: {line: 1, column: 17},
             end: {line: 1, column: 18}
           }
         }],
@@ -10530,7 +10498,6 @@ test("x = function(y = 1) {}", {
             end: {line: 1, column: 22}
           }
         },
-        rest: null,
         generator: false,
         expression: false,
         loc: {
@@ -10571,19 +10538,26 @@ test("function f(a = 1) {}", {
       }
     },
     params: [{
-      type: "Identifier",
-      name: "a",
+      type: "AssignmentPattern",
+      left: {
+        type: "Identifier",
+        name: "a",
+        loc: {
+          start: {line: 1, column: 11},
+          end: {line: 1, column: 12}
+        }
+      },
+      right: {
+        type: "Literal",
+        value: 1,
+        raw: "1",
+        loc: {
+          start: {line: 1, column: 15},
+          end: {line: 1, column: 16}
+        }
+      },
       loc: {
         start: {line: 1, column: 11},
-        end: {line: 1, column: 12}
-      }
-    }],
-    defaults: [{
-      type: "Literal",
-      value: 1,
-      raw: "1",
-      loc: {
-        start: {line: 1, column: 15},
         end: {line: 1, column: 16}
       }
     }],
@@ -10595,7 +10569,6 @@ test("function f(a = 1) {}", {
         end: {line: 1, column: 20}
       }
     },
-    rest: null,
     generator: false,
     expression: false,
     loc: {
@@ -10644,19 +10617,26 @@ test("x = { f: function(a=1) {} }", {
             type: "FunctionExpression",
             id: null,
             params: [{
-              type: "Identifier",
-              name: "a",
-              loc: {
-                start: {line: 1, column: 18},
-                end: {line: 1, column: 19}
-              }
-            }],
-            defaults: [{
-              type: "Literal",
-              value: 1,
-              raw: "1",
-              loc: {
-                start: {line: 1, column: 20},
+              type: "AssignmentPattern",
+              left: {
+                type: "Identifier",
+                name: "a",
+                loc: {
+                  start: {line: 1, column: 18},
+                  end: {line: 1, column: 19}
+                }
+              },
+              right: {
+                type: "Literal",
+                value: 1,
+                raw: "1",
+                loc: {
+                  start: {line: 1, column: 20},
+                  end: {line: 1, column: 21}
+                }
+              },
+              loc: {
+                start: {line: 1, column: 18},
                 end: {line: 1, column: 21}
               }
             }],
@@ -10668,7 +10648,6 @@ test("x = { f: function(a=1) {} }", {
                 end: {line: 1, column: 25}
               }
             },
-            rest: null,
             generator: false,
             expression: false,
             loc: {
@@ -10741,19 +10720,26 @@ test("x = { f(a=1) {} }", {
             type: "FunctionExpression",
             id: null,
             params: [{
-              type: "Identifier",
-              name: "a",
+              type: "AssignmentPattern",
+              left: {
+                type: "Identifier",
+                name: "a",
+                loc: {
+                  start: {line: 1, column: 8},
+                  end: {line: 1, column: 9}
+                }
+              },
+              right: {
+                type: "Literal",
+                value: 1,
+                raw: "1",
+                loc: {
+                  start: {line: 1, column: 10},
+                  end: {line: 1, column: 11}
+                }
+              },
               loc: {
                 start: {line: 1, column: 8},
-                end: {line: 1, column: 9}
-              }
-            }],
-            defaults: [{
-              type: "Literal",
-              value: 1,
-              raw: "1",
-              loc: {
-                start: {line: 1, column: 10},
                 end: {line: 1, column: 11}
               }
             }],
@@ -10765,7 +10751,6 @@ test("x = { f(a=1) {} }", {
                 end: {line: 1, column: 15}
               }
             },
-            rest: null,
             generator: false,
             expression: false,
             loc: {
@@ -10821,15 +10806,27 @@ test("function f(a, ...b) {}", {
         end: {line: 1, column: 10}
       }
     },
-    params: [{
-      type: "Identifier",
-      name: "a",
-      loc: {
-        start: {line: 1, column: 11},
-        end: {line: 1, column: 12}
+    params: [
+      {
+        type: "Identifier",
+        name: "a",
+        loc: {
+          start: {line: 1, column: 11},
+          end: {line: 1, column: 12}
+        }
+      },
+      {
+        type: "RestElement",
+        argument: {
+          type: "Identifier",
+          name: "b",
+          loc: {
+            start: {line: 1, column: 17},
+            end: {line: 1, column: 18}
+          }
+        }
       }
-    }],
-    defaults: [],
+    ],
     body: {
       type: "BlockStatement",
       body: [],
@@ -10838,14 +10835,6 @@ test("function f(a, ...b) {}", {
         end: {line: 1, column: 22}
       }
     },
-    rest: {
-      type: "Identifier",
-      name: "b",
-      loc: {
-        start: {line: 1, column: 17},
-        end: {line: 1, column: 18}
-      }
-    },
     generator: false,
     expression: false,
     loc: {
@@ -10902,7 +10891,6 @@ test("function x([ a, b ]){}", {
         end: {line: 1, column: 19}
       }
     }],
-    defaults: [],
     body: {
       type: "BlockStatement",
       body: [],
@@ -10911,7 +10899,6 @@ test("function x([ a, b ]){}", {
         end: {line: 1, column: 22}
       }
     },
-    rest: null,
     generator: false,
     expression: false,
     loc: {
@@ -11004,7 +10991,6 @@ test("function x({ a, b }){}", {
         end: {line: 1, column: 19}
       }
     }],
-    defaults: [],
     body: {
       type: "BlockStatement",
       body: [],
@@ -11013,7 +10999,6 @@ test("function x({ a, b }){}", {
         end: {line: 1, column: 22}
       }
     },
-    rest: null,
     generator: false,
     expression: false,
     loc: {
@@ -11087,7 +11072,6 @@ test("function x(a, { a }){}", {
         }
       }
     ],
-    defaults: [],
     body: {
       type: "BlockStatement",
       body: [],
@@ -11096,7 +11080,6 @@ test("function x(a, { a }){}", {
         end: {line: 1, column: 22}
       }
     },
-    rest: null,
     generator: false,
     expression: false,
     loc: {
@@ -11126,8 +11109,34 @@ test("function x(...[ a, b ]){}", {
         end: {line: 1, column: 10}
       }
     },
-    params: [],
-    defaults: [],
+    params: [{
+      type: "RestElement",
+      argument: {
+        type: "ArrayPattern",
+        elements: [
+          {
+            type: "Identifier",
+            name: "a",
+            loc: {
+              start: {line: 1, column: 16},
+              end: {line: 1, column: 17}
+            }
+          },
+          {
+            type: "Identifier",
+            name: "b",
+            loc: {
+              start: {line: 1, column: 19},
+              end: {line: 1, column: 20}
+            }
+          }
+        ],
+        loc: {
+          start: {line: 1, column: 14},
+          end: {line: 1, column: 22}
+        }
+      }
+    }],
     body: {
       type: "BlockStatement",
       body: [],
@@ -11136,31 +11145,6 @@ test("function x(...[ a, b ]){}", {
         end: {line: 1, column: 25}
       }
     },
-    rest: {
-      type: "ArrayPattern",
-      elements: [
-        {
-          type: "Identifier",
-          name: "a",
-          loc: {
-            start: {line: 1, column: 16},
-            end: {line: 1, column: 17}
-          }
-        },
-        {
-          type: "Identifier",
-          name: "b",
-          loc: {
-            start: {line: 1, column: 19},
-            end: {line: 1, column: 20}
-          }
-        }
-      ],
-      loc: {
-        start: {line: 1, column: 14},
-        end: {line: 1, column: 22}
-      }
-    },
     generator: false,
     expression: false,
     loc: {
@@ -11190,142 +11174,179 @@ test("function x({ a: { w, x }, b: [y, z] }, ...[a, b, c]){}", {
         end: {line: 1, column: 10}
       }
     },
-    params: [{
-      type: "ObjectPattern",
-      properties: [
-        {
-          type: "Property",
-          key: {
-            type: "Identifier",
-            name: "a",
-            loc: {
-              start: {line: 1, column: 13},
-              end: {line: 1, column: 14}
-            }
-          },
-          value: {
-            type: "ObjectPattern",
-            properties: [
-              {
-                type: "Property",
-                key: {
-                  type: "Identifier",
-                  name: "w",
-                  loc: {
-                    start: {line: 1, column: 18},
-                    end: {line: 1, column: 19}
-                  }
-                },
-                value: {
-                  type: "Identifier",
-                  name: "w",
+    params: [
+      {
+        type: "ObjectPattern",
+        properties: [
+          {
+            type: "Property",
+            key: {
+              type: "Identifier",
+              name: "a",
+              loc: {
+                start: {line: 1, column: 13},
+                end: {line: 1, column: 14}
+              }
+            },
+            value: {
+              type: "ObjectPattern",
+              properties: [
+                {
+                  type: "Property",
+                  key: {
+                    type: "Identifier",
+                    name: "w",
+                    loc: {
+                      start: {line: 1, column: 18},
+                      end: {line: 1, column: 19}
+                    }
+                  },
+                  value: {
+                    type: "Identifier",
+                    name: "w",
+                    loc: {
+                      start: {line: 1, column: 18},
+                      end: {line: 1, column: 19}
+                    }
+                  },
+                  kind: "init",
+                  method: false,
+                  shorthand: true,
+                  computed: false,
                   loc: {
                     start: {line: 1, column: 18},
                     end: {line: 1, column: 19}
                   }
                 },
-                kind: "init",
-                method: false,
-                shorthand: true,
-                computed: false,
-                loc: {
-                  start: {line: 1, column: 18},
-                  end: {line: 1, column: 19}
-                }
-              },
-              {
-                type: "Property",
-                key: {
-                  type: "Identifier",
-                  name: "x",
-                  loc: {
-                    start: {line: 1, column: 21},
-                    end: {line: 1, column: 22}
-                  }
-                },
-                value: {
-                  type: "Identifier",
-                  name: "x",
+                {
+                  type: "Property",
+                  key: {
+                    type: "Identifier",
+                    name: "x",
+                    loc: {
+                      start: {line: 1, column: 21},
+                      end: {line: 1, column: 22}
+                    }
+                  },
+                  value: {
+                    type: "Identifier",
+                    name: "x",
+                    loc: {
+                      start: {line: 1, column: 21},
+                      end: {line: 1, column: 22}
+                    }
+                  },
+                  kind: "init",
+                  method: false,
+                  shorthand: true,
+                  computed: false,
                   loc: {
                     start: {line: 1, column: 21},
                     end: {line: 1, column: 22}
                   }
-                },
-                kind: "init",
-                method: false,
-                shorthand: true,
-                computed: false,
-                loc: {
-                  start: {line: 1, column: 21},
-                  end: {line: 1, column: 22}
                 }
+              ],
+              loc: {
+                start: {line: 1, column: 16},
+                end: {line: 1, column: 24}
               }
-            ],
+            },
+            kind: "init",
+            method: false,
+            shorthand: false,
+            computed: false,
             loc: {
-              start: {line: 1, column: 16},
+              start: {line: 1, column: 13},
               end: {line: 1, column: 24}
             }
           },
-          kind: "init",
-          method: false,
-          shorthand: false,
-          computed: false,
-          loc: {
-            start: {line: 1, column: 13},
-            end: {line: 1, column: 24}
-          }
-        },
-        {
-          type: "Property",
-          key: {
-            type: "Identifier",
-            name: "b",
-            loc: {
-              start: {line: 1, column: 26},
-              end: {line: 1, column: 27}
-            }
-          },
-          value: {
-            type: "ArrayPattern",
-            elements: [
-              {
-                type: "Identifier",
-                name: "y",
-                loc: {
-                  start: {line: 1, column: 30},
-                  end: {line: 1, column: 31}
-                }
-              },
-              {
-                type: "Identifier",
-                name: "z",
-                loc: {
-                  start: {line: 1, column: 33},
-                  end: {line: 1, column: 34}
+          {
+            type: "Property",
+            key: {
+              type: "Identifier",
+              name: "b",
+              loc: {
+                start: {line: 1, column: 26},
+                end: {line: 1, column: 27}
+              }
+            },
+            value: {
+              type: "ArrayPattern",
+              elements: [
+                {
+                  type: "Identifier",
+                  name: "y",
+                  loc: {
+                    start: {line: 1, column: 30},
+                    end: {line: 1, column: 31}
+                  }
+                },
+                {
+                  type: "Identifier",
+                  name: "z",
+                  loc: {
+                    start: {line: 1, column: 33},
+                    end: {line: 1, column: 34}
+                  }
                 }
+              ],
+              loc: {
+                start: {line: 1, column: 29},
+                end: {line: 1, column: 35}
               }
-            ],
+            },
+            kind: "init",
+            method: false,
+            shorthand: false,
+            computed: false,
             loc: {
-              start: {line: 1, column: 29},
+              start: {line: 1, column: 26},
               end: {line: 1, column: 35}
             }
-          },
-          kind: "init",
-          method: false,
-          shorthand: false,
-          computed: false,
+          }
+        ],
+        loc: {
+          start: {line: 1, column: 11},
+          end: {line: 1, column: 37}
+        }
+      },
+      {
+        type: "RestElement",
+        argument: {
+          type: "ArrayPattern",
+          elements: [
+            {
+              type: "Identifier",
+              name: "a",
+              loc: {
+                start: {line: 1, column: 43},
+                end: {line: 1, column: 44}
+              }
+            },
+            {
+              type: "Identifier",
+              name: "b",
+              loc: {
+                start: {line: 1, column: 46},
+                end: {line: 1, column: 47}
+              }
+            },
+            {
+              type: "Identifier",
+              name: "c",
+              loc: {
+                start: {line: 1, column: 49},
+                end: {line: 1, column: 50}
+              }
+            }
+          ],
           loc: {
-            start: {line: 1, column: 26},
-            end: {line: 1, column: 35}
+            start: {line: 1, column: 42},
+            end: {line: 1, column: 51}
           }
         }
-      ],
-      loc: {
-        start: {line: 1, column: 11},
-        end: {line: 1, column: 37}
       }
-    }],
-    defaults: [],
+    ],
     body: {
       type: "BlockStatement",
       body: [],
@@ -11334,39 +11355,6 @@ test("function x({ a: { w, x }, b: [y, z] }, ...[a, b, c]){}", {
         end: {line: 1, column: 54}
       }
     },
-    rest: {
-      type: "ArrayPattern",
-      elements: [
-        {
-          type: "Identifier",
-          name: "a",
-          loc: {
-            start: {line: 1, column: 43},
-            end: {line: 1, column: 44}
-          }
-        },
-        {
-          type: "Identifier",
-          name: "b",
-          loc: {
-            start: {line: 1, column: 46},
-            end: {line: 1, column: 47}
-          }
-        },
-        {
-          type: "Identifier",
-          name: "c",
-          loc: {
-            start: {line: 1, column: 49},
-            end: {line: 1, column: 50}
-          }
-        }
-      ],
-      loc: {
-        start: {line: 1, column: 42},
-        end: {line: 1, column: 51}
-      }
-    },
     generator: false,
     expression: false,
     loc: {
@@ -11423,7 +11411,6 @@ test("(function x([ a, b ]){})", {
           end: {line: 1, column: 20}
         }
       }],
-      defaults: [],
       body: {
         type: "BlockStatement",
         body: [],
@@ -11432,7 +11419,6 @@ test("(function x([ a, b ]){})", {
           end: {line: 1, column: 23}
         }
       },
-      rest: null,
       generator: false,
       expression: false,
       loc: {
@@ -11532,7 +11518,6 @@ test("(function x({ a, b }){})", {
           end: {line: 1, column: 20}
         }
       }],
-      defaults: [],
       body: {
         type: "BlockStatement",
         body: [],
@@ -11541,7 +11526,6 @@ test("(function x({ a, b }){})", {
           end: {line: 1, column: 23}
         }
       },
-      rest: null,
       generator: false,
       expression: false,
       loc: {
@@ -11578,8 +11562,34 @@ test("(function x(...[ a, b ]){})", {
           end: {line: 1, column: 11}
         }
       },
-      params: [],
-      defaults: [],
+      params: [{
+        type: "RestElement",
+        argument: {
+          type: "ArrayPattern",
+          elements: [
+            {
+              type: "Identifier",
+              name: "a",
+              loc: {
+                start: {line: 1, column: 17},
+                end: {line: 1, column: 18}
+              }
+            },
+            {
+              type: "Identifier",
+              name: "b",
+              loc: {
+                start: {line: 1, column: 20},
+                end: {line: 1, column: 21}
+              }
+            }
+          ],
+          loc: {
+            start: {line: 1, column: 15},
+            end: {line: 1, column: 23}
+          }
+        }
+      }],
       body: {
         type: "BlockStatement",
         body: [],
@@ -11588,31 +11598,6 @@ test("(function x(...[ a, b ]){})", {
           end: {line: 1, column: 26}
         }
       },
-      rest: {
-        type: "ArrayPattern",
-        elements: [
-          {
-            type: "Identifier",
-            name: "a",
-            loc: {
-              start: {line: 1, column: 17},
-              end: {line: 1, column: 18}
-            }
-          },
-          {
-            type: "Identifier",
-            name: "b",
-            loc: {
-              start: {line: 1, column: 20},
-              end: {line: 1, column: 21}
-            }
-          }
-        ],
-        loc: {
-          start: {line: 1, column: 15},
-          end: {line: 1, column: 23}
-        }
-      },
       generator: false,
       expression: false,
       loc: {
@@ -11649,142 +11634,179 @@ test("(function x({ a: { w, x }, b: [y, z] }, ...[a, b, c]){})", {
           end: {line: 1, column: 11}
         }
       },
-      params: [{
-        type: "ObjectPattern",
-        properties: [
-          {
-            type: "Property",
-            key: {
-              type: "Identifier",
-              name: "a",
+      params: [
+        {
+          type: "ObjectPattern",
+          properties: [
+            {
+              type: "Property",
+              key: {
+                type: "Identifier",
+                name: "a",
+                loc: {
+                  start: {line: 1, column: 14},
+                  end: {line: 1, column: 15}
+                }
+              },
+              value: {
+                type: "ObjectPattern",
+                properties: [
+                  {
+                    type: "Property",
+                    key: {
+                      type: "Identifier",
+                      name: "w",
+                      loc: {
+                        start: {line: 1, column: 19},
+                        end: {line: 1, column: 20}
+                      }
+                    },
+                    value: {
+                      type: "Identifier",
+                      name: "w",
+                      loc: {
+                        start: {line: 1, column: 19},
+                        end: {line: 1, column: 20}
+                      }
+                    },
+                    kind: "init",
+                    method: false,
+                    shorthand: true,
+                    computed: false,
+                    loc: {
+                      start: {line: 1, column: 19},
+                      end: {line: 1, column: 20}
+                    }
+                  },
+                  {
+                    type: "Property",
+                    key: {
+                      type: "Identifier",
+                      name: "x",
+                      loc: {
+                        start: {line: 1, column: 22},
+                        end: {line: 1, column: 23}
+                      }
+                    },
+                    value: {
+                      type: "Identifier",
+                      name: "x",
+                      loc: {
+                        start: {line: 1, column: 22},
+                        end: {line: 1, column: 23}
+                      }
+                    },
+                    kind: "init",
+                    method: false,
+                    shorthand: true,
+                    computed: false,
+                    loc: {
+                      start: {line: 1, column: 22},
+                      end: {line: 1, column: 23}
+                    }
+                  }
+                ],
+                loc: {
+                  start: {line: 1, column: 17},
+                  end: {line: 1, column: 25}
+                }
+              },
+              kind: "init",
+              method: false,
+              shorthand: false,
+              computed: false,
               loc: {
                 start: {line: 1, column: 14},
-                end: {line: 1, column: 15}
+                end: {line: 1, column: 25}
               }
             },
-            value: {
-              type: "ObjectPattern",
-              properties: [
-                {
-                  type: "Property",
-                  key: {
+            {
+              type: "Property",
+              key: {
+                type: "Identifier",
+                name: "b",
+                loc: {
+                  start: {line: 1, column: 27},
+                  end: {line: 1, column: 28}
+                }
+              },
+              value: {
+                type: "ArrayPattern",
+                elements: [
+                  {
                     type: "Identifier",
-                    name: "w",
+                    name: "y",
                     loc: {
-                      start: {line: 1, column: 19},
-                      end: {line: 1, column: 20}
+                      start: {line: 1, column: 31},
+                      end: {line: 1, column: 32}
                     }
                   },
-                  value: {
+                  {
                     type: "Identifier",
-                    name: "w",
+                    name: "z",
                     loc: {
-                      start: {line: 1, column: 19},
-                      end: {line: 1, column: 20}
-                    }
-                  },
-                  kind: "init",
-                  method: false,
-                  shorthand: true,
-                  computed: false,
-                  loc: {
-                    start: {line: 1, column: 19},
-                    end: {line: 1, column: 20}
-                  }
-                },
-                {
-                  type: "Property",
-                  key: {
-                    type: "Identifier",
-                    name: "x",
-                    loc: {
-                      start: {line: 1, column: 22},
-                      end: {line: 1, column: 23}
-                    }
-                  },
-                  value: {
-                    type: "Identifier",
-                    name: "x",
-                    loc: {
-                      start: {line: 1, column: 22},
-                      end: {line: 1, column: 23}
+                      start: {line: 1, column: 34},
+                      end: {line: 1, column: 35}
                     }
-                  },
-                  kind: "init",
-                  method: false,
-                  shorthand: true,
-                  computed: false,
-                  loc: {
-                    start: {line: 1, column: 22},
-                    end: {line: 1, column: 23}
                   }
+                ],
+                loc: {
+                  start: {line: 1, column: 30},
+                  end: {line: 1, column: 36}
                 }
-              ],
-              loc: {
-                start: {line: 1, column: 17},
-                end: {line: 1, column: 25}
-              }
-            },
-            kind: "init",
-            method: false,
-            shorthand: false,
-            computed: false,
-            loc: {
-              start: {line: 1, column: 14},
-              end: {line: 1, column: 25}
-            }
-          },
-          {
-            type: "Property",
-            key: {
-              type: "Identifier",
-              name: "b",
+              },
+              kind: "init",
+              method: false,
+              shorthand: false,
+              computed: false,
               loc: {
                 start: {line: 1, column: 27},
-                end: {line: 1, column: 28}
+                end: {line: 1, column: 36}
               }
-            },
-            value: {
-              type: "ArrayPattern",
-              elements: [
-                {
-                  type: "Identifier",
-                  name: "y",
-                  loc: {
-                    start: {line: 1, column: 31},
-                    end: {line: 1, column: 32}
-                  }
-                },
-                {
-                  type: "Identifier",
-                  name: "z",
-                  loc: {
-                    start: {line: 1, column: 34},
-                    end: {line: 1, column: 35}
-                  }
+            }
+          ],
+          loc: {
+            start: {line: 1, column: 12},
+            end: {line: 1, column: 38}
+          }
+        },
+        {
+          type: "RestElement",
+          argument: {
+            type: "ArrayPattern",
+            elements: [
+              {
+                type: "Identifier",
+                name: "a",
+                loc: {
+                  start: {line: 1, column: 44},
+                  end: {line: 1, column: 45}
+                }
+              },
+              {
+                type: "Identifier",
+                name: "b",
+                loc: {
+                  start: {line: 1, column: 47},
+                  end: {line: 1, column: 48}
+                }
+              },
+              {
+                type: "Identifier",
+                name: "c",
+                loc: {
+                  start: {line: 1, column: 50},
+                  end: {line: 1, column: 51}
                 }
-              ],
-              loc: {
-                start: {line: 1, column: 30},
-                end: {line: 1, column: 36}
               }
-            },
-            kind: "init",
-            method: false,
-            shorthand: false,
-            computed: false,
+            ],
             loc: {
-              start: {line: 1, column: 27},
-              end: {line: 1, column: 36}
+              start: {line: 1, column: 43},
+              end: {line: 1, column: 52}
             }
           }
-        ],
-        loc: {
-          start: {line: 1, column: 12},
-          end: {line: 1, column: 38}
         }
-      }],
-      defaults: [],
+      ],
       body: {
         type: "BlockStatement",
         body: [],
@@ -11793,39 +11815,6 @@ test("(function x({ a: { w, x }, b: [y, z] }, ...[a, b, c]){})", {
           end: {line: 1, column: 55}
         }
       },
-      rest: {
-        type: "ArrayPattern",
-        elements: [
-          {
-            type: "Identifier",
-            name: "a",
-            loc: {
-              start: {line: 1, column: 44},
-              end: {line: 1, column: 45}
-            }
-          },
-          {
-            type: "Identifier",
-            name: "b",
-            loc: {
-              start: {line: 1, column: 47},
-              end: {line: 1, column: 48}
-            }
-          },
-          {
-            type: "Identifier",
-            name: "c",
-            loc: {
-              start: {line: 1, column: 50},
-              end: {line: 1, column: 51}
-            }
-          }
-        ],
-        loc: {
-          start: {line: 1, column: 43},
-          end: {line: 1, column: 52}
-        }
-      },
       generator: false,
       expression: false,
       loc: {
@@ -11892,7 +11881,6 @@ test("({ x([ a, b ]){} })", {
               end: {line: 1, column: 13}
             }
           }],
-          defaults: [],
           body: {
             type: "BlockStatement",
             body: [],
@@ -11901,7 +11889,6 @@ test("({ x([ a, b ]){} })", {
               end: {line: 1, column: 16}
             }
           },
-          rest: null,
           generator: false,
           expression: false,
           loc: {
@@ -11957,8 +11944,34 @@ test("({ x(...[ a, b ]){} })", {
         value: {
           type: "FunctionExpression",
           id: null,
-          params: [],
-          defaults: [],
+          params: [{
+            type: "RestElement",
+            argument: {
+              type: "ArrayPattern",
+              elements: [
+                {
+                  type: "Identifier",
+                  name: "a",
+                  loc: {
+                    start: {line: 1, column: 10},
+                    end: {line: 1, column: 11}
+                  }
+                },
+                {
+                  type: "Identifier",
+                  name: "b",
+                  loc: {
+                    start: {line: 1, column: 13},
+                    end: {line: 1, column: 14}
+                  }
+                }
+              ],
+              loc: {
+                start: {line: 1, column: 8},
+                end: {line: 1, column: 16}
+              }
+            }
+          }],
           body: {
             type: "BlockStatement",
             body: [],
@@ -11967,31 +11980,6 @@ test("({ x(...[ a, b ]){} })", {
               end: {line: 1, column: 19}
             }
           },
-          rest: {
-            type: "ArrayPattern",
-            elements: [
-              {
-                type: "Identifier",
-                name: "a",
-                loc: {
-                  start: {line: 1, column: 10},
-                  end: {line: 1, column: 11}
-                }
-              },
-              {
-                type: "Identifier",
-                name: "b",
-                loc: {
-                  start: {line: 1, column: 13},
-                  end: {line: 1, column: 14}
-                }
-              }
-            ],
-            loc: {
-              start: {line: 1, column: 8},
-              end: {line: 1, column: 16}
-            }
-          },
           generator: false,
           expression: false,
           loc: {
@@ -12047,7 +12035,8 @@ test("({ x({ a: { w, x }, b: [y, z] }, ...[a, b, c]){} })", {
         value: {
           type: "FunctionExpression",
           id: null,
-          params: [{
+          params: [
+          {
             type: "ObjectPattern",
             properties: [
               {
@@ -12181,8 +12170,44 @@ test("({ x({ a: { w, x }, b: [y, z] }, ...[a, b, c]){} })", {
               start: {line: 1, column: 5},
               end: {line: 1, column: 31}
             }
-          }],
-          defaults: [],
+          },
+          {
+            type: "RestElement",
+            argument: {
+              type: "ArrayPattern",
+              elements: [
+                {
+                  type: "Identifier",
+                  name: "a",
+                  loc: {
+                    start: {line: 1, column: 37},
+                    end: {line: 1, column: 38}
+                  }
+                },
+                {
+                  type: "Identifier",
+                  name: "b",
+                  loc: {
+                    start: {line: 1, column: 40},
+                    end: {line: 1, column: 41}
+                  }
+                },
+                {
+                  type: "Identifier",
+                  name: "c",
+                  loc: {
+                    start: {line: 1, column: 43},
+                    end: {line: 1, column: 44}
+                  }
+                }
+              ],
+              loc: {
+                start: {line: 1, column: 36},
+                end: {line: 1, column: 45}
+              }
+            }
+          }
+          ],
           body: {
             type: "BlockStatement",
             body: [],
@@ -12191,39 +12216,6 @@ test("({ x({ a: { w, x }, b: [y, z] }, ...[a, b, c]){} })", {
               end: {line: 1, column: 48}
             }
           },
-          rest: {
-            type: "ArrayPattern",
-            elements: [
-              {
-                type: "Identifier",
-                name: "a",
-                loc: {
-                  start: {line: 1, column: 37},
-                  end: {line: 1, column: 38}
-                }
-              },
-              {
-                type: "Identifier",
-                name: "b",
-                loc: {
-                  start: {line: 1, column: 40},
-                  end: {line: 1, column: 41}
-                }
-              },
-              {
-                type: "Identifier",
-                name: "c",
-                loc: {
-                  start: {line: 1, column: 43},
-                  end: {line: 1, column: 44}
-                }
-              }
-            ],
-            loc: {
-              start: {line: 1, column: 36},
-              end: {line: 1, column: 45}
-            }
-          },
           generator: false,
           expression: false,
           loc: {
@@ -12267,24 +12259,25 @@ test("(...a) => {}", {
     expression: {
       type: "ArrowFunctionExpression",
       id: null,
-      params: [],
-      defaults: [],
-      body: {
-        type: "BlockStatement",
+      params: [{
+        type: "RestElement",
+        argument: {
+          type: "Identifier",
+          name: "a",
+          loc: {
+            start: {line: 1, column: 4},
+            end: {line: 1, column: 5}
+          }
+        }
+      }],
+      body: {
+        type: "BlockStatement",
         body: [],
         loc: {
           start: {line: 1, column: 10},
           end: {line: 1, column: 12}
         }
       },
-      rest: {
-        type: "Identifier",
-        name: "a",
-        loc: {
-          start: {line: 1, column: 4},
-          end: {line: 1, column: 5}
-        }
-      },
       generator: false,
       expression: false,
       loc: {
@@ -12314,15 +12307,27 @@ test("(a, ...b) => {}", {
     expression: {
       type: "ArrowFunctionExpression",
       id: null,
-      params: [{
-        type: "Identifier",
-        name: "a",
-        loc: {
-          start: {line: 1, column: 1},
-          end: {line: 1, column: 2}
+      params: [
+        {
+          type: "Identifier",
+          name: "a",
+          loc: {
+            start: {line: 1, column: 1},
+            end: {line: 1, column: 2}
+          }
+        },
+        {
+          type: "RestElement",
+          argument: {
+            type: "Identifier",
+            name: "b",
+            loc: {
+              start: {line: 1, column: 7},
+              end: {line: 1, column: 8}
+            }
+          }
         }
-      }],
-      defaults: [],
+      ],
       body: {
         type: "BlockStatement",
         body: [],
@@ -12331,14 +12336,6 @@ test("(a, ...b) => {}", {
           end: {line: 1, column: 15}
         }
       },
-      rest: {
-        type: "Identifier",
-        name: "b",
-        loc: {
-          start: {line: 1, column: 7},
-          end: {line: 1, column: 8}
-        }
-      },
       generator: false,
       expression: false,
       loc: {
@@ -12402,7 +12399,6 @@ test("({ a }) => {}", {
           end: {line: 1, column: 6}
         }
       }],
-      defaults: [],
       body: {
         type: "BlockStatement",
         body: [],
@@ -12411,7 +12407,6 @@ test("({ a }) => {}", {
           end: {line: 1, column: 13}
         }
       },
-      rest: null,
       generator: false,
       expression: false,
       loc: {
@@ -12441,41 +12436,53 @@ test("({ a }, ...b) => {}", {
     expression: {
       type: "ArrowFunctionExpression",
       id: null,
-      params: [{
-        type: "ObjectPattern",
-        properties: [{
-          type: "Property",
-          key: {
-            type: "Identifier",
-            name: "a",
+      params: [
+        {
+          type: "ObjectPattern",
+          properties: [{
+            type: "Property",
+            key: {
+              type: "Identifier",
+              name: "a",
+              loc: {
+                start: {line: 1, column: 3},
+                end: {line: 1, column: 4}
+              }
+            },
+            value: {
+              type: "Identifier",
+              name: "a",
+              loc: {
+                start: {line: 1, column: 3},
+                end: {line: 1, column: 4}
+              }
+            },
+            kind: "init",
+            method: false,
+            shorthand: true,
+            computed: false,
             loc: {
               start: {line: 1, column: 3},
               end: {line: 1, column: 4}
             }
-          },
-          value: {
+          }],
+          loc: {
+            start: {line: 1, column: 1},
+            end: {line: 1, column: 6}
+          }
+        },
+        {
+          type: "RestElement",
+          argument: {
             type: "Identifier",
-            name: "a",
+            name: "b",
             loc: {
-              start: {line: 1, column: 3},
-              end: {line: 1, column: 4}
+              start: {line: 1, column: 11},
+              end: {line: 1, column: 12}
             }
-          },
-          kind: "init",
-          method: false,
-          shorthand: true,
-          computed: false,
-          loc: {
-            start: {line: 1, column: 3},
-            end: {line: 1, column: 4}
           }
-        }],
-        loc: {
-          start: {line: 1, column: 1},
-          end: {line: 1, column: 6}
         }
-      }],
-      defaults: [],
+      ],
       body: {
         type: "BlockStatement",
         body: [],
@@ -12484,14 +12491,6 @@ test("({ a }, ...b) => {}", {
           end: {line: 1, column: 19}
         }
       },
-      rest: {
-        type: "Identifier",
-        name: "b",
-        loc: {
-          start: {line: 1, column: 11},
-          end: {line: 1, column: 12}
-        }
-      },
       generator: false,
       expression: false,
       loc: {
@@ -12521,8 +12520,34 @@ test("(...[a, b]) => {}", {
     expression: {
       type: "ArrowFunctionExpression",
       id: null,
-      params: [],
-      defaults: [],
+      params: [{
+        type: "RestElement",
+        argument: {
+          type: "ArrayPattern",
+          elements: [
+            {
+              type: "Identifier",
+              name: "a",
+              loc: {
+                start: {line: 1, column: 5},
+                end: {line: 1, column: 6}
+              }
+            },
+            {
+              type: "Identifier",
+              name: "b",
+              loc: {
+                start: {line: 1, column: 8},
+                end: {line: 1, column: 9}
+              }
+            }
+          ],
+          loc: {
+            start: {line: 1, column: 4},
+            end: {line: 1, column: 10}
+          }
+        }
+      }],
       body: {
         type: "BlockStatement",
         body: [],
@@ -12531,31 +12556,6 @@ test("(...[a, b]) => {}", {
           end: {line: 1, column: 17}
         }
       },
-      rest: {
-        type: "ArrayPattern",
-        elements: [
-          {
-            type: "Identifier",
-            name: "a",
-            loc: {
-              start: {line: 1, column: 5},
-              end: {line: 1, column: 6}
-            }
-          },
-          {
-            type: "Identifier",
-            name: "b",
-            loc: {
-              start: {line: 1, column: 8},
-              end: {line: 1, column: 9}
-            }
-          }
-        ],
-        loc: {
-          start: {line: 1, column: 4},
-          end: {line: 1, column: 10}
-        }
-      },
       generator: false,
       expression: false,
       loc: {
@@ -12585,15 +12585,34 @@ test("(a, ...[b]) => {}", {
     expression: {
       type: "ArrowFunctionExpression",
       id: null,
-      params: [{
-        type: "Identifier",
-        name: "a",
-        loc: {
-          start: {line: 1, column: 1},
-          end: {line: 1, column: 2}
+      params: [
+        {
+          type: "Identifier",
+          name: "a",
+          loc: {
+            start: {line: 1, column: 1},
+            end: {line: 1, column: 2}
+          }
+        },
+        {
+          type: "RestElement",
+          argument: {
+            type: "ArrayPattern",
+            elements: [{
+              type: "Identifier",
+              name: "b",
+              loc: {
+                start: {line: 1, column: 8},
+                end: {line: 1, column: 9}
+              }
+            }],
+            loc: {
+              start: {line: 1, column: 7},
+              end: {line: 1, column: 10}
+            }
+          }
         }
-      }],
-      defaults: [],
+      ],
       body: {
         type: "BlockStatement",
         body: [],
@@ -12602,21 +12621,6 @@ test("(a, ...[b]) => {}", {
           end: {line: 1, column: 17}
         }
       },
-      rest: {
-        type: "ArrayPattern",
-        elements: [{
-          type: "Identifier",
-          name: "b",
-          loc: {
-            start: {line: 1, column: 8},
-            end: {line: 1, column: 9}
-          }
-        }],
-        loc: {
-          start: {line: 1, column: 7},
-          end: {line: 1, column: 10}
-        }
-      },
       generator: false,
       expression: false,
       loc: {
@@ -12646,58 +12650,70 @@ test("({ a: [a, b] }, ...c) => {}", {
     expression: {
       type: "ArrowFunctionExpression",
       id: null,
-      params: [{
-        type: "ObjectPattern",
-        properties: [{
-          type: "Property",
-          key: {
-            type: "Identifier",
-            name: "a",
-            loc: {
-              start: {line: 1, column: 3},
-              end: {line: 1, column: 4}
-            }
-          },
-          value: {
-            type: "ArrayPattern",
-            elements: [
-              {
-                type: "Identifier",
-                name: "a",
-                loc: {
-                  start: {line: 1, column: 7},
-                  end: {line: 1, column: 8}
-                }
-              },
-              {
-                type: "Identifier",
-                name: "b",
-                loc: {
-                  start: {line: 1, column: 10},
-                  end: {line: 1, column: 11}
-                }
-              }
-            ],
-            loc: {
-              start: {line: 1, column: 6},
-              end: {line: 1, column: 12}
-            }
-          },
-          kind: "init",
-          method: false,
-          shorthand: false,
-          computed: false,
+      params: [
+        {
+          type: "ObjectPattern",
+          properties: [{
+            type: "Property",
+            key: {
+              type: "Identifier",
+              name: "a",
+              loc: {
+                start: {line: 1, column: 3},
+                end: {line: 1, column: 4}
+              }
+            },
+            value: {
+              type: "ArrayPattern",
+              elements: [
+                {
+                  type: "Identifier",
+                  name: "a",
+                  loc: {
+                    start: {line: 1, column: 7},
+                    end: {line: 1, column: 8}
+                  }
+                },
+                {
+                  type: "Identifier",
+                  name: "b",
+                  loc: {
+                    start: {line: 1, column: 10},
+                    end: {line: 1, column: 11}
+                  }
+                }
+              ],
+              loc: {
+                start: {line: 1, column: 6},
+                end: {line: 1, column: 12}
+              }
+            },
+            kind: "init",
+            method: false,
+            shorthand: false,
+            computed: false,
+            loc: {
+              start: {line: 1, column: 3},
+              end: {line: 1, column: 12}
+            }
+          }],
           loc: {
-            start: {line: 1, column: 3},
-            end: {line: 1, column: 12}
+            start: {line: 1, column: 1},
+            end: {line: 1, column: 14}
+          }
+        },
+        {
+          type: "RestElement",
+          argument: {
+            type: "Identifier",
+            name: "c",
+            loc: {
+              start: {line: 1, column: 19},
+              end: {line: 1, column: 20}
+            }
           }
-        }],
-        loc: {
-          start: {line: 1, column: 1},
-          end: {line: 1, column: 14}
         }
-      }],
-      defaults: [],
+      ],
       body: {
         type: "BlockStatement",
         body: [],
@@ -12706,14 +12722,6 @@ test("({ a: [a, b] }, ...c) => {}", {
           end: {line: 1, column: 27}
         }
       },
-      rest: {
-        type: "Identifier",
-        name: "c",
-        loc: {
-          start: {line: 1, column: 19},
-          end: {line: 1, column: 20}
-        }
-      },
       generator: false,
       expression: false,
       loc: {
@@ -12831,9 +12839,19 @@ test("({ a: b, c }, [d, e], ...f) => {}", {
             start: {line: 1, column: 14},
             end: {line: 1, column: 20}
           }
+        },
+        {
+          type: "RestElement",
+          argument: {
+            type: "Identifier",
+            name: "f",
+            loc: {
+              start: {line: 1, column: 25},
+              end: {line: 1, column: 26}
+            }
+          }
         }
       ],
-      defaults: [],
       body: {
         type: "BlockStatement",
         body: [],
@@ -12842,14 +12860,6 @@ test("({ a: b, c }, [d, e], ...f) => {}", {
           end: {line: 1, column: 33}
         }
       },
-      rest: {
-        type: "Identifier",
-        name: "f",
-        loc: {
-          start: {line: 1, column: 25},
-          end: {line: 1, column: 26}
-        }
-      },
       generator: false,
       expression: false,
       loc: {
@@ -12884,7 +12894,7 @@ test("[...a] = b", {
       left: {
         type: "ArrayPattern",
         elements: [{
-          type: "SpreadElement",
+          type: "RestElement",
           argument: {
             type: "Identifier",
             name: "a",
@@ -12950,7 +12960,7 @@ test("[a, ...b] = c", {
             }
           },
           {
-            type: "SpreadElement",
+            type: "RestElement",
             argument: {
               type: "Identifier",
               name: "b",
@@ -13072,7 +13082,7 @@ test("[{ a, b }, ...c] = d", {
             }
           },
           {
-            type: "SpreadElement",
+            type: "RestElement",
             argument: {
               type: "Identifier",
               name: "c",
@@ -13139,7 +13149,7 @@ test("[a, ...[b, c]] = d", {
             }
           },
           {
-            type: "SpreadElement",
+            type: "RestElement",
             argument: {
               type: "ArrayPattern",
               elements: [
@@ -13213,7 +13223,7 @@ test("var [...a] = b", {
       id: {
         type: "ArrayPattern",
         elements: [{
-          type: "SpreadElement",
+          type: "RestElement",
           argument: {
             type: "Identifier",
             name: "a",
@@ -13279,7 +13289,7 @@ test("var [a, ...b] = c", {
             }
           },
           {
-            type: "SpreadElement",
+            type: "RestElement",
             argument: {
               type: "Identifier",
               name: "b",
@@ -13401,7 +13411,7 @@ test("var [{ a, b }, ...c] = d", {
             }
           },
           {
-            type: "SpreadElement",
+            type: "RestElement",
             argument: {
               type: "Identifier",
               name: "c",
@@ -13468,7 +13478,7 @@ test("var [a, ...[b, c]] = d", {
             }
           },
           {
-            type: "SpreadElement",
+            type: "RestElement",
             argument: {
               type: "ArrayPattern",
               elements: [
@@ -13828,7 +13838,7 @@ testFail("[2] = 42", "Assigning to rvalue (1:1)", {ecmaVersion: 6});
 
 testFail("({ obj:20 }) = 42", "Assigning to rvalue (1:7)", {ecmaVersion: 6});
 
-testFail("( { get x() {} } ) = 0", "Unexpected token (1:8)", {ecmaVersion: 6});
+testFail("( { get x() {} } ) = 0", "Object pattern can't contain getter or setter (1:8)", {ecmaVersion: 6});
 
 testFail("x \n is y", "Unexpected token (2:4)", {ecmaVersion: 6});
 
@@ -13862,9 +13872,9 @@ testFail("import { foo, bar }", "Unexpected token (1:19)", {ecmaVersion: 6});
 
 testFail("import foo from bar", "Unexpected token (1:16)", {ecmaVersion: 6});
 
-testFail("((a)) => 42", "Unexpected token (1:6)", {ecmaVersion: 6});
+testFail("((a)) => 42", "Unexpected token (1:1)", {ecmaVersion: 6});
 
-testFail("(a, (b)) => 42", "Unexpected token (1:9)", {ecmaVersion: 6});
+testFail("(a, (b)) => 42", "Unexpected token (1:4)", {ecmaVersion: 6});
 
 testFail("\"use strict\"; (eval = 10) => 42", "Assigning to eval in strict mode (1:15)", {ecmaVersion: 6});
 
@@ -13884,9 +13894,9 @@ testFail("\"use strict\"; (a) => 00", "Invalid number (1:21)", {ecmaVersion: 6})
 
 testFail("() <= 42", "Unexpected token (1:1)", {ecmaVersion: 6});
 
-testFail("(10) => 00", "Unexpected token (1:1)", {ecmaVersion: 6});
+testFail("(10) => 00", "Assigning to rvalue (1:1)", {ecmaVersion: 6});
 
-testFail("(10, 20) => 00", "Unexpected token (1:1)", {ecmaVersion: 6});
+testFail("(10, 20) => 00", "Assigning to rvalue (1:1)", {ecmaVersion: 6});
 
 testFail("yield v", "Unexpected token (1:6)", {ecmaVersion: 6});
 
@@ -13952,7 +13962,6 @@ test("e => yield* 10", {
           end: {line: 1, column: 1}
         }
       }],
-      defaults: [],
       body: {
         type: "BinaryExpression",
         operator: "*",
@@ -13978,7 +13987,6 @@ test("e => yield* 10", {
           end: {line: 1, column: 14}
         }
       },
-      rest: null,
       generator: false,
       expression: true,
       loc: {
@@ -14012,7 +14020,6 @@ test("(function () { yield* 10 })", {
       type: "FunctionExpression",
       id: null,
       params: [],
-      defaults: [],
       body: {
         type: "BlockStatement",
         body: [{
@@ -14052,7 +14059,6 @@ test("(function () { yield* 10 })", {
           end: {line: 1, column: 26}
         }
       },
-      rest: null,
       generator: false,
       expression: false,
       loc: {
@@ -14084,7 +14090,7 @@ testFail("class A extends yield B { }", "Unexpected token (1:22)", {ecmaVersion:
 
 testFail("class default", "Unexpected token (1:6)", {ecmaVersion: 6});
 
-testFail("`test", "Unterminated template (1:0)", {ecmaVersion: 6});
+testFail("`test", "Unterminated template (1:1)", {ecmaVersion: 6});
 
 testFail("switch `test`", "Unexpected token (1:7)", {ecmaVersion: 6});
 
@@ -14122,9 +14128,9 @@ testFail("\"use strict\"; function x({ b: { a } }, [{ b: { a } }]){}", "Argument
 
 testFail("\"use strict\"; function x(a, ...[a]){}", "Argument name clash in strict mode (1:32)", {ecmaVersion: 6});
 
-testFail("(...a, b) => {}", "Unexpected token (1:1)", {ecmaVersion: 6});
+testFail("(...a, b) => {}", "Unexpected token (1:5)", {ecmaVersion: 6});
 
-testFail("([ 5 ]) => {}", "Unexpected token (1:3)", {ecmaVersion: 6});
+testFail("([ 5 ]) => {}", "Assigning to rvalue (1:3)", {ecmaVersion: 6});
 
 testFail("({ 5 }) => {}", "Unexpected token (1:5)", {ecmaVersion: 6});
 
@@ -14132,7 +14138,7 @@ testFail("(...[ 5 ]) => {}", "Unexpected token (1:6)", {ecmaVersion: 6});
 
 testFail("[...{ a }] = b", "Unexpected token (1:4)", {ecmaVersion: 6});
 
-testFail("[...a, b] = c", "Unexpected token (1:1)", {ecmaVersion: 6});
+testFail("[...a, b] = c", "Assigning to rvalue (1:1)", {ecmaVersion: 6});
 
 testFail("({ t(eval) { \"use strict\"; } });", "Defining 'eval' in strict mode (1:5)", {ecmaVersion: 6});
 
@@ -14166,7 +14172,7 @@ test("[...a, ] = b", {
           end: {line: 1, column: 8}
         },
         elements: [{
-          type: "SpreadElement",
+          type: "RestElement",
           loc: {
             start: {line: 1, column: 1},
             end: {line: 1, column: 5}
@@ -14197,9 +14203,9 @@ test("[...a, ] = b", {
   locations: true
 });
 
-testFail("if (b,...a, );", "Unexpected token (1:12)", {ecmaVersion: 6});
+testFail("if (b,...a, );", "Unexpected token (1:6)", {ecmaVersion: 6});
 
-testFail("(b, ...a)", "Unexpected token (1:9)", {ecmaVersion: 6});
+testFail("(b, ...a)", "Unexpected token (1:4)", {ecmaVersion: 6});
 
 testFail("switch (cond) { case 10: let a = 20; ", "Unexpected token (1:37)", {ecmaVersion: 6});
 
@@ -14207,7 +14213,7 @@ testFail("\"use strict\"; (eval) => 42", "Defining 'eval' in strict mode (1:15)"
 
 testFail("(eval) => { \"use strict\"; 42 }", "Defining 'eval' in strict mode (1:1)", {ecmaVersion: 6});
 
-testFail("({ get test() { } }) => 42", "Unexpected token (1:7)", {ecmaVersion: 6});
+testFail("({ get test() { } }) => 42", "Object pattern can't contain getter or setter (1:7)", {ecmaVersion: 6});
 
 /* Regression tests */
 
@@ -14288,19 +14294,18 @@ test('function normal(x, y = 10) {}', {
         name: "x"
       },
       {
-        type: "Identifier",
-        name: "y"
-      }
-    ],
-    defaults: [
-      null,
-      {
-        type: "Literal",
-        value: 10,
-        raw: "10"
+        type: "AssignmentPattern",
+        left: {
+          type: "Identifier",
+          name: "y"
+        },
+        right: {
+          type: "Literal",
+          value: 10,
+          raw: "10"
+        }
       }
     ],
-    rest: null,
     generator: false,
     body: {
       type: "BlockStatement",
@@ -14405,3 +14410,693 @@ test("`{${x}}`, `}`", {
     }
   }]
 }, {ecmaVersion: 6});
+
+// https://github.com/marijnh/acorn/issues/186
+test('var {get} = obj;', {
+  type: "Program",
+  body: [{
+    type: "VariableDeclaration",
+    declarations: [{
+      type: "VariableDeclarator",
+      id: {
+        type: "ObjectPattern",
+        properties: [{
+          type: "Property",
+          method: false,
+          shorthand: true,
+          computed: false,
+          key: {
+            type: "Identifier",
+            name: "get"
+          },
+          kind: "init",
+          value: {
+            type: "Identifier",
+            name: "get"
+          }
+        }]
+      },
+      init: {
+        type: "Identifier",
+        name: "obj"
+      }
+    }],
+    kind: "var"
+  }]
+}, {ecmaVersion: 6});
+
+// Destructuring defaults (https://github.com/marijnh/acorn/issues/181)
+
+test("var {propName: localVar = defaultValue} = obj", {
+  type: "Program",
+  range: [0, 45],
+  body: [{
+    type: "VariableDeclaration",
+    range: [0, 45],
+    declarations: [{
+      type: "VariableDeclarator",
+      range: [4, 45],
+      id: {
+        type: "ObjectPattern",
+        range: [4, 39],
+        properties: [{
+          type: "Property",
+          range: [5, 38],
+          method: false,
+          shorthand: false,
+          computed: false,
+          key: {
+            type: "Identifier",
+            range: [5, 13],
+            name: "propName"
+          },
+          value: {
+            type: "AssignmentPattern",
+            range: [15, 38],
+            operator: "=",
+            left: {
+              type: "Identifier",
+              range: [15, 23],
+              name: "localVar"
+            },
+            right: {
+              type: "Identifier",
+              range: [26, 38],
+              name: "defaultValue"
+            }
+          },
+          kind: "init"
+        }]
+      },
+      init: {
+        type: "Identifier",
+        range: [42, 45],
+        name: "obj"
+      }
+    }],
+    kind: "var"
+  }]
+}, {
+  ecmaVersion: 6,
+  ranges: true,
+  locations: true
+});
+
+test("var {propName = defaultValue} = obj", {
+  type: "Program",
+  range: [0, 35],
+  body: [{
+    type: "VariableDeclaration",
+    range: [0, 35],
+    declarations: [{
+      type: "VariableDeclarator",
+      range: [4, 35],
+      id: {
+        type: "ObjectPattern",
+        range: [4, 29],
+        properties: [{
+          type: "Property",
+          range: [5, 28],
+          method: false,
+          shorthand: true,
+          computed: false,
+          key: {
+            type: "Identifier",
+            range: [5, 13],
+            name: "propName"
+          },
+          kind: "init",
+          value: {
+            type: "AssignmentPattern",
+            range: [5, 28],
+            operator: "=",
+            left: {
+              type: "Identifier",
+              range: [5, 13],
+              name: "propName"
+            },
+            right: {
+              type: "Identifier",
+              range: [16, 28],
+              name: "defaultValue"
+            }
+          }
+        }]
+      },
+      init: {
+        type: "Identifier",
+        range: [32, 35],
+        name: "obj"
+      }
+    }],
+    kind: "var"
+  }]
+}, {
+  ecmaVersion: 6,
+  ranges: true,
+  locations: true
+});
+
+test("var [localVar = defaultValue] = obj", {
+  type: "Program",
+  range: [0, 35],
+  body: [{
+    type: "VariableDeclaration",
+    range: [0, 35],
+    declarations: [{
+      type: "VariableDeclarator",
+      range: [4, 35],
+      id: {
+        type: "ArrayPattern",
+        range: [4, 29],
+        elements: [{
+          type: "AssignmentPattern",
+          range: [5, 28],
+          operator: "=",
+          left: {
+            type: "Identifier",
+            range: [5, 13],
+            name: "localVar"
+          },
+          right: {
+            type: "Identifier",
+            range: [16, 28],
+            name: "defaultValue"
+          }
+        }]
+      },
+      init: {
+        type: "Identifier",
+        range: [32, 35],
+        name: "obj"
+      }
+    }],
+    kind: "var"
+  }]
+}, {
+  ecmaVersion: 6,
+  ranges: true,
+  locations: true
+});
+
+test("({x = 0} = obj)", {
+  type: "Program",
+  range: [0, 15],
+  body: [{
+    type: "ExpressionStatement",
+    range: [0, 15],
+    expression: {
+      type: "AssignmentExpression",
+      range: [1, 14],
+      operator: "=",
+      left: {
+        type: "ObjectPattern",
+        range: [1, 8],
+        properties: [{
+          type: "Property",
+          range: [2, 7],
+          method: false,
+          shorthand: true,
+          computed: false,
+          key: {
+            type: "Identifier",
+            range: [2, 3],
+            name: "x"
+          },
+          kind: "init",
+          value: {
+            type: "AssignmentPattern",
+            range: [2, 7],
+            operator: "=",
+            left: {
+              type: "Identifier",
+              range: [2, 3],
+              name: "x"
+            },
+            right: {
+              type: "Literal",
+              range: [6, 7],
+              value: 0
+            }
+          }
+        }]
+      },
+      right: {
+        type: "Identifier",
+        range: [11, 14],
+        name: "obj"
+      }
+    }
+  }]
+}, {
+  ecmaVersion: 6,
+  ranges: true
+});
+
+test("({x = 0}) => x", {
+  type: "Program",
+  range: [0, 14],
+  body: [{
+    type: "ExpressionStatement",
+    range: [0, 14],
+    expression: {
+      type: "ArrowFunctionExpression",
+      range: [0, 14],
+      id: null,
+      generator: false,
+      expression: true,
+      params: [{
+        type: "ObjectPattern",
+        range: [1, 8],
+        properties: [{
+          type: "Property",
+          range: [2, 7],
+          method: false,
+          shorthand: true,
+          computed: false,
+          key: {
+            type: "Identifier",
+            range: [2, 3],
+            name: "x"
+          },
+          kind: "init",
+          value: {
+            type: "AssignmentPattern",
+            range: [2, 7],
+            operator: "=",
+            left: {
+              type: "Identifier",
+              range: [2, 3],
+              name: "x"
+            },
+            right: {
+              type: "Literal",
+              range: [6, 7],
+              value: 0
+            }
+          }
+        }]
+      }],
+      body: {
+        type: "Identifier",
+        range: [13, 14],
+        name: "x"
+      }
+    }
+  }]
+}, {
+  ecmaVersion: 6,
+  ranges: true
+});
+
+test("[a, {b: {c = 1}}] = arr", {
+  type: "Program",
+  range: [0, 23],
+  body: [{
+    type: "ExpressionStatement",
+    range: [0, 23],
+    expression: {
+      type: "AssignmentExpression",
+      range: [0, 23],
+      operator: "=",
+      left: {
+        type: "ArrayPattern",
+        range: [0, 17],
+        elements: [
+          {
+            type: "Identifier",
+            range: [1, 2],
+            name: "a"
+          },
+          {
+            type: "ObjectPattern",
+            range: [4, 16],
+            properties: [{
+              type: "Property",
+              range: [5, 15],
+              method: false,
+              shorthand: false,
+              computed: false,
+              key: {
+                type: "Identifier",
+                range: [5, 6],
+                name: "b"
+              },
+              value: {
+                type: "ObjectPattern",
+                range: [8, 15],
+                properties: [{
+                  type: "Property",
+                  range: [9, 14],
+                  method: false,
+                  shorthand: true,
+                  computed: false,
+                  key: {
+                    type: "Identifier",
+                    range: [9, 10],
+                    name: "c"
+                  },
+                  kind: "init",
+                  value: {
+                    type: "AssignmentPattern",
+                    range: [9, 14],
+                    operator: "=",
+                    left: {
+                      type: "Identifier",
+                      range: [9, 10],
+                      name: "c"
+                    },
+                    right: {
+                      type: "Literal",
+                      range: [13, 14],
+                      value: 1
+                    }
+                  }
+                }]
+              },
+              kind: "init"
+            }]
+          }
+        ]
+      },
+      right: {
+        type: "Identifier",
+        range: [20, 23],
+        name: "arr"
+      }
+    }
+  }]
+}, {
+  ecmaVersion: 6,
+  ranges: true
+});
+
+test("for ({x = 0} in arr);", {
+  type: "Program",
+  range: [0, 21],
+  body: [{
+    type: "ForInStatement",
+    range: [0, 21],
+    left: {
+      type: "ObjectPattern",
+      range: [5, 12],
+      properties: [{
+        type: "Property",
+        range: [6, 11],
+        method: false,
+        shorthand: true,
+        computed: false,
+        key: {
+          type: "Identifier",
+          range: [6, 7],
+          name: "x"
+        },
+        kind: "init",
+        value: {
+          type: "AssignmentPattern",
+          range: [6, 11],
+          operator: "=",
+          left: {
+            type: "Identifier",
+            range: [6, 7],
+            name: "x"
+          },
+          right: {
+            type: "Literal",
+            range: [10, 11],
+            value: 0
+          }
+        }
+      }]
+    },
+    right: {
+      type: "Identifier",
+      range: [16, 19],
+      name: "arr"
+    },
+    body: {
+      type: "EmptyStatement",
+      range: [20, 21]
+    }
+  }]
+}, {
+  ecmaVersion: 6,
+  ranges: true
+});
+
+testFail("obj = {x = 0}", "Unexpected token (1:9)", {ecmaVersion: 6});
+
+testFail("f({x = 0})", "Unexpected token (1:5)", {ecmaVersion: 6});
+
+// https://github.com/marijnh/acorn/issues/191
+
+test("try {} catch ({message}) {}", {
+  type: "Program",
+  range: [0, 27],
+  body: [{
+    type: "TryStatement",
+    range: [0, 27],
+    block: {
+      type: "BlockStatement",
+      range: [4, 6],
+      body: []
+    },
+    handler: {
+      type: "CatchClause",
+      range: [7, 27],
+      param: {
+        type: "ObjectPattern",
+        range: [14, 23],
+        properties: [{
+          type: "Property",
+          range: [15, 22],
+          method: false,
+          shorthand: true,
+          computed: false,
+          key: {
+            type: "Identifier",
+            range: [15, 22],
+            name: "message"
+          },
+          kind: "init",
+          value: {
+            type: "Identifier",
+            range: [15, 22],
+            name: "message"
+          }
+        }]
+      },
+      guard: null,
+      body: {
+        type: "BlockStatement",
+        range: [25, 27],
+        body: []
+      }
+    },
+    finalizer: null
+  }]
+}, {
+  ecmaVersion: 6,
+  ranges: true,
+  locations: true
+});
+
+// https://github.com/marijnh/acorn/issues/192
+
+test("class A { static() {} }", {
+  type: "Program",
+  range: [0, 23],
+  body: [{
+    type: "ClassDeclaration",
+    range: [0, 23],
+    id: {
+      type: "Identifier",
+      range: [6, 7],
+      name: "A"
+    },
+    superClass: null,
+    body: {
+      type: "ClassBody",
+      range: [8, 23],
+      body: [{
+        type: "MethodDefinition",
+        range: [10, 21],
+        computed: false,
+        key: {
+          type: "Identifier",
+          range: [10, 16],
+          name: "static"
+        },
+        static: false,
+        kind: "",
+        value: {
+          type: "FunctionExpression",
+          range: [16, 21],
+          id: null,
+          params: [],
+          generator: false,
+          body: {
+            type: "BlockStatement",
+            range: [19, 21],
+            body: []
+          },
+          expression: false
+        }
+      }]
+    }
+  }]
+}, {
+  ecmaVersion: 6,
+  ranges: true,
+  locations: true
+});
+
+test("class A { *static() {} }", {
+  type: "Program",
+  range: [0, 24],
+  body: [{
+    type: "ClassDeclaration",
+    range: [0, 24],
+    id: {
+      type: "Identifier",
+      range: [6, 7],
+      name: "A"
+    },
+    superClass: null,
+    body: {
+      type: "ClassBody",
+      range: [8, 24],
+      body: [{
+        type: "MethodDefinition",
+        range: [10, 22],
+        computed: false,
+        key: {
+          type: "Identifier",
+          range: [11, 17],
+          name: "static"
+        },
+        static: false,
+        kind: "",
+        value: {
+          type: "FunctionExpression",
+          range: [17, 22],
+          id: null,
+          params: [],
+          generator: true,
+          body: {
+            type: "BlockStatement",
+            range: [20, 22],
+            body: []
+          },
+          expression: false
+        }
+      }]
+    }
+  }]
+}, {
+  ecmaVersion: 6,
+  ranges: true,
+  locations: true
+});
+
+test("`${/\\d/.exec('1')[0]}`", {
+  "type": "Program",
+  "start": 0,
+  "end": 22,
+  "body": [
+    {
+      "type": "ExpressionStatement",
+      "start": 0,
+      "end": 22,
+      "expression": {
+        "type": "TemplateLiteral",
+        "start": 0,
+        "end": 22,
+        "expressions": [
+          {
+            "type": "MemberExpression",
+            "start": 3,
+            "end": 20,
+            "object": {
+              "type": "CallExpression",
+              "start": 3,
+              "end": 17,
+              "callee": {
+                "type": "MemberExpression",
+                "start": 3,
+                "end": 12,
+                "object": {
+                  "type": "Literal",
+                  "start": 3,
+                  "end": 7,
+                  "regex": {
+                    "pattern": "\\d",
+                    "flags": ""
+                  },
+                  "value": /\d/,
+                  "raw": "/\\d/"
+                },
+                "property": {
+                  "type": "Identifier",
+                  "start": 8,
+                  "end": 12,
+                  "name": "exec"
+                },
+                "computed": false
+              },
+              "arguments": [
+                {
+                  "type": "Literal",
+                  "start": 13,
+                  "end": 16,
+                  "value": "1",
+                  "raw": "'1'"
+                }
+              ]
+            },
+            "property": {
+              "type": "Literal",
+              "start": 18,
+              "end": 19,
+              "value": 0,
+              "raw": "0"
+            },
+            "computed": true
+          }
+        ],
+        "quasis": [
+          {
+            "type": "TemplateElement",
+            "start": 1,
+            "end": 1,
+            "value": {
+              "raw": "",
+              "cooked": ""
+            },
+            "tail": false
+          },
+          {
+            "type": "TemplateElement",
+            "start": 21,
+            "end": 21,
+            "value": {
+              "raw": "",
+              "cooked": ""
+            },
+            "tail": true
+          }
+        ]
+      }
+    }
+  ]
+}, {
+  ecmaVersion: 6
+});
+
+testFail("if (1) let x = 10;", "Unexpected token (1:7)", {ecmaVersion: 6});
+testFail("for (;;) const x = 10;", "Unexpected token (1:9)", {ecmaVersion: 6});
+testFail("while (1) function foo(){}", "Unexpected token (1:10)", {ecmaVersion: 6});
+testFail("if (1) ; else class Cls {}", "Unexpected token (1:14)", {ecmaVersion: 6});
+
+testFail("'use strict'; [...eval] = arr", "Assigning to eval in strict mode (1:18)", {ecmaVersion: 6});
+testFail("'use strict'; ({eval = defValue} = obj)", "Assigning to eval in strict mode (1:16)", {ecmaVersion: 6});
diff --git a/test/tests.js b/test/tests.js
index 72b9340..dfbfda0 100644
--- a/test/tests.js
+++ b/test/tests.js
@@ -169,7 +169,7 @@ test("/[a-z]/g", {
       type: "ExpressionStatement",
       expression: {
         type: "Literal",
-        value: /[a-z]/,
+        value: /[a-z]/g,
         regex: {
           pattern: "[a-z]",
           flags: "g"
@@ -7331,7 +7331,7 @@ test("var x = /[a-z]/i", {
           },
           init: {
             type: "Literal",
-            value: {},
+            value: /[a-z]/i,
             loc: {
               start: {
                 line: 1,
@@ -7404,7 +7404,7 @@ test("var x = /[x-z]/i", {
           },
           init: {
             type: "Literal",
-            value: {},
+            value: /[x-z]/i,
             loc: {
               start: {
                 line: 1,
@@ -7477,7 +7477,7 @@ test("var x = /[a-c]/i", {
           },
           init: {
             type: "Literal",
-            value: {},
+            value: /[a-c]/i,
             loc: {
               start: {
                 line: 1,
@@ -7550,7 +7550,7 @@ test("var x = /[P QR]/i", {
           },
           init: {
             type: "Literal",
-            value: {},
+            value: /[P QR]/i,
             loc: {
               start: {
                 line: 1,
@@ -7623,7 +7623,7 @@ test("var x = /foo\\/bar/", {
           },
           init: {
             type: "Literal",
-            value: {},
+            value: /foo\/bar/,
             loc: {
               start: {
                 line: 1,
@@ -7696,7 +7696,7 @@ test("var x = /=([^=\\s])+/g", {
           },
           init: {
             type: "Literal",
-            value: {},
+            value: /=([^=\s])+/g,
             loc: {
               start: {
                 line: 1,
@@ -7769,7 +7769,7 @@ test("var x = /[P QR]/\\u0067", {
           },
           init: {
             type: "Literal",
-            value: {},
+            value: /[P QR]/g,
             loc: {
               start: {
                 line: 1,
@@ -23788,21 +23788,23 @@ test("function hello(...rest) { }", {
           }
         }
       },
-      params: [],
-      rest: {
-        type: "Identifier",
-        name: "rest",
-        loc: {
-          start: {
-            line: 1,
-            column: 18
-          },
-          end: {
-            line: 1,
-            column: 22
+      params: [{
+        type: "RestElement",
+        argument: {
+          type: "Identifier",
+          name: "rest",
+          loc: {
+            start: {
+              line: 1,
+              column: 18
+            },
+            end: {
+              line: 1,
+              column: 22
+            }
           }
         }
-      },
+      }],
       body: {
         type: "BlockStatement",
         body: [],
@@ -23877,22 +23879,25 @@ test("function hello(a, ...rest) { }", {
               column: 16
             }
           }
-        }
-      ],
-      rest: {
-        type: "Identifier",
-        name: "rest",
-        loc: {
-          start: {
-            line: 1,
-            column: 21
-          },
-          end: {
-            line: 1,
-            column: 25
+        },
+        {
+          type: "RestElement",
+          argument: {
+            type: "Identifier",
+            name: "rest",
+            loc: {
+              start: {
+                line: 1,
+                column: 21
+              },
+              end: {
+                line: 1,
+                column: 25
+              }
+            }
           }
         }
-      },
+      ],
       body: {
         type: "BlockStatement",
         body: [],
@@ -24089,21 +24094,23 @@ test("var hi = function (...r) { sayHi() };", {
           init: {
             type: "FunctionExpression",
             id: null,
-            params: [],
-            rest: {
-              type: "Identifier",
-              name: "r",
-              loc: {
-                start: {
-                  line: 1,
-                  column: 22
-                },
-                end: {
-                  line: 1,
-                  column: 23
+            params: [{
+              type: "RestElement",
+              argument: {
+                type: "Identifier",
+                name: "r",
+                loc: {
+                  start: {
+                    line: 1,
+                    column: 22
+                  },
+                  end: {
+                    line: 1,
+                    column: 23
+                  }
                 }
               }
-            },
+            }],
             body: {
               type: "BlockStatement",
               body: [
@@ -26687,6 +26694,22 @@ test("a.in / b", {
   ]
 });
 
+// A number of slash-disambiguation corner cases
+test("return {} / 2", {}, {allowReturnOutsideFunction: true});
+test("return\n{}\n/foo/", {}, {allowReturnOutsideFunction: true});
+test("+{} / 2", {});
+test("{}\n/foo/", {});
+test("x++\n{}\n/foo/", {});
+test("{{}\n/foo/}", {});
+test("while (1) /foo/", {});
+test("(1) / 2", {});
+test("({a: [1]}+[]) / 2", {});
+test("{[1]}\n/foo/", {});
+test("switch(a) { case 1: {}\n/foo/ }", {});
+test("({1: {} / 2})", {});
+test("+x++ / 2", {});
+test("foo.in\n{}\n/foo/", {});
+
 test("{}/=/", {
   type: "Program",
   body: [
@@ -28757,6 +28780,7 @@ var tokTypes = acorn.tokTypes;
 
 test('var x = (1 + 2)', {}, {
   locations: true,
+  loose: false,
   onToken: [
     {
       type: tokTypes._var,
@@ -28834,3 +28858,59 @@ test('var x = (1 + 2)', {}, {
 });
 
 test("function f(f) { 'use strict'; }", {});
+
+// https://github.com/marijnh/acorn/issues/180
+test("#!/usr/bin/node\n;", {}, {
+  allowHashBang: true,
+  onComment: [{
+    type: "Line",
+    value: "/usr/bin/node",
+    start: 0,
+    end: 15
+  }]
+});
+
+// https://github.com/marijnh/acorn/issues/204
+test("(function () {} / 1)", {
+  type: "Program",
+  body: [{
+    type: "ExpressionStatement",
+    expression: {
+      type: "BinaryExpression",
+      left: {
+        type: "FunctionExpression",
+        id: null,
+        params: [],
+        body: {
+          type: "BlockStatement",
+          body: []
+        }
+      },
+      operator: "/",
+      right: {type: "Literal", value: 1}
+    }
+  }]
+});
+
+test("function f() {} / 1 /", {
+  type: "Program",
+  body: [
+    {
+      type: "FunctionDeclaration",
+      id: {type: "Identifier", name: "f"},
+      params: [],
+      body: {
+        type: "BlockStatement",
+        body: []
+      }
+    },
+    {
+      type: "ExpressionStatement",
+      expression: {
+        type: "Literal",
+        regex: {pattern: " 1 ", flags: ""},
+        value: / 1 /
+      }
+    }
+  ]
+});
diff --git a/util/walk.js b/util/walk.js
index 117f56f..9dcddaa 100644
--- a/util/walk.js
+++ b/util/walk.js
@@ -172,7 +172,7 @@
   };
   base.Statement = skipThrough;
   base.EmptyStatement = ignore;
-  base.ExpressionStatement = function(node, st, c) {
+  base.ExpressionStatement = base.ParenthesizedExpression = function(node, st, c) {
     c(node.expression, st, "Expression");
   };
   base.IfStatement = function(node, st, c) {
@@ -200,7 +200,7 @@
   base.ReturnStatement = base.YieldExpression = function(node, st, c) {
     if (node.argument) c(node.argument, st, "Expression");
   };
-  base.ThrowStatement = base.SpreadElement = function(node, st, c) {
+  base.ThrowStatement = base.SpreadElement = base.RestElement = function(node, st, c) {
     c(node.argument, st, "Expression");
   };
   base.TryStatement = function(node, st, c) {
@@ -249,13 +249,13 @@
 
   base.Expression = skipThrough;
   base.ThisExpression = ignore;
-  base.ArrayExpression = function(node, st, c) {
+  base.ArrayExpression = base.ArrayPattern =  function(node, st, c) {
     for (var i = 0; i < node.elements.length; ++i) {
       var elt = node.elements[i];
       if (elt) c(elt, st, "Expression");
     }
   };
-  base.ObjectExpression = function(node, st, c) {
+  base.ObjectExpression = base.ObjectPattern = function(node, st, c) {
     for (var i = 0; i < node.properties.length; ++i)
       c(node.properties[i], st);
   };
@@ -267,7 +267,7 @@
   base.UnaryExpression = base.UpdateExpression = function(node, st, c) {
     c(node.argument, st, "Expression");
   };
-  base.BinaryExpression = base.AssignmentExpression = base.LogicalExpression = function(node, st, c) {
+  base.BinaryExpression = base.AssignmentExpression = base.AssignmentPattern = base.LogicalExpression = function(node, st, c) {
     c(node.left, st, "Expression");
     c(node.right, st, "Expression");
   };
@@ -285,7 +285,15 @@
     c(node.object, st, "Expression");
     if (node.computed) c(node.property, st, "Expression");
   };
-  base.Identifier = base.Literal = base.ExportDeclaration = base.ImportDeclaration = ignore;
+  base.ExportDeclaration = function (node, st, c) {
+    c(node.declaration, st);
+  };
+  base.ImportDeclaration = function (node, st, c) {
+    node.specifiers.forEach(function (specifier) {
+      c(specifier, st);
+    });
+  };
+  base.ImportSpecifier = base.ImportBatchSpecifier = base.Identifier = base.Literal = ignore;
 
   base.TaggedTemplateExpression = function(node, st, c) {
     c(node.tag, st, "Expression");

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



More information about the Pkg-javascript-commits mailing list