Compare commits

...

55 Commits

Author SHA1 Message Date
Nicolò Ribaudo
d1fe2d05f4 v7.3.3 2019-02-15 22:06:01 +01:00
Simon Adcock
b9a3806f9e Upgrade to @babel/preset-typescript to use @babel/plugin-transform-typescript@^7.3.2 (#9497) [skip ci]
Bumps to 7.3.2 the version of `@babel/plugin-transform-typescript` used by `@babel/preset-typescript`.

This allows us to use `@babel/preset-typescript` and pick up at least one useful bug fix (#9095).

A similar PR (#9181) was closed as it bumped to a version that didn't have changes. However reading the comments from that PR, I get the sense that bumping the version in this manner should not be necessary, and should be handled by Lerna. Is this correct?

Please let me know if I can make any improvements to this PR, the description or if there's anything else I can do to help.
2019-02-15 21:59:21 +01:00
Nicolò Ribaudo
b25fea49fe Create a new release after a v*.*.* commit instead of the tag (#9470)
* Create a new release after a v*.*.* commit instead of the tag

* Fix bugs

* Avoid matching things like "v2"
2019-02-15 21:42:51 +01:00
Nicolò Ribaudo
83cbc11d46 Correctly output escapes in directives (#9501) 2019-02-15 21:08:45 +01:00
Daniel Tschinder
0f685d9b42 Only allow Identifiers, Patterns and Rest in parameters of FunctionDeclarations 2019-02-15 12:49:36 +01:00
Nicolò Ribaudo
d86b831364 Add duplicate-package-checker-webpack-plugin (#9517)
We are duplicating semver. It's such a small package that I don't think that it is worth spending much time trying to understand why.
2019-02-15 12:28:00 +01:00
Nicolò Ribaudo
0050266a50 Add missing dependencies (#9516) 2019-02-15 08:50:32 +01:00
Nicolò Ribaudo
b6300a0869 Add importKind to ImportDeclaration in babel/types 2019-02-14 21:53:29 +01:00
Daniel Tschinder
4ba998c5db Add importKind to spec 2019-02-14 21:53:29 +01:00
Nicolò Ribaudo
2fb1f9aed3 Add tests for options to babel-node (#9510) 2019-02-14 13:43:30 +01:00
Alec
85ea5b0b50 Version bump of lodash (#9500)
https://tools.cisco.com/security/center/viewAlert.x?alertId=59546
2019-02-13 16:17:39 +01:00
Daniel Tschinder
d349b74a4f Better error output in parser tests (#9491) 2019-02-11 02:13:24 -08:00
Nicolò Ribaudo
3a9743fce4 Show real version instead of core/preset-env versions in standalone pkgs (#9467) 2019-02-09 17:29:45 +01:00
Daniel Tschinder
2817844e89 Fix regression with let (#9477)
* Fix corner cases with let

* Handle generators correctly

* Fix flow plugin

* Fix typescript plugin
2019-02-08 13:36:37 -08:00
Daniel Tschinder
7943a48cc3 Update flow to 0.92.1 and fix related issues (#9468)
* Update flow to 0.92.1 and fix related issues

* Change isThenable check
2019-02-08 13:27:11 -08:00
Nicolò Ribaudo
953182d44a Exclude generate @babel/types files from coverage report (#9469) 2019-02-08 22:25:19 +01:00
Rubén Norte
045d019149 Fix duplicated assertThisInitialized calls in constructors (#9458) 2019-02-07 23:01:46 +01:00
Downpooooour
d1514f57bd Typescript function destructured params (#9431)
* fix typescript funtion destructured params for array

* update type name
2019-02-07 22:59:50 +01:00
Nicolò Ribaudo
fdb65ab8b1 Update publishing command (#9466) [skip ci]
This reflects how I have been releasing the last versions (https://github.com/babel/notes/issues/78#issuecomment-449519007).

In the future, we'll only need to run `make new-version && git push --tags` and it will run `make publish` from CI/Actions.


Co-authored-by: Henry Zhu <hi@henryzoo.com>
2019-02-07 22:15:45 +01:00
Daniel Tschinder
81123fb972 Fix typo in comment 2019-02-06 15:12:35 -08:00
Ilya Lesik
738060ebfa Fix support for Flow's DeclareClass type parameters (#9459) 2019-02-06 08:18:07 -06:00
Brian Ng
07b0f22a3f Fix range for TypeScript optional parameter in arrow function (#9463) 2019-02-06 08:17:32 -06:00
Yifei Fu
e03e5ba01d Add TypeScript definitions for parser plugin options. (#9457) 2019-02-06 10:03:54 +01:00
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
522 changed files with 7253 additions and 4184 deletions

View File

@@ -0,0 +1,16 @@
FROM debian:stable-slim
LABEL "name"="filter"
LABEL "version"="1.1.0"
LABEL "com.github.actions.name"="Filter commit message"
LABEL "com.github.actions.description"="Stop a workflow if the message of the current commit doesn't match the pattern"
LABEL "com.github.actions.icon"="filter"
LABEL "com.github.actions.color"="gray-dark"
ADD entrypoint.sh /action/entrypoint.sh
RUN chmod +x /action/entrypoint.sh
RUN apt-get update && apt-get install -y --no-install-recommends git
ENTRYPOINT ["/action/entrypoint.sh"]

View File

@@ -0,0 +1,15 @@
#!/bin/sh
set -e
pattern=$1
message=$(git log --oneline --format=%B -1 $GITHUB_SHA)
if echo "$message" | grep -Pq "$pattern"; then
echo "INFO: $message matches $pattern"
exit 0
else
echo "INFO: $message does not match $pattern"
# 78 is the "neutral" exit status
exit 78
fi

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,38 @@
#!/bin/sh
set -e
echo "INFO: Installing action dependencies..."
(cd /action; npm ci)
echo "INFO: Checking out current commit..."
git -c advice.detachedHead=false checkout $GITHUB_SHA
# GitHub doesn't support running actions on new tags yet: we need to run it on the commit.
# For this reason, we can't be sure that the tag already exists. We can use the commit
# message to create the tag. If the tag already exists locally, they won't conflict because
# they have the same name and are on the same commit.
echo "INFO: Getting release version..."
# current_tag=$(git describe --abbrev=0 --tags HEAD)
current_tag=$(git log --oneline --format=%B -1 HEAD)
echo "INFO: Creating new tag..."
(git tag $current_tag $GITHUB_SHA) || echo "INFO: Tag already exists"
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);
});

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

@@ -0,0 +1,28 @@
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 commit",
"On master branch",
]
}
action "Is version commit" {
uses = "./.github/actions/filter-commit-message"
# This regex is run using "grep -P".
# The (-\\S+) part is for 7.0.0-beta.1 releases.
args = "^v(\\d+\\.){2}\\d+(-\\S+)?$"
}
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");
@@ -17,8 +17,7 @@ const source = require("vinyl-source-stream");
const buffer = require("vinyl-buffer");
const rollupBabel = require("rollup-plugin-babel");
const rollupNodeResolve = require("rollup-plugin-node-resolve");
const registerStandalonePackageTask = require("./scripts/gulp-tasks")
.registerStandalonePackageTask;
const { registerStandalonePackageTask } = require("./scripts/gulp-tasks");
const sources = ["codemods", "packages"];
@@ -38,7 +37,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 +49,7 @@ function compilationLogger(rollup) {
function errorsLogger() {
return plumber({
errorHandler(err) {
gutil.log(err.stack);
fancyLog(err.stack);
},
});
}
@@ -138,7 +137,7 @@ registerStandalonePackageTask(
"babel",
"Babel",
path.join(__dirname, "packages"),
require("./packages/babel-core/package.json").version
require("./packages/babel-standalone/package.json").version
);
const presetEnvWebpackPlugins = [
@@ -167,6 +166,6 @@ registerStandalonePackageTask(
"babel-preset-env",
"babelPresetEnv",
path.join(__dirname, "packages"),
require("./packages/babel-preset-env/package.json").version,
require("./packages/babel-preset-env-standalone/package.json").version,
presetEnvWebpackPlugins
);

View File

@@ -130,8 +130,12 @@ prepublish:
make prepublish-build
make test
new-version:
./node_modules/.bin/lerna version --force-publish="@babel/runtime,@babel/runtime-corejs2,@babel/standalone,@babel/preset-env-standalone"
# NOTE: Run make new-version first
publish: prepublish
./node_modules/.bin/lerna publish --force-publish="@babel/runtime,@babel/runtime-corejs2,@babel/standalone,@babel/preset-env-standalone" --require-scripts
./node_modules/.bin/lerna publish from-git --require-scripts
make clean
bootstrap: clean-all

View File

@@ -8,3 +8,5 @@ coverage:
target: "80%"
patch:
enabled: false
ignore:
- packages/babel-types/src/*/generated/index.js

View File

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

View File

@@ -9,55 +9,55 @@
"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",
"duplicate-package-checker-webpack-plugin": "^2.1.0",
"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",
"flow-bin": "^0.87.0",
"graceful-fs": "^4.1.11",
"eslint-plugin-flowtype": "^3.2.1",
"eslint-plugin-prettier": "^3.0.1",
"fancy-log": "^1.3.3",
"flow-bin": "^0.92.1",
"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 +108,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 +133,6 @@
"moduleNameMapper": {
"^@babel/([a-zA-Z0-9_-]+)$": "<rootDir>/packages/babel-$1/"
}
}
},
"dependencies": {}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/core",
"version": "7.2.2",
"version": "7.3.3",
"description": "Babel compiler core.",
"main": "lib/index.js",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
@@ -34,16 +34,16 @@
},
"dependencies": {
"@babel/code-frame": "^7.0.0",
"@babel/generator": "^7.2.2",
"@babel/generator": "^7.3.3",
"@babel/helpers": "^7.2.0",
"@babel/parser": "^7.2.2",
"@babel/parser": "^7.3.3",
"@babel/template": "^7.2.2",
"@babel/traverse": "^7.2.2",
"@babel/types": "^7.2.2",
"@babel/types": "^7.3.3",
"convert-source-map": "^1.1.0",
"debug": "^4.1.0",
"json5": "^2.1.0",
"lodash": "^4.17.10",
"lodash": "^4.17.11",
"resolve": "^1.3.2",
"semver": "^5.4.1",
"source-map": "^0.5.0"

View File

@@ -43,7 +43,6 @@ export function makeWeakCache<
>(
handler: (ArgT, CacheConfigurator<SideChannel>) => ResultT,
): (ArgT, SideChannel) => ResultT {
// $FlowIssue https://github.com/facebook/flow/issues/4528
return makeCachedFunction(new WeakMap(), handler);
}

View File

@@ -10,7 +10,7 @@ import {
makeWeakCache,
type CacheConfigurator,
} from "../caching";
import makeAPI from "../helpers/config-api";
import makeAPI, { type PluginAPI } from "../helpers/config-api";
import { makeStaticFileCache } from "./utils";
import pathPatternToRegex from "../pattern-to-regex";
import type { FilePackageData, RelativeConfig, ConfigFile } from "./types";
@@ -150,7 +150,7 @@ const LOADING_CONFIGS = new Set();
const readConfigJS = makeStrongCache(
(
filepath,
filepath: string,
cache: CacheConfigurator<{
envName: string,
caller: CallerMetadata | void,
@@ -193,7 +193,7 @@ const readConfigJS = makeStrongCache(
}
if (typeof options === "function") {
options = options(makeAPI(cache));
options = ((options: any): (api: PluginAPI) => {})(makeAPI(cache));
if (!cache.configured()) throwConfigError();
}

View File

@@ -131,6 +131,7 @@ function isThenable(val: mixed): boolean {
return (
!!val &&
(typeof val === "object" || typeof val === "function") &&
!!val.then &&
typeof val.then === "function"
);
}

View File

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

View File

@@ -50,8 +50,35 @@ export function Directive(node: Object) {
this.semicolon();
}
// These regexes match an even number of \ followed by a quote
const unescapedSingleQuoteRE = /(?:^|[^\\])(?:\\\\)*'/;
const unescapedDoubleQuoteRE = /(?:^|[^\\])(?:\\\\)*"/;
export function DirectiveLiteral(node: Object) {
const raw = this.getPossibleRaw(node);
if (raw != null) {
this.token(raw);
return;
}
const { value } = node;
// NOTE: In directives we can't change escapings,
// because they change the behavior.
// e.g. "us\x65 string" (\x65 is e) is not a "use strict" directive.
if (!unescapedDoubleQuoteRE.test(value)) {
this.token(`"${value}"`);
} else if (!unescapedSingleQuoteRE.test(value)) {
this.token(`'${value}'`);
} else {
throw new Error(
"Malformed AST: it is not possible to print a directive containing" +
" both unescaped single and double quotes.",
);
}
}
export function InterpreterDirective(node: Object) {
this.token(`#!${node.value}\n`);
}
export { StringLiteral as DirectiveLiteral } from "./types";

View File

@@ -1 +1,2 @@
0; // Not a directive
"©";

View File

@@ -1 +1,2 @@
0;// Not a directive
"\u00A9";

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

@@ -384,6 +384,48 @@ describe("programmatic generation", function() {
[key: any]: number
}`);
});
describe("directives", function() {
it("preserves escapes", function() {
const directive = t.directive(
t.directiveLiteral(String.raw`us\x65 strict`),
);
const output = generate(directive).code;
expect(output).toBe(String.raw`"us\x65 strict";`);
});
it("preserves escapes in minified output", function() {
// https://github.com/babel/babel/issues/4767
const directive = t.directive(t.directiveLiteral(String.raw`foo\n\t\r`));
const output = generate(directive, { minified: true }).code;
expect(output).toBe(String.raw`"foo\n\t\r";`);
});
it("unescaped single quote", function() {
const directive = t.directive(t.directiveLiteral(String.raw`'\'\"`));
const output = generate(directive).code;
expect(output).toBe(String.raw`"'\'\"";`);
});
it("unescaped double quote", function() {
const directive = t.directive(t.directiveLiteral(String.raw`"\'\"`));
const output = generate(directive).code;
expect(output).toBe(String.raw`'"\'\"';`);
});
it("unescaped single and double quotes together throw", function() {
const directive = t.directive(t.directiveLiteral(String.raw`'"`));
expect(() => {
generate(directive);
}).toThrow();
});
});
});
describe("CodeGenerator", function() {

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",
@@ -18,7 +18,8 @@
"@babel/helper-member-expression-to-functions": "^7.0.0",
"@babel/helper-optimise-call-expression": "^7.0.0",
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/helper-replace-supers": "^7.2.3"
"@babel/helper-replace-supers": "^7.2.3",
"@babel/helper-split-export-declaration": "^7.0.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0"

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

@@ -11,6 +11,6 @@
"dependencies": {
"@babel/helper-function-name": "^7.1.0",
"@babel/types": "^7.0.0",
"lodash": "^4.17.10"
"lodash": "^4.17.11"
}
}

View File

@@ -10,7 +10,7 @@
"repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-fixtures",
"main": "lib/index.js",
"dependencies": {
"lodash": "^4.17.10",
"lodash": "^4.17.11",
"semver": "^5.3.0",
"try-resolve": "^1.0.0"
}

View File

@@ -16,6 +16,6 @@
"@babel/helper-split-export-declaration": "^7.0.0",
"@babel/template": "^7.2.2",
"@babel/types": "^7.2.2",
"lodash": "^4.17.10"
"lodash": "^4.17.11"
}
}

View File

@@ -9,6 +9,6 @@
},
"main": "lib/index.js",
"dependencies": {
"lodash": "^4.17.10"
"lodash": "^4.17.11"
}
}

View File

@@ -18,7 +18,7 @@
"babel-check-duplicated-nodes": "^1.0.0",
"jest": "^22.4.2",
"jest-diff": "^22.4.0",
"lodash": "^4.17.10",
"lodash": "^4.17.11",
"resolve": "^1.3.2",
"source-map": "^0.5.0"
}

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

@@ -22,7 +22,7 @@
"@babel/polyfill": "^7.0.0",
"@babel/register": "^7.0.0",
"commander": "^2.8.1",
"lodash": "^4.17.10",
"lodash": "^4.17.11",
"v8flags": "^3.1.1"
},
"peerDependencies": {

View File

@@ -0,0 +1,6 @@
{
"args": ["--inspect", "--eval", "console.log('foo');"],
"stderr": "Debugger listening on",
"stderrContains": true,
"stdout": "foo"
}

View File

@@ -0,0 +1,4 @@
{
"args": ["--nolazy", "--eval", "console.log('foo')"],
"stdout": "foo"
}

View File

@@ -0,0 +1,4 @@
{
"args": ["-gc", "--eval", "console.log(typeof global.gc)"],
"stdout": "function"
}

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

@@ -1149,6 +1149,7 @@ A specifier in an import or export declaration.
```js
interface ImportDeclaration <: ModuleDeclaration {
type: "ImportDeclaration";
importKind: null | "type" | "typeof" | "value";
specifiers: [ ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier ];
source: Literal;
}
@@ -1156,6 +1157,8 @@ interface ImportDeclaration <: ModuleDeclaration {
An import declaration, e.g., `import foo from "mod";`.
> importKind is only set when `flow` plugin enabled in babel-parser
### ImportSpecifier
```js

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/parser",
"version": "7.3.0",
"version": "7.3.3",
"description": "A JavaScript parser",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://babeljs.io/",
@@ -28,6 +28,7 @@
"node": ">=6.0.0"
},
"devDependencies": {
"@babel/code-frame": "^7.0.0",
"@babel/helper-fixtures": "^7.2.0",
"charcodes": "0.1.0",
"unicode-11.0.0": "^0.7.8"

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,35 @@ export default class StatementParser extends ExpressionParser {
return this.finishNode(node, "InterpreterDirective");
}
isLet(context: ?string): 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);
// For ambiguous cases, determine if a LexicalDeclaration (or only a
// Statement) is allowed here. If context is not empty then only a Statement
// is allowed. However, `let [` is an explicit negative lookahead for
// ExpressionStatement, so special-case it first.
if (nextCh === charCodes.leftSquareBracket) return true;
if (context) return false;
if (nextCh === charCodes.leftCurlyBrace) return true;
if (isIdentifierStart(nextCh)) {
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
@@ -78,16 +112,22 @@ export default class StatementParser extends ExpressionParser {
// `if (foo) /blah/.exec(foo)`, where looking at the previous token
// does not help.
parseStatement(declaration: boolean, topLevel?: boolean): N.Statement {
parseStatement(context: ?string, topLevel?: boolean): N.Statement {
if (this.match(tt.at)) {
this.parseDecorators(true);
}
return this.parseStatementContent(declaration, topLevel);
return this.parseStatementContent(context, topLevel);
}
parseStatementContent(declaration: boolean, topLevel: ?boolean): N.Statement {
const starttype = this.state.type;
parseStatementContent(context: ?string, topLevel: ?boolean): N.Statement {
let starttype = this.state.type;
const node = this.startNode();
let kind;
if (this.isLet(context)) {
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
@@ -104,18 +144,28 @@ export default class StatementParser extends ExpressionParser {
return this.parseDoStatement(node);
case tt._for:
return this.parseForStatement(node);
case tt._function:
case tt._function: {
if (this.lookahead().type === tt.dot) break;
if (!declaration) {
if (
context &&
(this.state.strict || (context !== "if" && context !== "label"))
) {
this.raise(
this.state.start,
"Function declaration not allowed in this context",
);
}
return this.parseFunctionStatement(node);
const result = this.parseFunctionStatement(node);
// TODO: Remove this once we have proper scope tracking in place.
if (context && result.generator) {
this.unexpected(node.start);
}
return result;
}
case tt._class:
if (!declaration) this.unexpected();
if (context) this.unexpected();
return this.parseClass(node, true);
case tt._if:
@@ -129,12 +179,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 (context && kind !== "var") this.unexpected();
return this.parseVarStatement(node, kind);
case tt._while:
return this.parseWhileStatement(node);
@@ -194,7 +243,7 @@ export default class StatementParser extends ExpressionParser {
const state = this.state.clone();
this.next();
if (this.match(tt._function) && !this.canInsertSemicolon()) {
if (!declaration) {
if (context) {
this.raise(
this.state.lastTokStart,
"Function declaration not allowed in this context",
@@ -221,7 +270,7 @@ export default class StatementParser extends ExpressionParser {
expr.type === "Identifier" &&
this.eat(tt.colon)
) {
return this.parseLabeledStatement(node, maybeName, expr, declaration);
return this.parseLabeledStatement(node, maybeName, expr, context);
} else {
return this.parseExpressionStatement(node, expr);
}
@@ -387,7 +436,7 @@ export default class StatementParser extends ExpressionParser {
// outside of the loop body.
this.withTopicForbiddingContext(() =>
// Parse the loop body's body.
this.parseStatement(false),
this.parseStatement("do"),
);
this.state.labels.pop();
@@ -410,32 +459,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 +496,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 +514,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);
}
@@ -479,8 +532,8 @@ export default class StatementParser extends ExpressionParser {
parseIfStatement(node: N.IfStatement): N.IfStatement {
this.next();
node.test = this.parseParenExpression();
node.consequent = this.parseStatement(false);
node.alternate = this.eat(tt._else) ? this.parseStatement(false) : null;
node.consequent = this.parseStatement("if");
node.alternate = this.eat(tt._else) ? this.parseStatement("if") : null;
return this.finishNode(node, "IfStatement");
}
@@ -536,7 +589,7 @@ export default class StatementParser extends ExpressionParser {
this.expect(tt.colon);
} else {
if (cur) {
cur.consequent.push(this.parseStatement(true));
cur.consequent.push(this.parseStatement(null));
} else {
this.unexpected();
}
@@ -606,7 +659,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);
@@ -625,7 +678,7 @@ export default class StatementParser extends ExpressionParser {
// They are permitted in test expressions, outside of the loop body.
this.withTopicForbiddingContext(() =>
// Parse loop body.
this.parseStatement(false),
this.parseStatement("while"),
);
this.state.labels.pop();
@@ -647,7 +700,7 @@ export default class StatementParser extends ExpressionParser {
// part of the outer context, outside of the function body.
this.withTopicForbiddingContext(() =>
// Parse the statement body.
this.parseStatement(false),
this.parseStatement("with"),
);
return this.finishNode(node, "WithStatement");
@@ -662,7 +715,7 @@ export default class StatementParser extends ExpressionParser {
node: N.LabeledStatement,
maybeName: string,
expr: N.Identifier,
declaration: boolean,
context: ?string,
): N.LabeledStatement {
for (const label of this.state.labels) {
if (label.name === maybeName) {
@@ -690,16 +743,13 @@ export default class StatementParser extends ExpressionParser {
kind: kind,
statementStart: this.state.start,
});
node.body = this.parseStatement(declaration);
if (
node.body.type === "ClassDeclaration" ||
(node.body.type === "VariableDeclaration" && node.body.kind !== "var") ||
(node.body.type === "FunctionDeclaration" &&
(this.state.strict || node.body.generator || node.body.async))
) {
this.raise(node.body.start, "Invalid labeled declaration");
}
node.body = this.parseStatement(
context
? context.indexOf("label") === -1
? context + "label"
: context
: "label",
);
this.state.labels.pop();
node.label = expr;
@@ -766,7 +816,7 @@ export default class StatementParser extends ExpressionParser {
octalPosition = this.state.octalPosition;
}
const stmt = this.parseStatement(true, topLevel);
const stmt = this.parseStatement(null, topLevel);
if (directives && !parsedNonDirective && this.isValidDirective(stmt)) {
const directive = this.stmtToDirective(stmt);
@@ -814,7 +864,7 @@ export default class StatementParser extends ExpressionParser {
// outside of the loop body.
this.withTopicForbiddingContext(() =>
// Parse the loop body.
this.parseStatement(false),
this.parseStatement("for"),
);
this.state.labels.pop();
@@ -828,16 +878,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();
@@ -849,7 +899,7 @@ export default class StatementParser extends ExpressionParser {
// They are permitted in test expressions, outside of the loop body.
this.withTopicForbiddingContext(() =>
// Parse loop body.
this.parseStatement(false),
this.parseStatement("for"),
);
this.state.labels.pop();
@@ -862,20 +912,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 +949,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 +972,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 +1001,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 +1028,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 +1046,7 @@ export default class StatementParser extends ExpressionParser {
);
this.state.inParameters = oldInParameters;
this.checkYieldAwaitInDefaultParams();
}
// Parse a class declaration or literal (depending on the
@@ -1008,12 +1059,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 +1521,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 +1636,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 +1689,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.",
@@ -1586,12 +1703,12 @@ export default class StatementParser extends ExpressionParser {
// eslint-disable-next-line no-unused-vars
parseExportDeclaration(node: N.ExportNamedDeclaration): ?N.Declaration {
return this.parseStatement(true);
return this.parseStatement(null);
}
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 +1722,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 +1737,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 +1757,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 +1836,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 +1893,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 +1929,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 +1938,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 +1955,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)
) {
@@ -1566,7 +1566,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
}
// interfaces
parseStatement(declaration: boolean, topLevel?: boolean): N.Statement {
parseStatement(context: ?string, topLevel?: boolean): N.Statement {
// strict mode handling of `interface` since it's a reserved word
if (
this.state.strict &&
@@ -1577,7 +1577,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
this.next();
return this.flowParseInterface(node);
} else {
const stmt = super.parseStatement(declaration, topLevel);
const stmt = super.parseStatement(context, topLevel);
// We will parse a flow pragma in any comment before the first statement.
if (this.flowPragma === undefined && !this.isValidDirective(stmt)) {
this.flowPragma = null;
@@ -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

@@ -342,17 +342,18 @@ export default (superClass: Class<Parser>): Class<Parser> =>
}
tsParseBindingListForSignature(): $ReadOnlyArray<
N.Identifier | N.RestElement | N.ObjectPattern,
N.Identifier | N.RestElement | N.ObjectPattern | N.ArrayPattern,
> {
return this.parseBindingList(tt.parenR).map(pattern => {
if (
pattern.type !== "Identifier" &&
pattern.type !== "RestElement" &&
pattern.type !== "ObjectPattern"
pattern.type !== "ObjectPattern" &&
pattern.type !== "ArrayPattern"
) {
throw this.unexpected(
pattern.start,
`Name in a signature must be an Identifier or ObjectPattern, instead got ${
`Name in a signature must be an Identifier, ObjectPattern or ArrayPattern, instead got ${
pattern.type
}`,
);
@@ -794,6 +795,21 @@ export default (superClass: Class<Parser>): Class<Parser> =>
return true;
}
if (this.match(tt.bracketL)) {
let braceStackCounter = 1;
this.next();
while (braceStackCounter > 0) {
if (this.match(tt.bracketL)) {
++braceStackCounter;
} else if (this.match(tt.bracketR)) {
--braceStackCounter;
}
this.next();
}
return true;
}
return false;
}
@@ -1190,8 +1206,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 +1233,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 +1638,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);
@@ -1678,10 +1699,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
return super.parseExportDefaultExpression();
}
parseStatementContent(
declaration: boolean,
topLevel: ?boolean,
): N.Statement {
parseStatementContent(context: ?string, topLevel: ?boolean): N.Statement {
if (this.state.type === tt._const) {
const ahead = this.lookahead();
if (ahead.type === tt.name && ahead.value === "enum") {
@@ -1691,7 +1709,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
return this.tsParseEnumDeclaration(node, /* isConst */ true);
}
}
return super.parseStatementContent(declaration, topLevel);
return super.parseStatementContent(context, topLevel);
}
parseAccessModifier(): ?N.Accessibility {
@@ -1844,14 +1862,19 @@ export default (superClass: Class<Parser>): Class<Parser> =>
return this.finishNode(typeCastNode, "TSTypeCastExpression");
}
return node;
return this.finishNode(node, node.type);
}
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 +1883,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 +1969,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:
@@ -1069,7 +1076,9 @@ export type TsSignatureDeclaration =
export type TsSignatureDeclarationOrIndexSignatureBase = NodeBase & {
// Not using TypeScript's "ParameterDeclaration" here, since it's inconsistent with regular functions.
parameters: $ReadOnlyArray<Identifier | RestElement | ObjectPattern>,
parameters: $ReadOnlyArray<
Identifier | RestElement | ObjectPattern | ArrayPattern,
>,
typeAnnotation: ?TsTypeAnnotation,
};

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)"
}

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