[Pkg-javascript-commits] [acorn] 01/05: New upstream version 5.2.1+ds1

Julien Puydt julien.puydt at laposte.net
Mon Nov 6 02:18:26 UTC 2017


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

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

commit 5c5c566667ffd6ed2851e7a91407a359dee151da
Author: Julien Puydt <julien.puydt at laposte.net>
Date:   Mon Nov 6 03:11:42 2017 +0100

    New upstream version 5.2.1+ds1
---
 CHANGELOG.md                            |   24 +
 README.md                               |    4 +-
 package.json                            |    2 +-
 src/bin/acorn.js                        |    2 +-
 src/expression.js                       |   88 +-
 src/index.js                            |    2 +-
 src/loose/expression.js                 |   13 +-
 src/loose/statement.js                  |    3 +-
 src/lval.js                             |   28 +-
 src/statement.js                        |   17 +
 src/tokenize.js                         |    2 +-
 src/walk/index.js                       |    4 +-
 test/run.js                             |    1 +
 test/tests-asyncawait.js                |    3 +-
 test/tests-directive.js                 | 1360 +++++++++++++++++++++++++++++++
 test/tests-es7.js                       |    4 +
 test/tests-harmony.js                   |  117 ++-
 test/tests-template-literal-revision.js |    5 +
 test/tests.js                           |    3 +-
 19 files changed, 1610 insertions(+), 72 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 73894d1..3003a04 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,27 @@
+## 5.2.1 (2017-10-30)
+
+### Bug fixes
+
+Fix a token context corruption bug.
+
+## 5.2.0 (2017-10-30)
+
+### Bug fixes
+
+Fix token context tracking for `class` and `function` in property-name position.
+
+Make sure `%*` isn't parsed as a valid operator.
+
+The `full` and `fullAncestor` walkers no longer visit nodes multiple times.
+
+Allow shorthand properties `get` and `set` to be followed by default values.
+
+Disallow `super` when not in callee or object position.
+
+### New features
+
+Support [`directive` property](https://github.com/estree/estree/compare/b3de58c9997504d6fba04b72f76e6dd1619ee4eb...1da8e603237144f44710360f8feb7a9977e905e0) on directive expression statements.
+
 ## 5.1.2 (2017-09-04)
 
 ### Bug fixes
diff --git a/README.md b/README.md
index bd853c4..ab2c12e 100644
--- a/README.md
+++ b/README.md
@@ -351,8 +351,8 @@ The `bin/acorn` utility can be used to parse a file from the command
 line. It accepts as arguments its input file and the following
 options:
 
-- `--ecma3|--ecma5|--ecma6|--ecma7`: Sets the ECMAScript version to parse. Default is
-  version 5.
+- `--ecma3|--ecma5|--ecma6|--ecma7|--ecma8|--ecma9`: Sets the ECMAScript version
+  to parse. Default is version 7.
 
 - `--module`: Sets the parsing mode to `"module"`. Is set to `"script"` otherwise.
 
diff --git a/package.json b/package.json
index 035bc3c..56c63a4 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,7 @@
   "homepage": "https://github.com/ternjs/acorn",
   "main": "dist/acorn.js",
   "module": "dist/acorn.es.js",
-  "version": "5.1.2",
+  "version": "5.2.1",
   "engines": {
     "node": ">=0.4.0"
   },
diff --git a/src/bin/acorn.js b/src/bin/acorn.js
index b9ee5ee..d5fe425 100644
--- a/src/bin/acorn.js
+++ b/src/bin/acorn.js
@@ -7,7 +7,7 @@ const options = {}
 
 function help(status) {
   const print = (status == 0) ? console.log : console.error
-  print("usage: " + basename(process.argv[1]) + " [--ecma3|--ecma5|--ecma6|--ecma7|...|--ecma2015|--ecma2016|...]")
+  print("usage: " + basename(process.argv[1]) + " [--ecma3|--ecma5|--ecma6|--ecma7|--ecma8|--ecma9|...|--ecma2015|--ecma2016|--ecma2017|--ecma2018|...]")
   print("        [--tokenize] [--locations] [---allow-hash-bang] [--compact] [--silent] [--module] [--help] [--] [infile]")
   process.exit(status)
 }
diff --git a/src/expression.js b/src/expression.js
index 635642c..033d13c 100644
--- a/src/expression.js
+++ b/src/expression.js
@@ -194,7 +194,7 @@ pp.buildBinary = function(startPos, startLoc, left, right, op, logical) {
 pp.parseMaybeUnary = function(refDestructuringErrors, sawUnary) {
   let startPos = this.start, startLoc = this.startLoc, expr
   if (this.inAsync && this.isContextual("await")) {
-    expr = this.parseAwait(refDestructuringErrors)
+    expr = this.parseAwait()
     sawUnary = true
   } else if (this.type.prefix) {
     let node = this.startNode(), update = this.type === tt.incDec
@@ -296,12 +296,22 @@ pp.parseExprAtom = function(refDestructuringErrors) {
   case tt._super:
     if (!this.inFunction)
       this.raise(this.start, "'super' outside of function or class")
+    node = this.startNode()
+    this.next()
+    // The `super` keyword can appear at below:
+    // SuperProperty:
+    //     super [ Expression ]
+    //     super . IdentifierName
+    // SuperCall:
+    //     super Arguments
+    if (this.type !== tt.dot && this.type !== tt.bracketL && this.type !== tt.parenL)
+      this.unexpected()
+    return this.finishNode(node, "Super")
 
   case tt._this:
-    let type = this.type === tt._this ? "ThisExpression" : "Super"
     node = this.startNode()
     this.next()
-    return this.finishNode(node, type)
+    return this.finishNode(node, "ThisExpression")
 
   case tt.name:
     let startPos = this.start, startLoc = this.startLoc
@@ -528,14 +538,14 @@ pp.parseTemplate = function({isTagged = false} = {}) {
   return this.finishNode(node, "TemplateLiteral")
 }
 
-// Parse an object literal or binding pattern.
-
 pp.isAsyncProp = function(prop) {
   return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" &&
     (this.type === tt.name || this.type === tt.num || this.type === tt.string || this.type === tt.bracketL || this.type.keyword) &&
     !lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
 }
 
+// Parse an object literal or binding pattern.
+
 pp.parseObj = function(isPattern, refDestructuringErrors) {
   let node = this.startNode(), first = true, propHash = {}
   node.properties = []
@@ -546,31 +556,36 @@ pp.parseObj = function(isPattern, refDestructuringErrors) {
       if (this.afterTrailingComma(tt.braceR)) break
     } else first = false
 
-    let prop = this.startNode(), isGenerator, isAsync, startPos, startLoc
-    if (this.options.ecmaVersion >= 6) {
-      prop.method = false
-      prop.shorthand = false
-      if (isPattern || refDestructuringErrors) {
-        startPos = this.start
-        startLoc = this.startLoc
-      }
-      if (!isPattern)
-        isGenerator = this.eat(tt.star)
-    }
-    this.parsePropertyName(prop)
-    if (!isPattern && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) {
-      isAsync = true
-      this.parsePropertyName(prop, refDestructuringErrors)
-    } else {
-      isAsync = false
-    }
-    this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors)
+    const prop = this.parseProperty(isPattern, refDestructuringErrors)
     this.checkPropClash(prop, propHash)
-    node.properties.push(this.finishNode(prop, "Property"))
+    node.properties.push(prop)
   }
   return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression")
 }
 
+pp.parseProperty = function(isPattern, refDestructuringErrors) {
+  let prop = this.startNode(), isGenerator, isAsync, startPos, startLoc
+  if (this.options.ecmaVersion >= 6) {
+    prop.method = false
+    prop.shorthand = false
+    if (isPattern || refDestructuringErrors) {
+      startPos = this.start
+      startLoc = this.startLoc
+    }
+    if (!isPattern)
+      isGenerator = this.eat(tt.star)
+  }
+  this.parsePropertyName(prop)
+  if (!isPattern && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) {
+    isAsync = true
+    this.parsePropertyName(prop, refDestructuringErrors)
+  } else {
+    isAsync = false
+  }
+  this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors)
+  return this.finishNode(prop, "Property")
+}
+
 pp.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors) {
   if ((isGenerator || isAsync) && this.type === tt.colon)
     this.unexpected()
@@ -583,10 +598,11 @@ pp.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos
     prop.kind = "init"
     prop.method = true
     prop.value = this.parseMethod(isGenerator, isAsync)
-  } else if (this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" &&
+  } else if (!isPattern &&
+             this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" &&
              (prop.key.name === "get" || prop.key.name === "set") &&
              (this.type != tt.comma && this.type != tt.braceR)) {
-    if (isGenerator || isAsync || isPattern) this.unexpected()
+    if (isGenerator || isAsync) this.unexpected()
     prop.kind = prop.key.name
     this.parsePropertyName(prop)
     prop.value = this.parseMethod(false)
@@ -734,6 +750,7 @@ pp.parseFunctionBody = function(node, isArrowFunction) {
     this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && this.isSimpleParamList(node.params))
     node.body = this.parseBlock(false)
     node.expression = false
+    this.adaptDirectivePrologue(node.body.body)
     this.labels = oldLabels
   }
   this.exitFunctionScope()
@@ -789,10 +806,6 @@ pp.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructur
   return elts
 }
 
