Compare commits

...

32 Commits

Author SHA1 Message Date
Nicolò Ribaudo
d896ce2b53 v7.3.2 2019-02-04 23:20:05 +01:00
Nicolò Ribaudo
44d8a59361 Use a GitHub Action to generate the changelog (#9434) [skip ci]
* Use a GitHub Action to generate the changelog

* Update main.workflow [skip ci]
2019-02-04 22:15:44 +01:00
Daniel Tschinder
344d35bbe9 Simplify await and yield tracking in params (#9405) 2019-02-04 22:01:17 +01:00
Thiago Arrais
fe71154626 Support for await and yield in pipelines (#9401) 2019-02-04 21:58:46 +01:00
gverni
65cbbc1ef8 Fix duplicate definition error in private class methods (#9453) 2019-02-04 09:19:04 -06:00
Nicolò Ribaudo
d37c958637 Transform private async and generator functions (#9423) 2019-02-04 15:10:46 +01:00
Daniel Tschinder
9eb010da50 Unify reserved word checking and update error messages (#9402)
* Unify reserved word checking and update error messages

* Fix test
2019-01-31 19:02:32 -08:00
Galymzhan Abdugalimov
7e9029e337 Switched gutil.log to fancyLog due to deprecation (#9432) 2019-01-30 08:23:02 -06:00
Galymzhan Abdugalimov
00c3e3c8e0 Fixed link to @babel/parser's issues in README (#9427) 2019-01-30 08:18:43 -06:00
Nicolò Ribaudo
7192546eb8 Run prettier again 2019-01-30 11:35:42 +01:00
Nicolò Ribaudo
4c4c22a316 Run prettier 2019-01-30 11:30:31 +01:00
Rizky
56044c7851 install polyfill & runtime to dependency instead of devDependency [skip ci] (#9409) 2019-01-29 08:09:08 -06:00
Daniel Tschinder
828169e611 Fix line continuation with Unicode line terminators (#9403) 2019-01-28 13:35:35 -08:00
Moti Zilberman
1452e977a0 Destructuring: Create assignments from ForX non-declaration patterns (#9414) 2019-01-28 09:50:24 +01:00
Brian Ng
ede69eef7f Bump deps (#9417) 2019-01-26 22:49:48 -05:00
Dylan Staley
03230eaa9c Retain JSX pragma if defined as a comment (#9095) 2019-01-26 15:36:10 -06:00
Brian Ng
7dc157f9be Fix location/range on TypeScript ExportNamedDeclarations (#9406) 2019-01-24 19:44:22 -06:00
Yuri Karadzhov
854313a759 Correctly visit param decorators to prevent their imports being removed in typescript transform (#8738)
* Remove types on program exit in typescript transform

* Revert changes to typescript transform

* Correctly add visitors for param decorators

* Fix plugin for node 6
2019-01-24 15:07:56 -08:00
Daniel Tschinder
46ba5940c2 Make yield a contextual keyword (#9400) 2019-01-23 14:33:23 -08:00
Daniel Tschinder
42c5d3fc4b Correctly fail for invalid yield in for (#9398) 2019-01-23 13:39:30 -08:00
Brian Ng
d4e045ac24 Fix support for Flow's QualifiedTypeIdentifier (#9396) 2019-01-23 15:19:17 -06:00
Daniel Tschinder
8bc9f9a05f fix: Allow toplevel await when option true and correctly mark await keyword as unexpected (#9371) 2019-01-22 14:56:30 -08:00
Daniel Tschinder
93e1b5e612 Merge pull request #9375 from danez/contextual-let
Make let a contextual keyword
2019-01-22 14:55:49 -08:00
Daniel Tschinder
4f69699b71 Fix parsing in non-declaration places 2019-01-22 13:12:03 -08:00
Daniel Tschinder
f4f5ca2aaa Parse class name in strict mode
The specification defines that the whole class declaration is parsed in strict mode
2019-01-22 13:12:03 -08:00
Daniel Tschinder
8071dca9ad Disallow const let or let let 2019-01-22 13:12:02 -08:00
Daniel Tschinder
178f2d7949 Make let a contextual keyword 2019-01-22 13:12:02 -08:00
Nicolò Ribaudo
65febdd13a Refactor import and export parsing (#9326)
* [parser] Refactor import parsing

* [parser] Refactor export parsing

* Fix types
2019-01-22 19:52:56 +01:00
Brian Ng
f77c450cda Bump prettier (#9373) 2019-01-22 09:16:32 -06:00
Nicolò Ribaudo
f2af6c1170 v7.3.1 2019-01-22 08:07:23 +01:00
Daniel Tschinder
43b83f8ed7 Revert "Differentiate object spread and non-spread properties (#9341)" (#9379)
This reverts commit 3ae5e79ec8.
2019-01-21 23:03:54 -08:00
Daniel Tschinder
af88e63dff fix new keyword broken by recent refactoring (#9377) 2019-01-21 22:25:37 -08:00
443 changed files with 5823 additions and 3790 deletions

View File

@@ -0,0 +1,18 @@
FROM node:10
LABEL "name" = "trigger-github-release"
LABEL "version" = "0.0.1"
LABEL "com.github.actions.name" = "Trigger GitHub release"
LABEL "com.github.actions.description" = "Trigger a new GitHub release and generate the changelog using lerna-changelog."
LABEL "com.github.actions.icon" = "tag"
LABEL "com.github.actions.color" = "yellow"
ADD entrypoint.sh /action/entrypoint.sh
ADD package.json /action/package.json
ADD package-lock.json /action/package-lock.json
ADD release.js /action/release.js
RUN chmod +x /action/entrypoint.sh
ENTRYPOINT ["/action/entrypoint.sh"]

View File

@@ -0,0 +1,29 @@
#!/bin/sh
set -e
echo "INFO: Installing action dependencies..."
(cd /action; npm ci)
echo "INFO: Checking out current tag..."
git -c advice.detachedHead=false checkout $GITHUB_REF
echo "INFO: Getting tag info..."
current_tag=$(git describe --abbrev=0 --tags)
last_tag=$(git describe --abbrev=0 --tags HEAD^)
echo "INFO: New version is $current_tag; last version is $last_tag."
echo "INFO: Generating the changelog..."
# lerna-changelog expects the token to be provided as GITHUB_AUTH,
# but GitHub actions don't allow to predefine custom env vars prefixed with
# GITHUB_. We need to define it here.
changelog=$(
GITHUB_AUTH="$GITHUB_TOKEN" \
node /action/node_modules/.bin/lerna-changelog --tag-from $last_tag --tag-to $current_tag
)
echo "INFO: Publishing the new GitHub release..."
echo "$changelog" | node /action/release $current_tag
echo "INFO: Done! Don't forget to thank new contributors :)"

1415
.github/actions/trigger-github-release/package-lock.json generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,12 @@
{
"private": true,
"name": "@internal/trigger-github-release",
"version": "0.0.1",
"author": "Nicolò Ribaudo <nicolo.ribaudo@gmail.com>",
"license": "MIT",
"dependencies": {
"@octokit/rest": "^16.3.0",
"get-stdin": "^6.0.0",
"lerna-changelog": "^0.8.2"
}
}

View File

@@ -0,0 +1,25 @@
"use strict";
const [ /* node */, /* file */, tag ] = process.argv;
const getStdin = require("get-stdin");
const octokit = require("@octokit/rest")();
octokit.authenticate({
type: "token",
token: process.env.GITHUB_TOKEN
});
const [ repoOwner, repoName ] = process.env.GITHUB_REPOSITORY.split("/");
getStdin()
.then(changelog => octokit.repos.createRelease({
owner: repoOwner,
repo: repoName,
tag_name: tag,
body: changelog,
}))
.catch(err => {
console.error(err);
process.exit(1);
});

26
.github/main.workflow vendored Normal file
View File

@@ -0,0 +1,26 @@
workflow "Release" {
on = "push"
resolves = ["Trigger GitHub release"]
}
action "Trigger GitHub release" {
uses = "./.github/actions/trigger-github-release/"
secrets = ["GITHUB_TOKEN"]
# When GitHub Actions will support the "release" event for public
# repositories, we won't need these checks anymore.
needs = [
"Is version tag",
"On master branch",
]
}
action "Is version tag" {
uses = "actions/bin/filter@master"
args = "tag v*"
}
action "On master branch" {
uses = "actions/bin/filter@master"
args = "branch master"
}

2
.gitignore vendored
View File

@@ -1,5 +1,6 @@
.DS_Store
/node_modules
/.github/actions/*/node_modules
/packages/*/node_modules
/packages/*/LICENSE
!/packages/babel-parser/LICENSE
@@ -15,6 +16,7 @@ coverage
dist
/.package.json
package-lock.json
!/.github/actions/*/package-lock.json
/packages/babel-runtime/helpers/*.js
!/packages/babel-runtime/helpers/toArray.js

View File

@@ -6,7 +6,7 @@ const chalk = require("chalk");
const newer = require("gulp-newer");
const babel = require("gulp-babel");
const gulpWatch = require("gulp-watch");
const gutil = require("gulp-util");
const fancyLog = require("fancy-log");
const filter = require("gulp-filter");
const gulp = require("gulp");
const path = require("path");
@@ -38,7 +38,7 @@ function getIndexFromPackage(name) {
function compilationLogger(rollup) {
return through.obj(function(file, enc, callback) {
gutil.log(
fancyLog(
`Compiling '${chalk.cyan(file.relative)}'${
rollup ? " with rollup " : ""
}...`
@@ -50,7 +50,7 @@ function compilationLogger(rollup) {
function errorsLogger() {
return plumber({
errorHandler(err) {
gutil.log(err.stack);
fancyLog(err.stack);
},
});
}

View File

@@ -1,5 +1,5 @@
{
"version": "7.3.0",
"version": "7.3.2",
"changelog": {
"repo": "babel/babel",
"cacheDir": ".changelog",

View File

@@ -9,55 +9,54 @@
"test": "make test"
},
"devDependencies": {
"@babel/cli": "^7.2.0",
"@babel/core": "^7.2.0",
"@babel/cli": "^7.2.3",
"@babel/core": "^7.2.2",
"@babel/eslint-plugin-development": "^1.0.1",
"@babel/plugin-proposal-class-properties": "^7.2.1",
"@babel/plugin-proposal-class-properties": "^7.3.0",
"@babel/plugin-proposal-export-namespace-from": "^7.2.0",
"@babel/plugin-proposal-numeric-separator": "^7.2.0",
"@babel/plugin-transform-modules-commonjs": "^7.2.0",
"@babel/plugin-transform-runtime": "^7.2.0",
"@babel/preset-env": "^7.2.0",
"@babel/preset-env": "^7.3.1",
"@babel/preset-flow": "^7.0.0",
"@babel/register": "^7.0.0",
"@babel/runtime": "^7.2.0",
"babel-core": "^7.0.0-0",
"babel-eslint": "^10.0.1",
"babel-jest": "^23.6.0",
"babel-loader": "^8.0.4",
"babel-plugin-transform-charcodes": "^0.1.1",
"browserify": "^16.2.2",
"@babel/runtime": "^7.3.1",
"babel-eslint": "^11.0.0-beta.0",
"babel-jest": "^24.0.0",
"babel-loader": "^8.0.5",
"babel-plugin-transform-charcodes": "^0.2.0",
"browserify": "^16.2.3",
"bundle-collapser": "^1.2.1",
"chalk": "^2.3.2",
"charcodes": "^0.1.1",
"charcodes": "^0.2.0",
"derequire": "^2.0.2",
"enhanced-resolve": "^3.0.0",
"eslint": "^5.9.0",
"eslint": "^5.12.1",
"eslint-config-babel": "^8.0.2",
"eslint-plugin-flowtype": "^3.2.0",
"eslint-plugin-prettier": "^3.0.0",
"eslint-plugin-flowtype": "^3.2.1",
"eslint-plugin-prettier": "^3.0.1",
"fancy-log": "^1.3.3",
"flow-bin": "^0.87.0",
"graceful-fs": "^4.1.11",
"graceful-fs": "^4.1.15",
"gulp": "^4.0.0",
"gulp-babel": "^8.0.0",
"gulp-filter": "^5.1.0",
"gulp-newer": "^1.0.0",
"gulp-plumber": "^1.2.0",
"gulp-plumber": "^1.2.1",
"gulp-rename": "^1.4.0",
"gulp-uglify": "^3.0.1",
"gulp-util": "^3.0.7",
"gulp-watch": "^5.0.1",
"husky": "^1.2.0",
"jest": "^23.6.0",
"husky": "^1.3.1",
"jest": "^24.0.0",
"lerna": "^3.6.0",
"lerna-changelog": "^0.5.0",
"lint-staged": "^8.1.0",
"lodash": "^4.17.10",
"lodash": "^4.17.11",
"merge-stream": "^1.0.1",
"output-file-sync": "^2.0.0",
"prettier": "^1.15.2",
"prettier": "^1.16.1",
"pump": "^3.0.0",
"rimraf": "^2.4.3",
"rimraf": "^2.6.3",
"rollup-plugin-babel": "^4.0.0-beta.0",
"rollup-plugin-node-resolve": "^3.0.2",
"rollup-stream": "^1.24.1",
@@ -108,7 +107,9 @@
"_browser\\.js"
],
"testEnvironment": "node",
"setupTestFrameworkScriptFile": "<rootDir>/test/testSetupFile.js",
"setupFilesAfterEnv": [
"<rootDir>/test/testSetupFile.js"
],
"transformIgnorePatterns": [
"/node_modules/",
"<rootDir>/packages/babel-standalone/babel(\\.min)?\\.js",
@@ -131,5 +132,6 @@
"moduleNameMapper": {
"^@babel/([a-zA-Z0-9_-]+)$": "<rootDir>/packages/babel-$1/"
}
}
},
"dependencies": {}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/generator",
"version": "7.3.0",
"version": "7.3.2",
"description": "Turns an AST into code.",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://babeljs.io/",
@@ -14,7 +14,7 @@
"lib"
],
"dependencies": {
"@babel/types": "^7.3.0",
"@babel/types": "^7.3.2",
"jsesc": "^2.5.1",
"lodash": "^4.17.10",
"source-map": "^0.5.0",
@@ -22,6 +22,6 @@
},
"devDependencies": {
"@babel/helper-fixtures": "^7.2.0",
"@babel/parser": "^7.3.0"
"@babel/parser": "^7.3.2"
}
}

View File

@@ -1,3 +1,4 @@
type A = interface { p: string };
type B = interface extends X { p: string };
type C = interface extends X, Y { p: string };
type D = interface extends X.Y<Z> { p: string };

View File

@@ -6,4 +6,7 @@ type B = interface extends X {
};
type C = interface extends X, Y {
p: string
};
};
type D = interface extends X.Y<Z> {
p: string
};

View File

@@ -14,3 +14,5 @@ type overloads =
;
type func = string => string;
type D = X.Y<Z>;

View File

@@ -9,3 +9,4 @@ type union = {
};
type overloads = (x: string) => number & (x: number) => string;
type func = (string) => string;
type D = X.Y<Z>;

View File

@@ -1,19 +1,19 @@
# @babel/plugin-class-features
# @babel/helper-create-class-features-plugin
> Compile class public and private fields, private methods and decorators to ES6
See our website [@babel/plugin-class-features](https://babeljs.io/docs/en/next/babel-plugin-class-features.html) for more information.
See our website [@babel/helper-create-class-features-plugin](https://babeljs.io/docs/en/next/babel-helper-create-class-features-plugin.html) for more information.
## Install
Using npm:
```sh
npm install --save-dev @babel/plugin-class-features
npm install --save-dev @babel/helper-create-class-features-plugin
```
or using yarn:
```sh
yarn add @babel/plugin-class-features --dev
yarn add @babel/helper-create-class-features-plugin --dev
```

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/helper-create-class-features-plugin",
"version": "7.3.0",
"version": "7.3.2",
"author": "The Babel Team (https://babeljs.io/team)",
"license": "MIT",
"description": "Compile class public and private fields, private methods and decorators to ES6",

View File

@@ -410,8 +410,14 @@ function buildPrivateInstanceMethodDeclaration(prop, privateNamesMap) {
getterDeclared,
setterDeclared,
} = privateName;
const { params, body } = prop.node;
const methodValue = t.functionExpression(methodId, params, body);
const { params, body, generator, async } = prop.node;
const methodValue = t.functionExpression(
methodId,
params,
body,
generator,
async,
);
const isGetter = getId && !getterDeclared && params.length === 0;
const isSetter = setId && !setterDeclared && params.length > 0;

View File

@@ -1,8 +1,4 @@
{
"presets": [
"flow"
],
"plugins": [
"proposal-class-properties"
]
"presets": ["flow"],
"plugins": ["proposal-class-properties"]
}

View File

@@ -1,8 +1,4 @@
{
"presets": [
"flow"
],
"plugins": [
"proposal-class-properties"
]
"presets": ["flow"],
"plugins": ["proposal-class-properties"]
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/helpers",
"version": "7.3.0",
"version": "7.3.1",
"description": "Collection of helper functions used by Babel transforms.",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://babeljs.io/",

View File

@@ -389,20 +389,16 @@ helpers.objectSpread = helper("7.0.0-beta.0")`
export default function _objectSpread(target) {
for (var i = 1; i < arguments.length; i++) {
if (i % 2) {
var source = (arguments[i] != null) ? arguments[i] : {};
var ownKeys = Object.keys(source);
if (typeof Object.getOwnPropertySymbols === 'function') {
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
}));
}
ownKeys.forEach(function(key) {
defineProperty(target, key, source[key]);
});
} else {
Object.defineProperties(target, Object.getOwnPropertyDescriptors(arguments[i]));
var source = (arguments[i] != null) ? arguments[i] : {};
var ownKeys = Object.keys(source);
if (typeof Object.getOwnPropertySymbols === 'function') {
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
}));
}
ownKeys.forEach(function(key) {
defineProperty(target, key, source[key]);
});
}
return target;
}

View File

@@ -2,7 +2,7 @@
> A JavaScript parser
See our website [@babel/parser](https://babeljs.io/docs/en/next/babel-parser.html) for more information or the [issues](https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A%20babylon%22+is%3Aopen) associated with this package.
See our website [@babel/parser](https://babeljs.io/docs/en/next/babel-parser.html) for more information or the [issues](https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen) associated with this package.
## Install

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/parser",
"version": "7.3.0",
"version": "7.3.2",
"description": "A JavaScript parser",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://babeljs.io/",

View File

@@ -1,8 +1,6 @@
// @flow
import type { Options } from "../options";
import { isES2015ReservedWord } from "../util/identifier";
import type State from "../tokenizer/state";
import type { PluginsMap } from "./index";
@@ -17,14 +15,6 @@ export default class BaseParser {
// Initialized by Tokenizer
state: State;
isReservedWord(word: string): boolean {
if (word === "await") {
return this.inModule;
} else {
return isES2015ReservedWord(word);
}
}
hasPlugin(name: string): boolean {
return this.plugins.has(name);
}

View File

@@ -22,9 +22,10 @@ import { types as tt, type TokenType } from "../tokenizer/types";
import * as N from "../types";
import LValParser from "./lval";
import {
isKeyword,
isReservedWord,
isStrictReservedWord,
isStrictBindReservedWord,
isKeyword,
} from "../util/identifier";
import type { Pos, Position } from "../util/location";
import * as charCodes from "charcodes";
@@ -126,12 +127,18 @@ export default class ExpressionParser extends LValParser {
): N.Expression {
const startPos = this.state.start;
const startLoc = this.state.startLoc;
if (this.match(tt._yield) && this.state.inGenerator) {
let left = this.parseYield();
if (afterLeftParse) {
left = afterLeftParse.call(this, left, startPos, startLoc);
if (this.isContextual("yield")) {
if (this.state.inGenerator) {
let left = this.parseYield(noIn);
if (afterLeftParse) {
left = afterLeftParse.call(this, left, startPos, startLoc);
}
return left;
} else {
// The tokenizer will assume an expression is allowed after
// `yield`, but this isn't that kind of yield
this.state.exprAllowed = false;
}
return left;
}
const oldCommaAfterSpreadAt = this.state.commaAfterSpreadAt;
@@ -145,7 +152,7 @@ export default class ExpressionParser extends LValParser {
failOnShorthandAssign = true;
}
if (this.match(tt.parenL) || this.match(tt.name) || this.match(tt._yield)) {
if (this.match(tt.parenL) || this.match(tt.name)) {
this.state.potentialArrowAt = this.state.start;
}
@@ -412,7 +419,13 @@ export default class ExpressionParser extends LValParser {
// Parse unary operators, both prefix and postfix.
parseMaybeUnary(refShorthandDefaultPos: ?Pos): N.Expression {
if (this.state.type.prefix) {
if (
this.isContextual("await") &&
(this.state.inAsync ||
(!this.state.inFunction && this.options.allowAwaitOutsideFunction))
) {
return this.parseAwait();
} else if (this.state.type.prefix) {
const node = this.startNode();
const update = this.match(tt.incDec);
node.operator = this.state.value;
@@ -584,9 +597,11 @@ export default class ExpressionParser extends LValParser {
return this.finishNode(node, "MemberExpression");
} else if (!noCalls && this.match(tt.parenL)) {
const oldMaybeInArrowParameters = this.state.maybeInArrowParameters;
const oldYOAIPAP = this.state.yieldOrAwaitInPossibleArrowParameters;
const oldYieldPos = this.state.yieldPos;
const oldAwaitPos = this.state.awaitPos;
this.state.maybeInArrowParameters = true;
this.state.yieldOrAwaitInPossibleArrowParameters = null;
this.state.yieldPos = 0;
this.state.awaitPos = 0;
const possibleAsync = this.atPossibleAsync(base);
this.next();
@@ -617,14 +632,16 @@ export default class ExpressionParser extends LValParser {
this.startNodeAt(startPos, startLoc),
node,
);
this.state.yieldOrAwaitInPossibleArrowParameters = oldYOAIPAP;
this.checkYieldAwaitInDefaultParams();
this.state.yieldPos = oldYieldPos;
this.state.awaitPos = oldAwaitPos;
} else {
this.toReferencedListDeep(node.arguments);
// We keep the old value if it isn't null, for cases like
// (x = async(yield)) => {}
this.state.yieldOrAwaitInPossibleArrowParameters =
this.state.yieldOrAwaitInPossibleArrowParameters || oldYOAIPAP;
this.state.yieldPos = oldYieldPos || this.state.yieldPos;
this.state.awaitPos = oldAwaitPos || this.state.awaitPos;
}
this.state.maybeInArrowParameters = oldMaybeInArrowParameters;
@@ -841,29 +858,12 @@ export default class ExpressionParser extends LValParser {
this.next();
return this.finishNode(node, "ThisExpression");
case tt._yield:
if (this.state.inGenerator) this.unexpected();
case tt.name: {
node = this.startNode();
const allowAwait =
this.state.value === "await" &&
(this.state.inAsync ||
(!this.state.inFunction && this.options.allowAwaitOutsideFunction));
const containsEsc = this.state.containsEsc;
const allowYield = this.shouldAllowYieldIdentifier();
const id = this.parseIdentifier(allowAwait || allowYield);
const id = this.parseIdentifier();
if (id.name === "await") {
if (
this.state.inAsync ||
this.inModule ||
(!this.state.inFunction && this.options.allowAwaitOutsideFunction)
) {
return this.parseAwait(node);
}
} else if (
if (
!containsEsc &&
id.name === "async" &&
this.match(tt._function) &&
@@ -877,25 +877,19 @@ export default class ExpressionParser extends LValParser {
this.match(tt.name) &&
!this.canInsertSemicolon()
) {
const oldYOAIPAP = this.state.yieldOrAwaitInPossibleArrowParameters;
const oldInAsync = this.state.inAsync;
this.state.yieldOrAwaitInPossibleArrowParameters = null;
this.state.inAsync = true;
const params = [this.parseIdentifier()];
this.expect(tt.arrow);
// let foo = async bar => {};
this.parseArrowExpression(node, params, true);
this.state.yieldOrAwaitInPossibleArrowParameters = oldYOAIPAP;
this.state.inAsync = oldInAsync;
return node;
}
if (canBeArrow && this.match(tt.arrow) && !this.canInsertSemicolon()) {
this.next();
const oldYOAIPAP = this.state.yieldOrAwaitInPossibleArrowParameters;
this.state.yieldOrAwaitInPossibleArrowParameters = null;
this.parseArrowExpression(node, [id]);
this.state.yieldOrAwaitInPossibleArrowParameters = oldYOAIPAP;
this.parseArrowExpression(node, [id], false);
return node;
}
@@ -1176,9 +1170,11 @@ export default class ExpressionParser extends LValParser {
this.expect(tt.parenL);
const oldMaybeInArrowParameters = this.state.maybeInArrowParameters;
const oldYOAIPAP = this.state.yieldOrAwaitInPossibleArrowParameters;
const oldYieldPos = this.state.yieldPos;
const oldAwaitPos = this.state.awaitPos;
this.state.maybeInArrowParameters = true;
this.state.yieldOrAwaitInPossibleArrowParameters = null;
this.state.yieldPos = 0;
this.state.awaitPos = 0;
const innerStartPos = this.state.start;
const innerStartLoc = this.state.startLoc;
@@ -1239,21 +1235,23 @@ export default class ExpressionParser extends LValParser {
this.shouldParseArrow() &&
(arrowNode = this.parseArrow(arrowNode))
) {
this.checkYieldAwaitInDefaultParams();
this.state.yieldPos = oldYieldPos;
this.state.awaitPos = oldAwaitPos;
for (const param of exprList) {
if (param.extra && param.extra.parenthesized) {
this.unexpected(param.extra.parenStart);
}
}
this.parseArrowExpression(arrowNode, exprList);
this.state.yieldOrAwaitInPossibleArrowParameters = oldYOAIPAP;
this.parseArrowExpression(arrowNode, exprList, false);
return arrowNode;
}
// We keep the old value if it isn't null, for cases like
// (x = (yield)) => {}
this.state.yieldOrAwaitInPossibleArrowParameters =
this.state.yieldOrAwaitInPossibleArrowParameters || oldYOAIPAP;
this.state.yieldPos = oldYieldPos || this.state.yieldPos;
this.state.awaitPos = oldAwaitPos || this.state.awaitPos;
if (!exprList.length) {
this.unexpected(this.state.lastTokStart);
@@ -1721,21 +1719,28 @@ export default class ExpressionParser extends LValParser {
const oldInMethod = this.state.inMethod;
const oldInAsync = this.state.inAsync;
const oldInGenerator = this.state.inGenerator;
const oldYieldPos = this.state.yieldPos;
const oldAwaitPos = this.state.awaitPos;
this.state.inFunction = true;
this.state.inMethod = node.kind || true;
this.state.inAsync = isAsync;
this.state.inGenerator = isGenerator;
this.state.yieldPos = 0;
this.state.awaitPos = 0;
this.initFunction(node, isAsync);
node.generator = !!isGenerator;
const allowModifiers = isConstructor; // For TypeScript parameter properties
this.parseFunctionParams((node: any), allowModifiers);
this.checkYieldAwaitInDefaultParams();
this.parseFunctionBodyAndFinish(node, type);
this.state.inFunction = oldInFunc;
this.state.inMethod = oldInMethod;
this.state.inAsync = oldInAsync;
this.state.inGenerator = oldInGenerator;
this.state.yieldPos = oldYieldPos;
this.state.awaitPos = oldAwaitPos;
return node;
}
@@ -1745,44 +1750,33 @@ export default class ExpressionParser extends LValParser {
// assignable list.
parseArrowExpression(
node: N.ArrowFunctionExpression,
params?: ?(N.Expression[]),
isAsync?: boolean = false,
params: ?(N.Expression[]),
isAsync: boolean,
): N.ArrowFunctionExpression {
// if we got there, it's no more "yield in possible arrow parameters";
// it's just "yield in arrow parameters"
const yOAIPAP = this.state.yieldOrAwaitInPossibleArrowParameters;
if (yOAIPAP) {
if (yOAIPAP.type === "YieldExpression") {
this.raise(
yOAIPAP.start,
"yield is not allowed in the parameters of an arrow function" +
" inside a generator",
);
} else {
this.raise(
yOAIPAP.start,
"await is not allowed in the parameters of an arrow function" +
" inside an async function",
);
}
}
this.initFunction(node, isAsync);
const oldInFunc = this.state.inFunction;
this.state.inFunction = true;
this.initFunction(node, isAsync);
if (params) this.setArrowFunctionParameters(node, params);
const oldInAsync = this.state.inAsync;
const oldInGenerator = this.state.inGenerator;
const oldMaybeInArrowParameters = this.state.maybeInArrowParameters;
const oldYieldPos = this.state.yieldPos;
const oldAwaitPos = this.state.awaitPos;
this.state.inFunction = true;
this.state.inAsync = isAsync;
this.state.inGenerator = false;
this.state.maybeInArrowParameters = false;
this.state.yieldPos = 0;
this.state.awaitPos = 0;
if (params) this.setArrowFunctionParameters(node, params);
this.parseFunctionBody(node, true);
this.state.inAsync = oldInAsync;
this.state.inGenerator = oldInGenerator;
this.state.inFunction = oldInFunc;
this.state.maybeInArrowParameters = oldMaybeInArrowParameters;
this.state.yieldPos = oldYieldPos;
this.state.awaitPos = oldAwaitPos;
return this.finishNode(node, "ArrowFunctionExpression");
}
@@ -1832,17 +1826,14 @@ export default class ExpressionParser extends LValParser {
if (isExpression) {
node.body = this.parseMaybeAssign();
} else {
// Start a new scope with regard to labels and the `inGenerator`
// Start a new scope with regard to labels
// flag (restore them to their old value afterwards).
const oldInGen = this.state.inGenerator;
const oldInFunc = this.state.inFunction;
const oldLabels = this.state.labels;
this.state.inGenerator = node.generator;
this.state.inFunction = true;
this.state.labels = [];
node.body = this.parseBlock(true);
this.state.inFunction = oldInFunc;
this.state.inGenerator = oldInGen;
this.state.labels = oldLabels;
}
@@ -1952,15 +1943,6 @@ export default class ExpressionParser extends LValParser {
}
parseIdentifierName(pos: number, liberal?: boolean): string {
if (!liberal) {
this.checkReservedWord(
this.state.value,
this.state.start,
!!this.state.type.keyword,
false,
);
}
let name: string;
if (this.match(tt.name)) {
@@ -1985,11 +1967,17 @@ export default class ExpressionParser extends LValParser {
throw this.unexpected();
}
if (!liberal && name === "await" && this.state.inAsync) {
this.raise(pos, "invalid use of await inside of an async function");
if (!liberal) {
this.checkReservedWord(
name,
this.state.start,
!!this.state.type.keyword,
false,
);
}
this.next();
return name;
}
@@ -1999,43 +1987,58 @@ export default class ExpressionParser extends LValParser {
checkKeywords: boolean,
isBinding: boolean,
): void {
if (
this.state.strict &&
(isStrictReservedWord(word) ||
(isBinding && isStrictBindReservedWord(word)))
) {
this.raise(startLoc, word + " is a reserved word in strict mode");
}
if (this.state.inGenerator && word === "yield") {
const state = this.state;
if (state.inGenerator && word === "yield") {
this.raise(
startLoc,
"yield is a reserved word inside generator functions",
"Can not use 'yield' as identifier inside a generator",
);
}
if (this.state.inClassProperty && word === "arguments") {
if (state.inAsync && word === "await") {
this.raise(
startLoc,
"Can not use 'await' as identifier inside an async function",
);
}
if (state.inClassProperty && word === "arguments") {
this.raise(
startLoc,
"'arguments' is not allowed in class field initializer",
);
}
if (checkKeywords && isKeyword(word)) {
this.raise(startLoc, `Unexpected keyword '${word}'`);
}
if (this.isReservedWord(word) || (checkKeywords && isKeyword(word))) {
this.raise(startLoc, word + " is a reserved word");
const reservedTest = !state.strict
? isReservedWord
: isBinding
? isStrictBindReservedWord
: isStrictReservedWord;
if (reservedTest(word, this.inModule)) {
if (!state.inAsync && word === "await") {
this.raise(
startLoc,
"Can not use keyword 'await' outside an async function",
);
}
this.raise(startLoc, `Unexpected reserved word '${word}'`);
}
}
// Parses await expression inside async function.
parseAwait(node: N.AwaitExpression): N.AwaitExpression {
// istanbul ignore next: this condition is checked at the call site so won't be hit here
if (
!this.state.inAsync &&
(this.state.inFunction || !this.options.allowAwaitOutsideFunction)
) {
this.unexpected();
parseAwait(): N.AwaitExpression {
if (!this.state.awaitPos) {
this.state.awaitPos = this.state.start;
}
const node = this.startNode();
this.next();
if (this.state.inParameters) {
this.raise(
node.start,
@@ -2048,14 +2051,6 @@ export default class ExpressionParser extends LValParser {
"await* has been removed from the async functions proposal. Use Promise.all() instead.",
);
}
if (
this.state.maybeInArrowParameters &&
// We only set yieldOrAwaitInPossibleArrowParameters if we haven't already
// found a possible invalid AwaitExpression.
!this.state.yieldOrAwaitInPossibleArrowParameters
) {
this.state.yieldOrAwaitInPossibleArrowParameters = node;
}
node.argument = this.parseMaybeUnary();
return this.finishNode(node, "AwaitExpression");
@@ -2063,20 +2058,15 @@ export default class ExpressionParser extends LValParser {
// Parses yield expression inside generator.
parseYield(): N.YieldExpression {
parseYield(noIn?: ?boolean): N.YieldExpression {
if (!this.state.yieldPos) {
this.state.yieldPos = this.state.start;
}
const node = this.startNode();
if (this.state.inParameters) {
this.raise(node.start, "yield is not allowed in generator parameters");
}
if (
this.state.maybeInArrowParameters &&
// We only set yieldOrAwaitInPossibleArrowParameters if we haven't already
// found a possible invalid YieldExpression.
!this.state.yieldOrAwaitInPossibleArrowParameters
) {
this.state.yieldOrAwaitInPossibleArrowParameters = node;
}
this.next();
if (
@@ -2088,7 +2078,7 @@ export default class ExpressionParser extends LValParser {
node.argument = null;
} else {
node.delegate = this.eat(tt.star);
node.argument = this.parseMaybeAssign();
node.argument = this.parseMaybeAssign(noIn);
}
return this.finishNode(node, "YieldExpression");
}

View File

@@ -14,16 +14,11 @@ import type {
SpreadElement,
} from "../types";
import type { Pos, Position } from "../util/location";
import { isStrictBindReservedWord } from "../util/identifier";
import { NodeUtils } from "./node";
export default class LValParser extends NodeUtils {
// Forward-declaration: defined in expression.js
+checkReservedWord: (
word: string,
startLoc: number,
checkKeywords: boolean,
isBinding: boolean,
) => void;
+parseIdentifier: (liberal?: boolean) => Identifier;
+parseMaybeAssign: (
noIn?: ?boolean,
@@ -224,22 +219,11 @@ export default class LValParser extends NodeUtils {
return this.finishNode(node, "RestElement");
}
shouldAllowYieldIdentifier(): boolean {
return (
this.match(tt._yield) && !this.state.strict && !this.state.inGenerator
);
}
parseBindingIdentifier(): Identifier {
return this.parseIdentifier(this.shouldAllowYieldIdentifier());
}
// Parses lvalue (assignable) atom.
parseBindingAtom(): Pattern {
switch (this.state.type) {
case tt._yield:
case tt.name:
return this.parseBindingIdentifier();
return this.parseIdentifier();
case tt.bracketL: {
const node = this.startNode();
@@ -347,7 +331,17 @@ export default class LValParser extends NodeUtils {
): void {
switch (expr.type) {
case "Identifier":
this.checkReservedWord(expr.name, expr.start, false, true);
if (
this.state.strict &&
isStrictBindReservedWord(expr.name, this.inModule)
) {
this.raise(
expr.start,
`${isBinding ? "Binding" : "Assigning to"} '${
expr.name
}' in strict mode`,
);
}
if (checkClashes) {
// we need to prefix this with an underscore for the cases where we have a key of

View File

@@ -91,12 +91,16 @@ export class NodeUtils extends UtilParser {
return node;
}
resetStartLocation(node: NodeBase, start: number, startLoc: Position): void {
node.start = start;
node.loc.start = startLoc;
if (this.options.ranges) node.range[0] = start;
}
/**
* Reset the start location of node to the start location of locationNode
*/
resetStartLocationFromNode(node: NodeBase, locationNode: NodeBase): void {
node.start = locationNode.start;
node.loc.start = locationNode.loc.start;
if (this.options.ranges) node.range[0] = locationNode.range[0];
this.resetStartLocation(node, locationNode.start, locationNode.loc.start);
}
}

View File

@@ -3,8 +3,13 @@
import * as N from "../types";
import { types as tt, type TokenType } from "../tokenizer/types";
import ExpressionParser from "./expression";
import { isIdentifierChar } from "../util/identifier";
import {
isIdentifierChar,
isIdentifierStart,
keywordRelationalOperator,
} from "../util/identifier";
import { lineBreak, skipWhiteSpace } from "../util/whitespace";
import * as charCodes from "charcodes";
// Reused empty array added for node fields that are always empty.
@@ -71,6 +76,39 @@ export default class StatementParser extends ExpressionParser {
return this.finishNode(node, "InterpreterDirective");
}
isLet(declaration?: boolean): boolean {
if (!this.isContextual("let")) {
return false;
}
skipWhiteSpace.lastIndex = this.state.pos;
const skip = skipWhiteSpace.exec(this.state.input);
// $FlowIgnore
const next = this.state.pos + skip[0].length;
const nextCh = this.state.input.charCodeAt(next);
if (
(nextCh === charCodes.leftCurlyBrace &&
!lineBreak.test(this.state.input.slice(this.state.end, next))) ||
nextCh === charCodes.leftSquareBracket
) {
return true;
}
if (isIdentifierStart(nextCh)) {
if (
!declaration &&
lineBreak.test(this.state.input.slice(this.state.end, next))
) {
return false;
}
let pos = next + 1;
while (isIdentifierChar(this.state.input.charCodeAt(pos))) {
++pos;
}
const ident = this.state.input.slice(next, pos);
if (!keywordRelationalOperator.test(ident)) return true;
}
return false;
}
// Parse a single statement.
//
// If expecting a statement and finding a slash operator, parse a
@@ -86,8 +124,14 @@ export default class StatementParser extends ExpressionParser {
}
parseStatementContent(declaration: boolean, topLevel: ?boolean): N.Statement {
const starttype = this.state.type;
let starttype = this.state.type;
const node = this.startNode();
let kind;
if (this.isLet(declaration)) {
starttype = tt._var;
kind = "let";
}
// Most types of statements are recognized by the keyword they
// start with. Many are trivial to parse, some require a bit of
@@ -129,12 +173,11 @@ export default class StatementParser extends ExpressionParser {
case tt._try:
return this.parseTryStatement(node);
case tt._let:
case tt._const:
if (!declaration) this.unexpected(); // NOTE: falls through to _var
case tt._var:
return this.parseVarStatement(node, starttype);
kind = kind || this.state.value;
if (!declaration && kind !== "var") this.unexpected();
return this.parseVarStatement(node, kind);
case tt._while:
return this.parseWhileStatement(node);
@@ -410,32 +453,36 @@ export default class StatementParser extends ExpressionParser {
this.next();
this.state.labels.push(loopLabel);
let forAwait = false;
if (this.state.inAsync && this.isContextual("await")) {
forAwait = true;
this.next();
let awaitAt = -1;
if (
(this.state.inAsync ||
(!this.state.inFunction && this.options.allowAwaitOutsideFunction)) &&
this.eatContextual("await")
) {
awaitAt = this.state.lastTokStart;
}
this.expect(tt.parenL);
if (this.match(tt.semi)) {
if (forAwait) {
this.unexpected();
if (awaitAt > -1) {
this.unexpected(awaitAt);
}
return this.parseFor(node, null);
}
if (this.match(tt._var) || this.match(tt._let) || this.match(tt._const)) {
const isLet = this.isLet();
if (this.match(tt._var) || this.match(tt._const) || isLet) {
const init = this.startNode();
const varKind = this.state.type;
const kind = isLet ? "let" : this.state.value;
this.next();
this.parseVar(init, true, varKind);
this.parseVar(init, true, kind);
this.finishNode(init, "VariableDeclaration");
if (this.match(tt._in) || this.isContextual("of")) {
if (init.declarations.length === 1) {
const declaration = init.declarations[0];
const isForInInitializer =
varKind === tt._var &&
kind === "var" &&
declaration.init &&
declaration.id.type != "ObjectPattern" &&
declaration.id.type != "ArrayPattern" &&
@@ -443,12 +490,12 @@ export default class StatementParser extends ExpressionParser {
if (this.state.strict && isForInInitializer) {
this.raise(this.state.start, "for-in initializer in strict mode");
} else if (isForInInitializer || !declaration.init) {
return this.parseForIn(node, init, forAwait);
return this.parseForIn(node, init, awaitAt);
}
}
}
if (forAwait) {
this.unexpected();
if (awaitAt > -1) {
this.unexpected(awaitAt);
}
return this.parseFor(node, init);
}
@@ -461,12 +508,12 @@ export default class StatementParser extends ExpressionParser {
: "for-in statement";
this.toAssignable(init, undefined, description);
this.checkLVal(init, undefined, undefined, description);
return this.parseForIn(node, init, forAwait);
return this.parseForIn(node, init, awaitAt);
} else if (refShorthandDefaultPos.start) {
this.unexpected(refShorthandDefaultPos.start);
}
if (forAwait) {
this.unexpected();
if (awaitAt > -1) {
this.unexpected(awaitAt);
}
return this.parseFor(node, init);
}
@@ -606,7 +653,7 @@ export default class StatementParser extends ExpressionParser {
parseVarStatement(
node: N.VariableDeclaration,
kind: TokenType,
kind: "var" | "let" | "const",
): N.VariableDeclaration {
this.next();
this.parseVar(node, false, kind);
@@ -828,16 +875,16 @@ export default class StatementParser extends ExpressionParser {
parseForIn(
node: N.ForInOf,
init: N.VariableDeclaration,
forAwait: boolean,
awaitAt: number,
): N.ForInOf {
const type = this.match(tt._in) ? "ForInStatement" : "ForOfStatement";
if (forAwait) {
if (awaitAt > -1) {
this.eatContextual("of");
} else {
this.next();
}
if (type === "ForOfStatement") {
node.await = !!forAwait;
node.await = awaitAt > -1;
}
node.left = init;
node.right = this.parseExpression();
@@ -862,20 +909,19 @@ export default class StatementParser extends ExpressionParser {
parseVar(
node: N.VariableDeclaration,
isFor: boolean,
kind: TokenType,
kind: "var" | "let" | "const",
): N.VariableDeclaration {
const declarations = (node.declarations = []);
const isTypescript = this.hasPlugin("typescript");
// $FlowFixMe
node.kind = kind.keyword;
node.kind = kind;
for (;;) {
const decl = this.startNode();
this.parseVarHead(decl);
this.parseVarId(decl, kind);
if (this.eat(tt.eq)) {
decl.init = this.parseMaybeAssign(isFor);
} else {
if (
kind === tt._const &&
kind === "const" &&
!(this.match(tt._in) || this.isContextual("of"))
) {
// `const` with no initializer is allowed in TypeScript.
@@ -900,7 +946,10 @@ export default class StatementParser extends ExpressionParser {
return node;
}
parseVarHead(decl: N.VariableDeclarator): void {
parseVarId(decl: N.VariableDeclarator, kind: "var" | "let" | "const"): void {
if ((kind === "const" || kind === "let") && this.isContextual("let")) {
this.unexpected(null, "let is disallowed as a lexically bound name");
}
decl.id = this.parseBindingAtom();
this.checkLVal(decl.id, true, undefined, "variable declaration");
}
@@ -920,23 +969,19 @@ export default class StatementParser extends ExpressionParser {
const oldInAsync = this.state.inAsync;
const oldInGenerator = this.state.inGenerator;
const oldInClassProperty = this.state.inClassProperty;
const oldYieldPos = this.state.yieldPos;
const oldAwaitPos = this.state.awaitPos;
this.state.inFunction = true;
this.state.inMethod = false;
this.state.inClassProperty = false;
this.state.yieldPos = 0;
this.state.awaitPos = 0;
this.initFunction(node, isAsync);
if (this.match(tt.star)) {
node.generator = true;
this.next();
}
node.generator = this.eat(tt.star);
if (
isStatement &&
!optionalId &&
!this.match(tt.name) &&
!this.match(tt._yield)
) {
if (isStatement && !optionalId && !this.match(tt.name)) {
this.unexpected();
}
@@ -953,8 +998,8 @@ export default class StatementParser extends ExpressionParser {
this.state.inAsync = isAsync;
this.state.inGenerator = node.generator;
}
if (this.match(tt.name) || this.match(tt._yield)) {
node.id = this.parseBindingIdentifier();
if (this.match(tt.name)) {
node.id = this.parseIdentifier();
}
if (isStatement) {
this.state.inAsync = isAsync;
@@ -980,6 +1025,8 @@ export default class StatementParser extends ExpressionParser {
this.state.inAsync = oldInAsync;
this.state.inGenerator = oldInGenerator;
this.state.inClassProperty = oldInClassProperty;
this.state.yieldPos = oldYieldPos;
this.state.awaitPos = oldAwaitPos;
return node;
}
@@ -996,6 +1043,7 @@ export default class StatementParser extends ExpressionParser {
);
this.state.inParameters = oldInParameters;
this.checkYieldAwaitInDefaultParams();
}
// Parse a class declaration or literal (depending on the
@@ -1008,12 +1056,12 @@ export default class StatementParser extends ExpressionParser {
): T {
this.next();
this.takeDecorators(node);
this.parseClassId(node, isStatement, optionalId);
// class bodies and heritages are implicitly strict
// A class definition is always strict mode code.
const oldStrict = this.state.strict;
this.state.strict = true;
this.parseClassId(node, isStatement, optionalId);
this.parseClassSuper(node);
this.parseClassBody(node);
@@ -1470,35 +1518,109 @@ export default class StatementParser extends ExpressionParser {
// Parses module export declaration.
// TODO: better type. Node is an N.AnyExport.
parseExport(node: N.Node): N.Node {
// export * from '...'
if (this.shouldParseExportStar()) {
this.parseExportStar(node);
if (node.type === "ExportAllDeclaration") return node;
} else if (this.isExportDefaultSpecifier()) {
this.expectPlugin("exportDefaultFrom");
const specifier = this.startNode();
specifier.exported = this.parseIdentifier(true);
const specifiers = [this.finishNode(specifier, "ExportDefaultSpecifier")];
node.specifiers = specifiers;
if (this.match(tt.comma) && this.lookahead().type === tt.star) {
this.expect(tt.comma);
const specifier = this.startNode();
this.expect(tt.star);
this.expectContextual("as");
specifier.exported = this.parseIdentifier();
specifiers.push(this.finishNode(specifier, "ExportNamespaceSpecifier"));
} else {
this.parseExportSpecifiersMaybe(node);
}
parseExport(node: N.Node): N.AnyExport {
const hasDefault = this.maybeParseExportDefaultSpecifier(node);
const parseAfterDefault = !hasDefault || this.eat(tt.comma);
const hasStar = parseAfterDefault && this.eatExportStar(node);
const hasNamespace =
hasStar && this.maybeParseExportNamespaceSpecifier(node);
const parseAfterNamespace =
parseAfterDefault && (!hasNamespace || this.eat(tt.comma));
const isFromRequired = hasDefault || hasStar;
if (hasStar && !hasNamespace) {
if (hasDefault) this.unexpected();
this.parseExportFrom(node, true);
} else if (this.eat(tt._default)) {
return this.finishNode(node, "ExportAllDeclaration");
}
const hasSpecifiers = this.maybeParseExportNamedSpecifiers(node);
if (
(hasDefault && parseAfterDefault && !hasStar && !hasSpecifiers) ||
(hasNamespace && parseAfterNamespace && !hasSpecifiers)
) {
throw this.unexpected(null, tt.braceL);
}
let hasDeclaration;
if (isFromRequired || hasSpecifiers) {
hasDeclaration = false;
this.parseExportFrom(node, isFromRequired);
} else {
hasDeclaration = this.maybeParseExportDeclaration(node);
}
if (isFromRequired || hasSpecifiers || hasDeclaration) {
this.checkExport(node, true);
return this.finishNode(node, "ExportNamedDeclaration");
}
if (this.eat(tt._default)) {
// export default ...
node.declaration = this.parseExportDefaultExpression();
this.checkExport(node, true, true);
return this.finishNode(node, "ExportDefaultDeclaration");
} else if (this.shouldParseExportDeclaration()) {
}
throw this.unexpected(null, tt.braceL);
}
// eslint-disable-next-line no-unused-vars
eatExportStar(node: N.Node): boolean {
return this.eat(tt.star);
}
maybeParseExportDefaultSpecifier(node: N.Node): boolean {
if (this.isExportDefaultSpecifier()) {
// export defaultObj ...
this.expectPlugin("exportDefaultFrom");
const specifier = this.startNode();
specifier.exported = this.parseIdentifier(true);
node.specifiers = [this.finishNode(specifier, "ExportDefaultSpecifier")];
return true;
}
return false;
}
maybeParseExportNamespaceSpecifier(node: N.Node): boolean {
if (this.isContextual("as")) {
if (!node.specifiers) node.specifiers = [];
this.expectPlugin("exportNamespaceFrom");
const specifier = this.startNodeAt(
this.state.lastTokStart,
this.state.lastTokStartLoc,
);
this.next();
specifier.exported = this.parseIdentifier(true);
node.specifiers.push(
this.finishNode(specifier, "ExportNamespaceSpecifier"),
);
return true;
}
return false;
}
maybeParseExportNamedSpecifiers(node: N.Node): boolean {
if (this.match(tt.braceL)) {
if (!node.specifiers) node.specifiers = [];
node.specifiers.push(...this.parseExportSpecifiers());
node.source = null;
node.declaration = null;
return true;
}
return false;
}
maybeParseExportDeclaration(node: N.Node): boolean {
if (this.shouldParseExportDeclaration()) {
if (this.isContextual("async")) {
const next = this.lookahead();
@@ -1511,14 +1633,10 @@ export default class StatementParser extends ExpressionParser {
node.specifiers = [];
node.source = null;
node.declaration = this.parseExportDeclaration(node);
} else {
// export { x, y as z } [from '...']
node.declaration = null;
node.specifiers = this.parseExportSpecifiers();
this.parseExportFrom(node);
return true;
}
this.checkExport(node, true);
return this.finishNode(node, "ExportNamedDeclaration");
return false;
}
isAsyncFunction() {
@@ -1568,11 +1686,7 @@ export default class StatementParser extends ExpressionParser {
}
this.parseDecorators(false);
return this.parseClass(expr, true, true);
} else if (
this.match(tt._let) ||
this.match(tt._const) ||
this.match(tt._var)
) {
} else if (this.match(tt._const) || this.match(tt._var) || this.isLet()) {
return this.raise(
this.state.start,
"Only expressions, functions or classes are allowed as the `default` export.",
@@ -1591,7 +1705,7 @@ export default class StatementParser extends ExpressionParser {
isExportDefaultSpecifier(): boolean {
if (this.match(tt.name)) {
return this.state.value !== "async";
return this.state.value !== "async" && this.state.value !== "let";
}
if (!this.match(tt._default)) {
@@ -1605,17 +1719,9 @@ export default class StatementParser extends ExpressionParser {
);
}
parseExportSpecifiersMaybe(node: N.ExportNamedDeclaration): void {
if (this.eat(tt.comma)) {
node.specifiers = node.specifiers.concat(this.parseExportSpecifiers());
}
}
parseExportFrom(node: N.ExportNamedDeclaration, expect?: boolean): void {
if (this.eatContextual("from")) {
node.source = this.match(tt.string)
? this.parseExprAtom()
: this.unexpected();
node.source = this.parseImportSource();
this.checkExport(node);
} else {
if (expect) {
@@ -1628,39 +1734,6 @@ export default class StatementParser extends ExpressionParser {
this.semicolon();
}
shouldParseExportStar(): boolean {
return this.match(tt.star);
}
parseExportStar(node: N.ExportNamedDeclaration): void {
this.expect(tt.star);
if (this.isContextual("as")) {
this.parseExportNamespace(node);
} else {
this.parseExportFrom(node, true);
this.finishNode(node, "ExportAllDeclaration");
}
}
parseExportNamespace(node: N.ExportNamedDeclaration): void {
this.expectPlugin("exportNamespaceFrom");
const specifier = this.startNodeAt(
this.state.lastTokStart,
this.state.lastTokStartLoc,
);
this.next();
specifier.exported = this.parseIdentifier(true);
node.specifiers = [this.finishNode(specifier, "ExportNamespaceSpecifier")];
this.parseExportSpecifiersMaybe(node);
this.parseExportFrom(node, true);
}
shouldParseExportDeclaration(): boolean {
if (this.match(tt.at)) {
this.expectOnePlugin(["decorators", "decorators-legacy"]);
@@ -1681,9 +1754,9 @@ export default class StatementParser extends ExpressionParser {
return (
this.state.type.keyword === "var" ||
this.state.type.keyword === "const" ||
this.state.type.keyword === "let" ||
this.state.type.keyword === "function" ||
this.state.type.keyword === "class" ||
this.isLet() ||
this.isAsyncFunction()
);
}
@@ -1760,27 +1833,24 @@ export default class StatementParser extends ExpressionParser {
}
checkDuplicateExports(
node: N.Identifier | N.ExportNamedDeclaration | N.ExportSpecifier,
node:
| N.Identifier
| N.ExportNamedDeclaration
| N.ExportSpecifier
| N.ExportDefaultSpecifier,
name: string,
): void {
if (this.state.exportedIdentifiers.indexOf(name) > -1) {
this.raiseDuplicateExportError(node, name);
throw this.raise(
node.start,
name === "default"
? "Only one default export allowed per module."
: `\`${name}\` has already been exported. Exported identifiers must be unique.`,
);
}
this.state.exportedIdentifiers.push(name);
}
raiseDuplicateExportError(
node: N.Identifier | N.ExportNamedDeclaration | N.ExportSpecifier,
name: string,
): empty {
throw this.raise(
node.start,
name === "default"
? "Only one default export allowed per module."
: `\`${name}\` has already been exported. Exported identifiers must be unique.`,
);
}
// Parses a comma-separated list of module exports.
parseExportSpecifiers(): Array<N.ExportSpecifier> {
@@ -1820,23 +1890,26 @@ export default class StatementParser extends ExpressionParser {
// Parses import declaration.
parseImport(node: N.Node): N.ImportDeclaration | N.TsImportEqualsDeclaration {
parseImport(node: N.Node): N.AnyImport {
// import '...'
if (this.match(tt.string)) {
node.specifiers = [];
node.source = this.parseExprAtom();
} else {
node.specifiers = [];
this.parseImportSpecifiers(node);
node.specifiers = [];
if (!this.match(tt.string)) {
const hasDefault = this.maybeParseDefaultImportSpecifier(node);
const parseNext = !hasDefault || this.eat(tt.comma);
const hasStar = parseNext && this.maybeParseStarImportSpecifier(node);
if (parseNext && !hasStar) this.parseNamedImportSpecifiers(node);
this.expectContextual("from");
node.source = this.match(tt.string)
? this.parseExprAtom()
: this.unexpected();
}
node.source = this.parseImportSource();
this.semicolon();
return this.finishNode(node, "ImportDeclaration");
}
parseImportSource(): N.StringLiteral {
if (!this.match(tt.string)) this.unexpected();
return this.parseExprAtom();
}
// eslint-disable-next-line no-unused-vars
shouldParseDefaultImport(node: N.ImportDeclaration): boolean {
return this.match(tt.name);
@@ -1853,9 +1926,7 @@ export default class StatementParser extends ExpressionParser {
node.specifiers.push(this.finishNode(specifier, type));
}
// Parses a comma-separated list of module imports.
parseImportSpecifiers(node: N.ImportDeclaration): void {
let first = true;
maybeParseDefaultImportSpecifier(node: N.ImportDeclaration): boolean {
if (this.shouldParseDefaultImport(node)) {
// import defaultObj, { x, y as z } from '...'
this.parseImportSpecifierLocal(
@@ -1864,10 +1935,12 @@ export default class StatementParser extends ExpressionParser {
"ImportDefaultSpecifier",
"default import specifier",
);
if (!this.eat(tt.comma)) return;
return true;
}
return false;
}
maybeParseStarImportSpecifier(node: N.ImportDeclaration): boolean {
if (this.match(tt.star)) {
const specifier = this.startNode();
this.next();
@@ -1879,10 +1952,13 @@ export default class StatementParser extends ExpressionParser {
"ImportNamespaceSpecifier",
"import namespace specifier",
);
return;
return true;
}
return false;
}
parseNamedImportSpecifiers(node: N.ImportDeclaration) {
let first = true;
this.expect(tt.braceL);
while (!this.eat(tt.braceR)) {
if (first) {

View File

@@ -147,4 +147,22 @@ export default class UtilParser extends Tokenizer {
);
}
}
checkYieldAwaitInDefaultParams() {
if (
this.state.yieldPos &&
(!this.state.awaitPos || this.state.yieldPos < this.state.awaitPos)
) {
this.raise(
this.state.yieldPos,
"Yield cannot be used as name inside a generator function",
);
}
if (this.state.awaitPos) {
this.raise(
this.state.awaitPos,
"Await cannot be used as name inside an async function",
);
}
}
}

View File

@@ -344,7 +344,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
} else {
if (
this.match(tt._const) ||
this.match(tt._let) ||
this.isLet() ||
((this.isContextual("type") || this.isContextual("interface")) &&
!insideModule)
) {
@@ -1847,17 +1847,15 @@ export default (superClass: Class<Parser>): Class<Parser> =>
super.assertModuleNodeAllowed(node);
}
parseExport(
node: N.ExportNamedDeclaration | N.ExportAllDeclaration,
): N.ExportNamedDeclaration | N.ExportAllDeclaration {
node = super.parseExport(node);
parseExport(node: N.Node): N.AnyExport {
const decl = super.parseExport(node);
if (
node.type === "ExportNamedDeclaration" ||
node.type === "ExportAllDeclaration"
decl.type === "ExportNamedDeclaration" ||
decl.type === "ExportAllDeclaration"
) {
node.exportKind = node.exportKind || "value";
decl.exportKind = decl.exportKind || "value";
}
return node;
return decl;
}
parseExportDeclaration(node: N.ExportNamedDeclaration): ?N.Declaration {
@@ -1893,27 +1891,26 @@ export default (superClass: Class<Parser>): Class<Parser> =>
}
}
shouldParseExportStar(): boolean {
return (
super.shouldParseExportStar() ||
(this.isContextual("type") && this.lookahead().type === tt.star)
);
}
eatExportStar(node: N.Node): boolean {
if (super.eatExportStar(...arguments)) return true;
parseExportStar(node: N.ExportNamedDeclaration): void {
if (this.eatContextual("type")) {
if (this.isContextual("type") && this.lookahead().type === tt.star) {
node.exportKind = "type";
this.next();
this.next();
return true;
}
return super.parseExportStar(node);
return false;
}
parseExportNamespace(node: N.ExportNamedDeclaration) {
if (node.exportKind === "type") {
this.unexpected();
maybeParseExportNamespaceSpecifier(node: N.Node): boolean {
const pos = this.state.start;
const hasNamespace = super.maybeParseExportNamespaceSpecifier(node);
if (hasNamespace && node.exportKind === "type") {
this.unexpected(pos);
}
return super.parseExportNamespace(node);
return hasNamespace;
}
parseClassId(node: N.Class, isStatement: boolean, optionalId: ?boolean) {
@@ -2225,7 +2222,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
}
// parse typeof and type imports
parseImportSpecifiers(node: N.ImportDeclaration): void {
maybeParseDefaultImportSpecifier(node: N.ImportDeclaration): boolean {
node.importKind = "value";
let kind = null;
@@ -2252,7 +2249,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
}
}
super.parseImportSpecifiers(node);
return super.maybeParseDefaultImportSpecifier(node);
}
// parse import-type/typeof shorthand
@@ -2347,8 +2344,11 @@ export default (superClass: Class<Parser>): Class<Parser> =>
}
// parse flow type annotations on variable declarator heads - let foo: string = bar
parseVarHead(decl: N.VariableDeclarator): void {
super.parseVarHead(decl);
parseVarId(
decl: N.VariableDeclarator,
kind: "var" | "let" | "const",
): void {
super.parseVarId(decl, kind);
if (this.match(tt.colon)) {
decl.id.typeAnnotation = this.flowParseTypeAnnotation();
this.finishNode(decl.id, decl.id.type);

View File

@@ -1190,8 +1190,15 @@ export default (superClass: Class<Parser>): Class<Parser> =>
if (this.isLineTerminator()) {
return;
}
let starttype = this.state.type;
let kind;
switch (this.state.type) {
if (this.isContextual("let")) {
starttype = tt._var;
kind = "let";
}
switch (starttype) {
case tt._function:
this.next();
return this.parseFunction(nany, /* isStatement */ true);
@@ -1210,8 +1217,8 @@ export default (superClass: Class<Parser>): Class<Parser> =>
}
// falls through
case tt._var:
case tt._let:
return this.parseVarStatement(nany, this.state.type);
kind = kind || this.state.value;
return this.parseVarStatement(nany, kind);
case tt.name: {
const value = this.state.value;
if (value === "global") {
@@ -1615,16 +1622,14 @@ export default (superClass: Class<Parser>): Class<Parser> =>
*/
checkDuplicateExports() {}
parseImport(
node: N.Node,
): N.ImportDeclaration | N.TsImportEqualsDeclaration {
parseImport(node: N.Node): N.AnyImport {
if (this.match(tt.name) && this.lookahead().type === tt.eq) {
return this.tsParseImportEqualsDeclaration(node);
}
return super.parseImport(node);
}
parseExport(node: N.Node): N.Node {
parseExport(node: N.Node): N.AnyExport {
if (this.match(tt._import)) {
// `export import A = B;`
this.expect(tt._import);
@@ -1848,10 +1853,15 @@ export default (superClass: Class<Parser>): Class<Parser> =>
}
parseExportDeclaration(node: N.ExportNamedDeclaration): ?N.Declaration {
// Store original location/position
const startPos = this.state.start;
const startLoc = this.state.startLoc;
// "export declare" is equivalent to just "export".
const isDeclare = this.eatContextual("declare");
let declaration: ?N.Declaration;
if (this.match(tt.name)) {
declaration = this.tsTryParseExportDeclaration();
}
@@ -1860,6 +1870,9 @@ export default (superClass: Class<Parser>): Class<Parser> =>
}
if (declaration && isDeclare) {
// Reset location to include `declare` in range
this.resetStartLocation(declaration, startPos, startLoc);
declaration.declare = true;
}
@@ -1943,8 +1956,11 @@ export default (superClass: Class<Parser>): Class<Parser> =>
}
// `let x: number;`
parseVarHead(decl: N.VariableDeclarator): void {
super.parseVarHead(decl);
parseVarId(
decl: N.VariableDeclarator,
kind: "var" | "let" | "const",
): void {
super.parseVarId(decl, kind);
if (decl.id.type === "Identifier" && this.eat(tt.bang)) {
decl.definite = true;
}

View File

@@ -1213,6 +1213,8 @@ export default class Tokenizer extends LocationParser {
case charCodes.lineFeed:
this.state.lineStart = this.state.pos;
++this.state.curLine;
case charCodes.lineSeparator:
case charCodes.paragraphSeparator:
return "";
default:
if (ch >= charCodes.digit0 && ch <= charCodes.digit7) {
@@ -1242,6 +1244,7 @@ export default class Tokenizer extends LocationParser {
this.state.pos += octalStr.length - 1;
return String.fromCharCode(octal);
}
return String.fromCharCode(ch);
}
}
@@ -1360,7 +1363,6 @@ export default class Tokenizer extends LocationParser {
// `tt.name`.
if (
prevType === tt._return ||
prevType === tt._yield ||
(prevType === tt.name && this.state.exprAllowed)
) {
return lineBreak.test(
@@ -1384,8 +1386,8 @@ export default class Tokenizer extends LocationParser {
if (
prevType === tt._var ||
prevType === tt._let ||
prevType === tt._const
prevType === tt._const ||
prevType === tt.name
) {
return false;
}

View File

@@ -102,13 +102,9 @@ export default class State {
// where @foo belongs to the outer class and @bar to the inner
decoratorStack: Array<Array<N.Decorator>> = [[]];
// The first yield or await expression inside parenthesized expressions
// and arrow function parameters. It is used to disallow yield and await in
// arrow function parameters.
yieldOrAwaitInPossibleArrowParameters:
| N.YieldExpression
| N.AwaitExpression
| null = null;
// Positions to delayed-check that yield/await does not exist in default parameters.
yieldPos: number = 0;
awaitPos: number = 0;
// Token store.
tokens: Array<Token | N.Comment> = [];

View File

@@ -180,18 +180,16 @@ export const keywords = Object.create(null, {
throw: makeKeywordProps("throw", { beforeExpr, prefix, startsExpr }),
try: makeKeywordProps("try"),
var: makeKeywordProps("var"),
let: makeKeywordProps("let"),
const: makeKeywordProps("const"),
while: makeKeywordProps("while", { isLoop }),
with: makeKeywordProps("with"),
new: makeKeywordProps("new"),
new: makeKeywordProps("new", { beforeExpr, startsExpr }),
this: makeKeywordProps("this", { startsExpr }),
super: makeKeywordProps("super", { startsExpr }),
class: makeKeywordProps("class", { startsExpr }),
extends: makeKeywordProps("extends", { beforeExpr }),
export: makeKeywordProps("export"),
import: makeKeywordProps("import", { startsExpr }),
yield: makeKeywordProps("yield", { beforeExpr, startsExpr }),
null: makeKeywordProps("null", { startsExpr }),
true: makeKeywordProps("true", { startsExpr }),
false: makeKeywordProps("false", { startsExpr }),

View File

@@ -783,7 +783,9 @@ export type AnyExport =
| ExportNamedDeclaration
| ExportDefaultDeclaration
| ExportAllDeclaration
| TsExportAssignment;
| TsExportAssignment
| TsImportEqualsDeclaration
| TsNamespaceExportDeclaration;
export type ModuleSpecifier = NodeBase & {
local: Identifier,
@@ -820,7 +822,7 @@ export type ImportNamespaceSpecifier = ModuleSpecifier & {
export type ExportNamedDeclaration = NodeBase & {
type: "ExportNamedDeclaration",
declaration: ?Declaration,
specifiers: $ReadOnlyArray<ExportSpecifier>,
specifiers: $ReadOnlyArray<ExportSpecifier | ExportDefaultSpecifier>,
source: ?Literal,
exportKind?: "type" | "value", // TODO: Not in spec
@@ -831,6 +833,11 @@ export type ExportSpecifier = NodeBase & {
exported: Identifier,
};
export type ExportDefaultSpecifier = NodeBase & {
type: "ExportDefaultSpecifier",
exported: Identifier,
};
export type ExportDefaultDeclaration = NodeBase & {
type: "ExportDefaultDeclaration",
declaration:

View File

@@ -4,27 +4,52 @@
import * as charCodes from "charcodes";
export const isES2015ReservedWord = (word: string): boolean => {
return word === "enum" || word === "await";
const reservedWords = {
strict: [
"implements",
"interface",
"let",
"package",
"private",
"protected",
"public",
"static",
"yield",
],
strictBind: ["eval", "arguments"],
};
const reservedWordsStrict = new Set([
"implements",
"interface",
"let",
"package",
"private",
"protected",
"public",
"static",
"yield",
]);
export function isStrictReservedWord(word: string): boolean {
return reservedWordsStrict.has(word);
const reservedWordsStrictSet = new Set(reservedWords.strict);
const reservedWordsStrictBindSet = new Set(
reservedWords.strict.concat(reservedWords.strictBind),
);
/**
* Checks if word is a reserved word in non-strict mode
*/
export const isReservedWord = (word: string, inModule: boolean): boolean => {
return (inModule && word === "await") || word === "enum";
};
/**
* Checks if word is a reserved word in non-binding strict mode
*
* Includes non-strict reserved words
*/
export function isStrictReservedWord(word: string, inModule: boolean): boolean {
return isReservedWord(word, inModule) || reservedWordsStrictSet.has(word);
}
export function isStrictBindReservedWord(word: string): boolean {
return word === "eval" || word === "arguments";
/**
* Checks if word is a reserved word in binding strict mode
*
* Includes non-strict reserved words and non-binding strict reserved words
*/
export function isStrictBindReservedWord(
word: string,
inModule: boolean,
): boolean {
return isReservedWord(word, inModule) || reservedWordsStrictBindSet.has(word);
}
const keywords = new Set([
@@ -57,13 +82,11 @@ const keywords = new Set([
"new",
"in",
"this",
"let",
"const",
"class",
"extends",
"export",
"import",
"yield",
"super",
]);
@@ -71,6 +94,8 @@ export function isKeyword(word: string): boolean {
return keywords.has(word);
}
export const keywordRelationalOperator = /^in(stanceof)?$/;
// ## Character categories
// Big ugly regular expressions that matches characters in the

View File

@@ -1,4 +1,4 @@
{
"strictMode": true,
"throws": "public is a reserved word in strict mode (2:0)"
"throws": "Unexpected reserved word 'public' (2:0)"
}

View File

@@ -0,0 +1 @@
for await (const i of imports) {}

View File

@@ -0,0 +1,3 @@
{
"throws": "Unexpected token, expected \"(\" (1:4)"
}

View File

@@ -0,0 +1 @@
for await (const i of imports) {}

View File

@@ -0,0 +1,3 @@
{
"allowAwaitOutsideFunction": true
}

View File

@@ -0,0 +1,136 @@
{
"type": "File",
"start": 0,
"end": 33,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 33
}
},
"program": {
"type": "Program",
"start": 0,
"end": 33,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 33
}
},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "ForOfStatement",
"start": 0,
"end": 33,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 33
}
},
"await": true,
"left": {
"type": "VariableDeclaration",
"start": 11,
"end": 18,
"loc": {
"start": {
"line": 1,
"column": 11
},
"end": {
"line": 1,
"column": 18
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 17,
"end": 18,
"loc": {
"start": {
"line": 1,
"column": 17
},
"end": {
"line": 1,
"column": 18
}
},
"id": {
"type": "Identifier",
"start": 17,
"end": 18,
"loc": {
"start": {
"line": 1,
"column": 17
},
"end": {
"line": 1,
"column": 18
},
"identifierName": "i"
},
"name": "i"
},
"init": null
}
],
"kind": "const"
},
"right": {
"type": "Identifier",
"start": 22,
"end": 29,
"loc": {
"start": {
"line": 1,
"column": 22
},
"end": {
"line": 1,
"column": 29
},
"identifierName": "imports"
},
"name": "imports"
},
"body": {
"type": "BlockStatement",
"start": 31,
"end": 33,
"loc": {
"start": {
"line": 1,
"column": 31
},
"end": {
"line": 1,
"column": 33
}
},
"body": [],
"directives": []
}
}
],
"directives": []
}
}

View File

@@ -0,0 +1,3 @@
function* test() {
yield new Foo();
}

View File

@@ -0,0 +1,152 @@
{
"type": "File",
"start": 0,
"end": 39,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"program": {
"type": "Program",
"start": 0,
"end": 39,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "FunctionDeclaration",
"start": 0,
"end": 39,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"id": {
"type": "Identifier",
"start": 10,
"end": 14,
"loc": {
"start": {
"line": 1,
"column": 10
},
"end": {
"line": 1,
"column": 14
},
"identifierName": "test"
},
"name": "test"
},
"generator": true,
"async": false,
"params": [],
"body": {
"type": "BlockStatement",
"start": 17,
"end": 39,
"loc": {
"start": {
"line": 1,
"column": 17
},
"end": {
"line": 3,
"column": 1
}
},
"body": [
{
"type": "ExpressionStatement",
"start": 21,
"end": 37,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 18
}
},
"expression": {
"type": "YieldExpression",
"start": 21,
"end": 36,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 17
}
},
"delegate": false,
"argument": {
"type": "NewExpression",
"start": 27,
"end": 36,
"loc": {
"start": {
"line": 2,
"column": 8
},
"end": {
"line": 2,
"column": 17
}
},
"callee": {
"type": "Identifier",
"start": 31,
"end": 34,
"loc": {
"start": {
"line": 2,
"column": 12
},
"end": {
"line": 2,
"column": 15
},
"identifierName": "Foo"
},
"name": "Foo"
},
"arguments": []
}
}
}
],
"directives": []
}
}
],
"directives": []
}
}

View File

@@ -1,4 +1,4 @@
{
"sourceType": "module",
"throws": "Legacy octal literals are not allowed in strict mode (1:0)"
"sourceType": "module",
"throws": "Legacy octal literals are not allowed in strict mode (1:0)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "Unexpected token, expected \";\" (1:2)"
}
}

View File

@@ -1,3 +1,3 @@
{
"throws": "eval is a reserved word in strict mode (1:36)"
}
"throws": "Binding 'eval' in strict mode (1:36)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "arguments is a reserved word in strict mode (1:36)"
}
"throws": "Binding 'arguments' in strict mode (1:36)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "eval is a reserved word in strict mode (1:47)"
}
"throws": "Binding 'eval' in strict mode (1:47)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "arguments is a reserved word in strict mode (1:47)"
}
"throws": "Binding 'arguments' in strict mode (1:47)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "eval is a reserved word in strict mode (1:32)"
}
"throws": "Assigning to 'eval' in strict mode (1:32)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "arguments is a reserved word in strict mode (1:32)"
}
"throws": "Assigning to 'arguments' in strict mode (1:32)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "eval is a reserved word in strict mode (1:34)"
}
"throws": "Assigning to 'eval' in strict mode (1:34)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "eval is a reserved word in strict mode (1:34)"
}
"throws": "Assigning to 'eval' in strict mode (1:34)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "arguments is a reserved word in strict mode (1:34)"
}
"throws": "Assigning to 'arguments' in strict mode (1:34)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "arguments is a reserved word in strict mode (1:34)"
}
"throws": "Assigning to 'arguments' in strict mode (1:34)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "eval is a reserved word in strict mode (1:32)"
}
"throws": "Assigning to 'eval' in strict mode (1:32)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "eval is a reserved word in strict mode (1:32)"
}
"throws": "Assigning to 'eval' in strict mode (1:32)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "arguments is a reserved word in strict mode (1:32)"
}
"throws": "Assigning to 'arguments' in strict mode (1:32)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "arguments is a reserved word in strict mode (1:32)"
}
"throws": "Assigning to 'arguments' in strict mode (1:32)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "eval is a reserved word in strict mode (1:41)"
}
"throws": "Binding 'eval' in strict mode (1:41)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "arguments is a reserved word in strict mode (1:41)"
}
"throws": "Binding 'arguments' in strict mode (1:41)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "eval is a reserved word in strict mode (1:9)"
}
"throws": "Binding 'eval' in strict mode (1:9)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "arguments is a reserved word in strict mode (1:9)"
}
"throws": "Binding 'arguments' in strict mode (1:9)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "eval is a reserved word in strict mode (1:42)"
}
"throws": "Binding 'eval' in strict mode (1:42)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "arguments is a reserved word in strict mode (1:42)"
}
"throws": "Binding 'arguments' in strict mode (1:42)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "eval is a reserved word in strict mode (1:10)"
}
"throws": "Binding 'eval' in strict mode (1:10)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "arguments is a reserved word in strict mode (1:10)"
}
"throws": "Binding 'arguments' in strict mode (1:10)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "eval is a reserved word in strict mode (1:47)"
}
"throws": "Binding 'eval' in strict mode (1:47)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "package is a reserved word in strict mode (1:10)"
}
"throws": "Binding 'package' in strict mode (1:10)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "eval is a reserved word in strict mode (1:48)"
}
"throws": "Binding 'eval' in strict mode (1:48)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "eval is a reserved word in strict mode (1:41)"
}
"throws": "Binding 'eval' in strict mode (1:41)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "eval is a reserved word in strict mode (1:49)"
}
"throws": "Binding 'eval' in strict mode (1:49)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "eval is a reserved word in strict mode (1:15)"
}
"throws": "Binding 'eval' in strict mode (1:15)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "arguments is a reserved word in strict mode (1:15)"
}
"throws": "Binding 'arguments' in strict mode (1:15)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "eval is a reserved word in strict mode (1:48)"
}
"throws": "Binding 'eval' in strict mode (1:48)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "arguments is a reserved word in strict mode (1:48)"
}
"throws": "Binding 'arguments' in strict mode (1:48)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "implements is a reserved word in strict mode (1:37)"
"throws": "Unexpected reserved word 'implements' (1:37)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "interface is a reserved word in strict mode (1:37)"
"throws": "Unexpected reserved word 'interface' (1:37)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "package is a reserved word in strict mode (1:37)"
"throws": "Unexpected reserved word 'package' (1:37)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "private is a reserved word in strict mode (1:37)"
"throws": "Unexpected reserved word 'private' (1:37)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "protected is a reserved word in strict mode (1:37)"
"throws": "Unexpected reserved word 'protected' (1:37)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "public is a reserved word in strict mode (1:37)"
"throws": "Unexpected reserved word 'public' (1:37)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "static is a reserved word in strict mode (1:37)"
"throws": "Unexpected reserved word 'static' (1:37)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "static is a reserved word in strict mode (1:15)"
}
"throws": "Binding 'static' in strict mode (1:15)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "static is a reserved word in strict mode (1:9)"
}
"throws": "Binding 'static' in strict mode (1:9)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "static is a reserved word in strict mode (1:23)"
"throws": "Unexpected reserved word 'static' (1:23)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "eval is a reserved word in strict mode (1:11)"
}
"throws": "Binding 'eval' in strict mode (1:11)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "package is a reserved word in strict mode (1:11)"
}
"throws": "Binding 'package' in strict mode (1:11)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "eval is a reserved word in strict mode (1:12)"
}
"throws": "Binding 'eval' in strict mode (1:12)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "package is a reserved word in strict mode (1:12)"
}
"throws": "Binding 'package' in strict mode (1:12)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "public is a reserved word in strict mode (2:8)"
"throws": "Unexpected reserved word 'public' (2:8)"
}

View File

@@ -1,4 +1,4 @@
{
"sourceType": "module",
"throws": "public is a reserved word in strict mode (1:8)"
"throws": "Unexpected reserved word 'public' (1:8)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "arguments is a reserved word in strict mode (2:8)"
"throws": "Unexpected reserved word 'arguments' (2:8)"
}

View File

@@ -1,4 +1,4 @@
{
"sourceType": "module",
"throws": "arguments is a reserved word in strict mode (1:8)"
"throws": "Unexpected reserved word 'arguments' (1:8)"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "'with' in strict mode (2:2)"
}
}

View File

@@ -1,3 +1,3 @@
{
"throws": "this is a reserved word (1:6)"
"throws": "Unexpected keyword 'this' (1:6)"
}

View File

@@ -0,0 +1 @@
let + 1

View File

@@ -0,0 +1,103 @@
{
"type": "File",
"start": 0,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 7
}
},
"program": {
"type": "Program",
"start": 0,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 7
}
},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "ExpressionStatement",
"start": 0,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 7
}
},
"expression": {
"type": "BinaryExpression",
"start": 0,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 7
}
},
"left": {
"type": "Identifier",
"start": 0,
"end": 3,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 3
},
"identifierName": "let"
},
"name": "let"
},
"operator": "+",
"right": {
"type": "NumericLiteral",
"start": 6,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 7
}
},
"extra": {
"rawValue": 1,
"raw": "1"
},
"value": 1
}
}
}
],
"directives": []
}
}

Some files were not shown because too many files have changed in this diff Show More