-// Parse the next token as an identifier. If `liberal` is true (used
-// when parsing properties), it will also convert keywords into
-// identifiers.
-
 pp.checkUnreserved = function({start, end, name}) {
   if (this.inGenerator && name === "yield")
     this.raiseRecoverable(start, "Can not use 'yield' as identifier inside a generator")
@@ -807,6 +820,10 @@ pp.checkUnreserved = function({start, end, name}) {
     this.raiseRecoverable(start, `The keyword '${name}' is reserved`)
 }
 
+// Parse the next token as an identifier. If `liberal` is true (used
+// when parsing properties), it will also convert keywords into
+// identifiers.
+
 pp.parseIdent = function(liberal, isBinding) {
   let node = this.startNode()
   if (liberal && this.options.allowReserved == "never") liberal = false
@@ -814,6 +831,15 @@ pp.parseIdent = function(liberal, isBinding) {
     node.name = this.value
   } else if (this.type.keyword) {
     node.name = this.type.keyword
+
+    // To fix https://github.com/ternjs/acorn/issues/575
+    // `class` and `function` keywords push new context into this.context.
+    // But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name.
+    // If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword
+    if ((node.name === "class" || node.name === "function") &&
+        (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) {
+      this.context.pop()
+    }
   } else {
     this.unexpected()
   }
diff --git a/src/index.js b/src/index.js
index c0c0065..d196b2a 100644
--- a/src/index.js
+++ b/src/index.js
@@ -37,7 +37,7 @@ export {isIdentifierChar, isIdentifierStart} from "./identifier"
 export {Token} from "./tokenize"
 export {isNewLine, lineBreak, lineBreakG, nonASCIIwhitespace} from "./whitespace"
 
-export const version = "5.1.2"
+export const version = "5.2.1"
 
 // The main exported interface (under `self.acorn` when in the
 // browser) is a `parse` function that takes a code string and
diff --git a/src/loose/expression.js b/src/loose/expression.js
index af9358e..21c2fd1 100644
--- a/src/loose/expression.js
+++ b/src/loose/expression.js
@@ -391,7 +391,7 @@ lp.parseObj = function() {
       prop.value = this.parseMethod(isGenerator, isAsync)
     } else if (this.options.ecmaVersion >= 5 && prop.key.type === "Identifier" &&
                !prop.computed && (prop.key.name === "get" || prop.key.name === "set") &&
-               (this.tok.type != tt.comma && this.tok.type != tt.braceR)) {
+               (this.tok.type != tt.comma && this.tok.type != tt.braceR && this.tok.type != tt.eq)) {
       prop.kind = prop.key.name
       this.parsePropertyName(prop)
       prop.value = this.parseMethod(false)
@@ -514,8 +514,8 @@ lp.parseMethod = function(isGenerator, isAsync) {
     node.async = !!isAsync
   this.inAsync = node.async
   node.params = this.parseFunctionParams()
-  node.expression = this.options.ecmaVersion >= 6 && this.tok.type !== tt.braceL
-  node.body = node.expression ? this.parseMaybeAssign() : this.parseBlock()
+  node.body = this.parseBlock()
+  this.toks.adaptDirectivePrologue(node.body.body)
   this.inAsync = oldInAsync
   return this.finishNode(node, "FunctionExpression")
 }
@@ -528,7 +528,12 @@ lp.parseArrowExpression = function(node, params, isAsync) {
   this.inAsync = node.async
   node.params = this.toAssignableList(params, true)
   node.expression = this.tok.type !== tt.braceL
-  node.body = node.expression ? this.parseMaybeAssign() : this.parseBlock()
+  if (node.expression) {
+    node.body = this.parseMaybeAssign()
+  } else {
+    node.body = this.parseBlock()
+    this.toks.adaptDirectivePrologue(node.body.body)
+  }
   this.inAsync = oldInAsync
   return this.finishNode(node, "ArrowFunctionExpression")
 }
diff --git a/src/loose/statement.js b/src/loose/statement.js
index 192df43..19e96b4 100644
--- a/src/loose/statement.js
+++ b/src/loose/statement.js
@@ -8,6 +8,7 @@ lp.parseTopLevel = function() {
   let node = this.startNodeAt(this.options.locations ? [0, getLineInfo(this.input, 0)] : 0)
   node.body = []
   while (this.tok.type !== tt.eof) node.body.push(this.parseStatement())
+  this.toks.adaptDirectivePrologue(node.body)
   this.last = this.tok
   if (this.options.ecmaVersion >= 6) {
     node.sourceType = this.options.sourceType
@@ -330,6 +331,7 @@ lp.parseFunction = function(node, isStatement, isAsync) {
   this.inAsync = node.async
   node.params = this.parseFunctionParams()
   node.body = this.parseBlock()
+  this.toks.adaptDirectivePrologue(node.body.body)
   this.inAsync = oldInAsync
   return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression")
 }
@@ -376,7 +378,6 @@ lp.parseImport = function() {
   if (this.tok.type === tt.string) {
     node.specifiers = []
     node.source = this.parseExprAtom()
-    node.kind = ""
   } else {
     let elt
     if (this.tok.type === tt.name && this.tok.value !== "from") {
diff --git a/src/lval.js b/src/lval.js
index 6d7dfed..1c47574 100644
--- a/src/lval.js
+++ b/src/lval.js
@@ -110,23 +110,19 @@ pp.parseRestBinding = function() {
 // Parses lvalue (assignable) atom.
 
 pp.parseBindingAtom = function() {
-  if (this.options.ecmaVersion < 6) return this.parseIdent()
-  switch (this.type) {
-  case tt.name:
-    return this.parseIdent()
-
-  case tt.bracketL:
-    let node = this.startNode()
-    this.next()
-    node.elements = this.parseBindingList(tt.bracketR, true, true)
-    return this.finishNode(node, "ArrayPattern")
-
-  case tt.braceL:
-    return this.parseObj(true)
-
-  default:
-    this.unexpected()
+  if (this.options.ecmaVersion >= 6) {
+    switch (this.type) {
+    case tt.bracketL:
+      let node = this.startNode()
+      this.next()
+      node.elements = this.parseBindingList(tt.bracketR, true, true)
+      return this.finishNode(node, "ArrayPattern")
+
+    case tt.braceL:
+      return this.parseObj(true)
+    }
   }
+  return this.parseIdent()
 }
 
 pp.parseBindingList = function(close, allowEmpty, allowTrailingComma) {
diff --git a/src/statement.js b/src/statement.js
index 0ce32f1..5d6cd1d 100644
--- a/src/statement.js
+++ b/src/statement.js
@@ -21,6 +21,7 @@ pp.parseTopLevel = function(node) {
     let stmt = this.parseStatement(true, true, exports)
     node.body.push(stmt)
   }
+  this.adaptDirectivePrologue(node.body)
   this.next()
   if (this.options.ecmaVersion >= 6) {
     node.sourceType = this.options.sourceType
@@ -760,3 +761,19 @@ pp.parseImportSpecifiers = function() {
   }
   return nodes
 }
+
+// Set `ExpressionStatement#directive` property for directive prologues.
+pp.adaptDirectivePrologue = function(statements) {
+  for (let i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) {
+    statements[i].directive = statements[i].expression.raw.slice(1, -1)
+  }
+}
+pp.isDirectiveCandidate = function(statement) {
+  return (
+    statement.type === "ExpressionStatement" &&
+    statement.expression.type === "Literal" &&
+    typeof statement.expression.value === "string" &&
+    // Reject parenthesized strings.
+    (this.input[statement.start] === "\"" || this.input[statement.start] === "'")
+  )
+}
diff --git a/src/tokenize.js b/src/tokenize.js
index 4f98e34..f2611b0 100644
--- a/src/tokenize.js
+++ b/src/tokenize.js
@@ -221,7 +221,7 @@ pp.readToken_mult_modulo_exp = function(code) { // '%*'
   let tokentype = code === 42 ? tt.star : tt.modulo
 
   // exponentiation operator ** and **=
-  if (this.options.ecmaVersion >= 7 && next === 42) {
+  if (this.options.ecmaVersion >= 7 && code == 42 && next === 42) {
     ++size
     tokentype = tt.starstar
     next = this.input.charCodeAt(this.pos + 2)
diff --git a/src/walk/index.js b/src/walk/index.js
index ac31bcd..28f42ff 100644
--- a/src/walk/index.js
+++ b/src/walk/index.js
@@ -72,7 +72,7 @@ export function full(node, callback, base, state, override) {
   ;(function c(node, st, override) {
     let type = override || node.type
     base[type](node, st, c)
-    callback(node, st, type)
+    if (!override) callback(node, st, type)
   })(node, state, override)
 }
 
@@ -86,7 +86,7 @@ export function fullAncestor(node, callback, base, state) {
     let isNew = node != ancestors[ancestors.length - 1]
     if (isNew) ancestors.push(node)
     base[type](node, st, c)
-    callback(node, st || ancestors, ancestors, type)
+    if (!override) callback(node, st || ancestors, ancestors, type)
     if (isNew) ancestors.pop()
   })(node, state)
 }
diff --git a/test/run.js b/test/run.js
index bfed09c..dce46c6 100644
--- a/test/run.js
+++ b/test/run.js
@@ -9,6 +9,7 @@
     require("./tests-asyncawait.js");
     require("./tests-trailing-commas-in-func.js");
     require("./tests-template-literal-revision.js");
+    require("./tests-directive.js");
     acorn = require("../dist/acorn")
     require("../dist/acorn_loose")
   } else {
diff --git a/test/tests-asyncawait.js b/test/tests-asyncawait.js
index 35ccd41..338ed91 100644
--- a/test/tests-asyncawait.js
+++ b/test/tests-asyncawait.js
@@ -3099,7 +3099,8 @@ test(
     body: [{
       type: "IfStatement",
       consequent: {
-        type: "FunctionDeclaration"
+        type: "FunctionDeclaration",
+        async: true
       },
       alternate: null
     }]
diff --git a/test/tests-directive.js b/test/tests-directive.js
new file mode 100644
index 0000000..90fb2ae
--- /dev/null
+++ b/test/tests-directive.js
@@ -0,0 +1,1360 @@
+
+if (typeof exports != "undefined") {
+  var driver = require("./driver.js");
+  var test = driver.test, testFail = driver.testFail, testAssert = driver.testAssert, misMatch = driver.misMatch;
+  var acorn = require("..");
+}
+
+//------------------------------------------------------------------------
+// No directives
+//------------------------------------------------------------------------
+
+test("foo", {
+  "type": "Program",
+  "start": 0,
+  "end": 3,
+  "body": [
+    {
+      "type": "ExpressionStatement",
+      "start": 0,
+      "end": 3,
+      "expression": {
+        "type": "Identifier",
+        "start": 0,
+        "end": 3,
+        "name": "foo"
+      },
+      "directive": undefined // check this property does not exist.
+    }
+  ]
+}, { ecmaVersion: 6 })
+
+test("function wrap() { foo }", {
+  "type": "Program",
+  "start": 0,
+  "end": 23,
+  "body": [
+    {
+      "type": "FunctionDeclaration",
+      "start": 0,
+      "end": 23,
+      "id": {
+        "type": "Identifier",
+        "start": 9,
+        "end": 13,
+        "name": "wrap"
+      },
+      "generator": false,
+      "expression": false,
+      "params": [],
+      "body": {
+        "type": "BlockStatement",
+        "start": 16,
+        "end": 23,
+        "body": [
+          {
+            "type": "ExpressionStatement",
+            "start": 18,
+            "end": 21,
+            "expression": {
+              "type": "Identifier",
+              "start": 18,
+              "end": 21,
+              "name": "foo"
+            },
+            "directive": undefined // check this property does not exist.
+          }
+        ]
+      }
+    }
+  ]
+}, { ecmaVersion: 6 })
+
+test("!function wrap() { foo }", {
+  "type": "Program",
+  "start": 0,
+  "end": 24,
+  "body": [
+    {
+      "type": "ExpressionStatement",
+      "start": 0,
+      "end": 24,
+      "expression": {
+        "type": "UnaryExpression",
+        "start": 0,
+        "end": 24,
+        "operator": "!",
+        "prefix": true,
+        "argument": {
+          "type": "FunctionExpression",
+          "start": 1,
+          "end": 24,
+          "id": {
+            "type": "Identifier",
+            "start": 10,
+            "end": 14,
+            "name": "wrap"
+          },
+          "generator": false,
+          "expression": false,
+          "params": [],
+          "body": {
+            "type": "BlockStatement",
+            "start": 17,
+            "end": 24,
+            "body": [
+              {
+                "type": "ExpressionStatement",
+                "start": 19,
+                "end": 22,
+                "expression": {
+                  "type": "Identifier",
+                  "start": 19,
+                  "end": 22,
+                  "name": "foo"
+                },
+                "directive": undefined // check this property does not exist.
+              }
+            ]
+          }
+        }
+      },
+      "directive": undefined // check this property does not exist.
+    }
+  ]
+}, { ecmaVersion: 6 })
+
+test("() => { foo }", {
+  "type": "Program",
+  "start": 0,
+  "end": 13,
+  "body": [
+    {
+      "type": "ExpressionStatement",
+      "start": 0,
+      "end": 13,
+      "expression": {
+        "type": "ArrowFunctionExpression",
+        "start": 0,
+        "end": 13,
+        "id": null,
+        "generator": false,
+        "expression": false,
+        "params": [],
+        "body": {
+          "type": "BlockStatement",
+          "start": 6,
+          "end": 13,
+          "body": [
+            {
+              "type": "ExpressionStatement",
+              "start": 8,
+              "end": 11,
+              "expression": {
+                "type": "Identifier",
+                "start": 8,
+                "end": 11,
+                "name": "foo"
+              },
+              "directive": undefined // check this property does not exist.
+            }
+          ]
+        }
+      },
+      "directive": undefined // check this property does not exist.
+    }
+  ]
+}, { ecmaVersion: 6 })
+
+test("100", {
+  "type": "Program",
+  "start": 0,
+  "end": 3,
+  "body": [
+    {
+      "type": "ExpressionStatement",
+      "start": 0,
+      "end": 3,
+      "expression": {
+        "type": "Literal",
+        "start": 0,
+        "end": 3,
+        "value": 100,
+        "raw": "100"
+      },
+      "directive": undefined // check this property does not exist.
+    }
+  ]
+}, { ecmaVersion: 6 })
+
+test("\"use strict\" + 1", {
+  "type": "Program",
+  "start": 0,
+  "end": 16,
+  "body": [
+    {
+      "type": "ExpressionStatement",
+      "start": 0,
+      "end": 16,
+      "expression": {
+        "type": "BinaryExpression",
+        "start": 0,
+        "end": 16,
+        "left": {
+          "type": "Literal",
+          "start": 0,
+          "end": 12,
+          "value": "use strict",
+          "raw": "\"use strict\""
+        },
+        "operator": "+",
+        "right": {
+          "type": "Literal",
+          "start": 15,
+          "end": 16,
+          "value": 1,
+          "raw": "1"
+        }
+      },
+      "directive": undefined // check this property does not exist.
+    }
+  ]
+}, { ecmaVersion: 6 })
+
+//------------------------------------------------------------------------
+// One directive
+//------------------------------------------------------------------------
+
+test("\"use strict\"\n foo", {
+  "type": "Program",
+  "start": 0,
+  "end": 17,
+  "body": [
+    {
+      "type": "ExpressionStatement",
+      "start": 0,
+      "end": 12,
+      "expression": {
+        "type": "Literal",
+        "start": 0,
+        "end": 12,
+        "value": "use strict",
+        "raw": "\"use strict\""
+      },
+      "directive": "use strict"
+    },
+    {
+      "type": "ExpressionStatement",
+      "start": 14,
+      "end": 17,
+      "expression": {
+        "type": "Identifier",
+        "start": 14,
+        "end": 17,
+        "name": "foo"
+      },
+      "directive": undefined // check this property does not exist.
+    }
+  ]
+}, { ecmaVersion: 6 })
+
+test("'use strict'; foo", {
+  "type": "Program",
+  "start": 0,
+  "end": 17,
+  "body": [
+    {
+      "type": "ExpressionStatement",
+      "start": 0,
+      "end": 13,
+      "expression": {
+        "type": "Literal",
+        "start": 0,
+        "end": 12,
+        "value": "use strict",
+        "raw": "'use strict'"
+      },
+      "directive": "use strict"
+    },
+    {
+      "type": "ExpressionStatement",
+      "start": 14,
+      "end": 17,
+      "expression": {
+        "type": "Identifier",
+        "start": 14,
+        "end": 17,
+        "name": "foo"
+      },
+      "directive": undefined // check this property does not exist.
+    }
+  ]
+}, { ecmaVersion: 6 })
+
+test("function wrap() { \"use strict\"\n foo }", {
+  "type": "Program",
+  "start": 0,
+  "end": 37,
+  "body": [
+    {
+      "type": "FunctionDeclaration",
+      "start": 0,
+      "end": 37,
+      "id": {
+        "type": "Identifier",
+        "start": 9,
+        "end": 13,
+        "name": "wrap"
+      },
+      "generator": false,
+      "expression": false,
+      "params": [],
+      "body": {
+        "type": "BlockStatement",
+        "start": 16,
+        "end": 37,
+        "body": [
+          {
+            "type": "ExpressionStatement",
+            "start": 18,
+            "end": 30,
+            "expression": {
+              "type": "Literal",
+              "start": 18,
+              "end": 30,
+              "value": "use strict",
+              "raw": "\"use strict\""
+            },
+            "directive": "use strict"
+          },
+          {
+            "type": "ExpressionStatement",
+            "start": 32,
+            "end": 35,
+            "expression": {
+              "type": "Identifier",
+              "start": 32,
+              "end": 35,
+              "name": "foo"
+            },
+            "directive": undefined // check this property does not exist.
+          }
+        ]
+      }
+    }
+  ]
+}, { ecmaVersion: 6 })
+
+test("!function wrap() { \"use strict\"\n foo }", {
+  "type": "Program",
+  "start": 0,
+  "end": 38,
+  "body": [
+    {
+      "type": "ExpressionStatement",
+      "start": 0,
+      "end": 38,
+      "expression": {
+        "type": "UnaryExpression",
+        "start": 0,
+        "end": 38,
+        "operator": "!",
+        "prefix": true,
+        "argument": {
+          "type": "FunctionExpression",
+          "start": 1,
+          "end": 38,
+          "id": {
+            "type": "Identifier",
+            "start": 10,
+            "end": 14,
+            "name": "wrap"
+          },
+          "generator": false,
+          "expression": false,
+          "params": [],
+          "body": {
+            "type": "BlockStatement",
+            "start": 17,
+            "end": 38,
+            "body": [
+              {
+                "type": "ExpressionStatement",
+                "start": 19,
+                "end": 31,
+                "expression": {
+                  "type": "Literal",
+                  "start": 19,
+                  "end": 31,
+                  "value": "use strict",
+                  "raw": "\"use strict\""
+                },
+                "directive": "use strict"
+              },
+              {
+                "type": "ExpressionStatement",
+                "start": 33,
+                "end": 36,
+                "expression": {
+                  "type": "Identifier",
+                  "start": 33,
+                  "end": 36,
+                  "name": "foo"
+                },
+                "directive": undefined // check this property does not exist.
+              }
+            ]
+          }
+        }
+      },
+      "directive": undefined // check this property does not exist.
+    }
+  ]
+}, { ecmaVersion: 6 })
+
+test("() => { \"use strict\"\n foo }", {
+  "type": "Program",
+  "start": 0,
+  "end": 27,
+  "body": [
+    {
+      "type": "ExpressionStatement",
+      "start": 0,
+      "end": 27,
+      "expression": {
+        "type": "ArrowFunctionExpression",
+        "start": 0,
+        "end": 27,
+        "id": null,
+        "generator": false,
+        "expression": false,
+        "params": [],
+        "body": {
+          "type": "BlockStatement",
+          "start": 6,
+          "end": 27,
+          "body": [
+            {
+              "type": "ExpressionStatement",
+              "start": 8,
+              "end": 20,
+              "expression": {
+                "type": "Literal",
+                "start": 8,
+                "end": 20,
+                "value": "use strict",
+                "raw": "\"use strict\""
+              },
+              "directive": "use strict"
+            },
+            {
+              "type": "ExpressionStatement",
+              "start": 22,
+              "end": 25,
+              "expression": {
+                "type": "Identifier",
+                "start": 22,
+                "end": 25,
+                "name": "foo"
+              },
+              "directive": undefined // check this property does not exist.
+            }
+          ]
+        }
+      },
+      "directive": undefined // check this property does not exist.
+    }
+  ]
+}, { ecmaVersion: 6 })
+
+test("() => \"use strict\"", {
+  "type": "Program",
+  "start": 0,
+  "end": 18,
+  "body": [
+    {
+      "type": "ExpressionStatement",
+      "start": 0,
+      "end": 18,
+      "expression": {
+        "type": "ArrowFunctionExpression",
+        "start": 0,
+        "end": 18,
+        "id": null,
+        "generator": false,
+        "expression": true,
+        "params": [],
+        "body": {
+          "type": "Literal",
+          "start": 6,
+          "end": 18,
+          "value": "use strict",
+          "raw": "\"use strict\""
+        }
+      },
+      "directive": undefined // check this property does not exist.
+    }
+  ]
+}, {ecmaVersion: 6})
+
+test("({ wrap() { \"use strict\"; foo } })", {
+  "type": "Program",
+  "start": 0,
+  "end": 34,
+  "body": [
+    {
+      "type": "ExpressionStatement",
+      "start": 0,
+      "end": 34,
+      "expression": {
+        "type": "ObjectExpression",
+        "start": 1,
+        "end": 33,
+        "properties": [
+          {
+            "type": "Property",
+            "start": 3,
+            "end": 31,
+            "method": true,
+            "shorthand": false,
+            "computed": false,
+            "key": {
+              "type": "Identifier",
+              "start": 3,
+              "end": 7,
+              "name": "wrap"
+            },
+            "kind": "init",
+            "value": {
+              "type": "FunctionExpression",
+              "start": 7,
+              "end": 31,
+              "id": null,
+              "generator": false,
+              "expression": false,
+              "params": [],
+              "body": {
+                "type": "BlockStatement",
+                "start": 10,
+                "end": 31,
+                "body": [
+                  {
+                    "type": "ExpressionStatement",
+                    "start": 12,
+                    "end": 25,
+                    "expression": {
+                      "type": "Literal",
+                      "start": 12,
+                      "end": 24,
+                      "value": "use strict",
+                      "raw": "\"use strict\""
+                    },
+                    "directive": "use strict"
+                  },
+                  {
+                    "type": "ExpressionStatement",
+                    "start": 26,
+                    "end": 29,
+                    "expression": {
+                      "type": "Identifier",
+                      "start": 26,
+                      "end": 29,
+                      "name": "foo"
+                    },
+                    "directive": undefined // check this property does not exist.
+                  }
+                ]
+              }
+            }
+          }
+        ]
+      },
+      "directive": undefined // check this property does not exist.
+    }
+  ]
+}, { ecmaVersion: 6 })
+
+test("(class { wrap() { \"use strict\"; foo } })", {
+  "type": "Program",
+  "start": 0,
+  "end": 40,
+  "body": [
+    {
+      "type": "ExpressionStatement",
+      "start": 0,
+      "end": 40,
+      "expression": {
+        "type": "ClassExpression",
+        "start": 1,
+        "end": 39,
+        "id": null,
+        "superClass": null,
+        "body": {
+          "type": "ClassBody",
+          "start": 7,
+          "end": 39,
+          "body": [
+            {
+              "type": "MethodDefinition",
+              "start": 9,
+              "end": 37,
+              "computed": false,
+              "key": {
+                "type": "Identifier",
+                "start": 9,
+                "end": 13,
+                "name": "wrap"
+              },
+              "static": false,
+              "kind": "method",
+              "value": {
+                "type": "FunctionExpression",
+                "start": 13,
+                "end": 37,
+                "id": null,
+                "generator": false,
+                "expression": false,
+                "params": [],
+                "body": {
+                  "type": "BlockStatement",
+                  "start": 16,
+                  "end": 37,
+                  "body": [
+                    {
+                      "type": "ExpressionStatement",
+                      "start": 18,
+                      "end": 31,
+                      "expression": {
+                        "type": "Literal",
+                        "start": 18,
+                        "end": 30,
+                        "value": "use strict",
+                        "raw": "\"use strict\""
+                      },
+                      "directive": "use strict"
+                    },
+                    {
+                      "type": "ExpressionStatement",
+                      "start": 32,
+                      "end": 35,
+                      "expression": {
+                        "type": "Identifier",
+                        "start": 32,
+                        "end": 35,
+                        "name": "foo"
+                      },
+                      "directive": undefined // check this property does not exist.
+                    }
+                  ]
+                }
+              }
+            }
+          ]
+        }
+      },
+      "directive": undefined // check this property does not exist.
+    }
+  ]
+}, { ecmaVersion: 6 })
+
+// Should not decode escape sequence.
+test("\"\\u0075se strict\"", {
+  "type": "Program",
+  "start": 0,
+  "end": 17,
+  "body": [
+    {
+      "type": "ExpressionStatement",
+      "start": 0,
+      "end": 17,
+      "expression": {
+        "type": "Literal",
+        "start": 0,
+        "end": 17,
+        "value": "use strict",
+        "raw": "\"\\u0075se strict\""
+      },
+      "directive": "\\u0075se strict"
+    }
+  ]
+}, { ecmaVersion: 6 })
+
+//------------------------------------------------------------------------
+// Two or more directives.
+//------------------------------------------------------------------------
+
+test("\"use asm\"; \"use strict\"; foo", {
+  "type": "Program",
+  "start": 0,
+  "end": 28,
+  "body": [
+    {
+      "type": "ExpressionStatement",
+      "start": 0,
+      "end": 10,
+      "expression": {
+        "type": "Literal",
+        "start": 0,
+        "end": 9,
+        "value": "use asm",
+        "raw": "\"use asm\""
+      },
+      "directive": "use asm"
+    },
+    {
+      "type": "ExpressionStatement",
+      "start": 11,
+      "end": 24,
+      "expression": {
+        "type": "Literal",
+        "start": 11,
+        "end": 23,
+        "value": "use strict",
+        "raw": "\"use strict\""
+      },
+      "directive": "use strict"
+    },
+    {
+      "type": "ExpressionStatement",
+      "start": 25,
+      "end": 28,
+      "expression": {
+        "type": "Identifier",
+        "start": 25,
+        "end": 28,
+        "name": "foo"
+      },
+      "directive": undefined // check this property does not exist.
+    }
+  ]
+}, { ecmaVersion: 6 })
+
+test("function wrap() { \"use asm\"; \"use strict\"; foo }", {
+  "type": "Program",
+  "start": 0,
+  "end": 48,
+  "body": [
+    {
+      "type": "FunctionDeclaration",
+      "start": 0,
+      "end": 48,
+      "id": {
+        "type": "Identifier",
+        "start": 9,
+        "end": 13,
+        "name": "wrap"
+      },
+      "generator": false,
+      "expression": false,
+      "params": [],
+      "body": {
+        "type": "BlockStatement",
+        "start": 16,
+        "end": 48,
+        "body": [
+          {
+            "type": "ExpressionStatement",
+            "start": 18,
+            "end": 28,
+            "expression": {
+              "type": "Literal",
+              "start": 18,
+              "end": 27,
+              "value": "use asm",
+              "raw": "\"use asm\""
+            },
+            "directive": "use asm"
+          },
+          {
+            "type": "ExpressionStatement",
+            "start": 29,
+            "end": 42,
+            "expression": {
+              "type": "Literal",
+              "start": 29,
+              "end": 41,
+              "value": "use strict",
+              "raw": "\"use strict\""
+            },
+            "directive": "use strict"
+          },
+          {
+            "type": "ExpressionStatement",
+            "start": 43,
+            "end": 46,
+            "expression": {
+              "type": "Identifier",
+              "start": 43,
+              "end": 46,
+              "name": "foo"
+            },
+            "directive": undefined // check this property does not exist.
+          }
+        ]
+      }
+    }
+  ]
+}, { ecmaVersion: 6 })
+
+//------------------------------------------------------------------------
+// One string after other expressions.
+//------------------------------------------------------------------------
+
+test("\"use strict\"; foo; \"use asm\"", {
+  "type": "Program",
+  "start": 0,
+  "end": 28,
+  "body": [
+    {
+      "type": "ExpressionStatement",
+      "start": 0,
+      "end": 13,
+      "expression": {
+        "type": "Literal",
+        "start": 0,
+        "end": 12,
+        "value": "use strict",
+        "raw": "\"use strict\""
+      },
+      "directive": "use strict"
+    },
+    {
+      "type": "ExpressionStatement",
+      "start": 14,
+      "end": 18,
+      "expression": {
+        "type": "Identifier",
+        "start": 14,
+        "end": 17,
+        "name": "foo"
+      },
+      "directive": undefined // check this property does not exist.
+    },
+    {
+      "type": "ExpressionStatement",
+      "start": 19,
+      "end": 28,
+      "expression": {
+        "type": "Literal",
+        "start": 19,
+        "end": 28,
+        "value": "use asm",
+        "raw": "\"use asm\""
+      },
+      "directive": undefined // check this property does not exist.
+    }
+  ]
+}, { ecmaVersion: 6 })
+
+test("function wrap() { \"use asm\"; foo; \"use strict\" }", {
+  "type": "Program",
+  "start": 0,
+  "end": 48,
+  "body": [
+    {
+      "type": "FunctionDeclaration",
+      "start": 0,
+      "end": 48,
+      "id": {
+        "type": "Identifier",
+        "start": 9,
+        "end": 13,
+        "name": "wrap"
+      },
+      "generator": false,
+      "expression": false,
+      "params": [],
+      "body": {
+        "type": "BlockStatement",
+        "start": 16,
+        "end": 48,
+        "body": [
+          {
+            "type": "ExpressionStatement",
+            "start": 18,
+            "end": 28,
+            "expression": {
+              "type": "Literal",
+              "start": 18,
+              "end": 27,
+              "value": "use asm",
+              "raw": "\"use asm\""
+            },
+            "directive": "use asm"
+          },
+          {
+            "type": "ExpressionStatement",
+            "start": 29,
+            "end": 33,
+            "expression": {
+              "type": "Identifier",
+              "start": 29,
+              "end": 32,
+              "name": "foo"
+            },
+            "directive": undefined // check this property does not exist.
+          },
+          {
+            "type": "ExpressionStatement",
+            "start": 34,
+            "end": 46,
+            "expression": {
+              "type": "Literal",
+              "start": 34,
+              "end": 46,
+              "value": "use strict",
+              "raw": "\"use strict\""
+            },
+            "directive": undefined // check this property does not exist.
+          }
+        ]
+      }
+    }
+  ]
+}, { ecmaVersion: 6 })
+
+//------------------------------------------------------------------------
+// One string in a block.
+//------------------------------------------------------------------------
+
+test("{ \"use strict\"; }", {
+  "type": "Program",
+  "start": 0,
+  "end": 17,
+  "body": [
+    {
+      "type": "BlockStatement",
+      "start": 0,
+      "end": 17,
+      "body": [
+        {
+          "type": "ExpressionStatement",
+          "start": 2,
+          "end": 15,
+          "expression": {
+            "type": "Literal",
+            "start": 2,
+            "end": 14,
+            "value": "use strict",
+            "raw": "\"use strict\""
+          },
+          "directive": undefined // check this property does not exist.
+        }
+      ]
+    }
+  ]
+}, { ecmaVersion: 6 })
+
+test("function wrap() { { \"use strict\" } foo }", {
+  "type": "Program",
+  "start": 0,
+  "end": 40,
+  "body": [
+    {
+      "type": "FunctionDeclaration",
+      "start": 0,
+      "end": 40,
+      "id": {
+        "type": "Identifier",
+        "start": 9,
+        "end": 13,
+        "name": "wrap"
+      },
+      "generator": false,
+      "expression": false,
+      "params": [],
+      "body": {
+        "type": "BlockStatement",
+        "start": 16,
+        "end": 40,
+        "body": [
+          {
+            "type": "BlockStatement",
+            "start": 18,
+            "end": 34,
+            "body": [
+              {
+                "type": "ExpressionStatement",
+                "start": 20,
+                "end": 32,
+                "expression": {
+                  "type": "Literal",
+                  "start": 20,
+                  "end": 32,
+                  "value": "use strict",
+                  "raw": "\"use strict\""
+                },
+                "directive": undefined // check this property does not exist.
+              }
+            ]
+          },
+          {
+            "type": "ExpressionStatement",
+            "start": 35,
+            "end": 38,
+            "expression": {
+              "type": "Identifier",
+              "start": 35,
+              "end": 38,
+              "name": "foo"
+            },
+            "directive": undefined // check this property does not exist.
+          }
+        ]
+      }
+    }
+  ]
+}, { ecmaVersion: 6 })
+
+//------------------------------------------------------------------------
+// One string with parentheses.
+//------------------------------------------------------------------------
+
+test("(\"use strict\"); foo", {
+  "type": "Program",
+  "start": 0,
+  "end": 19,
+  "body": [
+    {
+      "type": "ExpressionStatement",
+      "start": 0,
+      "end": 15,
+      "expression": {
+        "type": "Literal",
+        "start": 1,
+        "end": 13,
+        "value": "use strict",
+        "raw": "\"use strict\""
+      },
+      "directive": undefined // check this property does not exist.
+    },
+    {
+      "type": "ExpressionStatement",
+      "start": 16,
+      "end": 19,
+      "expression": {
+        "type": "Identifier",
+        "start": 16,
+        "end": 19,
+        "name": "foo"
+      },
+      "directive": undefined // check this property does not exist.
+    }
+  ]
+}, { ecmaVersion: 6 })
+
+test("function wrap() { (\"use strict\"); foo }", {
+  "type": "Program",
+  "start": 0,
+  "end": 39,
+  "body": [
+    {
+      "type": "FunctionDeclaration",
+      "start": 0,
+      "end": 39,
+      "id": {
+        "type": "Identifier",
+        "start": 9,
+        "end": 13,
+        "name": "wrap"
+      },
+      "generator": false,
+      "expression": false,
+      "params": [],
+      "body": {
+        "type": "BlockStatement",
+        "start": 16,
+        "end": 39,
+        "body": [
+          {
+            "type": "ExpressionStatement",
+            "start": 18,
+            "end": 33,
+            "expression": {
+              "type": "Literal",
+              "start": 19,
+              "end": 31,
+              "value": "use strict",
+              "raw": "\"use strict\""
+            },
+            "directive": undefined // check this property does not exist.
+          },
+          {
+            "type": "ExpressionStatement",
+            "start": 34,
+            "end": 37,
+            "expression": {
+              "type": "Identifier",
+              "start": 34,
+              "end": 37,
+              "name": "foo"
+            },
+            "directive": undefined // check this property does not exist.
+          }
+        ]
+      }
+    }
+  ]
+}, { ecmaVersion: 6 })
+
+//------------------------------------------------------------------------
+// Complex cases such as the function in a default parameter.
+//------------------------------------------------------------------------
+
+test("function a() { \"use strict\" } \"use strict\"; foo", {
+  "type": "Program",
+  "start": 0,
+  "end": 47,
+  "body": [
+    {
+      "type": "FunctionDeclaration",
+      "start": 0,
+      "end": 29,
+      "id": {
+        "type": "Identifier",
+        "start": 9,
+        "end": 10,
+        "name": "a"
+      },
+      "generator": false,
+      "expression": false,
+      "params": [],
+      "body": {
+        "type": "BlockStatement",
+        "start": 13,
+        "end": 29,
+        "body": [
+          {
+            "type": "ExpressionStatement",
+            "start": 15,
+            "end": 27,
+            "expression": {
+              "type": "Literal",
+              "start": 15,
+              "end": 27,
+              "value": "use strict",
+              "raw": "\"use strict\""
+            },
+            "directive": "use strict"
+          }
+        ]
+      }
+    },
+    {
+      "type": "ExpressionStatement",
+      "start": 30,
+      "end": 43,
+      "expression": {
+        "type": "Literal",
+        "start": 30,
+        "end": 42,
+        "value": "use strict",
+        "raw": "\"use strict\""
+      },
+      "directive": undefined // check this property does not exist.
+    },
+    {
+      "type": "ExpressionStatement",
+      "start": 44,
+      "end": 47,
+      "expression": {
+        "type": "Identifier",
+        "start": 44,
+        "end": 47,
+        "name": "foo"
+      },
+      "directive": undefined // check this property does not exist.
+    }
+  ]
+}, { ecmaVersion: 6 })
+
+test("function a(a = function() { \"use strict\"; foo }) { \"use strict\" }", {
+  "type": "Program",
+  "start": 0,
+  "end": 65,
+  "body": [
+    {
+      "type": "FunctionDeclaration",
+      "start": 0,
+      "end": 65,
+      "id": {
+        "type": "Identifier",
+        "start": 9,
+        "end": 10,
+        "name": "a"
+      },
+      "generator": false,
+      "expression": false,
+      "params": [
+        {
+          "type": "AssignmentPattern",
+          "start": 11,
+          "end": 47,
+          "left": {
+            "type": "Identifier",
+            "start": 11,
+            "end": 12,
+            "name": "a"
+          },
+          "right": {
+            "type": "FunctionExpression",
+            "start": 15,
+            "end": 47,
+            "id": null,
+            "generator": false,
+            "expression": false,
+            "params": [],
+            "body": {
+              "type": "BlockStatement",
+              "start": 26,
+              "end": 47,
+              "body": [
+                {
+                  "type": "ExpressionStatement",
+                  "start": 28,
+                  "end": 41,
+                  "expression": {
+                    "type": "Literal",
+                    "start": 28,
+                    "end": 40,
+                    "value": "use strict",
+                    "raw": "\"use strict\""
+                  },
+                  "directive": "use strict"
+                },
+                {
+                  "type": "ExpressionStatement",
+                  "start": 42,
+                  "end": 45,
+                  "expression": {
+                    "type": "Identifier",
+                    "start": 42,
+                    "end": 45,
+                    "name": "foo"
+                  },
+                  "directive": undefined // check this property does not exist.
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "body": {
+        "type": "BlockStatement",
+        "start": 49,
+        "end": 65,
+        "body": [
+          {
+            "type": "ExpressionStatement",
+            "start": 51,
+            "end": 63,
+            "expression": {
+              "type": "Literal",
+              "start": 51,
+              "end": 63,
+              "value": "use strict",
+              "raw": "\"use strict\""
+            },
+            "directive": "use strict"
+          }
+        ]
+      }
+    }
+  ]
+}, { ecmaVersion: 6 })
+
+test("(a = () => { \"use strict\"; foo }) => { \"use strict\" }", {
+  "type": "Program",
+  "start": 0,
+  "end": 53,
+  "body": [
+    {
+      "type": "ExpressionStatement",
+      "start": 0,
+      "end": 53,
+      "expression": {
+        "type": "ArrowFunctionExpression",
+        "start": 0,
+        "end": 53,
+        "id": null,
+        "generator": false,
+        "expression": false,
+        "params": [
+          {
+            "type": "AssignmentPattern",
+            "start": 1,
+            "end": 32,
+            "left": {
+              "type": "Identifier",
+              "start": 1,
+              "end": 2,
+              "name": "a"
+            },
+            "right": {
+              "type": "ArrowFunctionExpression",
+              "start": 5,
+              "end": 32,
+              "id": null,
+              "generator": false,
+              "expression": false,
+              "params": [],
+              "body": {
+                "type": "BlockStatement",
+                "start": 11,
+                "end": 32,
+                "body": [
+                  {
+                    "type": "ExpressionStatement",
+                    "start": 13,
+                    "end": 26,
+                    "expression": {
+                      "type": "Literal",
+                      "start": 13,
+                      "end": 25,
+                      "value": "use strict",
+                      "raw": "\"use strict\""
+                    },
+                    "directive": "use strict"
+                  },
+                  {
+                    "type": "ExpressionStatement",
+                    "start": 27,
+                    "end": 30,
+                    "expression": {
+                      "type": "Identifier",
+                      "start": 27,
+                      "end": 30,
+                      "name": "foo"
+                    },
+                    "directive": undefined // check this property does not exist.
+                  }
+                ]
+              }
+            }
+          }
+        ],
+        "body": {
+          "type": "BlockStatement",
+          "start": 37,
+          "end": 53,
+          "body": [
+            {
+              "type": "ExpressionStatement",
+              "start": 39,
+              "end": 51,
+              "expression": {
+                "type": "Literal",
+                "start": 39,
+                "end": 51,
+                "value": "use strict",
+                "raw": "\"use strict\""
+              },
+              "directive": "use strict"
+            }
+          ]
+        }
+      },
+      "directive": undefined // check this property does not exist.
+    }
+  ]
+}, { ecmaVersion: 6 })
diff --git a/test/tests-es7.js b/test/tests-es7.js
index 32c2efb..4130cb2 100644
--- a/test/tests-es7.js
+++ b/test/tests-es7.js
@@ -342,6 +342,10 @@ test("a-- ** 2", {
   "sourceType": "script"
 }, {ecmaVersion: 7})
 
+testFail("x %* y", "Unexpected token (1:3)", { ecmaVersion: 7 });
+
+testFail("x %*= y", "Unexpected token (1:3)", { ecmaVersion: 7 });
+
 testFail("function foo(a=2) { 'use strict'; }", "Illegal 'use strict' directive in function with non-simple parameter list (1:0)", { ecmaVersion: 7 })
 testFail("(a=2) => { 'use strict'; }", "Illegal 'use strict' directive in function with non-simple parameter list (1:0)", { ecmaVersion: 7 })
 testFail("function foo({a}) { 'use strict'; }", "Illegal 'use strict' directive in function with non-simple parameter list (1:0)", { ecmaVersion: 7 })
diff --git a/test/tests-harmony.js b/test/tests-harmony.js
index 1f06847..6ed18e6 100644
--- a/test/tests-harmony.js
+++ b/test/tests-harmony.js
@@ -12692,13 +12692,13 @@ testFail("function hello() {'use strict'; ({ i: 10, s(eval) { } }); }", "Binding
 
 testFail("function a() { \"use strict\"; ({ b(t, t) { } }); }", "Argument name clash (1:37)", {ecmaVersion: 6});
 
-testFail("var super", "Unexpected token (1:4)", {ecmaVersion: 6});
+testFail("var super", "Unexpected keyword 'super' (1:4)", {ecmaVersion: 6});
 
-testFail("var default", "Unexpected token (1:4)", {ecmaVersion: 6});
+testFail("var default", "Unexpected keyword 'default' (1:4)", {ecmaVersion: 6});
 
 testFail("let default", "Unexpected token (1:4)", {ecmaVersion: 6});
 
-testFail("const default", "Unexpected token (1:6)", {ecmaVersion: 6});
+testFail("const default", "Unexpected keyword 'default' (1:6)", {ecmaVersion: 6});
 
 testFail("\"use strict\"; ({ v: eval } = obj)", "Assigning to eval in strict mode (1:20)", {ecmaVersion: 6});
 
@@ -12750,10 +12750,10 @@ testFail("yield 10", "Unexpected token (1:6)", {ecmaVersion: 6});
 
 testFail("void { [1, 2]: 3 };", "Unexpected token (1:9)", {ecmaVersion: 6});
 
-testFail("let [this] = [10]", "Unexpected token (1:5)", {ecmaVersion: 6});
+testFail("let [this] = [10]", "Unexpected keyword 'this' (1:5)", {ecmaVersion: 6});
 testFail("let {this} = x", "Unexpected keyword 'this' (1:5)", {ecmaVersion: 6});
-testFail("let [function] = [10]", "Unexpected token (1:5)", {ecmaVersion: 6});
-testFail("let [function] = x", "Unexpected token (1:5)", {ecmaVersion: 6});
+testFail("let [function] = [10]", "Unexpected keyword 'function' (1:5)", {ecmaVersion: 6});
+testFail("let [function] = x", "Unexpected keyword 'function' (1:5)", {ecmaVersion: 6});
 testFail("([function] = [10])", "Unexpected token (1:10)", {ecmaVersion: 6});
 testFail("([this] = [10])", "Assigning to rvalue (1:2)", {ecmaVersion: 6});
 testFail("({this} = x)", "Unexpected keyword 'this' (1:2)", {ecmaVersion: 6});
@@ -13183,7 +13183,8 @@ test("() => 42", {
   body: [{
     type: "ExpressionStatement",
     expression: {
-      type: "ArrowFunctionExpression"
+      type: "ArrowFunctionExpression",
+      expression: true
     }
   }]
 }, {ecmaVersion: 6, preserveParens: true});
@@ -13402,6 +13403,60 @@ test("var {propName = defaultValue} = obj", {
   locations: true
 });
 
+test("var {get = defaultValue} = obj", {
+  type: "Program",
+  range: [0, 30],
+  body: [{
+    type: "VariableDeclaration",
+    range: [0, 30],
+    declarations: [{
+      type: "VariableDeclarator",
+      range: [4, 30],
+      id: {
+        type: "ObjectPattern",
+        range: [4, 24],
+        properties: [{
+          type: "Property",
+          range: [5, 23],
+          method: false,
+          shorthand: true,
+          computed: false,
+          key: {
+            type: "Identifier",
+            range: [5, 8],
+            name: "get"
+          },
+          kind: "init",
+          value: {
+            type: "AssignmentPattern",
+            range: [5, 23],
+            left: {
+              type: "Identifier",
+              range: [5, 8],
+              name: "get"
+            },
+            right: {
+              type: "Identifier",
+              range: [11, 23],
+              name: "defaultValue"
+            }
+          }
+        }]
+      },
+      init: {
+        type: "Identifier",
+        range: [27, 30],
+        name: "obj"
+      }
+    }],
+    kind: "var"
+  }]
+}, {
+  ecmaVersion: 6,
+  ranges: true,
+  locations: true
+});
+
 test("var [localVar = defaultValue] = obj", {
   type: "Program",
   range: [0, 35],
@@ -14482,7 +14537,8 @@ test("(([,]) => 0)", {
         type: "Literal",
         value: 0,
         raw: "0"
-      }
+      },
+      expression: true
     }
   }]
 }, {ecmaVersion: 6});
@@ -15549,7 +15605,8 @@ test("function *f() { yield\n{}/1/g\n}", {
             "type": "ExpressionStatement",
             "expression": {
               "type": "YieldExpression",
-              "argument": null
+              "argument": null,
+              delegate: false
             }
           },
           {
@@ -15568,7 +15625,8 @@ test("function *f() { yield\n{}/1/g\n}", {
             }
           }
         ]
-      }
+      },
+      generator: true
     }
   ]
 }, {ecmaVersion: 6})
@@ -15738,3 +15796,42 @@ test("1 <!--b", {
     }
   }]
 }, {ecmaVersion: 6, sourceType: "module"})
+
+testFail("class A extends B { constructor() { super } }", "Unexpected token (1:42)", { ecmaVersion: 6 })
+testFail("class A extends B { constructor() { super; } }", "Unexpected token (1:41)", { ecmaVersion: 6 })
+testFail("class A extends B { constructor() { (super)() } }", "Unexpected token (1:42)", { ecmaVersion: 6 })
+testFail("class A extends B { foo() { (super).foo } }", "Unexpected token (1:34)", { ecmaVersion: 6 })
+test("({super: 1})", {}, { ecmaVersion: 6 })
+test("import {super as a} from 'a'", {}, { ecmaVersion: 6, sourceType: "module" })
+test("export {a as super}", {}, { ecmaVersion: 6, sourceType: "module" })
+test("let instanceof Foo", {
+  "type": "Program",
+  "start": 0,
+  "end": 18,
+  "body": [
+    {
+      "type": "ExpressionStatement",
+      "start": 0,
+      "end": 18,
+      "expression": {
+        "type": "BinaryExpression",
+        "start": 0,
+        "end": 18,
+        "left": {
+          "type": "Identifier",
+          "start": 0,
+          "end": 3,
+          "name": "let"
+        },
+        "operator": "instanceof",
+        "right": {
+          "type": "Identifier",
+          "start": 15,
+          "end": 18,
+          "name": "Foo"
+        }
+      }
+    }
+  ],
+  "sourceType": "script"
+}, {ecmaVersion: 6})
diff --git a/test/tests-template-literal-revision.js b/test/tests-template-literal-revision.js
index 3b4de1c..ce275c2 100644
--- a/test/tests-template-literal-revision.js
+++ b/test/tests-template-literal-revision.js
@@ -549,3 +549,8 @@ test("foo`\\unicode\\\\`", {
   ],
   sourceType: "script"
 }, {ecmaVersion: 9})
+
+test("`${ {class: 1} }`", {}, { ecmaVersion: 9 })
+test("`${ {delete: 1} }`", {}, { ecmaVersion: 9 })
+test("`${ {enum: 1} }`", {}, { ecmaVersion: 9 })
+test("`${ {function: 1} }`", {}, { ecmaVersion: 9 })
diff --git a/test/tests.js b/test/tests.js
index 4261ad4..25ac432 100644
--- a/test/tests.js
+++ b/test/tests.js
@@ -28966,7 +28966,7 @@ test('var x = (1 + 2)', {}, {
       }
     },
     {
-      type: {binop: 9, prefix: true, beforeExpr: true},
+      type: tokTypes.plusMin,
       value: "+",
       loc: {
         start: {line: 1, column: 11},
@@ -29217,3 +29217,4 @@ test("try {} catch (foo) { function x(foo) {} }", {}, {ecmaVersion: 6})
 test("'use strict'; let foo = function foo() {}", {}, {ecmaVersion: 6})
 
 test("/**/ --> comment\n", {})
+test("x.class++", {})

-- 
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