From 46949187445aebc41655daae0535d2420a85c229 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Sun, 26 Apr 2020 14:47:10 +0800 Subject: [PATCH 01/24] - Linting: Move ESLint to npm script; remove jshintrc - Babel: Switch to use "json" extension - Maintenance: Add `.editorconfig` - Travis: Add Node 10 and 12 - package.json: Add `bugs` - npm: Add npmrc to avoid `package-lock.json` --- .babelrc => .babelrc.json | 0 .editorconfig | 18 ++++++++++++ .eslintignore | 5 ++++ .eslintrc.js | 60 +++++++++++++++++++++++++++++++++++++++ .jshintrc | 20 ------------- .npmrc | 1 + .travis.yml | 13 +++++---- README.md | 20 ++++++------- gulpfile.js | 32 --------------------- package.json | 5 ++-- 10 files changed, 105 insertions(+), 69 deletions(-) rename .babelrc => .babelrc.json (100%) create mode 100644 .editorconfig create mode 100644 .eslintignore create mode 100644 .eslintrc.js delete mode 100644 .jshintrc create mode 100644 .npmrc diff --git a/.babelrc b/.babelrc.json similarity index 100% rename from .babelrc rename to .babelrc.json diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..d83d722 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,18 @@ +# This file is for unifying the coding style for different editors and IDEs +# editorconfig.org + +root = true + +[*] +end_of_line = lf +charset = utf-8 +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = space +indent_size = 4 + +[*.json] +indent_size = 2 + +[*.yml] +indent_size = 2 diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..06d1b84 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,5 @@ +node_modules +lib + +!.eslintrc.js +third_party diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..3abf717 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,60 @@ +'use strict'; +module.exports = { + extends: 'eslint:recommended', + globals: { + Atomics: 'readonly', + SharedArrayBuffer: 'readonly' + }, + overrides: [{ + files: '.eslintrc.js', + parserOptions: { + sourceType: 'script' + }, + rules: { + strict: 'error' + } + }, { + files: 'test/**', + globals: { + expect: true + }, + env: { + mocha: true + } + }], + rules: { + eqeqeq: 0, + 'no-use-before-define': 0, + 'no-shadow': 0, + 'no-new': 0, + 'no-underscore-dangle': 0, + 'no-multi-spaces': 0, + 'no-native-reassign': 0, + 'no-loop-func': 0, + 'no-lone-blocks': 0, + + semi: ['error'], + indent: ['error', 4, { SwitchCase: 1 }], + 'prefer-const': ['error'], + 'no-var': ['error'], + 'prefer-destructuring': ['error'], + 'object-shorthand': ['error'], + 'object-curly-spacing': ['error', 'always'], + quotes: ['error', 'single'], + 'quote-props': ['error', 'as-needed'], + 'brace-style': ['error', '1tbs', { allowSingleLine: true }], + 'prefer-template': ['error'] + }, + ecmaFeatures: { + jsx: false, + modules: true + }, + env: { + node: true, + es6: true + }, + parserOptions: { + sourceType: 'module', + ecmaVersion: 2018 + }, +}; diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index defbf02..0000000 --- a/.jshintrc +++ /dev/null @@ -1,20 +0,0 @@ -{ - "curly": true, - "eqeqeq": true, - "immed": true, - "indent": 4, - "eqnull": true, - "latedef": true, - "noarg": true, - "noempty": true, - "quotmark": "single", - "undef": true, - "unused": true, - "strict": true, - "trailing": true, - "validthis": true, - - "onevar": true, - - "node": true -} diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..c1ca392 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +package-lock = false diff --git a/.travis.yml b/.travis.yml index 8791ce6..003a69b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,11 @@ sudo: false language: node_js node_js: - - "4" - - "6" - - "7" - - "8.0" - - "8.1" + - 4 + - 6 + - 7 + - 8.0 + - 8.1 + - 10 + - 12 + - 14 diff --git a/README.md b/README.md index 02b3a3e..0d71c35 100644 --- a/README.md +++ b/README.md @@ -7,28 +7,28 @@ scope analyzer extracted from [esmangle project](http://github.com/estools/esman ### Example ```js -var escope = require('escope'); -var esprima = require('esprima'); -var estraverse = require('estraverse'); +const escope = require('escope'); +const esprima = require('esprima'); +const estraverse = require('estraverse'); -var ast = esprima.parse(code); -var scopeManager = escope.analyze(ast); +const ast = esprima.parse(code); +const scopeManager = escope.analyze(ast); -var currentScope = scopeManager.acquire(ast); // global scope +const currentScope = scopeManager.acquire(ast); // global scope estraverse.traverse(ast, { - enter: function(node, parent) { + enter (node, parent) { // do stuff - + if (/Function/.test(node.type)) { currentScope = scopeManager.acquire(node); // get current function scope } }, - leave: function(node, parent) { + leave (node, parent) { if (/Function/.test(node.type)) { currentScope = currentScope.upper; // set to parent scope } - + // do stuff } }); diff --git a/gulpfile.js b/gulpfile.js index 64cc31d..aa4a357 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -36,7 +36,6 @@ var gulp = require('gulp'), source = require('vinyl-source-stream'), browserify = require('browserify'), lazypipe = require('lazypipe'), - eslint = require('gulp-eslint'), fs = require('fs'); require('babel-register')({ @@ -46,29 +45,6 @@ require('babel-register')({ var TEST = [ 'test/*.js' ]; var SOURCE = [ 'src/**/*.js' ]; -var ESLINT_OPTION = { - rules: { - 'quotes': 0, - 'eqeqeq': 0, - 'no-use-before-define': 0, - 'no-shadow': 0, - 'no-new': 0, - 'no-underscore-dangle': 0, - 'no-multi-spaces': 0, - 'no-native-reassign': 0, - 'no-loop-func': 0, - 'no-lone-blocks': 0 - }, - ecmaFeatures: { - jsx: false, - modules: true - }, - env: { - node: true, - es6: true - } -}; - var BABEL_OPTIONS = JSON.parse(fs.readFileSync('.babelrc', { encoding: 'utf8' })); var build = lazypipe() @@ -106,14 +82,6 @@ gulp.task('watch', [ 'build-for-watch' ], function () { gulp.watch(SOURCE, [ 'build-for-watch' ]); }); -// Currently, not works for ES6. -gulp.task('lint', function () { - return gulp.src(SOURCE) - .pipe(eslint(ESLINT_OPTION)) - .pipe(eslint.formatEach('stylish', process.stderr)) - .pipe(eslint.failOnError()); -}); - /** * Bumping version number and tagging the repository with it. * Please read http://semver.org/ diff --git a/package.json b/package.json index 369f9e1..a4018d1 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "escope", "description": "ECMAScript scope analyzer", "homepage": "http://github.com/estools/escope", + "bugs": "http://github.com/estools/escope/issues", "main": "lib/index.js", "files": [ "lib" @@ -31,12 +32,12 @@ "babel-register": "^6.3.13", "browserify": "^14.4.0", "chai": "^4.0.2", + "eslint": "^6.8.0", "espree": "^3.1.1", "esprima": "^3.0.0", "gulp": "^3.9.0", "gulp-babel": "^6.1.1", "gulp-bump": "^2.7.0", - "gulp-eslint": "^4.0.0", "gulp-espower": "^1.0.2", "gulp-filter": "^5.0.0", "gulp-git": "^2.4.1", @@ -52,7 +53,7 @@ "scripts": { "test": "gulp travis", "unit-test": "gulp test", - "lint": "gulp lint", + "lint": "eslint .", "jsdoc": "jsdoc src/*.js README.md" } } From 80f4484e8c9af38b7722529b02195b2c374a5b3f Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Sun, 26 Apr 2020 14:48:29 +0800 Subject: [PATCH 02/24] - Linting: Apply automated fixes (e.g., prefer-const) - Linting: Remove deprecated `ecmaFeatures` from config --- .eslintrc.js | 4 - gulpfile.js | 24 ++--- src/definition.js | 2 +- src/index.js | 4 +- src/pattern-visitor.js | 4 +- src/referencer.js | 94 ++++++++++---------- src/scope-manager.js | 4 +- src/scope.js | 122 +++++++++++++------------- test/child-visitor-keys.js | 4 +- test/es6-arrow-function-expression.js | 6 +- test/es6-block-scope.js | 10 +-- test/es6-catch.js | 2 +- test/es6-class.js | 10 +-- test/es6-default-parameters.js | 16 ++-- test/es6-destructuring-assignments.js | 54 ++++++------ test/es6-export.js | 36 ++++---- test/es6-import.js | 16 ++-- test/es6-iteration-scope.js | 6 +- test/es6-new-target.js | 2 +- test/es6-object.js | 4 +- test/es6-rest-args.js | 4 +- test/es6-super.js | 2 +- test/es6-switch.js | 2 +- test/es6-template-literal.js | 2 +- test/fallback.js | 8 +- test/get-declared-variables.js | 10 +-- test/global-increment.js | 2 +- test/implied-strict.js | 10 +-- test/label.js | 2 +- test/nodejs-scope.js | 6 +- test/optimistic.js | 4 +- test/references.js | 58 ++++++------ 32 files changed, 265 insertions(+), 269 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 3abf717..55f0344 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -45,10 +45,6 @@ module.exports = { 'brace-style': ['error', '1tbs', { allowSingleLine: true }], 'prefer-template': ['error'] }, - ecmaFeatures: { - jsx: false, - modules: true - }, env: { node: true, es6: true diff --git a/gulpfile.js b/gulpfile.js index aa4a357..8c12777 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -24,7 +24,7 @@ 'use strict'; -var gulp = require('gulp'), +const gulp = require('gulp'), mocha = require('gulp-mocha'), babel = require('gulp-babel'), git = require('gulp-git'), @@ -42,12 +42,12 @@ require('babel-register')({ only: /escope\/(src|test)\// }); -var TEST = [ 'test/*.js' ]; -var SOURCE = [ 'src/**/*.js' ]; +const TEST = [ 'test/*.js' ]; +const SOURCE = [ 'src/**/*.js' ]; -var BABEL_OPTIONS = JSON.parse(fs.readFileSync('.babelrc', { encoding: 'utf8' })); +const BABEL_OPTIONS = JSON.parse(fs.readFileSync('.babelrc', { encoding: 'utf8' })); -var build = lazypipe() +const build = lazypipe() .pipe(sourcemaps.init) .pipe(babel, BABEL_OPTIONS) .pipe(sourcemaps.write) @@ -65,9 +65,9 @@ gulp.task('browserify', [ 'build' ], function () { return browserify({ entries: [ './lib/index.js' ] }) - .bundle() - .pipe(source('bundle.js')) - .pipe(gulp.dest('build')) + .bundle() + .pipe(source('bundle.js')) + .pipe(gulp.dest('build')); }); gulp.task('test', [ 'build' ], function () { @@ -100,7 +100,7 @@ function inc(importance) { // get all the files to bump version in return gulp.src(['./package.json']) // bump the version number in those files - .pipe(bump({type: importance})) + .pipe(bump({ type: importance })) // save it back to filesystem .pipe(gulp.dest('./')) // commit the changed version number @@ -113,9 +113,9 @@ function inc(importance) { })); } -gulp.task('patch', [ 'build' ], function () { return inc('patch'); }) -gulp.task('minor', [ 'build' ], function () { return inc('minor'); }) -gulp.task('major', [ 'build' ], function () { return inc('major'); }) +gulp.task('patch', [ 'build' ], function () { return inc('patch'); }); +gulp.task('minor', [ 'build' ], function () { return inc('minor'); }); +gulp.task('major', [ 'build' ], function () { return inc('major'); }); gulp.task('travis', [ 'test' ]); gulp.task('default', [ 'travis' ]); diff --git a/src/definition.js b/src/definition.js index faef938..a178009 100644 --- a/src/definition.js +++ b/src/definition.js @@ -73,6 +73,6 @@ class ParameterDefinition extends Definition { export { ParameterDefinition, Definition -} +}; /* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/src/index.js b/src/index.js index a345e1c..1055a8c 100644 --- a/src/index.js +++ b/src/index.js @@ -71,7 +71,7 @@ function defaultOptions() { } function updateDeeply(target, override) { - var key, val; + let key, val; function isHashObject(target) { return typeof target === 'object' && target instanceof Object && !(target instanceof Array) && !(target instanceof RegExp); @@ -115,7 +115,7 @@ function updateDeeply(target, override) { * @return {ScopeManager} */ export function analyze(tree, providedOptions) { - var scopeManager, referencer, options; + let scopeManager, referencer, options; options = updateDeeply(defaultOptions(), providedOptions); diff --git a/src/pattern-visitor.js b/src/pattern-visitor.js index b98e98a..f39cf40 100644 --- a/src/pattern-visitor.js +++ b/src/pattern-visitor.js @@ -31,7 +31,7 @@ function getLast(xs) { export default class PatternVisitor extends esrecurse.Visitor { static isPattern(node) { - var nodeType = node.type; + const nodeType = node.type; return ( nodeType === Syntax.Identifier || nodeType === Syntax.ObjectPattern || @@ -73,7 +73,7 @@ export default class PatternVisitor extends esrecurse.Visitor { } ArrayPattern(pattern) { - var i, iz, element; + let i, iz, element; for (i = 0, iz = pattern.elements.length; i < iz; ++i) { element = pattern.elements[i]; this.visit(element); diff --git a/src/referencer.js b/src/referencer.js index bd81080..5f239da 100644 --- a/src/referencer.js +++ b/src/referencer.js @@ -31,7 +31,7 @@ import assert from 'assert'; function traverseIdentifierInPattern(options, rootPattern, referencer, callback) { // Call the callback at left hand identifier nodes, and Collect right hand nodes. - var visitor = new PatternVisitor(options, rootPattern, callback); + const visitor = new PatternVisitor(options, rootPattern, callback); visitor.visit(rootPattern); // Process the right hand nodes recursively. @@ -63,24 +63,24 @@ class Importer extends esrecurse.Visitor { this.declaration, null, null - )); + )); }); } ImportNamespaceSpecifier(node) { - let local = (node.local || node.id); + const local = (node.local || node.id); if (local) { this.visitImport(local, node); } } ImportDefaultSpecifier(node) { - let local = (node.local || node.id); + const local = (node.local || node.id); this.visitImport(local, node); } ImportSpecifier(node) { - let local = (node.local || node.id); + const local = (node.local || node.id); if (node.name) { this.visitImport(node.name, node); } else { @@ -110,7 +110,7 @@ export default class Referencer extends esrecurse.Visitor { } pushInnerMethodDefinition(isInnerMethodDefinition) { - var previous = this.isInnerMethodDefinition; + const previous = this.isInnerMethodDefinition; this.isInnerMethodDefinition = isInnerMethodDefinition; return previous; } @@ -128,7 +128,7 @@ export default class Referencer extends esrecurse.Visitor { materializeIterationScope(node) { // Generate iteration scope for upper ForIn/ForOf Statements. - var letOrConstDecl; + let letOrConstDecl; this.scopeManager.__nestForScope(node); letOrConstDecl = node.left; this.visitVariableDeclaration(this.currentScope(), Variable.Variable, letOrConstDecl, 0); @@ -153,7 +153,7 @@ export default class Referencer extends esrecurse.Visitor { visitPattern(node, options, callback) { if (typeof options === 'function') { callback = options; - options = {processRightHandNodes: false} + options = { processRightHandNodes: false }; } traverseIdentifierInPattern( this.options, @@ -163,7 +163,7 @@ export default class Referencer extends esrecurse.Visitor { } visitFunction(node) { - var i, iz; + let i, iz; // FunctionDeclaration name is defined in upper scope // NOTE: Not referring variableScope. It is intended. // Since @@ -172,14 +172,14 @@ export default class Referencer extends esrecurse.Visitor { if (node.type === Syntax.FunctionDeclaration) { // id is defined in upper scope this.currentScope().__define(node.id, - new Definition( - Variable.FunctionName, - node.id, - node, - null, - null, - null - )); + new Definition( + Variable.FunctionName, + node.id, + node, + null, + null, + null + )); } // FunctionExpression with name creates its special scope; @@ -193,7 +193,7 @@ export default class Referencer extends esrecurse.Visitor { // Process parameter declarations. for (i = 0, iz = node.params.length; i < iz; ++i) { - this.visitPattern(node.params[i], {processRightHandNodes: true}, (pattern, info) => { + this.visitPattern(node.params[i], { processRightHandNodes: true }, (pattern, info) => { this.currentScope().__define(pattern, new ParameterDefinition( pattern, @@ -235,14 +235,14 @@ export default class Referencer extends esrecurse.Visitor { visitClass(node) { if (node.type === Syntax.ClassDeclaration) { this.currentScope().__define(node.id, - new Definition( - Variable.ClassName, - node.id, - node, - null, - null, - null - )); + new Definition( + Variable.ClassName, + node.id, + node, + null, + null, + null + )); } // FIXME: Maybe consider TDZ. @@ -252,11 +252,11 @@ export default class Referencer extends esrecurse.Visitor { if (node.id) { this.currentScope().__define(node.id, - new Definition( - Variable.ClassName, - node.id, - node - )); + new Definition( + Variable.ClassName, + node.id, + node + )); } this.visit(node.body); @@ -264,7 +264,7 @@ export default class Referencer extends esrecurse.Visitor { } visitProperty(node) { - var previous, isMethodDefinition; + let previous, isMethodDefinition; if (node.computed) { this.visit(node.key); } @@ -295,12 +295,12 @@ export default class Referencer extends esrecurse.Visitor { this.currentScope().__referencing(pattern, Reference.WRITE, node.right, null, true, true); }); } else { - this.visitPattern(node.left, {processRightHandNodes: true}, (pattern, info) => { - var maybeImplicitGlobal = null; + this.visitPattern(node.left, { processRightHandNodes: true }, (pattern, info) => { + let maybeImplicitGlobal = null; if (!this.currentScope().isStrict) { maybeImplicitGlobal = { - pattern: pattern, - node: node + pattern, + node }; } this.referencingDefaultValue(pattern, info.assignments, maybeImplicitGlobal, false); @@ -314,11 +314,11 @@ export default class Referencer extends esrecurse.Visitor { visitVariableDeclaration(variableTargetScope, type, node, index, fromTDZ) { // If this was called to initialize a TDZ scope, this needs to make definitions, but doesn't make references. - var decl, init; + let decl, init; decl = node.declarations[index]; init = decl.init; - this.visitPattern(decl.id, {processRightHandNodes: !fromTDZ}, (pattern, info) => { + this.visitPattern(decl.id, { processRightHandNodes: !fromTDZ }, (pattern, info) => { variableTargetScope.__define(pattern, new Definition( type, @@ -341,12 +341,12 @@ export default class Referencer extends esrecurse.Visitor { AssignmentExpression(node) { if (PatternVisitor.isPattern(node.left)) { if (node.operator === '=') { - this.visitPattern(node.left, {processRightHandNodes: true}, (pattern, info) => { - var maybeImplicitGlobal = null; + this.visitPattern(node.left, { processRightHandNodes: true }, (pattern, info) => { + let maybeImplicitGlobal = null; if (!this.currentScope().isStrict) { maybeImplicitGlobal = { - pattern: pattern, - node: node + pattern, + node }; } this.referencingDefaultValue(pattern, info.assignments, maybeImplicitGlobal, false); @@ -364,7 +364,7 @@ export default class Referencer extends esrecurse.Visitor { CatchClause(node) { this.scopeManager.__nestCatchScope(node); - this.visitPattern(node.param, {processRightHandNodes: true}, (pattern, info) => { + this.visitPattern(node.param, { processRightHandNodes: true }, (pattern, info) => { this.currentScope().__define(pattern, new Definition( Variable.CatchClause, @@ -494,7 +494,7 @@ export default class Referencer extends esrecurse.Visitor { } VariableDeclaration(node) { - var variableTargetScope, i, iz, decl; + let variableTargetScope, i, iz, decl; variableTargetScope = (node.kind === 'var') ? this.currentScope().variableScope : this.currentScope(); for (i = 0, iz = node.declarations.length; i < iz; ++i) { decl = node.declarations[i]; @@ -507,7 +507,7 @@ export default class Referencer extends esrecurse.Visitor { // sec 13.11.8 SwitchStatement(node) { - var i, iz; + let i, iz; this.visit(node.discriminant); @@ -543,7 +543,7 @@ export default class Referencer extends esrecurse.Visitor { } ImportDeclaration(node) { - var importer; + let importer; assert(this.scopeManager.__isES6() && this.scopeManager.isModule(), 'ImportDeclaration should appear when the mode is ES6 and in the module context.'); @@ -572,7 +572,7 @@ export default class Referencer extends esrecurse.Visitor { } ExportSpecifier(node) { - let local = (node.id || node.local); + const local = (node.id || node.local); this.visit(local); } diff --git a/src/scope-manager.js b/src/scope-manager.js index c174ab0..5ffbc03 100644 --- a/src/scope-manager.js +++ b/src/scope-manager.js @@ -107,7 +107,7 @@ export default class ScopeManager { * @return {Scope?} */ acquire(node, inner) { - var scopes, scope, i, iz; + let scopes, scope, i, iz; function predicate(scope) { if (scope.type === 'function' && scope.functionExpressionScope) { @@ -167,7 +167,7 @@ export default class ScopeManager { * @return {Scope?} upper scope for the node. */ release(node, inner) { - var scopes, scope; + let scopes, scope; scopes = this.__get(node); if (scopes && scopes.length) { scope = scopes[0].upper; diff --git a/src/scope.js b/src/scope.js index 254bcb5..f4e115b 100644 --- a/src/scope.js +++ b/src/scope.js @@ -30,7 +30,7 @@ import Definition from './definition'; import assert from 'assert'; function isStrictScope(scope, block, isMethodDefinition, useDirective) { - var body, i, iz, stmt, expr; + let body, i, iz, stmt, expr; // When upper scope is exists and strict, inner scope is also strict. if (scope.upper && scope.upper.isStrict) { @@ -102,7 +102,7 @@ function isStrictScope(scope, block, isMethodDefinition, useDirective) { } function registerScope(scopeManager, scope) { - var scopes; + let scopes; scopeManager.scopes.push(scope); @@ -131,7 +131,7 @@ export default class Scope { * @member {String} Scope#type */ this.type = type; - /** + /** * The scoped {@link Variable}s of this scope, as { Variable.name * : Variable }. * @member {Map} Scope#set @@ -158,19 +158,19 @@ export default class Scope { * @member {esprima.Node} Scope#block */ this.block = block; - /** + /** * The {@link Reference|references} that are not resolved with this scope. * @member {Reference[]} Scope#through */ this.through = []; - /** + /** * The scoped {@link Variable}s of this scope. In the case of a * 'function' scope this includes the automatic argument arguments as * its first element, as well as all further formal arguments. * @member {Variable[]} Scope#variables */ this.variables = []; - /** + /** * Any variable {@link Reference|reference} found in this scope. This * includes occurrences of local variables as well as variables from * parent scopes (including the global scope). For local variables @@ -181,7 +181,7 @@ export default class Scope { */ this.references = []; - /** + /** * For 'global' and 'function' scopes, this is a self-reference. For * other scope types this is the variableScope value of the * parent scope. @@ -189,35 +189,35 @@ export default class Scope { */ this.variableScope = (this.type === 'global' || this.type === 'function' || this.type === 'module') ? this : upperScope.variableScope; - /** + /** * Whether this scope is created by a FunctionExpression. * @member {boolean} Scope#functionExpressionScope */ this.functionExpressionScope = false; - /** + /** * Whether this is a scope that contains an 'eval()' invocation. * @member {boolean} Scope#directCallToEvalScope */ this.directCallToEvalScope = false; - /** + /** * @member {boolean} Scope#thisFound */ this.thisFound = false; this.__left = []; - /** + /** * Reference to the parent {@link Scope|scope}. * @member {Scope} Scope#upper */ this.upper = upperScope; - /** + /** * Whether 'use strict' is in effect in this scope. * @member {boolean} Scope#isStrict */ this.isStrict = isStrictScope(this, block, isMethodDefinition, scopeManager.__useDirective()); - /** + /** * List of nested {@link Scope}s. * @member {Scope[]} Scope#childScopes */ @@ -237,13 +237,13 @@ export default class Scope { __shouldStaticallyCloseForGlobal(ref) { // On global scope, let/const/class declarations should be resolved statically. - var name = ref.identifier.name; + const { name } = ref.identifier; if (!this.set.has(name)) { return false; } - var variable = this.set.get(name); - var defs = variable.defs; + const variable = this.set.get(name); + const { defs } = variable; return defs.length > 0 && defs.every(shouldBeStatically); } @@ -273,7 +273,7 @@ export default class Scope { } __close(scopeManager) { - var closeRef; + let closeRef; if (this.__shouldStaticallyClose(scopeManager)) { closeRef = this.__staticCloseRef; } else if (this.type !== 'global') { @@ -284,7 +284,7 @@ export default class Scope { // Try Resolving all references in this scope. for (let i = 0, iz = this.__left.length; i < iz; ++i) { - let ref = this.__left[i]; + const ref = this.__left[i]; closeRef.call(this, ref); } this.__left = null; @@ -293,7 +293,7 @@ export default class Scope { } __resolve(ref) { - var variable, name; + let variable, name; name = ref.identifier.name; if (this.set.has(name)) { variable = this.set.get(name); @@ -321,7 +321,7 @@ export default class Scope { return; } - var variables = this.__declaredVariables.get(node); + let variables = this.__declaredVariables.get(node); if (variables == null) { variables = []; this.__declaredVariables.set(node, variables); @@ -332,7 +332,7 @@ export default class Scope { } __defineGeneric(name, set, variables, node, def) { - var variable; + let variable; variable = set.get(name); if (!variable) { @@ -356,11 +356,11 @@ export default class Scope { __define(node, def) { if (node && node.type === Syntax.Identifier) { this.__defineGeneric( - node.name, - this.set, - this.variables, - node, - def); + node.name, + this.set, + this.variables, + node, + def); } } @@ -375,13 +375,13 @@ export default class Scope { return; } - let ref = new Reference(node, this, assign || Reference.READ, writeExpr, maybeImplicitGlobal, !!partial, !!init); + const ref = new Reference(node, this, assign || Reference.READ, writeExpr, maybeImplicitGlobal, !!partial, !!init); this.references.push(ref); this.__left.push(ref); } __detectEval() { - var current; + let current; current = this; this.directCallToEvalScope = true; do { @@ -405,7 +405,7 @@ export default class Scope { * @return {Reference} */ resolve(ident) { - var ref, i, iz; + let ref, i, iz; assert(this.__isClosed(), 'Scope should be closed.'); assert(ident.type === Syntax.Identifier, 'Target should be identifier.'); for (i = 0, iz = this.references.length; i < iz; ++i) { @@ -448,7 +448,7 @@ export default class Scope { if (this.set.has(name)) { return true; } - for (var i = 0, iz = this.through.length; i < iz; ++i) { + for (let i = 0, iz = this.through.length; i < iz; ++i) { if (this.through[i].identifier.name === name) { return true; } @@ -473,9 +473,9 @@ export class GlobalScope extends Scope { } __close(scopeManager) { - let implicit = []; + const implicit = []; for (let i = 0, iz = this.__left.length; i < iz; ++i) { - let ref = this.__left[i]; + const ref = this.__left[i]; if (ref.__maybeImplicitGlobal && !this.set.has(ref.identifier.name)) { implicit.push(ref.__maybeImplicitGlobal); } @@ -483,16 +483,16 @@ export class GlobalScope extends Scope { // create an implicit global variable from assignment expression for (let i = 0, iz = implicit.length; i < iz; ++i) { - let info = implicit[i]; + const info = implicit[i]; this.__defineImplicit(info.pattern, - new Definition( - Variable.ImplicitGlobalVariable, - info.pattern, - info.node, - null, - null, - null - )); + new Definition( + Variable.ImplicitGlobalVariable, + info.pattern, + info.node, + null, + null, + null + )); } @@ -504,11 +504,11 @@ export class GlobalScope extends Scope { __defineImplicit(node, def) { if (node && node.type === Syntax.Identifier) { this.__defineGeneric( - node.name, - this.implicit.set, - this.implicit.variables, - node, - def); + node.name, + this.implicit.set, + this.implicit.variables, + node, + def); } } } @@ -523,14 +523,14 @@ export class FunctionExpressionNameScope extends Scope { constructor(scopeManager, upperScope, block) { super(scopeManager, 'function-expression-name', upperScope, block, false); this.__define(block.id, - new Definition( - Variable.FunctionName, - block.id, - block, - null, - null, - null - )); + new Definition( + Variable.FunctionName, + block.id, + block, + null, + null, + null + )); this.functionExpressionScope = true; } } @@ -552,7 +552,7 @@ export class WithScope extends Scope { } for (let i = 0, iz = this.__left.length; i < iz; ++i) { - let ref = this.__left[i]; + const ref = this.__left[i]; ref.tainted = true; this.__delegateToUpperScope(ref); } @@ -608,7 +608,7 @@ export class FunctionScope extends Scope { return true; } - let variable = this.set.get('arguments'); + const variable = this.set.get('arguments'); assert(variable, 'Always have arguments variable.'); return variable.tainted || variable.references.length !== 0; } @@ -622,11 +622,11 @@ export class FunctionScope extends Scope { __defineArguments() { this.__defineGeneric( - 'arguments', - this.set, - this.variables, - null, - null); + 'arguments', + this.set, + this.variables, + null, + null); this.taints.set('arguments', true); } } diff --git a/test/child-visitor-keys.js b/test/child-visitor-keys.js index c8d7095..9b79ab3 100644 --- a/test/child-visitor-keys.js +++ b/test/child-visitor-keys.js @@ -55,7 +55,7 @@ describe('childVisitorKeys option', function() { argument: ast.body[0].declarations[0].init }; - var result = analyze( + const result = analyze( ast, { childVisitorKeys: { @@ -81,7 +81,7 @@ describe('childVisitorKeys option', function() { argument: ast.body[0].declarations[0].init }; - var result = analyze( + const result = analyze( ast, { childVisitorKeys: { diff --git a/test/es6-arrow-function-expression.js b/test/es6-arrow-function-expression.js index af0a687..715d85d 100644 --- a/test/es6-arrow-function-expression.js +++ b/test/es6-arrow-function-expression.js @@ -35,7 +35,7 @@ describe('ES6 arrow function expression', function() { } `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; @@ -55,9 +55,9 @@ describe('ES6 arrow function expression', function() { }); it('generate bindings for parameters', function() { - const ast = parse(`var arrow = (a, b, c, d) => {}`); + const ast = parse('var arrow = (a, b, c, d) => {}'); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; diff --git a/test/es6-block-scope.js b/test/es6-block-scope.js index 861cee8..c23740e 100644 --- a/test/es6-block-scope.js +++ b/test/es6-block-scope.js @@ -34,7 +34,7 @@ describe('ES6 block scope', function() { } `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // Program and BlcokStatement scope. let scope = scopeManager.scopes[0]; @@ -59,7 +59,7 @@ describe('ES6 block scope', function() { } `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // Program and BlcokStatement scope. let scope = scopeManager.scopes[0]; @@ -86,7 +86,7 @@ describe('ES6 block scope', function() { } `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(3); let scope = scopeManager.scopes[0]; @@ -117,7 +117,7 @@ describe('ES6 block scope', function() { } `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); const globalScope = scopeManager.scopes[0]; @@ -155,7 +155,7 @@ describe('ES6 block scope', function() { }()); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(4); const globalScope = scopeManager.scopes[0]; diff --git a/test/es6-catch.js b/test/es6-catch.js index f05a4a6..5275e20 100644 --- a/test/es6-catch.js +++ b/test/es6-catch.js @@ -38,7 +38,7 @@ describe('ES6 catch', function() { } `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(4); let scope = scopeManager.scopes[0]; diff --git a/test/es6-class.js b/test/es6-class.js index 8c6ffac..a8cbe74 100644 --- a/test/es6-class.js +++ b/test/es6-class.js @@ -35,7 +35,7 @@ describe('ES6 class', function() { new Derived(); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(3); let scope = scopeManager.scopes[0]; @@ -73,7 +73,7 @@ describe('ES6 class', function() { }); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(3); let scope = scopeManager.scopes[0]; @@ -105,7 +105,7 @@ describe('ES6 class', function() { }); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(3); let scope = scopeManager.scopes[0]; @@ -139,7 +139,7 @@ describe('ES6 class', function() { }()); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(5); let scope = scopeManager.scopes[0]; @@ -177,7 +177,7 @@ describe('ES6 class', function() { let shoe = new Shoe(); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(3); const scope = scopeManager.scopes[0]; diff --git a/test/es6-default-parameters.js b/test/es6-default-parameters.js index 96f1765..6a77878 100644 --- a/test/es6-default-parameters.js +++ b/test/es6-default-parameters.js @@ -28,9 +28,9 @@ import { analyze } from '..'; describe('ES6 default parameters:', function() { describe('a default parameter creates a writable reference for its initialization:', function() { const patterns = { - FunctionDeclaration: `function foo(a, b = 0) {}`, - FunctionExpression: `let foo = function(a, b = 0) {};`, - ArrowExpression: `let foo = (a, b = 0) => {};` + FunctionDeclaration: 'function foo(a, b = 0) {}', + FunctionExpression: 'let foo = function(a, b = 0) {};', + ArrowExpression: 'let foo = (a, b = 0) => {};' }; for (const name in patterns) { @@ -40,7 +40,7 @@ describe('ES6 default parameters:', function() { const numVars = name === 'ArrowExpression' ? 2 : 3; const ast = espree(code); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // [global, foo] const scope = scopeManager.scopes[1]; @@ -82,7 +82,7 @@ describe('ES6 default parameters:', function() { const numVars = name === 'ArrowExpression' ? 1 : 2; const ast = espree(code); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // [global, foo] const scope = scopeManager.scopes[1]; @@ -124,7 +124,7 @@ describe('ES6 default parameters:', function() { const numVars = name === 'ArrowExpression' ? 1 : 2; const ast = espree(code); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // [global, foo] const scope = scopeManager.scopes[1]; @@ -166,7 +166,7 @@ describe('ES6 default parameters:', function() { const numVars = name === 'ArrowExpression' ? 1 : 2; const ast = espree(code); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // [global, foo] const scope = scopeManager.scopes[1]; @@ -207,7 +207,7 @@ describe('ES6 default parameters:', function() { it(name, function() { const ast = espree(code); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(3); // [global, foo, anonymous] const scope = scopeManager.scopes[2]; diff --git a/test/es6-destructuring-assignments.js b/test/es6-destructuring-assignments.js index 76eb999..7c395d9 100644 --- a/test/es6-destructuring-assignments.js +++ b/test/es6-destructuring-assignments.js @@ -34,7 +34,7 @@ describe('ES6 destructuring assignments', function() { }()); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; @@ -75,7 +75,7 @@ describe('ES6 destructuring assignments', function() { }()); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(4); // [global, function, TDZ, for] let scope = scopeManager.scopes[0]; @@ -123,7 +123,7 @@ describe('ES6 destructuring assignments', function() { }()); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; @@ -173,7 +173,7 @@ describe('ES6 destructuring assignments', function() { }()); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(4); // [global, function, TDZ, for] let scope = scopeManager.scopes[0]; @@ -234,7 +234,7 @@ describe('ES6 destructuring assignments', function() { }()); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; @@ -299,7 +299,7 @@ describe('ES6 destructuring assignments', function() { }()); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(4); // [global, function, TDZ, for] let scope = scopeManager.scopes[0]; @@ -375,7 +375,7 @@ describe('ES6 destructuring assignments', function() { }()); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; @@ -426,7 +426,7 @@ describe('ES6 destructuring assignments', function() { }()); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; @@ -470,7 +470,7 @@ describe('ES6 destructuring assignments', function() { }()); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; @@ -511,7 +511,7 @@ describe('ES6 destructuring assignments', function() { }()); `); - let scopeManager = analyze(ast, {ecmaVersion: 6}); + let scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; @@ -550,7 +550,7 @@ describe('ES6 destructuring assignments', function() { }()); `); - scopeManager = analyze(ast, {ecmaVersion: 6}); + scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); scope = scopeManager.scopes[0]; @@ -606,7 +606,7 @@ describe('ES6 destructuring assignments', function() { }()); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; @@ -653,7 +653,7 @@ describe('ES6 destructuring assignments', function() { }()); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; @@ -705,7 +705,7 @@ describe('ES6 destructuring assignments', function() { }()); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; @@ -749,7 +749,7 @@ describe('ES6 destructuring assignments', function() { }()); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; @@ -789,7 +789,7 @@ describe('ES6 destructuring assignments', function() { }()); `); - let scopeManager = analyze(ast, {ecmaVersion: 6}); + let scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; @@ -830,7 +830,7 @@ describe('ES6 destructuring assignments', function() { }()); `); - scopeManager = analyze(ast, {ecmaVersion: 6}); + scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); scope = scopeManager.scopes[0]; @@ -878,7 +878,7 @@ describe('ES6 destructuring assignments', function() { }()); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; @@ -925,7 +925,7 @@ describe('ES6 destructuring assignments', function() { }()); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; @@ -974,7 +974,7 @@ describe('ES6 destructuring assignments', function() { }()); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; @@ -1022,7 +1022,7 @@ describe('ES6 destructuring assignments', function() { }(array)); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; @@ -1049,7 +1049,7 @@ describe('ES6 destructuring assignments', function() { }(array)); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; @@ -1132,7 +1132,7 @@ describe('ES6 destructuring assignments', function() { }(object)); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; @@ -1165,7 +1165,7 @@ describe('ES6 destructuring assignments', function() { }(object)); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; @@ -1202,7 +1202,7 @@ describe('ES6 destructuring assignments', function() { }()); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; @@ -1244,7 +1244,7 @@ describe('ES6 destructuring assignments', function() { }()); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; @@ -1287,7 +1287,7 @@ describe('ES6 destructuring assignments', function() { }()); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; diff --git a/test/es6-export.js b/test/es6-export.js index 018e7ec..dabe3cb 100644 --- a/test/es6-export.js +++ b/test/es6-export.js @@ -28,9 +28,9 @@ import { analyze } from '..'; describe('export declaration', function() { // http://people.mozilla.org/~jorendorff/es6-draft.html#sec-static-and-runtme-semantics-module-records it('should create vairable bindings', function() { - const ast = espree(`export var v;`, {sourceType: 'module'}); + const ast = espree('export var v;', { sourceType: 'module' }); - const scopeManager = analyze(ast, {ecmaVersion: 6, sourceType: 'module'}); + const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(2); const globalScope = scopeManager.scopes[0]; expect(globalScope.type).to.be.equal('global'); @@ -46,9 +46,9 @@ describe('export declaration', function() { }); it('should create function declaration bindings', function() { - const ast = espree(`export default function f(){};`, {sourceType: 'module'}); + const ast = espree('export default function f(){};', { sourceType: 'module' }); - const scopeManager = analyze(ast, {ecmaVersion: 6, sourceType: 'module'}); + const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(3); const globalScope = scopeManager.scopes[0]; expect(globalScope.type).to.be.equal('global'); @@ -71,9 +71,9 @@ describe('export declaration', function() { it('should export function expression', function() { - const ast = espree(`export default function(){};`, {sourceType: 'module'}); + const ast = espree('export default function(){};', { sourceType: 'module' }); - const scopeManager = analyze(ast, {ecmaVersion: 6, sourceType: 'module'}); + const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(3); const globalScope = scopeManager.scopes[0]; expect(globalScope.type).to.be.equal('global'); @@ -93,9 +93,9 @@ describe('export declaration', function() { }); it('should export literal', function() { - const ast = espree(`export default 42;`, {sourceType: 'module'}); + const ast = espree('export default 42;', { sourceType: 'module' }); - const scopeManager = analyze(ast, {ecmaVersion: 6, sourceType: 'module'}); + const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(2); const globalScope = scopeManager.scopes[0]; expect(globalScope.type).to.be.equal('global'); @@ -109,9 +109,9 @@ describe('export declaration', function() { }); it('should refer exported references#1', function() { - const ast = espree(`export {x};`, {sourceType: 'module'}); + const ast = espree('export {x};', { sourceType: 'module' }); - const scopeManager = analyze(ast, {ecmaVersion: 6, sourceType: 'module'}); + const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(2); const globalScope = scopeManager.scopes[0]; expect(globalScope.type).to.be.equal('global'); @@ -126,9 +126,9 @@ describe('export declaration', function() { }); it('should refer exported references#2', function() { - const ast = espree(`export {v as x};`, {sourceType: 'module'}); + const ast = espree('export {v as x};', { sourceType: 'module' }); - const scopeManager = analyze(ast, {ecmaVersion: 6, sourceType: 'module'}); + const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(2); const globalScope = scopeManager.scopes[0]; expect(globalScope.type).to.be.equal('global'); @@ -143,9 +143,9 @@ describe('export declaration', function() { }); it('should not refer exported references from other source#1', function() { - const ast = espree(`export {x} from "mod";`, {sourceType: 'module'}); + const ast = espree('export {x} from "mod";', { sourceType: 'module' }); - const scopeManager = analyze(ast, {ecmaVersion: 6, sourceType: 'module'}); + const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(2); const globalScope = scopeManager.scopes[0]; expect(globalScope.type).to.be.equal('global'); @@ -159,9 +159,9 @@ describe('export declaration', function() { }); it('should not refer exported references from other source#2', function() { - const ast = espree(`export {v as x} from "mod";`, {sourceType: 'module'}); + const ast = espree('export {v as x} from "mod";', { sourceType: 'module' }); - const scopeManager = analyze(ast, {ecmaVersion: 6, sourceType: 'module'}); + const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(2); const globalScope = scopeManager.scopes[0]; expect(globalScope.type).to.be.equal('global'); @@ -175,9 +175,9 @@ describe('export declaration', function() { }); it('should not refer exported references from other source#3', function() { - const ast = espree(`export * from "mod";`, {sourceType: 'module'}); + const ast = espree('export * from "mod";', { sourceType: 'module' }); - const scopeManager = analyze(ast, {ecmaVersion: 6, sourceType: 'module'}); + const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(2); const globalScope = scopeManager.scopes[0]; expect(globalScope.type).to.be.equal('global'); diff --git a/test/es6-import.js b/test/es6-import.js index 48e996b..ef6b0a9 100644 --- a/test/es6-import.js +++ b/test/es6-import.js @@ -28,9 +28,9 @@ import { analyze } from '..'; describe('import declaration', function() { // http://people.mozilla.org/~jorendorff/es6-draft.html#sec-static-and-runtme-semantics-module-records it('should import names from source', function() { - const ast = espree(`import v from "mod";`, {sourceType: 'module'}); + const ast = espree('import v from "mod";', { sourceType: 'module' }); - const scopeManager = analyze(ast, {ecmaVersion: 6, sourceType: 'module'}); + const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(2); const globalScope = scopeManager.scopes[0]; expect(globalScope.type).to.be.equal('global'); @@ -47,10 +47,10 @@ describe('import declaration', function() { }); it('should import namespaces', function() { - const ast = espree( `import * as ns from "mod";`, {sourceType: 'module' + const ast = espree( 'import * as ns from "mod";', { sourceType: 'module' }); - const scopeManager = analyze(ast, {ecmaVersion: 6, sourceType: 'module'}); + const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(2); const globalScope = scopeManager.scopes[0]; expect(globalScope.type).to.be.equal('global'); @@ -67,10 +67,10 @@ describe('import declaration', function() { }); it('should import insided names#1', function() { - const ast = espree(`import {x} from "mod";`, {sourceType: 'module' + const ast = espree('import {x} from "mod";', { sourceType: 'module' }); - const scopeManager = analyze(ast, {ecmaVersion: 6, sourceType: 'module'}); + const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(2); const globalScope = scopeManager.scopes[0]; expect(globalScope.type).to.be.equal('global'); @@ -87,9 +87,9 @@ describe('import declaration', function() { }); it('should import insided names#2', function() { - const ast = espree(`import {x as v} from "mod";`, {sourceType: 'module'}); + const ast = espree('import {x as v} from "mod";', { sourceType: 'module' }); - const scopeManager = analyze(ast, {ecmaVersion: 6, sourceType: 'module'}); + const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(2); const globalScope = scopeManager.scopes[0]; expect(globalScope.type).to.be.equal('global'); diff --git a/test/es6-iteration-scope.js b/test/es6-iteration-scope.js index d1957e7..98e58e9 100644 --- a/test/es6-iteration-scope.js +++ b/test/es6-iteration-scope.js @@ -36,7 +36,7 @@ describe('ES6 iteration scope', function() { }()); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(5); let scope = scopeManager.scopes[0]; @@ -89,7 +89,7 @@ describe('ES6 iteration scope', function() { }()); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(5); let scope = scopeManager.scopes[0]; @@ -153,7 +153,7 @@ describe('ES6 iteration scope', function() { }()); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(4); let scope = scopeManager.scopes[0]; diff --git a/test/es6-new-target.js b/test/es6-new-target.js index 029a31f..dadc8a2 100644 --- a/test/es6-new-target.js +++ b/test/es6-new-target.js @@ -36,7 +36,7 @@ describe('ES6 new.target', function() { } `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(3); const scope = scopeManager.scopes[2]; diff --git a/test/es6-object.js b/test/es6-object.js index 0fd7623..bda3326 100644 --- a/test/es6-object.js +++ b/test/es6-object.js @@ -33,7 +33,7 @@ describe('ES6 object', function() { } })`); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; @@ -64,7 +64,7 @@ describe('ES6 object', function() { }()); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(4); let scope = scopeManager.scopes[0]; diff --git a/test/es6-rest-args.js b/test/es6-rest-args.js index 89ff2da..fa10ffc 100644 --- a/test/es6-rest-args.js +++ b/test/es6-rest-args.js @@ -34,7 +34,7 @@ describe('ES6 rest arguments', function() { } `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; @@ -59,7 +59,7 @@ describe('ES6 rest arguments', function() { } `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; diff --git a/test/es6-super.js b/test/es6-super.js index 4da988d..0813f5e 100644 --- a/test/es6-super.js +++ b/test/es6-super.js @@ -39,7 +39,7 @@ describe('ES6 super', function() { } `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(4); let scope = scopeManager.scopes[0]; diff --git a/test/es6-switch.js b/test/es6-switch.js index e32061a..7a92a4d 100644 --- a/test/es6-switch.js +++ b/test/es6-switch.js @@ -40,7 +40,7 @@ describe('ES6 switch', function() { } `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; diff --git a/test/es6-template-literal.js b/test/es6-template-literal.js index 113f795..363e8db 100644 --- a/test/es6-template-literal.js +++ b/test/es6-template-literal.js @@ -36,7 +36,7 @@ describe('ES6 template literal', function() { }()); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(3); let scope = scopeManager.scopes[0]; diff --git a/test/fallback.js b/test/fallback.js index 0cd001c..931ff5b 100644 --- a/test/fallback.js +++ b/test/fallback.js @@ -34,8 +34,8 @@ describe('fallback option', function() { ast.body[0].declarations[0].init.type = 'NumericLiteral'; expect(function() { - analyze(ast, {fallback: 'none'}); - }).to.throw("Unknown node type NumericLiteral"); + analyze(ast, { fallback: 'none' }); + }).to.throw('Unknown node type NumericLiteral'); }); it('should not raise an error even if it encountered an unknown node when fallback is iteration.', function() { @@ -46,7 +46,7 @@ describe('fallback option', function() { ast.body[0].declarations[0].init.type = 'NumericLiteral'; analyze(ast); // default is `fallback: 'iteration'` - analyze(ast, {fallback: 'iteration'}); + analyze(ast, { fallback: 'iteration' }); }); it('should not raise an error even if it encountered an unknown node when fallback is a function.', function() { @@ -56,7 +56,7 @@ describe('fallback option', function() { ast.body[0].declarations[0].init.type = 'NumericLiteral'; - analyze(ast, {fallback: node => Object.keys(node)}); + analyze(ast, { fallback: node => Object.keys(node) }); }); }); diff --git a/test/get-declared-variables.js b/test/get-declared-variables.js index ef0e227..62ffdb8 100644 --- a/test/get-declared-variables.js +++ b/test/get-declared-variables.js @@ -206,7 +206,7 @@ describe('ScopeManager.prototype.getDeclaredVariables', function() { import "aaa"; import * as a from "bbb"; import b, {c, x as d} from "ccc";`, - {sourceType: 'module'} + { sourceType: 'module' } ); verify(ast, 'ImportDeclaration', [ @@ -222,7 +222,7 @@ describe('ScopeManager.prototype.getDeclaredVariables', function() { import "aaa"; import * as a from "bbb"; import b, {c, x as d} from "ccc";`, - {sourceType: 'module'} + { sourceType: 'module' } ); verify(ast, 'ImportSpecifier', [ @@ -237,7 +237,7 @@ describe('ScopeManager.prototype.getDeclaredVariables', function() { import "aaa"; import * as a from "bbb"; import b, {c, x as d} from "ccc";`, - {sourceType: 'module'} + { sourceType: 'module' } ); verify(ast, 'ImportDefaultSpecifier', [ @@ -251,7 +251,7 @@ describe('ScopeManager.prototype.getDeclaredVariables', function() { import "aaa"; import * as a from "bbb"; import b, {c, x as d} from "ccc";`, - {sourceType: 'module'} + { sourceType: 'module' } ); verify(ast, 'ImportNamespaceSpecifier', [ @@ -261,7 +261,7 @@ describe('ScopeManager.prototype.getDeclaredVariables', function() { it('should not get duplicate even if it\'s declared twice', function() { - const ast = espree(`var a = 0, a = 1;`); + const ast = espree('var a = 0, a = 1;'); verify(ast, 'VariableDeclaration', [ ['a'] diff --git a/test/global-increment.js b/test/global-increment.js index b613473..b4d887c 100644 --- a/test/global-increment.js +++ b/test/global-increment.js @@ -27,7 +27,7 @@ import { analyze } from '..'; describe('global increment', function() { it('becomes read/write', function() { - const ast = parse(`b++;`); + const ast = parse('b++;'); const scopeManager = analyze(ast); expect(scopeManager.scopes).to.have.length(1); diff --git a/test/implied-strict.js b/test/implied-strict.js index f415e15..cadfe22 100644 --- a/test/implied-strict.js +++ b/test/implied-strict.js @@ -35,7 +35,7 @@ describe('impliedStrict option', function() { } `); - const scopeManager = analyze(ast, {ecmaVersion: 5, impliedStrict: true}); + const scopeManager = analyze(ast, { ecmaVersion: 5, impliedStrict: true }); expect(scopeManager.scopes).to.have.length(3); let scope = scopeManager.scopes[0]; @@ -59,7 +59,7 @@ describe('impliedStrict option', function() { function foo() {} `); - const scopeManager = analyze(ast, {ecmaVersion: 3, impliedStrict: true}); + const scopeManager = analyze(ast, { ecmaVersion: 3, impliedStrict: true }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; @@ -78,7 +78,7 @@ describe('impliedStrict option', function() { function foo() {} `); - let scopeManager = analyze(ast, {ecmaVersion: 5, nodejsScope: true, impliedStrict: true}); + const scopeManager = analyze(ast, { ecmaVersion: 5, nodejsScope: true, impliedStrict: true }); expect(scopeManager.scopes).to.have.length(3); let scope = scopeManager.scopes[0]; @@ -100,10 +100,10 @@ describe('impliedStrict option', function() { it('omits a module global scope when ensuring all user scopes are strict', function() { const ast = parse(` function foo() {}`, - {sourceType: 'module'} + { sourceType: 'module' } ); - let scopeManager = analyze(ast, {ecmaVersion: 6, impliedStrict: true, sourceType: 'module'}); + const scopeManager = analyze(ast, { ecmaVersion: 6, impliedStrict: true, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(3); let scope = scopeManager.scopes[0]; diff --git a/test/label.js b/test/label.js index 6b67f89..bd92ed6 100644 --- a/test/label.js +++ b/test/label.js @@ -27,7 +27,7 @@ import { analyze } from '..'; describe('label', function() { it('should not create variables', function() { - const ast = parse(`function bar() { q: for(;;) { break q; } }`); + const ast = parse('function bar() { q: for(;;) { break q; } }'); const scopeManager = analyze(ast); expect(scopeManager.scopes).to.have.length(2); diff --git a/test/nodejs-scope.js b/test/nodejs-scope.js index 2ea861e..a424961 100644 --- a/test/nodejs-scope.js +++ b/test/nodejs-scope.js @@ -32,7 +32,7 @@ describe('nodejsScope option', function() { var hello = 20; `); - const scopeManager = analyze(ast, {ecmaVersion: 6, nodejsScope: true}); + const scopeManager = analyze(ast, { ecmaVersion: 6, nodejsScope: true }); expect(scopeManager.scopes).to.have.length(2); let scope = scopeManager.scopes[0]; @@ -53,10 +53,10 @@ describe('nodejsScope option', function() { it('creates a function scope following the global scope immediately and creates module scope', function() { const ast = parse(` import {x as v} from "mod";`, - {sourceType: 'module' } + { sourceType: 'module' } ); - const scopeManager = analyze(ast, {ecmaVersion: 6, nodejsScope: true, sourceType: 'module'}); + const scopeManager = analyze(ast, { ecmaVersion: 6, nodejsScope: true, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(3); let scope = scopeManager.scopes[0]; diff --git a/test/optimistic.js b/test/optimistic.js index 4144d04..6793cda 100644 --- a/test/optimistic.js +++ b/test/optimistic.js @@ -37,7 +37,7 @@ describe('optimistic', function() { } `); - const { scopes } = analyze(ast, {optimistic: true}); + const { scopes } = analyze(ast, { optimistic: true }); expect(scopes.map(scope => scope.variables.map(variable => variable.name))).to.be.eql( [ @@ -67,7 +67,7 @@ describe('optimistic', function() { } `); - const { scopes } = analyze(ast, {optimistic: true}); + const { scopes } = analyze(ast, { optimistic: true }); expect(scopes.map(scope => scope.variables.map(variable => variable.name))).to.be.eql( [ diff --git a/test/references.js b/test/references.js index c76cc6f..d5194bf 100644 --- a/test/references.js +++ b/test/references.js @@ -28,9 +28,9 @@ import { analyze } from '..'; describe('References:', function() { describe('When there is a `let` declaration on global,', function() { it('the reference on global should be resolved.', function() { - const ast = espree(`let a = 0;`); + const ast = espree('let a = 0;'); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(1); const scope = scopeManager.scopes[0]; @@ -54,7 +54,7 @@ describe('References:', function() { } `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // [global, foo] const scope = scopeManager.scopes[1]; @@ -77,7 +77,7 @@ describe('References:', function() { } `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // [global, foo] const scope = scopeManager.scopes[1]; @@ -96,9 +96,9 @@ describe('References:', function() { describe('When there is a `const` declaration on global,', function() { it('the reference on global should be resolved.', function() { - const ast = espree(`const a = 0;`); + const ast = espree('const a = 0;'); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(1); const scope = scopeManager.scopes[0]; @@ -122,7 +122,7 @@ describe('References:', function() { } `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // [global, foo] const scope = scopeManager.scopes[1]; @@ -141,9 +141,9 @@ describe('References:', function() { describe('When there is a `var` declaration on global,', function() { it('the reference on global should NOT be resolved.', function() { - const ast = espree(`var a = 0;`); + const ast = espree('var a = 0;'); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(1); const scope = scopeManager.scopes[0]; @@ -167,7 +167,7 @@ describe('References:', function() { } `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // [global, foo] const scope = scopeManager.scopes[1]; @@ -191,7 +191,7 @@ describe('References:', function() { a(); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // [global, a] const scope = scopeManager.scopes[0]; @@ -215,7 +215,7 @@ describe('References:', function() { } `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(3); // [global, a, foo] const scope = scopeManager.scopes[2]; @@ -239,7 +239,7 @@ describe('References:', function() { let b = new A(); `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // [global, A] const scope = scopeManager.scopes[0]; @@ -263,7 +263,7 @@ describe('References:', function() { } `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(3); // [global, A, foo] const scope = scopeManager.scopes[2]; @@ -288,7 +288,7 @@ describe('References:', function() { } `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // [global, foo] const scope = scopeManager.scopes[1]; @@ -314,7 +314,7 @@ describe('References:', function() { } `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(3); // [global, foo, bar] const scope = scopeManager.scopes[2]; @@ -339,7 +339,7 @@ describe('References:', function() { } `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // [global, foo] const scope = scopeManager.scopes[1]; @@ -365,7 +365,7 @@ describe('References:', function() { } `); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(3); // [global, foo, bar] const scope = scopeManager.scopes[2]; @@ -384,9 +384,9 @@ describe('References:', function() { describe('When there is a `let` declaration with destructuring assignment', function() { it('"let [a] = [1];", the reference should be resolved.', function() { - const ast = espree(`let [a] = [1];`); + const ast = espree('let [a] = [1];'); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(1); const scope = scopeManager.scopes[0]; @@ -403,9 +403,9 @@ describe('References:', function() { }); it('"let {a} = {a: 1};", the reference should be resolved.', function() { - const ast = espree(`let {a} = {a: 1};`); + const ast = espree('let {a} = {a: 1};'); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(1); const scope = scopeManager.scopes[0]; @@ -422,9 +422,9 @@ describe('References:', function() { }); it('"let {a: {a}} = {a: {a: 1}};", the reference should be resolved.', function() { - const ast = espree(`let {a: {a}} = {a: {a: 1}};`); + const ast = espree('let {a: {a}} = {a: {a: 1}};'); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(1); const scope = scopeManager.scopes[0]; @@ -480,7 +480,7 @@ describe('References:', function() { it(`"${code}", all references should be true.`, function() { const ast = espree(code); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.be.length.of.at.least(1); const scope = scopeManager.scopes[scopeManager.scopes.length - 1]; @@ -512,7 +512,7 @@ describe('References:', function() { it(`"${code}", all references should be false.`, function() { const ast = espree(code); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.be.length.of.at.least(1); const scope = scopeManager.scopes[scopeManager.scopes.length - 1]; @@ -523,7 +523,7 @@ describe('References:', function() { expect(reference.identifier.name).to.equal('a'); expect(reference.isWrite()).to.be.true; expect(reference.init).to.be.false; - }) + }); }) ); @@ -547,7 +547,7 @@ describe('References:', function() { it(`"${code}", readonly references of "a" should be undefined.`, function() { const ast = espree(code); - const scopeManager = analyze(ast, {ecmaVersion: 6}); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.be.length.of.at.least(1); const scope = scopeManager.scopes[0]; @@ -562,7 +562,7 @@ describe('References:', function() { expect(reference.init).to.be.undefined; }); }) - ) + ); }); }); From 86632c0932150d5d3785124db4f9049881e97f27 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Sun, 26 Apr 2020 15:16:42 +0800 Subject: [PATCH 03/24] - Linting: Manual fixes per config (e.g., destructuring) and moving `const`/`let` closer to necessary scope --- src/index.js | 16 ++-- src/pattern-visitor.js | 5 +- src/referencer.js | 31 +++---- src/scope-manager.js | 21 ++--- src/scope.js | 29 +++---- test/arguments.js | 4 +- test/catch-scope.js | 6 +- test/child-visitor-keys.js | 4 +- test/es6-arrow-function-expression.js | 8 +- test/es6-block-scope.js | 32 +++---- test/es6-catch.js | 8 +- test/es6-class.js | 26 +++--- test/es6-default-parameters.js | 20 ++--- test/es6-destructuring-assignments.js | 118 +++++++++++++------------- test/es6-export.js | 40 ++++----- test/es6-import.js | 16 ++-- test/es6-iteration-scope.js | 33 ++++--- test/es6-new-target.js | 2 +- test/es6-object.js | 8 +- test/es6-rest-args.js | 8 +- test/es6-super.js | 8 +- test/es6-switch.js | 4 +- test/es6-template-literal.js | 4 +- test/function-expression-name.js | 6 +- test/global-increment.js | 2 +- test/implied-strict.js | 22 ++--- test/label.js | 6 +- test/nodejs-scope.js | 10 +-- test/object-expression.js | 2 +- test/references.js | 76 ++++++++--------- test/with-scope.js | 6 +- 31 files changed, 282 insertions(+), 299 deletions(-) diff --git a/src/index.js b/src/index.js index 1055a8c..39a6630 100644 --- a/src/index.js +++ b/src/index.js @@ -71,15 +71,13 @@ function defaultOptions() { } function updateDeeply(target, override) { - let key, val; - function isHashObject(target) { return typeof target === 'object' && target instanceof Object && !(target instanceof Array) && !(target instanceof RegExp); } - for (key in override) { - if (override.hasOwnProperty(key)) { - val = override[key]; + for (const key in override) { + if (Object.hasOwnProperty.call(override, key)) { + const val = override[key]; if (isHashObject(val)) { if (isHashObject(target[key])) { updateDeeply(target[key], val); @@ -115,13 +113,11 @@ function updateDeeply(target, override) { * @return {ScopeManager} */ export function analyze(tree, providedOptions) { - let scopeManager, referencer, options; - - options = updateDeeply(defaultOptions(), providedOptions); + const options = updateDeeply(defaultOptions(), providedOptions); - scopeManager = new ScopeManager(options); + const scopeManager = new ScopeManager(options); - referencer = new Referencer(options, scopeManager); + const referencer = new Referencer(options, scopeManager); referencer.visit(tree); assert(scopeManager.__currentScope === null, 'currentScope should be null.'); diff --git a/src/pattern-visitor.js b/src/pattern-visitor.js index f39cf40..dfa8768 100644 --- a/src/pattern-visitor.js +++ b/src/pattern-visitor.js @@ -73,9 +73,8 @@ export default class PatternVisitor extends esrecurse.Visitor { } ArrayPattern(pattern) { - let i, iz, element; - for (i = 0, iz = pattern.elements.length; i < iz; ++i) { - element = pattern.elements[i]; + for (let i = 0, iz = pattern.elements.length; i < iz; ++i) { + const element = pattern.elements[i]; this.visit(element); } } diff --git a/src/referencer.js b/src/referencer.js index 5f239da..9af33df 100644 --- a/src/referencer.js +++ b/src/referencer.js @@ -128,9 +128,8 @@ export default class Referencer extends esrecurse.Visitor { materializeIterationScope(node) { // Generate iteration scope for upper ForIn/ForOf Statements. - let letOrConstDecl; this.scopeManager.__nestForScope(node); - letOrConstDecl = node.left; + const letOrConstDecl = node.left; this.visitVariableDeclaration(this.currentScope(), Variable.Variable, letOrConstDecl, 0); this.visitPattern(letOrConstDecl.declarations[0].id, (pattern) => { this.currentScope().__referencing(pattern, Reference.WRITE, node.right, null, true, true); @@ -163,7 +162,6 @@ export default class Referencer extends esrecurse.Visitor { } visitFunction(node) { - let i, iz; // FunctionDeclaration name is defined in upper scope // NOTE: Not referring variableScope. It is intended. // Since @@ -192,7 +190,7 @@ export default class Referencer extends esrecurse.Visitor { this.scopeManager.__nestFunctionScope(node, this.isInnerMethodDefinition); // Process parameter declarations. - for (i = 0, iz = node.params.length; i < iz; ++i) { + for (let i = 0, iz = node.params.length; i < iz; ++i) { this.visitPattern(node.params[i], { processRightHandNodes: true }, (pattern, info) => { this.currentScope().__define(pattern, new ParameterDefinition( @@ -264,12 +262,12 @@ export default class Referencer extends esrecurse.Visitor { } visitProperty(node) { - let previous, isMethodDefinition; + let previous; if (node.computed) { this.visit(node.key); } - isMethodDefinition = node.type === Syntax.MethodDefinition; + const isMethodDefinition = node.type === Syntax.MethodDefinition; if (isMethodDefinition) { previous = this.pushInnerMethodDefinition(true); } @@ -314,10 +312,8 @@ export default class Referencer extends esrecurse.Visitor { visitVariableDeclaration(variableTargetScope, type, node, index, fromTDZ) { // If this was called to initialize a TDZ scope, this needs to make definitions, but doesn't make references. - let decl, init; - - decl = node.declarations[index]; - init = decl.init; + const decl = node.declarations[index]; + const { init } = decl; this.visitPattern(decl.id, { processRightHandNodes: !fromTDZ }, (pattern, info) => { variableTargetScope.__define(pattern, new Definition( @@ -494,10 +490,9 @@ export default class Referencer extends esrecurse.Visitor { } VariableDeclaration(node) { - let variableTargetScope, i, iz, decl; - variableTargetScope = (node.kind === 'var') ? this.currentScope().variableScope : this.currentScope(); - for (i = 0, iz = node.declarations.length; i < iz; ++i) { - decl = node.declarations[i]; + const variableTargetScope = (node.kind === 'var') ? this.currentScope().variableScope : this.currentScope(); + for (let i = 0, iz = node.declarations.length; i < iz; ++i) { + const decl = node.declarations[i]; this.visitVariableDeclaration(variableTargetScope, Variable.Variable, node, i); if (decl.init) { this.visit(decl.init); @@ -507,15 +502,13 @@ export default class Referencer extends esrecurse.Visitor { // sec 13.11.8 SwitchStatement(node) { - let i, iz; - this.visit(node.discriminant); if (this.scopeManager.__isES6()) { this.scopeManager.__nestSwitchScope(node); } - for (i = 0, iz = node.cases.length; i < iz; ++i) { + for (let i = 0, iz = node.cases.length; i < iz; ++i) { this.visit(node.cases[i]); } @@ -543,11 +536,9 @@ export default class Referencer extends esrecurse.Visitor { } ImportDeclaration(node) { - let importer; - assert(this.scopeManager.__isES6() && this.scopeManager.isModule(), 'ImportDeclaration should appear when the mode is ES6 and in the module context.'); - importer = new Importer(node, this); + const importer = new Importer(node, this); importer.visit(node); } diff --git a/src/scope-manager.js b/src/scope-manager.js index 5ffbc03..b1d0a33 100644 --- a/src/scope-manager.js +++ b/src/scope-manager.js @@ -22,7 +22,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import Scope from './scope'; +// import Scope from './scope'; import assert from 'assert'; import { @@ -107,8 +107,6 @@ export default class ScopeManager { * @return {Scope?} */ acquire(node, inner) { - let scopes, scope, i, iz; - function predicate(scope) { if (scope.type === 'function' && scope.functionExpressionScope) { return false; @@ -119,7 +117,7 @@ export default class ScopeManager { return true; } - scopes = this.__get(node); + const scopes = this.__get(node); if (!scopes || scopes.length === 0) { return null; } @@ -131,15 +129,15 @@ export default class ScopeManager { } if (inner) { - for (i = scopes.length - 1; i >= 0; --i) { - scope = scopes[i]; + for (let i = scopes.length - 1; i >= 0; --i) { + const scope = scopes[i]; if (predicate(scope)) { return scope; } } } else { - for (i = 0, iz = scopes.length; i < iz; ++i) { - scope = scopes[i]; + for (let i = 0, iz = scopes.length; i < iz; ++i) { + const scope = scopes[i]; if (predicate(scope)) { return scope; } @@ -167,10 +165,9 @@ export default class ScopeManager { * @return {Scope?} upper scope for the node. */ release(node, inner) { - let scopes, scope; - scopes = this.__get(node); + const scopes = this.__get(node); if (scopes && scopes.length) { - scope = scopes[0].upper; + const scope = scopes[0].upper; if (!scope) { return null; } @@ -196,7 +193,7 @@ export default class ScopeManager { return this.__nestScope(new GlobalScope(this, node)); } - __nestBlockScope(node, isMethodDefinition) { + __nestBlockScope(node /* , isMethodDefinition */) { return this.__nestScope(new BlockScope(this, this.__currentScope, node)); } diff --git a/src/scope.js b/src/scope.js index f4e115b..b71378b 100644 --- a/src/scope.js +++ b/src/scope.js @@ -30,8 +30,6 @@ import Definition from './definition'; import assert from 'assert'; function isStrictScope(scope, block, isMethodDefinition, useDirective) { - let body, i, iz, stmt, expr; - // When upper scope is exists and strict, inner scope is also strict. if (scope.upper && scope.upper.isStrict) { return true; @@ -54,11 +52,12 @@ function isStrictScope(scope, block, isMethodDefinition, useDirective) { return false; } + let body; if (scope.type === 'function') { if (block.type === Syntax.Program) { body = block; } else { - body = block.body; + ({ body } = block); } } else if (scope.type === 'global') { body = block; @@ -68,8 +67,8 @@ function isStrictScope(scope, block, isMethodDefinition, useDirective) { // Search 'use strict' directive. if (useDirective) { - for (i = 0, iz = body.body.length; i < iz; ++i) { - stmt = body.body[i]; + for (let i = 0, iz = body.body.length; i < iz; ++i) { + const stmt = body.body[i]; if (stmt.type !== Syntax.DirectiveStatement) { break; } @@ -78,12 +77,12 @@ function isStrictScope(scope, block, isMethodDefinition, useDirective) { } } } else { - for (i = 0, iz = body.body.length; i < iz; ++i) { - stmt = body.body[i]; + for (let i = 0, iz = body.body.length; i < iz; ++i) { + const stmt = body.body[i]; if (stmt.type !== Syntax.ExpressionStatement) { break; } - expr = stmt.expression; + const expr = stmt.expression; if (expr.type !== Syntax.Literal || typeof expr.value !== 'string') { break; } @@ -102,11 +101,9 @@ function isStrictScope(scope, block, isMethodDefinition, useDirective) { } function registerScope(scopeManager, scope) { - let scopes; - scopeManager.scopes.push(scope); - scopes = scopeManager.__nodeToScope.get(scope.block); + const scopes = scopeManager.__nodeToScope.get(scope.block); if (scopes) { scopes.push(scope); } else { @@ -293,10 +290,9 @@ export default class Scope { } __resolve(ref) { - let variable, name; - name = ref.identifier.name; + const { name } = ref.identifier; if (this.set.has(name)) { - variable = this.set.get(name); + const variable = this.set.get(name); variable.references.push(ref); variable.stack = variable.stack && ref.from.variableScope === this.variableScope; if (ref.tainted) { @@ -405,11 +401,10 @@ export default class Scope { * @return {Reference} */ resolve(ident) { - let ref, i, iz; assert(this.__isClosed(), 'Scope should be closed.'); assert(ident.type === Syntax.Identifier, 'Target should be identifier.'); - for (i = 0, iz = this.references.length; i < iz; ++i) { - ref = this.references[i]; + for (let i = 0, iz = this.references.length; i < iz; ++i) { + const ref = this.references[i]; if (ref.identifier === ident) { return ref; } diff --git a/test/arguments.js b/test/arguments.js index 2e32a43..43bbf50 100644 --- a/test/arguments.js +++ b/test/arguments.js @@ -35,12 +35,12 @@ describe('arguments', function() { const scopeManager = analyze(ast); expect(scopeManager.scopes).to.have.length(2); - const globalScope = scopeManager.scopes[0]; + const [globalScope] = scopeManager.scopes; expect(globalScope.type).to.be.equal('global'); expect(globalScope.variables).to.have.length(0); expect(globalScope.references).to.have.length(0); - const scope = scopeManager.scopes[1]; + const [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('arguments'); diff --git a/test/catch-scope.js b/test/catch-scope.js index 0e05e3c..0d7adb5 100644 --- a/test/catch-scope.js +++ b/test/catch-scope.js @@ -37,19 +37,19 @@ describe('catch', function() { const scopeManager = analyze(ast); expect(scopeManager.scopes).to.have.length(3); - const globalScope = scopeManager.scopes[0]; + const [globalScope] = scopeManager.scopes; expect(globalScope.type).to.be.equal('global'); expect(globalScope.variables).to.have.length(0); expect(globalScope.references).to.have.length(0); - let scope = scopeManager.scopes[1]; + let [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('arguments'); expect(scope.isArgumentsMaterialized()).to.be.false; expect(scope.references).to.have.length(0); - scope = scopeManager.scopes[2]; + [, , scope] = scopeManager.scopes; expect(scope.type).to.be.equal('catch'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('e'); diff --git a/test/child-visitor-keys.js b/test/child-visitor-keys.js index 9b79ab3..d6bab62 100644 --- a/test/child-visitor-keys.js +++ b/test/child-visitor-keys.js @@ -65,7 +65,7 @@ describe('childVisitorKeys option', function() { ); expect(result.scopes).to.have.length(1); - const globalScope = result.scopes[0]; + const [globalScope] = result.scopes; // `bar` in TestNode has not been visited. expect(globalScope.through).to.have.length(0); @@ -91,7 +91,7 @@ describe('childVisitorKeys option', function() { ); expect(result.scopes).to.have.length(1); - const globalScope = result.scopes[0]; + const [globalScope] = result.scopes; // `bar` in TestNode has been visited. expect(globalScope.through).to.have.length(1); diff --git a/test/es6-arrow-function-expression.js b/test/es6-arrow-function-expression.js index 715d85d..36258b1 100644 --- a/test/es6-arrow-function-expression.js +++ b/test/es6-arrow-function-expression.js @@ -38,13 +38,13 @@ describe('ES6 arrow function expression', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.block.type).to.be.equal('Program'); expect(scope.isStrict).to.be.false; expect(scope.variables).to.have.length(1); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.block.type).to.be.equal('ArrowFunctionExpression'); expect(scope.isStrict).to.be.true; @@ -60,13 +60,13 @@ describe('ES6 arrow function expression', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.block.type).to.be.equal('Program'); expect(scope.isStrict).to.be.false; expect(scope.variables).to.have.length(1); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.block.type).to.be.equal('ArrowFunctionExpression'); expect(scope.isStrict).to.be.true; diff --git a/test/es6-block-scope.js b/test/es6-block-scope.js index c23740e..5c3160d 100644 --- a/test/es6-block-scope.js +++ b/test/es6-block-scope.js @@ -37,11 +37,11 @@ describe('ES6 block scope', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // Program and BlcokStatement scope. - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.variables).to.have.length(0); // No variable in Program scope. - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('block'); expect(scope.variables).to.have.length(1); // `i` in block scope. expect(scope.variables[0].name).to.be.equal('i'); @@ -62,12 +62,12 @@ describe('ES6 block scope', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // Program and BlcokStatement scope. - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.variables).to.have.length(1); // No variable in Program scope. expect(scope.variables[0].name).to.be.equal('i'); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('block'); expect(scope.variables).to.have.length(1); // `i` in block scope. expect(scope.variables[0].name).to.be.equal('i'); @@ -89,18 +89,18 @@ describe('ES6 block scope', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(3); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.variables).to.have.length(0); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('block'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('test'); expect(scope.references).to.have.length(1); expect(scope.references[0].identifier.name).to.be.equal('test'); - scope = scopeManager.scopes[2]; + [, , scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('arguments'); @@ -120,13 +120,13 @@ describe('ES6 block scope', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - const globalScope = scopeManager.scopes[0]; + const [globalScope] = scopeManager.scopes; expect(globalScope.type).to.be.equal('global'); expect(globalScope.variables).to.have.length(1); expect(globalScope.variables[0].name).to.be.equal('i'); expect(globalScope.references).to.have.length(1); - const scope = scopeManager.scopes[1]; + const [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('block'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('i'); @@ -158,37 +158,37 @@ describe('ES6 block scope', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(4); - const globalScope = scopeManager.scopes[0]; + const [globalScope] = scopeManager.scopes; expect(globalScope.type).to.be.equal('global'); expect(globalScope.variables).to.have.length(0); expect(globalScope.references).to.have.length(0); - let scope = scopeManager.scopes[1]; + let [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(2); expect(scope.variables[0].name).to.be.equal('arguments'); expect(scope.variables[1].name).to.be.equal('i'); - const v1 = scope.variables[1]; + const [, v1] = scope.variables; expect(scope.references).to.have.length(3); expect(scope.references[0].resolved).to.be.equal(v1); expect(scope.references[1].resolved).to.be.equal(v1); expect(scope.references[2].resolved).to.be.equal(v1); - scope = scopeManager.scopes[2]; + [, , scope] = scopeManager.scopes; expect(scope.type).to.be.equal('block'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('i'); - const v3 = scope.variables[0]; + const [v3] = scope.variables; expect(scope.references).to.have.length(3); expect(scope.references[0].resolved).to.be.equal(v3); expect(scope.references[1].resolved).to.be.equal(v3); expect(scope.references[2].resolved).to.be.equal(v3); - scope = scopeManager.scopes[3]; + [, , , scope] = scopeManager.scopes; expect(scope.type).to.be.equal('block'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('i'); - const v2 = scope.variables[0]; + const [v2] = scope.variables; expect(scope.references).to.have.length(3); expect(scope.references[0].resolved).to.be.equal(v2); expect(scope.references[1].resolved).to.be.equal(v2); diff --git a/test/es6-catch.js b/test/es6-catch.js index 5275e20..b9f0f2c 100644 --- a/test/es6-catch.js +++ b/test/es6-catch.js @@ -41,21 +41,21 @@ describe('ES6 catch', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(4); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.block.type).to.be.equal('Program'); expect(scope.isStrict).to.be.false; expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('block'); expect(scope.block.type).to.be.equal('BlockStatement'); expect(scope.isStrict).to.be.false; expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); - scope = scopeManager.scopes[2]; + [, , scope] = scopeManager.scopes; expect(scope.type).to.be.equal('catch'); expect(scope.block.type).to.be.equal('CatchClause'); expect(scope.isStrict).to.be.false; @@ -70,7 +70,7 @@ describe('ES6 catch', function() { // expect(scope.variables[3].name).to.be.equal('d'); // expect(scope.references).to.have.length(0); - scope = scopeManager.scopes[3]; + [, , , scope] = scopeManager.scopes; expect(scope.type).to.be.equal('block'); expect(scope.block.type).to.be.equal('BlockStatement'); expect(scope.isStrict).to.be.false; diff --git a/test/es6-class.js b/test/es6-class.js index a8cbe74..1aedf59 100644 --- a/test/es6-class.js +++ b/test/es6-class.js @@ -38,7 +38,7 @@ describe('ES6 class', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(3); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.block.type).to.be.equal('Program'); expect(scope.isStrict).to.be.false; @@ -48,7 +48,7 @@ describe('ES6 class', function() { expect(scope.references[0].identifier.name).to.be.equal('Base'); expect(scope.references[1].identifier.name).to.be.equal('Derived'); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('class'); expect(scope.block.type).to.be.equal('ClassDeclaration'); expect(scope.isStrict).to.be.true; @@ -56,7 +56,7 @@ describe('ES6 class', function() { expect(scope.variables[0].name).to.be.equal('Derived'); expect(scope.references).to.have.length(0); - scope = scopeManager.scopes[2]; + [, , scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.block.type).to.be.equal('FunctionExpression'); expect(scope.isStrict).to.be.true; @@ -76,7 +76,7 @@ describe('ES6 class', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(3); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.block.type).to.be.equal('Program'); expect(scope.isStrict).to.be.false; @@ -84,7 +84,7 @@ describe('ES6 class', function() { expect(scope.references).to.have.length(1); expect(scope.references[0].identifier.name).to.be.equal('Base'); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('class'); expect(scope.block.type).to.be.equal('ClassExpression'); expect(scope.isStrict).to.be.true; @@ -92,7 +92,7 @@ describe('ES6 class', function() { expect(scope.variables[0].name).to.be.equal('Derived'); expect(scope.references).to.have.length(0); - scope = scopeManager.scopes[2]; + [, , scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.block.type).to.be.equal('FunctionExpression'); }); @@ -108,7 +108,7 @@ describe('ES6 class', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(3); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.block.type).to.be.equal('Program'); expect(scope.isStrict).to.be.false; @@ -116,11 +116,11 @@ describe('ES6 class', function() { expect(scope.references).to.have.length(1); expect(scope.references[0].identifier.name).to.be.equal('Base'); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('class'); expect(scope.block.type).to.be.equal('ClassExpression'); - scope = scopeManager.scopes[2]; + [, , scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.block.type).to.be.equal('FunctionExpression'); }); @@ -142,12 +142,12 @@ describe('ES6 class', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(5); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.block.type).to.be.equal('Program'); expect(scope.isStrict).to.be.false; - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.block.type).to.be.equal('FunctionExpression'); expect(scope.isStrict).to.be.false; @@ -157,7 +157,7 @@ describe('ES6 class', function() { expect(scope.references).to.have.length(1); expect(scope.references[0].identifier.name).to.be.equal('yuyushiki'); - scope = scopeManager.scopes[2]; + [, , scope] = scopeManager.scopes; expect(scope.type).to.be.equal('class'); expect(scope.block.type).to.be.equal('ClassExpression'); expect(scope.isStrict).to.be.true; @@ -180,7 +180,7 @@ describe('ES6 class', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(3); - const scope = scopeManager.scopes[0]; + const [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.block.type).to.be.equal('Program'); expect(scope.isStrict).to.be.false; diff --git a/test/es6-default-parameters.js b/test/es6-default-parameters.js index 6a77878..e645595 100644 --- a/test/es6-default-parameters.js +++ b/test/es6-default-parameters.js @@ -43,11 +43,11 @@ describe('ES6 default parameters:', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // [global, foo] - const scope = scopeManager.scopes[1]; + const [, scope] = scopeManager.scopes; expect(scope.variables).to.have.length(numVars); // [arguments?, a, b] expect(scope.references).to.have.length(1); - const reference = scope.references[0]; + const [reference] = scope.references; expect(reference.from).to.equal(scope); expect(reference.identifier.name).to.equal('b'); expect(reference.resolved).to.equal(scope.variables[numVars - 1]); @@ -85,11 +85,11 @@ describe('ES6 default parameters:', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // [global, foo] - const scope = scopeManager.scopes[1]; + const [, scope] = scopeManager.scopes; expect(scope.variables).to.have.length(numVars); // [arguments?, b] expect(scope.references).to.have.length(2); // [b, a] - const reference = scope.references[1]; + const [, reference] = scope.references; expect(reference.from).to.equal(scope); expect(reference.identifier.name).to.equal('a'); expect(reference.resolved).to.equal(scopeManager.scopes[0].variables[0]); @@ -127,11 +127,11 @@ describe('ES6 default parameters:', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // [global, foo] - const scope = scopeManager.scopes[1]; + const [, scope] = scopeManager.scopes; expect(scope.variables).to.have.length(numVars); // [arguments?, b] expect(scope.references).to.have.length(2); // [b, a] - const reference = scope.references[1]; + const [, reference] = scope.references; expect(reference.from).to.equal(scope); expect(reference.identifier.name).to.equal('a'); expect(reference.resolved).to.equal(scopeManager.scopes[0].variables[0]); @@ -169,11 +169,11 @@ describe('ES6 default parameters:', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // [global, foo] - const scope = scopeManager.scopes[1]; + const [, scope] = scopeManager.scopes; expect(scope.variables).to.have.length(numVars); // [arguments?, b] expect(scope.references).to.have.length(2); // [b, a] - const reference = scope.references[1]; + const [, reference] = scope.references; expect(reference.from).to.equal(scope); expect(reference.identifier.name).to.equal('a'); expect(reference.resolved).to.equal(scopeManager.scopes[0].variables[0]); @@ -210,11 +210,11 @@ describe('ES6 default parameters:', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(3); // [global, foo, anonymous] - const scope = scopeManager.scopes[2]; + const [, , scope] = scopeManager.scopes; expect(scope.variables).to.have.length(1); // [arguments] expect(scope.references).to.have.length(1); // [a] - const reference = scope.references[0]; + const [reference] = scope.references; expect(reference.from).to.equal(scope); expect(reference.identifier.name).to.equal('a'); expect(reference.resolved).to.equal(scopeManager.scopes[0].variables[0]); diff --git a/test/es6-destructuring-assignments.js b/test/es6-destructuring-assignments.js index 7c395d9..99e42ce 100644 --- a/test/es6-destructuring-assignments.js +++ b/test/es6-destructuring-assignments.js @@ -37,14 +37,14 @@ describe('ES6 destructuring assignments', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); expect(scope.implicit.left).to.have.length(1); expect(scope.implicit.left[0].identifier.name).to.be.equal('array'); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(4); expect(scope.variables[0].name).to.be.equal('arguments'); @@ -78,14 +78,14 @@ describe('ES6 destructuring assignments', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(4); // [global, function, TDZ, for] - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.equal('global'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); expect(scope.implicit.left).to.have.length(1); expect(scope.implicit.left[0].identifier.name).to.equal('array'); - scope = scopeManager.scopes[2]; + [, , scope] = scopeManager.scopes; expect(scope.type).to.equal('TDZ'); expect(scope.variables).to.have.length(3); expect(scope.variables[0].name).to.equal('a'); @@ -95,7 +95,7 @@ describe('ES6 destructuring assignments', function() { expect(scope.references[0].identifier.name).to.equal('array'); expect(scope.references[0].isWrite()).to.be.false; - scope = scopeManager.scopes[3]; + [, , , scope] = scopeManager.scopes; expect(scope.type).to.equal('for'); expect(scope.variables).to.have.length(3); expect(scope.variables[0].name).to.equal('a'); @@ -126,7 +126,7 @@ describe('ES6 destructuring assignments', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.equal('global'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); @@ -134,7 +134,7 @@ describe('ES6 destructuring assignments', function() { expect(scope.implicit.left[0].identifier.name).to.equal('d'); expect(scope.implicit.left[1].identifier.name).to.equal('array'); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.equal('function'); expect(scope.variables).to.have.length(4); expect(scope.variables[0].name).to.equal('arguments'); @@ -176,7 +176,7 @@ describe('ES6 destructuring assignments', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(4); // [global, function, TDZ, for] - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.equal('global'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); @@ -186,7 +186,7 @@ describe('ES6 destructuring assignments', function() { expect(scope.implicit.left[1].identifier.name).to.equal('d'); expect(scope.implicit.left[1].from.type).to.equal('for'); - scope = scopeManager.scopes[2]; + [, , scope] = scopeManager.scopes; expect(scope.type).to.equal('TDZ'); expect(scope.variables).to.have.length(3); expect(scope.variables[0].name).to.equal('a'); @@ -196,7 +196,7 @@ describe('ES6 destructuring assignments', function() { expect(scope.references[0].identifier.name).to.equal('array'); expect(scope.references[0].isWrite()).to.be.false; - scope = scopeManager.scopes[3]; + [, , , scope] = scopeManager.scopes; expect(scope.type).to.equal('for'); expect(scope.variables).to.have.length(3); expect(scope.variables[0].name).to.equal('a'); @@ -237,7 +237,7 @@ describe('ES6 destructuring assignments', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.equal('global'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); @@ -246,7 +246,7 @@ describe('ES6 destructuring assignments', function() { expect(scope.implicit.left[1].identifier.name).to.equal('e'); expect(scope.implicit.left[2].identifier.name).to.equal('array'); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.equal('function'); expect(scope.variables).to.have.length(4); expect(scope.variables[0].name).to.equal('arguments'); @@ -302,7 +302,7 @@ describe('ES6 destructuring assignments', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(4); // [global, function, TDZ, for] - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.equal('global'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); @@ -314,7 +314,7 @@ describe('ES6 destructuring assignments', function() { expect(scope.implicit.left[2].identifier.name).to.equal('e'); expect(scope.implicit.left[2].from.type).to.equal('for'); - scope = scopeManager.scopes[2]; + [, , scope] = scopeManager.scopes; expect(scope.type).to.equal('TDZ'); expect(scope.variables).to.have.length(3); expect(scope.variables[0].name).to.equal('a'); @@ -324,7 +324,7 @@ describe('ES6 destructuring assignments', function() { expect(scope.references[0].identifier.name).to.equal('array'); expect(scope.references[0].isWrite()).to.be.false; - scope = scopeManager.scopes[3]; + [, , , scope] = scopeManager.scopes; expect(scope.type).to.equal('for'); expect(scope.variables).to.have.length(3); expect(scope.variables[0].name).to.equal('a'); @@ -378,7 +378,7 @@ describe('ES6 destructuring assignments', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.equal('global'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); @@ -386,7 +386,7 @@ describe('ES6 destructuring assignments', function() { expect(scope.implicit.left[0].identifier.name).to.equal('d'); expect(scope.implicit.left[1].identifier.name).to.equal('array'); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.equal('function'); expect(scope.variables).to.have.length(4); expect(scope.variables[0].name).to.equal('arguments'); @@ -429,7 +429,7 @@ describe('ES6 destructuring assignments', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.equal('global'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); @@ -437,7 +437,7 @@ describe('ES6 destructuring assignments', function() { expect(scope.implicit.left[0].identifier.name).to.equal('d'); expect(scope.implicit.left[1].identifier.name).to.equal('array'); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.equal('function'); expect(scope.variables).to.have.length(2); expect(scope.variables[0].name).to.equal('arguments'); @@ -473,14 +473,14 @@ describe('ES6 destructuring assignments', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); expect(scope.implicit.left).to.have.length(1); expect(scope.implicit.left[0].identifier.name).to.be.equal('array'); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(4); expect(scope.variables[0].name).to.be.equal('arguments'); @@ -514,14 +514,14 @@ describe('ES6 destructuring assignments', function() { let scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); expect(scope.implicit.left).to.have.length(1); expect(scope.implicit.left[0].identifier.name).to.be.equal('array'); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(4); expect(scope.variables[0].name).to.be.equal('arguments'); @@ -553,14 +553,14 @@ describe('ES6 destructuring assignments', function() { scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - scope = scopeManager.scopes[0]; + [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); expect(scope.implicit.left).to.have.length(1); expect(scope.implicit.left[0].identifier.name).to.be.equal('array'); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(6); @@ -609,14 +609,14 @@ describe('ES6 destructuring assignments', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); expect(scope.implicit.left).to.have.length(1); expect(scope.implicit.left[0].identifier.name).to.be.equal('object'); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(4); expect(scope.variables[0].name).to.be.equal('arguments'); @@ -656,14 +656,14 @@ describe('ES6 destructuring assignments', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); expect(scope.implicit.left).to.have.length(1); expect(scope.implicit.left[0].identifier.name).to.be.equal('object'); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(8); const expectedVariableNames = [ @@ -708,7 +708,7 @@ describe('ES6 destructuring assignments', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); @@ -720,7 +720,7 @@ describe('ES6 destructuring assignments', function() { 'array' ]); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('arguments'); @@ -752,14 +752,14 @@ describe('ES6 destructuring assignments', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.equal('global'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); expect(scope.implicit.left).to.have.length(1); expect(scope.implicit.left[0].identifier.name).to.equal('array'); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.equal('function'); expect(scope.variables).to.have.length(2); expect(scope.variables[0].name).to.equal('arguments'); @@ -792,7 +792,7 @@ describe('ES6 destructuring assignments', function() { let scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); @@ -804,7 +804,7 @@ describe('ES6 destructuring assignments', function() { 'array' ]); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('arguments'); @@ -833,7 +833,7 @@ describe('ES6 destructuring assignments', function() { scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - scope = scopeManager.scopes[0]; + [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); @@ -847,7 +847,7 @@ describe('ES6 destructuring assignments', function() { 'array' ]); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(1); @@ -881,7 +881,7 @@ describe('ES6 destructuring assignments', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.equal('global'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); @@ -893,7 +893,7 @@ describe('ES6 destructuring assignments', function() { 'array' ]); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.equal('function'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.equal('arguments'); @@ -928,7 +928,7 @@ describe('ES6 destructuring assignments', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); @@ -940,7 +940,7 @@ describe('ES6 destructuring assignments', function() { 'object' ]); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('arguments'); @@ -977,7 +977,7 @@ describe('ES6 destructuring assignments', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); @@ -993,7 +993,7 @@ describe('ES6 destructuring assignments', function() { 'object' ]); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('arguments'); @@ -1025,7 +1025,7 @@ describe('ES6 destructuring assignments', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(1); @@ -1033,7 +1033,7 @@ describe('ES6 destructuring assignments', function() { expect(scope.implicit.left).to.have.length(1); expect(scope.implicit.left[0].identifier.name).to.be.equal('array'); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(4); expect(scope.variables[0].name).to.be.equal('arguments'); @@ -1052,7 +1052,7 @@ describe('ES6 destructuring assignments', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(1); @@ -1060,7 +1060,7 @@ describe('ES6 destructuring assignments', function() { expect(scope.implicit.left).to.have.length(1); expect(scope.implicit.left[0].identifier.name).to.be.equal('array'); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(5); expect(scope.variables[0].name).to.be.equal('arguments'); @@ -1080,14 +1080,14 @@ describe('ES6 destructuring assignments', function() { // scopeManager = analyze(ast, {ecmaVersion: 6}); // expect(scopeManager.scopes).to.have.length(2); - // scope = scopeManager.scopes[0]; + // [scope] = scopeManager.scopes; // expect(scope.type).to.be.equal('global'); // expect(scope.variables).to.have.length(0); // expect(scope.references).to.have.length(0); // expect(scope.implicit.left).to.have.length(1); // expect(scope.implicit.left[0].identifier.name).to.be.equal('array'); - // scope = scopeManager.scopes[1]; + // [, scope] = scopeManager.scopes; // expect(scope.type).to.be.equal('function'); // expect(scope.variables).to.have.length(6); @@ -1135,7 +1135,7 @@ describe('ES6 destructuring assignments', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(1); @@ -1143,7 +1143,7 @@ describe('ES6 destructuring assignments', function() { expect(scope.implicit.left).to.have.length(1); expect(scope.implicit.left[0].identifier.name).to.be.equal('object'); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(4); expect(scope.variables[0].name).to.be.equal('arguments'); @@ -1168,7 +1168,7 @@ describe('ES6 destructuring assignments', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(1); @@ -1176,7 +1176,7 @@ describe('ES6 destructuring assignments', function() { expect(scope.implicit.left).to.have.length(1); expect(scope.implicit.left[0].identifier.name).to.be.equal('object'); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(8); const expectedVariableNames = [ @@ -1205,12 +1205,12 @@ describe('ES6 destructuring assignments', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(5); const expectedVariableNames = [ @@ -1247,12 +1247,12 @@ describe('ES6 destructuring assignments', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(5); const expectedVariableNames = [ @@ -1290,12 +1290,12 @@ describe('ES6 destructuring assignments', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.equal('global'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.equal('function'); expect(scope.variables).to.have.length(5); const expectedVariableNames = [ diff --git a/test/es6-export.js b/test/es6-export.js index dabe3cb..629ec8b 100644 --- a/test/es6-export.js +++ b/test/es6-export.js @@ -32,12 +32,12 @@ describe('export declaration', function() { const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(2); - const globalScope = scopeManager.scopes[0]; + const [globalScope] = scopeManager.scopes; expect(globalScope.type).to.be.equal('global'); expect(globalScope.variables).to.have.length(0); expect(globalScope.references).to.have.length(0); - const scope = scopeManager.scopes[1]; + const [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('module'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('v'); @@ -50,19 +50,19 @@ describe('export declaration', function() { const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(3); - const globalScope = scopeManager.scopes[0]; + const [globalScope] = scopeManager.scopes; expect(globalScope.type).to.be.equal('global'); expect(globalScope.variables).to.have.length(0); expect(globalScope.references).to.have.length(0); - let scope = scopeManager.scopes[1]; + let [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('module'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('f'); expect(scope.variables[0].defs[0].type).to.be.equal('FunctionName'); expect(scope.references).to.have.length(0); - scope = scopeManager.scopes[2]; + [, , scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('arguments'); @@ -75,17 +75,17 @@ describe('export declaration', function() { const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(3); - const globalScope = scopeManager.scopes[0]; + const [globalScope] = scopeManager.scopes; expect(globalScope.type).to.be.equal('global'); expect(globalScope.variables).to.have.length(0); expect(globalScope.references).to.have.length(0); - let scope = scopeManager.scopes[1]; + let [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('module'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); - scope = scopeManager.scopes[2]; + [, , scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('arguments'); @@ -97,12 +97,12 @@ describe('export declaration', function() { const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(2); - const globalScope = scopeManager.scopes[0]; + const [globalScope] = scopeManager.scopes; expect(globalScope.type).to.be.equal('global'); expect(globalScope.variables).to.have.length(0); expect(globalScope.references).to.have.length(0); - const scope = scopeManager.scopes[1]; + const [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('module'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); @@ -113,12 +113,12 @@ describe('export declaration', function() { const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(2); - const globalScope = scopeManager.scopes[0]; + const [globalScope] = scopeManager.scopes; expect(globalScope.type).to.be.equal('global'); expect(globalScope.variables).to.have.length(0); expect(globalScope.references).to.have.length(0); - const scope = scopeManager.scopes[1]; + const [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('module'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(1); @@ -130,12 +130,12 @@ describe('export declaration', function() { const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(2); - const globalScope = scopeManager.scopes[0]; + const [globalScope] = scopeManager.scopes; expect(globalScope.type).to.be.equal('global'); expect(globalScope.variables).to.have.length(0); expect(globalScope.references).to.have.length(0); - const scope = scopeManager.scopes[1]; + const [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('module'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(1); @@ -147,12 +147,12 @@ describe('export declaration', function() { const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(2); - const globalScope = scopeManager.scopes[0]; + const [globalScope] = scopeManager.scopes; expect(globalScope.type).to.be.equal('global'); expect(globalScope.variables).to.have.length(0); expect(globalScope.references).to.have.length(0); - const scope = scopeManager.scopes[1]; + const [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('module'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); @@ -163,12 +163,12 @@ describe('export declaration', function() { const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(2); - const globalScope = scopeManager.scopes[0]; + const [globalScope] = scopeManager.scopes; expect(globalScope.type).to.be.equal('global'); expect(globalScope.variables).to.have.length(0); expect(globalScope.references).to.have.length(0); - const scope = scopeManager.scopes[1]; + const [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('module'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); @@ -179,12 +179,12 @@ describe('export declaration', function() { const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(2); - const globalScope = scopeManager.scopes[0]; + const [globalScope] = scopeManager.scopes; expect(globalScope.type).to.be.equal('global'); expect(globalScope.variables).to.have.length(0); expect(globalScope.references).to.have.length(0); - const scope = scopeManager.scopes[1]; + const [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('module'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(0); diff --git a/test/es6-import.js b/test/es6-import.js index ef6b0a9..59d331d 100644 --- a/test/es6-import.js +++ b/test/es6-import.js @@ -32,12 +32,12 @@ describe('import declaration', function() { const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(2); - const globalScope = scopeManager.scopes[0]; + const [globalScope] = scopeManager.scopes; expect(globalScope.type).to.be.equal('global'); expect(globalScope.variables).to.have.length(0); expect(globalScope.references).to.have.length(0); - const scope = scopeManager.scopes[1]; + const [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('module'); expect(scope.isStrict).to.be.true; expect(scope.variables).to.have.length(1); @@ -52,12 +52,12 @@ describe('import declaration', function() { const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(2); - const globalScope = scopeManager.scopes[0]; + const [globalScope] = scopeManager.scopes; expect(globalScope.type).to.be.equal('global'); expect(globalScope.variables).to.have.length(0); expect(globalScope.references).to.have.length(0); - const scope = scopeManager.scopes[1]; + const [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('module'); expect(scope.isStrict).to.be.true; expect(scope.variables).to.have.length(1); @@ -72,12 +72,12 @@ describe('import declaration', function() { const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(2); - const globalScope = scopeManager.scopes[0]; + const [globalScope] = scopeManager.scopes; expect(globalScope.type).to.be.equal('global'); expect(globalScope.variables).to.have.length(0); expect(globalScope.references).to.have.length(0); - const scope = scopeManager.scopes[1]; + const [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('module'); expect(scope.isStrict).to.be.true; expect(scope.variables).to.have.length(1); @@ -91,12 +91,12 @@ describe('import declaration', function() { const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(2); - const globalScope = scopeManager.scopes[0]; + const [globalScope] = scopeManager.scopes; expect(globalScope.type).to.be.equal('global'); expect(globalScope.variables).to.have.length(0); expect(globalScope.references).to.have.length(0); - const scope = scopeManager.scopes[1]; + const [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('module'); expect(scope.isStrict).to.be.true; expect(scope.variables).to.have.length(1); diff --git a/test/es6-iteration-scope.js b/test/es6-iteration-scope.js index 98e58e9..02b61d4 100644 --- a/test/es6-iteration-scope.js +++ b/test/es6-iteration-scope.js @@ -39,11 +39,11 @@ describe('ES6 iteration scope', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(5); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.variables).to.have.length(0); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(2); expect(scope.variables[0].name).to.be.equal('arguments'); @@ -52,7 +52,7 @@ describe('ES6 iteration scope', function() { expect(scope.references[0].identifier.name).to.be.equal('i'); expect(scope.references[0].resolved).to.be.equal(scope.variables[1]); - let iterScope = scope = scopeManager.scopes[2]; + [, , scope] = scopeManager.scopes; expect(scope.type).to.be.equal('TDZ'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('i'); @@ -61,7 +61,8 @@ describe('ES6 iteration scope', function() { expect(scope.references[0].identifier.name).to.be.equal('i'); expect(scope.references[0].resolved).to.be.equal(scope.variables[0]); - iterScope = scope = scopeManager.scopes[3]; + [, , , scope] = scopeManager.scopes; + const iterScope = scope; expect(scope.type).to.be.equal('for'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('i'); @@ -69,7 +70,7 @@ describe('ES6 iteration scope', function() { expect(scope.references[0].identifier.name).to.be.equal('i'); expect(scope.references[0].resolved).to.be.equal(scope.variables[0]); - scope = scopeManager.scopes[4]; + [, , , , scope] = scopeManager.scopes; expect(scope.type).to.be.equal('block'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(2); @@ -92,11 +93,11 @@ describe('ES6 iteration scope', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(5); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.variables).to.have.length(0); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(2); expect(scope.variables[0].name).to.be.equal('arguments'); @@ -105,7 +106,8 @@ describe('ES6 iteration scope', function() { expect(scope.references[0].identifier.name).to.be.equal('i'); expect(scope.references[0].resolved).to.be.equal(scope.variables[1]); - let iterScope = scope = scopeManager.scopes[2]; + [, , scope] = scopeManager.scopes; + let iterScope = scope; expect(scope.type).to.be.equal('TDZ'); expect(scope.variables).to.have.length(3); expect(scope.variables[0].name).to.be.equal('i'); @@ -118,7 +120,8 @@ describe('ES6 iteration scope', function() { expect(scope.references[0].identifier.name).to.be.equal('i'); expect(scope.references[0].resolved).to.be.equal(scope.variables[0]); - iterScope = scope = scopeManager.scopes[3]; + [, , , scope] = scopeManager.scopes; + iterScope = scope; expect(scope.type).to.be.equal('for'); expect(scope.variables).to.have.length(3); expect(scope.variables[0].name).to.be.equal('i'); @@ -132,7 +135,7 @@ describe('ES6 iteration scope', function() { expect(scope.references[2].identifier.name).to.be.equal('k'); expect(scope.references[2].resolved).to.be.equal(scope.variables[2]); - scope = scopeManager.scopes[4]; + [, , , , scope] = scopeManager.scopes; expect(scope.type).to.be.equal('block'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(2); @@ -156,11 +159,12 @@ describe('ES6 iteration scope', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(4); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.variables).to.have.length(0); - const functionScope = scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; + const functionScope = scope; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(3); expect(scope.variables[0].name).to.be.equal('arguments'); @@ -172,7 +176,8 @@ describe('ES6 iteration scope', function() { expect(scope.references[1].identifier.name).to.be.equal('obj'); expect(scope.references[1].resolved).to.be.equal(scope.variables[2]); - const iterScope = scope = scopeManager.scopes[2]; + [, , scope] = scopeManager.scopes; + const iterScope = scope; expect(scope.type).to.be.equal('for'); expect(scope.variables).to.have.length(3); expect(scope.variables[0].name).to.be.equal('i'); @@ -197,7 +202,7 @@ describe('ES6 iteration scope', function() { expect(scope.references[6].identifier.name).to.be.equal('i'); expect(scope.references[6].resolved).to.be.equal(scope.variables[0]); - scope = scopeManager.scopes[3]; + [, , , scope] = scopeManager.scopes; expect(scope.type).to.be.equal('block'); expect(scope.variables).to.have.length(0); expect(scope.references).to.have.length(4); diff --git a/test/es6-new-target.js b/test/es6-new-target.js index dadc8a2..2358343 100644 --- a/test/es6-new-target.js +++ b/test/es6-new-target.js @@ -39,7 +39,7 @@ describe('ES6 new.target', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(3); - const scope = scopeManager.scopes[2]; + const [, , scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.block.type).to.be.equal('FunctionExpression'); expect(scope.isStrict).to.be.true; diff --git a/test/es6-object.js b/test/es6-object.js index bda3326..56f6807 100644 --- a/test/es6-object.js +++ b/test/es6-object.js @@ -36,12 +36,12 @@ describe('ES6 object', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.block.type).to.be.equal('Program'); expect(scope.isStrict).to.be.false; - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.block.type).to.be.equal('FunctionExpression'); expect(scope.isStrict).to.be.false; @@ -67,12 +67,12 @@ describe('ES6 object', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(4); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.block.type).to.be.equal('Program'); expect(scope.isStrict).to.be.false; - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.block.type).to.be.equal('FunctionExpression'); expect(scope.isStrict).to.be.false; diff --git a/test/es6-rest-args.js b/test/es6-rest-args.js index fa10ffc..d5db01f 100644 --- a/test/es6-rest-args.js +++ b/test/es6-rest-args.js @@ -37,13 +37,13 @@ describe('ES6 rest arguments', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.block.type).to.be.equal('Program'); expect(scope.isStrict).to.be.false; expect(scope.variables).to.have.length(1); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(2); expect(scope.variables[0].name).to.be.equal('arguments'); @@ -62,13 +62,13 @@ describe('ES6 rest arguments', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.block.type).to.be.equal('Program'); expect(scope.isStrict).to.be.false; expect(scope.variables).to.have.length(1); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(2); expect(scope.variables[0].name).to.be.equal('arguments'); diff --git a/test/es6-super.js b/test/es6-super.js index 0813f5e..0fce093 100644 --- a/test/es6-super.js +++ b/test/es6-super.js @@ -42,25 +42,25 @@ describe('ES6 super', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(4); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('Hello'); expect(scope.references).to.have.length(0); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('class'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('Hello'); expect(scope.references).to.have.length(0); - scope = scopeManager.scopes[2]; + [, , scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('arguments'); expect(scope.references).to.have.length(0); // super is specially handled like `this`. - scope = scopeManager.scopes[3]; + [, , , scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('arguments'); diff --git a/test/es6-switch.js b/test/es6-switch.js index 7a92a4d..aa067e9 100644 --- a/test/es6-switch.js +++ b/test/es6-switch.js @@ -43,7 +43,7 @@ describe('ES6 switch', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.block.type).to.be.equal('Program'); expect(scope.isStrict).to.be.false; @@ -51,7 +51,7 @@ describe('ES6 switch', function() { expect(scope.references).to.have.length(1); expect(scope.references[0].identifier.name).to.be.equal('ok'); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('switch'); expect(scope.block.type).to.be.equal('SwitchStatement'); expect(scope.isStrict).to.be.false; diff --git a/test/es6-template-literal.js b/test/es6-template-literal.js index 363e8db..70518c9 100644 --- a/test/es6-template-literal.js +++ b/test/es6-template-literal.js @@ -39,13 +39,13 @@ describe('ES6 template literal', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(3); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.block.type).to.be.equal('Program'); expect(scope.isStrict).to.be.false; expect(scope.variables).to.have.length(0); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.block.type).to.be.equal('FunctionExpression'); expect(scope.isStrict).to.be.false; diff --git a/test/function-expression-name.js b/test/function-expression-name.js index e488b83..a64792d 100644 --- a/test/function-expression-name.js +++ b/test/function-expression-name.js @@ -34,14 +34,14 @@ describe('function name', function() { const scopeManager = analyze(ast); expect(scopeManager.scopes).to.have.length(3); - const globalScope = scopeManager.scopes[0]; + const [globalScope] = scopeManager.scopes; expect(globalScope.type).to.be.equal('global'); expect(globalScope.variables).to.have.length(0); expect(globalScope.references).to.have.length(0); expect(globalScope.isArgumentsMaterialized()).to.be.true; // Function expression name scope - let scope = scopeManager.scopes[1]; + let [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function-expression-name'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('name'); @@ -50,7 +50,7 @@ describe('function name', function() { expect(scope.upper === globalScope).to.be.true; // Function scope - scope = scopeManager.scopes[2]; + [, , scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('arguments'); diff --git a/test/global-increment.js b/test/global-increment.js index b4d887c..e97a86c 100644 --- a/test/global-increment.js +++ b/test/global-increment.js @@ -31,7 +31,7 @@ describe('global increment', function() { const scopeManager = analyze(ast); expect(scopeManager.scopes).to.have.length(1); - const globalScope = scopeManager.scopes[0]; + const [globalScope] = scopeManager.scopes; expect(globalScope.type).to.be.equal('global'); expect(globalScope.variables).to.have.length(0); expect(globalScope.references).to.have.length(1); diff --git a/test/implied-strict.js b/test/implied-strict.js index cadfe22..0d460c2 100644 --- a/test/implied-strict.js +++ b/test/implied-strict.js @@ -38,17 +38,17 @@ describe('impliedStrict option', function() { const scopeManager = analyze(ast, { ecmaVersion: 5, impliedStrict: true }); expect(scopeManager.scopes).to.have.length(3); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.block.type).to.be.equal('Program'); expect(scope.isStrict).to.be.true; - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.block.type).to.be.equal('FunctionDeclaration'); expect(scope.isStrict).to.be.true; - scope = scopeManager.scopes[2]; + [, , scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.block.type).to.be.equal('FunctionDeclaration'); expect(scope.isStrict).to.be.true; @@ -62,12 +62,12 @@ describe('impliedStrict option', function() { const scopeManager = analyze(ast, { ecmaVersion: 3, impliedStrict: true }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.block.type).to.be.equal('Program'); expect(scope.isStrict).to.be.false; - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.block.type).to.be.equal('FunctionDeclaration'); expect(scope.isStrict).to.be.false; @@ -81,17 +81,17 @@ describe('impliedStrict option', function() { const scopeManager = analyze(ast, { ecmaVersion: 5, nodejsScope: true, impliedStrict: true }); expect(scopeManager.scopes).to.have.length(3); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.block.type).to.be.equal('Program'); expect(scope.isStrict).to.be.false; - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.block.type).to.be.equal('Program'); expect(scope.isStrict).to.be.true; - scope = scopeManager.scopes[2]; + [, , scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.block.type).to.be.equal('FunctionDeclaration'); expect(scope.isStrict).to.be.true; @@ -106,16 +106,16 @@ describe('impliedStrict option', function() { const scopeManager = analyze(ast, { ecmaVersion: 6, impliedStrict: true, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(3); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.block.type).to.be.equal('Program'); expect(scope.isStrict).to.be.false; - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('module'); expect(scope.isStrict).to.be.true; - scope = scopeManager.scopes[2]; + [, , scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.block.type).to.be.equal('FunctionDeclaration'); expect(scope.isStrict).to.be.true; diff --git a/test/label.js b/test/label.js index bd92ed6..e2dd7d5 100644 --- a/test/label.js +++ b/test/label.js @@ -31,13 +31,13 @@ describe('label', function() { const scopeManager = analyze(ast); expect(scopeManager.scopes).to.have.length(2); - const globalScope = scopeManager.scopes[0]; + const [globalScope] = scopeManager.scopes; expect(globalScope.type).to.be.equal('global'); expect(globalScope.variables).to.have.length(1); expect(globalScope.variables[0].name).to.be.equal('bar'); expect(globalScope.references).to.have.length(0); - const scope = scopeManager.scopes[1]; + const [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('arguments'); @@ -57,7 +57,7 @@ describe('label', function() { const scopeManager = analyze(ast); expect(scopeManager.scopes).to.have.length(1); - const globalScope = scopeManager.scopes[0]; + const [globalScope] = scopeManager.scopes; expect(globalScope.type).to.be.equal('global'); expect(globalScope.variables).to.have.length(1); expect(globalScope.variables[0].name).to.be.equal('foo'); diff --git a/test/nodejs-scope.js b/test/nodejs-scope.js index a424961..92bfd93 100644 --- a/test/nodejs-scope.js +++ b/test/nodejs-scope.js @@ -35,13 +35,13 @@ describe('nodejsScope option', function() { const scopeManager = analyze(ast, { ecmaVersion: 6, nodejsScope: true }); expect(scopeManager.scopes).to.have.length(2); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.block.type).to.be.equal('Program'); expect(scope.isStrict).to.be.false; expect(scope.variables).to.have.length(0); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.block.type).to.be.equal('Program'); expect(scope.isStrict).to.be.true; @@ -59,20 +59,20 @@ describe('nodejsScope option', function() { const scopeManager = analyze(ast, { ecmaVersion: 6, nodejsScope: true, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(3); - let scope = scopeManager.scopes[0]; + let [scope] = scopeManager.scopes; expect(scope.type).to.be.equal('global'); expect(scope.block.type).to.be.equal('Program'); expect(scope.isStrict).to.be.false; expect(scope.variables).to.have.length(0); - scope = scopeManager.scopes[1]; + [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.block.type).to.be.equal('Program'); expect(scope.isStrict).to.be.false; expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('arguments'); - scope = scopeManager.scopes[2]; + [, , scope] = scopeManager.scopes; expect(scope.type).to.be.equal('module'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('v'); diff --git a/test/object-expression.js b/test/object-expression.js index f36e28c..c962a4f 100644 --- a/test/object-expression.js +++ b/test/object-expression.js @@ -34,7 +34,7 @@ describe('object expression', function() { }] }; - const scope = analyze(ast).scopes[0]; + const [scope] = analyze(ast).scopes; expect(scope.variables).to.have.length(1); expect(scope.references).to.have.length(2); expect(scope.variables[0].name).to.be.equal('a'); diff --git a/test/references.js b/test/references.js index d5194bf..94626c1 100644 --- a/test/references.js +++ b/test/references.js @@ -33,11 +33,11 @@ describe('References:', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(1); - const scope = scopeManager.scopes[0]; + const [scope] = scopeManager.scopes; expect(scope.variables).to.have.length(1); expect(scope.references).to.have.length(1); - const reference = scope.references[0]; + const [reference] = scope.references; expect(reference.from).to.equal(scope); expect(reference.identifier.name).to.equal('a'); expect(reference.resolved).to.equal(scope.variables[0]); @@ -57,11 +57,11 @@ describe('References:', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // [global, foo] - const scope = scopeManager.scopes[1]; + const [, scope] = scopeManager.scopes; expect(scope.variables).to.have.length(2); // [arguments, b] expect(scope.references).to.have.length(2); // [b, a] - const reference = scope.references[1]; + const [, reference] = scope.references; expect(reference.from).to.equal(scope); expect(reference.identifier.name).to.equal('a'); expect(reference.resolved).to.equal(scopeManager.scopes[0].variables[0]); @@ -80,11 +80,11 @@ describe('References:', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // [global, foo] - const scope = scopeManager.scopes[1]; + const [, scope] = scopeManager.scopes; expect(scope.variables).to.have.length(2); // [arguments, b] expect(scope.references).to.have.length(2); // [b, a] - const reference = scope.references[1]; + const [, reference] = scope.references; expect(reference.from).to.equal(scope); expect(reference.identifier.name).to.equal('a'); expect(reference.resolved).to.equal(scopeManager.scopes[0].variables[0]); @@ -101,11 +101,11 @@ describe('References:', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(1); - const scope = scopeManager.scopes[0]; + const [scope] = scopeManager.scopes; expect(scope.variables).to.have.length(1); expect(scope.references).to.have.length(1); - const reference = scope.references[0]; + const [reference] = scope.references; expect(reference.from).to.equal(scope); expect(reference.identifier.name).to.equal('a'); expect(reference.resolved).to.equal(scope.variables[0]); @@ -125,11 +125,11 @@ describe('References:', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // [global, foo] - const scope = scopeManager.scopes[1]; + const [, scope] = scopeManager.scopes; expect(scope.variables).to.have.length(2); // [arguments, b] expect(scope.references).to.have.length(2); // [b, a] - const reference = scope.references[1]; + const [, reference] = scope.references; expect(reference.from).to.equal(scope); expect(reference.identifier.name).to.equal('a'); expect(reference.resolved).to.equal(scopeManager.scopes[0].variables[0]); @@ -146,11 +146,11 @@ describe('References:', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(1); - const scope = scopeManager.scopes[0]; + const [scope] = scopeManager.scopes; expect(scope.variables).to.have.length(1); expect(scope.references).to.have.length(1); - const reference = scope.references[0]; + const [reference] = scope.references; expect(reference.from).to.equal(scope); expect(reference.identifier.name).to.equal('a'); expect(reference.resolved).to.be.null; @@ -170,11 +170,11 @@ describe('References:', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // [global, foo] - const scope = scopeManager.scopes[1]; + const [, scope] = scopeManager.scopes; expect(scope.variables).to.have.length(2); // [arguments, b] expect(scope.references).to.have.length(2); // [b, a] - const reference = scope.references[1]; + const [, reference] = scope.references; expect(reference.from).to.equal(scope); expect(reference.identifier.name).to.equal('a'); expect(reference.resolved).to.be.null; @@ -194,11 +194,11 @@ describe('References:', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // [global, a] - const scope = scopeManager.scopes[0]; + const [scope] = scopeManager.scopes; expect(scope.variables).to.have.length(1); expect(scope.references).to.have.length(1); - const reference = scope.references[0]; + const [reference] = scope.references; expect(reference.from).to.equal(scope); expect(reference.identifier.name).to.equal('a'); expect(reference.resolved).to.be.null; @@ -218,11 +218,11 @@ describe('References:', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(3); // [global, a, foo] - const scope = scopeManager.scopes[2]; + const [, , scope] = scopeManager.scopes; expect(scope.variables).to.have.length(2); // [arguments, b] expect(scope.references).to.have.length(2); // [b, a] - const reference = scope.references[1]; + const [, reference] = scope.references; expect(reference.from).to.equal(scope); expect(reference.identifier.name).to.equal('a'); expect(reference.resolved).to.be.null; @@ -242,11 +242,11 @@ describe('References:', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // [global, A] - const scope = scopeManager.scopes[0]; + const [scope] = scopeManager.scopes; expect(scope.variables).to.have.length(2); // [A, b] expect(scope.references).to.have.length(2); // [b, A] - const reference = scope.references[1]; + const [, reference] = scope.references; expect(reference.from).to.equal(scope); expect(reference.identifier.name).to.equal('A'); expect(reference.resolved).to.equal(scope.variables[0]); @@ -266,11 +266,11 @@ describe('References:', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(3); // [global, A, foo] - const scope = scopeManager.scopes[2]; + const [, , scope] = scopeManager.scopes; expect(scope.variables).to.have.length(2); // [arguments, b] expect(scope.references).to.have.length(2); // [b, A] - const reference = scope.references[1]; + const [, reference] = scope.references; expect(reference.from).to.equal(scope); expect(reference.identifier.name).to.equal('A'); expect(reference.resolved).to.equal(scopeManager.scopes[0].variables[0]); @@ -291,11 +291,11 @@ describe('References:', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // [global, foo] - const scope = scopeManager.scopes[1]; + const [, scope] = scopeManager.scopes; expect(scope.variables).to.have.length(2); // [arguments, a] expect(scope.references).to.have.length(1); - const reference = scope.references[0]; + const [reference] = scope.references; expect(reference.from).to.equal(scope); expect(reference.identifier.name).to.equal('a'); expect(reference.resolved).to.equal(scope.variables[1]); @@ -317,11 +317,11 @@ describe('References:', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(3); // [global, foo, bar] - const scope = scopeManager.scopes[2]; + const [, , scope] = scopeManager.scopes; expect(scope.variables).to.have.length(2); // [arguments, b] expect(scope.references).to.have.length(2); // [b, a] - const reference = scope.references[1]; + const [, reference] = scope.references; expect(reference.from).to.equal(scope); expect(reference.identifier.name).to.equal('a'); expect(reference.resolved).to.equal(scopeManager.scopes[1].variables[1]); @@ -342,11 +342,11 @@ describe('References:', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(2); // [global, foo] - const scope = scopeManager.scopes[1]; + const [, scope] = scopeManager.scopes; expect(scope.variables).to.have.length(2); // [arguments, a] expect(scope.references).to.have.length(1); - const reference = scope.references[0]; + const [reference] = scope.references; expect(reference.from).to.equal(scope); expect(reference.identifier.name).to.equal('a'); expect(reference.resolved).to.equal(scope.variables[1]); @@ -368,11 +368,11 @@ describe('References:', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(3); // [global, foo, bar] - const scope = scopeManager.scopes[2]; + const [, , scope] = scopeManager.scopes; expect(scope.variables).to.have.length(2); // [arguments, b] expect(scope.references).to.have.length(2); // [b, a] - const reference = scope.references[1]; + const [, reference] = scope.references; expect(reference.from).to.equal(scope); expect(reference.identifier.name).to.equal('a'); expect(reference.resolved).to.equal(scopeManager.scopes[1].variables[1]); @@ -389,11 +389,11 @@ describe('References:', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(1); - const scope = scopeManager.scopes[0]; + const [scope] = scopeManager.scopes; expect(scope.variables).to.have.length(1); expect(scope.references).to.have.length(1); - const reference = scope.references[0]; + const [reference] = scope.references; expect(reference.from).to.equal(scope); expect(reference.identifier.name).to.equal('a'); expect(reference.resolved).to.equal(scope.variables[0]); @@ -408,11 +408,11 @@ describe('References:', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(1); - const scope = scopeManager.scopes[0]; + const [scope] = scopeManager.scopes; expect(scope.variables).to.have.length(1); expect(scope.references).to.have.length(1); - const reference = scope.references[0]; + const [reference] = scope.references; expect(reference.from).to.equal(scope); expect(reference.identifier.name).to.equal('a'); expect(reference.resolved).to.equal(scope.variables[0]); @@ -427,11 +427,11 @@ describe('References:', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.have.length(1); - const scope = scopeManager.scopes[0]; + const [scope] = scopeManager.scopes; expect(scope.variables).to.have.length(1); expect(scope.references).to.have.length(1); - const reference = scope.references[0]; + const [reference] = scope.references; expect(reference.from).to.equal(scope); expect(reference.identifier.name).to.equal('a'); expect(reference.resolved).to.equal(scope.variables[0]); @@ -550,11 +550,11 @@ describe('References:', function() { const scopeManager = analyze(ast, { ecmaVersion: 6 }); expect(scopeManager.scopes).to.be.length.of.at.least(1); - const scope = scopeManager.scopes[0]; + const [scope] = scopeManager.scopes; expect(scope.variables).to.have.length.of.at.least(1); expect(scope.variables[0].name).to.equal('a'); - const { references } = scope.variables[0]; + const [{ references }] = scope.variables; expect(references).to.have.length.of.at.least(1); references.forEach(reference => { diff --git a/test/with-scope.js b/test/with-scope.js index 5dc93f2..a42be9f 100644 --- a/test/with-scope.js +++ b/test/with-scope.js @@ -37,12 +37,12 @@ describe('with', function() { const scopeManager = analyze(ast); expect(scopeManager.scopes).to.have.length(3); - const globalScope = scopeManager.scopes[0]; + const [globalScope] = scopeManager.scopes; expect(globalScope.type).to.be.equal('global'); expect(globalScope.variables).to.have.length(0); expect(globalScope.references).to.have.length(0); - let scope = scopeManager.scopes[1]; + let [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('function'); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal('arguments'); @@ -50,7 +50,7 @@ describe('with', function() { expect(scope.references).to.have.length(1); expect(scope.references[0].resolved).to.be.null; - scope = scopeManager.scopes[2]; + [, , scope] = scopeManager.scopes; expect(scope.type).to.be.equal('with'); expect(scope.variables).to.have.length(0); expect(scope.isArgumentsMaterialized()).to.be.true; From 3ec159d6e4f78b1198585d24d0661fb932f43e2c Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Sun, 26 Apr 2020 15:59:34 +0800 Subject: [PATCH 04/24] - Move Mocha and Babel building/watch to npm - npm: Switch to non-deprecated babel/preset-env and to Babel 7 - npm: Update deps. (esrecurse, estraverse (major bump)) and devDeps. - Testing: Fix esprima imports - Testing: Add nyc - Testing: Update export tests to avoid error with exported variable not being defined --- .babelrc.json | 2 +- .eslintignore | 1 + .gitignore | 1 + gulpfile.js | 46 +---------------------------- package.json | 60 +++++++++++++++++++++++--------------- test/arguments.js | 2 +- test/catch-scope.js | 2 +- test/child-visitor-keys.js | 2 +- test/es6-export.js | 12 ++++---- test/fallback.js | 2 +- 10 files changed, 51 insertions(+), 79 deletions(-) diff --git a/.babelrc.json b/.babelrc.json index c13c5f6..1320b9a 100644 --- a/.babelrc.json +++ b/.babelrc.json @@ -1,3 +1,3 @@ { - "presets": ["es2015"] + "presets": ["@babel/preset-env"] } diff --git a/.eslintignore b/.eslintignore index 06d1b84..37975dc 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,3 +3,4 @@ lib !.eslintrc.js third_party +coverage diff --git a/.gitignore b/.gitignore index b448737..548a6ce 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ npm-debug.log # Cover .coverage_data/ cover_html/ +coverage npm-debug.log .vimrc.local diff --git a/gulpfile.js b/gulpfile.js index 8c12777..f001f2e 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -25,41 +25,12 @@ 'use strict'; const gulp = require('gulp'), - mocha = require('gulp-mocha'), - babel = require('gulp-babel'), git = require('gulp-git'), bump = require('gulp-bump'), filter = require('gulp-filter'), tagVersion = require('gulp-tag-version'), - sourcemaps = require('gulp-sourcemaps'), - plumber = require('gulp-plumber'), source = require('vinyl-source-stream'), - browserify = require('browserify'), - lazypipe = require('lazypipe'), - fs = require('fs'); - -require('babel-register')({ - only: /escope\/(src|test)\// -}); - -const TEST = [ 'test/*.js' ]; -const SOURCE = [ 'src/**/*.js' ]; - -const BABEL_OPTIONS = JSON.parse(fs.readFileSync('.babelrc', { encoding: 'utf8' })); - -const build = lazypipe() - .pipe(sourcemaps.init) - .pipe(babel, BABEL_OPTIONS) - .pipe(sourcemaps.write) - .pipe(gulp.dest, 'lib'); - -gulp.task('build-for-watch', function () { - return gulp.src(SOURCE).pipe(plumber()).pipe(build()); -}); - -gulp.task('build', function () { - return gulp.src(SOURCE).pipe(build()); -}); + browserify = require('browserify'); gulp.task('browserify', [ 'build' ], function () { return browserify({ @@ -70,18 +41,6 @@ gulp.task('browserify', [ 'build' ], function () { .pipe(gulp.dest('build')); }); -gulp.task('test', [ 'build' ], function () { - return gulp.src(TEST) - .pipe(mocha({ - reporter: 'spec', - timeout: 100000 // 100s - })); -}); - -gulp.task('watch', [ 'build-for-watch' ], function () { - gulp.watch(SOURCE, [ 'build-for-watch' ]); -}); - /** * Bumping version number and tagging the repository with it. * Please read http://semver.org/ @@ -116,6 +75,3 @@ function inc(importance) { gulp.task('patch', [ 'build' ], function () { return inc('patch'); }); gulp.task('minor', [ 'build' ], function () { return inc('minor'); }); gulp.task('major', [ 'build' ], function () { return inc('major'); }); - -gulp.task('travis', [ 'test' ]); -gulp.task('default', [ 'travis' ]); diff --git a/package.json b/package.json index a4018d1..d8596cf 100644 --- a/package.json +++ b/package.json @@ -23,36 +23,50 @@ "url": "https://github.com/estools/escope.git" }, "dependencies": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "esrecurse": "^4.2.1", + "estraverse": "^5.1.0" }, "devDependencies": { - "babel": "^6.3.26", - "babel-preset-es2015": "^6.3.13", - "babel-register": "^6.3.13", + "@babel/cli": "^7.8.4", + "@babel/core": "^7.9.0", + "@babel/preset-env": "^7.9.5", + "@babel/register": "^7.9.0", "browserify": "^14.4.0", - "chai": "^4.0.2", + "chai": "^4.2.0", "eslint": "^6.8.0", - "espree": "^3.1.1", - "esprima": "^3.0.0", - "gulp": "^3.9.0", - "gulp-babel": "^6.1.1", - "gulp-bump": "^2.7.0", - "gulp-espower": "^1.0.2", - "gulp-filter": "^5.0.0", - "gulp-git": "^2.4.1", - "gulp-mocha": "^3.0.0", - "gulp-plumber": "^1.0.1", - "gulp-sourcemaps": "^2.6.0", - "gulp-tag-version": "^1.3.0", - "jsdoc": "^3.4.0", - "lazypipe": "^1.0.1", - "vinyl-source-stream": "^1.1.0" + "espree": "^6.2.1", + "esprima": "^4.0.1", + "gulp": "^4.0.2", + "gulp-bump": "^3.1.3", + "gulp-espower": "^1.1.0", + "gulp-filter": "^6.0.0", + "gulp-git": "^2.10.1", + "gulp-tag-version": "^1.3.1", + "jsdoc": "^3.6.4", + "mocha": "^7.1.2", + "nyc": "^15.0.1", + "vinyl-source-stream": "^2.0.0" }, "license": "BSD-2-Clause", + "nyc": { + "branches": 100, + "lines": 100, + "functions": 100, + "statements": 100, + "reporter": [ + "html", + "text" + ], + "exclude": [ + "test", + "third_party" + ] + }, "scripts": { - "test": "gulp travis", - "unit-test": "gulp test", + "build-watch": "babel src/**/*.js --out-dir lib --source-maps --watch", + "build": "babel src/**/*.js --out-dir lib --source-maps", + "unit-test": "nyc mocha --require @babel/register test/*.js --timeout 100000", + "test": "npm run build && npm run unit-test", "lint": "eslint .", "jsdoc": "jsdoc src/*.js README.md" } diff --git a/test/arguments.js b/test/arguments.js index 43bbf50..31d7f36 100644 --- a/test/arguments.js +++ b/test/arguments.js @@ -22,7 +22,7 @@ // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import { expect } from 'chai'; -import esprima from 'esprima'; +import * as esprima from 'esprima'; import { analyze } from '..'; describe('arguments', function() { diff --git a/test/catch-scope.js b/test/catch-scope.js index 0d7adb5..61e4290 100644 --- a/test/catch-scope.js +++ b/test/catch-scope.js @@ -22,7 +22,7 @@ // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import { expect } from 'chai'; -import esprima from 'esprima'; +import * as esprima from 'esprima'; import { analyze } from '..'; describe('catch', function() { diff --git a/test/child-visitor-keys.js b/test/child-visitor-keys.js index d6bab62..9cbee11 100644 --- a/test/child-visitor-keys.js +++ b/test/child-visitor-keys.js @@ -22,7 +22,7 @@ // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import { expect } from 'chai'; -import esprima from 'esprima'; +import * as esprima from 'esprima'; import { analyze } from '..'; describe('childVisitorKeys option', function() { diff --git a/test/es6-export.js b/test/es6-export.js index 629ec8b..52f6cd4 100644 --- a/test/es6-export.js +++ b/test/es6-export.js @@ -109,7 +109,7 @@ describe('export declaration', function() { }); it('should refer exported references#1', function() { - const ast = espree('export {x};', { sourceType: 'module' }); + const ast = espree('var x = 5; export {x};', { sourceType: 'module' }); const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(2); @@ -120,13 +120,13 @@ describe('export declaration', function() { const [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('module'); - expect(scope.variables).to.have.length(0); - expect(scope.references).to.have.length(1); + expect(scope.variables).to.have.length(1); + expect(scope.references).to.have.length(2); expect(scope.references[0].identifier.name).to.be.equal('x'); }); it('should refer exported references#2', function() { - const ast = espree('export {v as x};', { sourceType: 'module' }); + const ast = espree('var v = 5; export {v as x};', { sourceType: 'module' }); const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: 'module' }); expect(scopeManager.scopes).to.have.length(2); @@ -137,8 +137,8 @@ describe('export declaration', function() { const [, scope] = scopeManager.scopes; expect(scope.type).to.be.equal('module'); - expect(scope.variables).to.have.length(0); - expect(scope.references).to.have.length(1); + expect(scope.variables).to.have.length(1); + expect(scope.references).to.have.length(2); expect(scope.references[0].identifier.name).to.be.equal('v'); }); diff --git a/test/fallback.js b/test/fallback.js index 931ff5b..5ce5b69 100644 --- a/test/fallback.js +++ b/test/fallback.js @@ -22,7 +22,7 @@ // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import { expect } from 'chai'; -import esprima from 'esprima'; +import * as esprima from 'esprima'; import { analyze } from '..'; describe('fallback option', function() { From a1deffeccb0f9e4ec5ae318eca101ff3449471cf Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Sun, 26 Apr 2020 16:44:20 +0800 Subject: [PATCH 05/24] - package.json: Add keywords --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index d8596cf..f734e71 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "web": "http://github.com/Constellation" } ], + "keywords": ["scope", "analysis"], "repository": { "type": "git", "url": "https://github.com/estools/escope.git" From aa7fd5220e2b7ec286944768a1a0d5fb6e49709b Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Sun, 26 Apr 2020 16:44:58 +0800 Subject: [PATCH 06/24] - Breaking change: Remove deprecated bower --- bower.json | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 bower.json diff --git a/bower.json b/bower.json deleted file mode 100644 index 70ad5e5..0000000 --- a/bower.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "escope", - "version": "2.0.2-dev", - "main": "escope.js", - "dependencies": { - "estraverse": ">= 0.0.2" - }, - "ignore": [ - "**/.*", - "node_modules", - "components" - ] -} From b23352df0926d31dcb09fe0f09146317b0374edd Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Sun, 26 Apr 2020 16:47:04 +0800 Subject: [PATCH 07/24] - Lint espree wrapper file --- .eslintignore | 2 +- third_party/espree.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.eslintignore b/.eslintignore index 37975dc..4f865e5 100644 --- a/.eslintignore +++ b/.eslintignore @@ -2,5 +2,5 @@ node_modules lib !.eslintrc.js -third_party +third_party/esprima.js coverage diff --git a/third_party/espree.js b/third_party/espree.js index 2f68051..c6d5323 100644 --- a/third_party/espree.js +++ b/third_party/espree.js @@ -22,7 +22,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -var espree = require('espree'); +const espree = require('espree'); module.exports = function (code) { return espree.parse(code, { @@ -49,7 +49,7 @@ module.exports = function (code) { // enable es6 features. ecmaVersion: 6, - sourceType: "module" + sourceType: 'module' }); }; From 77fa91ef9fa18ad207a2d0c22fdc74daae78da2b Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Sun, 26 Apr 2020 16:49:43 +0800 Subject: [PATCH 08/24] - Switch from local copy to npm package for esprima - Testing: Fix `es6-destructuring-assignments.js` check of rest element per updated Esprima --- .eslintignore | 1 - test/es6-arrow-function-expression.js | 2 +- test/es6-block-scope.js | 2 +- test/es6-catch.js | 2 +- test/es6-class.js | 2 +- test/es6-destructuring-assignments.js | 4 +- test/es6-iteration-scope.js | 2 +- test/es6-object.js | 2 +- test/es6-rest-args.js | 2 +- test/es6-super.js | 2 +- test/es6-switch.js | 2 +- test/es6-template-literal.js | 2 +- test/implied-strict.js | 2 +- test/nodejs-scope.js | 2 +- third_party/esprima.js | 5445 ------------------------- 15 files changed, 14 insertions(+), 5460 deletions(-) delete mode 100644 third_party/esprima.js diff --git a/.eslintignore b/.eslintignore index 4f865e5..44f17c7 100644 --- a/.eslintignore +++ b/.eslintignore @@ -2,5 +2,4 @@ node_modules lib !.eslintrc.js -third_party/esprima.js coverage diff --git a/test/es6-arrow-function-expression.js b/test/es6-arrow-function-expression.js index 36258b1..2ee7561 100644 --- a/test/es6-arrow-function-expression.js +++ b/test/es6-arrow-function-expression.js @@ -22,7 +22,7 @@ // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import { expect } from 'chai'; -import { parse } from '../third_party/esprima'; +import { parse } from 'esprima'; import { analyze } from '..'; describe('ES6 arrow function expression', function() { diff --git a/test/es6-block-scope.js b/test/es6-block-scope.js index 5c3160d..528cd50 100644 --- a/test/es6-block-scope.js +++ b/test/es6-block-scope.js @@ -22,7 +22,7 @@ // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import { expect } from 'chai'; -import { parse } from '../third_party/esprima'; +import { parse } from 'esprima'; import { analyze } from '..'; describe('ES6 block scope', function() { diff --git a/test/es6-catch.js b/test/es6-catch.js index b9f0f2c..6e8abf5 100644 --- a/test/es6-catch.js +++ b/test/es6-catch.js @@ -21,7 +21,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import { expect } from 'chai'; -import { parse } from '../third_party/esprima'; +import { parse } from 'esprima'; import { analyze } from '..'; describe('ES6 catch', function() { diff --git a/test/es6-class.js b/test/es6-class.js index 1aedf59..a2bb0f3 100644 --- a/test/es6-class.js +++ b/test/es6-class.js @@ -22,7 +22,7 @@ // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import { expect } from 'chai'; -import { parse } from '../third_party/esprima'; +import { parse } from 'esprima'; import { analyze } from '..'; describe('ES6 class', function() { diff --git a/test/es6-destructuring-assignments.js b/test/es6-destructuring-assignments.js index 99e42ce..f827c2b 100644 --- a/test/es6-destructuring-assignments.js +++ b/test/es6-destructuring-assignments.js @@ -22,7 +22,7 @@ // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import { expect } from 'chai'; -import harmony from '../third_party/esprima'; +import * as harmony from 'esprima'; import espree from '../third_party/espree'; import { analyze } from '..'; @@ -1067,7 +1067,7 @@ describe('ES6 destructuring assignments', function() { expect(scope.variables[1].name).to.be.equal('a'); expect(scope.variables[2].name).to.be.equal('b'); expect(scope.variables[3].name).to.be.equal('rest'); - expect(scope.variables[3].defs[0].rest).to.be.false; + expect(scope.variables[3].defs[0].rest).to.be.true; expect(scope.variables[4].name).to.be.equal('rest2'); expect(scope.variables[4].defs[0].rest).to.be.true; expect(scope.references).to.have.length(0); diff --git a/test/es6-iteration-scope.js b/test/es6-iteration-scope.js index 02b61d4..2e95481 100644 --- a/test/es6-iteration-scope.js +++ b/test/es6-iteration-scope.js @@ -22,7 +22,7 @@ // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import { expect } from 'chai'; -import { parse } from '../third_party/esprima'; +import { parse } from 'esprima'; import { analyze } from '..'; describe('ES6 iteration scope', function() { diff --git a/test/es6-object.js b/test/es6-object.js index 56f6807..d3db05a 100644 --- a/test/es6-object.js +++ b/test/es6-object.js @@ -22,7 +22,7 @@ // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import { expect } from 'chai'; -import { parse } from '../third_party/esprima'; +import { parse } from 'esprima'; import { analyze } from '..'; describe('ES6 object', function() { diff --git a/test/es6-rest-args.js b/test/es6-rest-args.js index d5db01f..e75c814 100644 --- a/test/es6-rest-args.js +++ b/test/es6-rest-args.js @@ -22,7 +22,7 @@ // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import { expect } from 'chai'; -import { parse as esprima } from '../third_party/esprima'; +import { parse as esprima } from 'esprima'; import espree from '../third_party/espree'; import { analyze } from '..'; diff --git a/test/es6-super.js b/test/es6-super.js index 0fce093..f612200 100644 --- a/test/es6-super.js +++ b/test/es6-super.js @@ -22,7 +22,7 @@ // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import { expect } from 'chai'; -import { parse } from '../third_party/esprima'; +import { parse } from 'esprima'; import { analyze } from '..'; describe('ES6 super', function() { diff --git a/test/es6-switch.js b/test/es6-switch.js index aa067e9..8b3571e 100644 --- a/test/es6-switch.js +++ b/test/es6-switch.js @@ -22,7 +22,7 @@ // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import { expect } from 'chai'; -import { parse } from '../third_party/esprima'; +import { parse } from 'esprima'; import { analyze } from '..'; describe('ES6 switch', function() { diff --git a/test/es6-template-literal.js b/test/es6-template-literal.js index 70518c9..123b098 100644 --- a/test/es6-template-literal.js +++ b/test/es6-template-literal.js @@ -22,7 +22,7 @@ // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import { expect } from 'chai'; -import { parse } from '../third_party/esprima'; +import { parse } from 'esprima'; import { analyze } from '..'; describe('ES6 template literal', function() { diff --git a/test/implied-strict.js b/test/implied-strict.js index 0d460c2..e4c68ab 100644 --- a/test/implied-strict.js +++ b/test/implied-strict.js @@ -22,7 +22,7 @@ // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import { expect } from 'chai'; -import { parse } from '../third_party/esprima'; +import { parse } from 'esprima'; import { analyze } from '..'; describe('impliedStrict option', function() { diff --git a/test/nodejs-scope.js b/test/nodejs-scope.js index 92bfd93..4f5e23f 100644 --- a/test/nodejs-scope.js +++ b/test/nodejs-scope.js @@ -22,7 +22,7 @@ // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import { expect } from 'chai'; -import { parse } from '../third_party/esprima'; +import { parse } from 'esprima'; import { analyze } from '..'; describe('nodejsScope option', function() { diff --git a/third_party/esprima.js b/third_party/esprima.js deleted file mode 100644 index 24abe57..0000000 --- a/third_party/esprima.js +++ /dev/null @@ -1,5445 +0,0 @@ -/* - Copyright (C) 2013 Ariya Hidayat - Copyright (C) 2013 Thaddee Tyl - Copyright (C) 2012 Ariya Hidayat - Copyright (C) 2012 Mathias Bynens - Copyright (C) 2012 Joost-Wim Boekesteijn - Copyright (C) 2012 Kris Kowal - Copyright (C) 2012 Yusuke Suzuki - Copyright (C) 2012 Arpad Borsos - Copyright (C) 2011 Ariya Hidayat - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/*jslint bitwise:true plusplus:true */ -/*global esprima:true, define:true, exports:true, window: true, -throwError: true, generateStatement: true, peek: true, -parseAssignmentExpression: true, parseBlock: true, -parseClassExpression: true, parseClassDeclaration: true, parseExpression: true, -parseForStatement: true, -parseFunctionDeclaration: true, parseFunctionExpression: true, -parseFunctionSourceElements: true, parseVariableIdentifier: true, -parseImportSpecifier: true, -parseLeftHandSideExpression: true, parseParams: true, validateParam: true, -parseSpreadOrAssignmentExpression: true, -parseStatement: true, parseSourceElement: true, parseConciseBody: true, -parseYieldExpression: true -*/ - -(function (root, factory) { - 'use strict'; - - // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, - // Rhino, and plain browser loading. - - /* istanbul ignore next */ - if (typeof define === 'function' && define.amd) { - define(['exports'], factory); - } else if (typeof exports !== 'undefined') { - factory(exports); - } else { - factory((root.esprima = {})); - } -}(this, function (exports) { - 'use strict'; - - var Token, - TokenName, - FnExprTokens, - Syntax, - PropertyKind, - Messages, - Regex, - SyntaxTreeDelegate, - ClassPropertyType, - source, - strict, - index, - lineNumber, - lineStart, - length, - delegate, - lookahead, - state, - extra; - - Token = { - BooleanLiteral: 1, - EOF: 2, - Identifier: 3, - Keyword: 4, - NullLiteral: 5, - NumericLiteral: 6, - Punctuator: 7, - StringLiteral: 8, - RegularExpression: 9, - Template: 10 - }; - - TokenName = {}; - TokenName[Token.BooleanLiteral] = 'Boolean'; - TokenName[Token.EOF] = ''; - TokenName[Token.Identifier] = 'Identifier'; - TokenName[Token.Keyword] = 'Keyword'; - TokenName[Token.NullLiteral] = 'Null'; - TokenName[Token.NumericLiteral] = 'Numeric'; - TokenName[Token.Punctuator] = 'Punctuator'; - TokenName[Token.StringLiteral] = 'String'; - TokenName[Token.RegularExpression] = 'RegularExpression'; - - // A function following one of those tokens is an expression. - FnExprTokens = ['(', '{', '[', 'in', 'typeof', 'instanceof', 'new', - 'return', 'case', 'delete', 'throw', 'void', - // assignment operators - '=', '+=', '-=', '*=', '/=', '%=', '<<=', '>>=', '>>>=', - '&=', '|=', '^=', ',', - // binary/unary operators - '+', '-', '*', '/', '%', '++', '--', '<<', '>>', '>>>', '&', - '|', '^', '!', '~', '&&', '||', '?', ':', '===', '==', '>=', - '<=', '<', '>', '!=', '!==']; - - Syntax = { - ArrayExpression: 'ArrayExpression', - ArrayPattern: 'ArrayPattern', - ArrowFunctionExpression: 'ArrowFunctionExpression', - AssignmentExpression: 'AssignmentExpression', - BinaryExpression: 'BinaryExpression', - BlockStatement: 'BlockStatement', - BreakStatement: 'BreakStatement', - CallExpression: 'CallExpression', - CatchClause: 'CatchClause', - ClassBody: 'ClassBody', - ClassDeclaration: 'ClassDeclaration', - ClassExpression: 'ClassExpression', - ComprehensionBlock: 'ComprehensionBlock', - ComprehensionExpression: 'ComprehensionExpression', - ConditionalExpression: 'ConditionalExpression', - ContinueStatement: 'ContinueStatement', - DebuggerStatement: 'DebuggerStatement', - DoWhileStatement: 'DoWhileStatement', - EmptyStatement: 'EmptyStatement', - ExportDeclaration: 'ExportDeclaration', - ExportBatchSpecifier: 'ExportBatchSpecifier', - ExportSpecifier: 'ExportSpecifier', - ExpressionStatement: 'ExpressionStatement', - ForInStatement: 'ForInStatement', - ForOfStatement: 'ForOfStatement', - ForStatement: 'ForStatement', - FunctionDeclaration: 'FunctionDeclaration', - FunctionExpression: 'FunctionExpression', - Identifier: 'Identifier', - IfStatement: 'IfStatement', - ImportDeclaration: 'ImportDeclaration', - ImportDefaultSpecifier: 'ImportDefaultSpecifier', - ImportNamespaceSpecifier: 'ImportNamespaceSpecifier', - ImportSpecifier: 'ImportSpecifier', - LabeledStatement: 'LabeledStatement', - Literal: 'Literal', - LogicalExpression: 'LogicalExpression', - MemberExpression: 'MemberExpression', - MethodDefinition: 'MethodDefinition', - ModuleSpecifier: 'ModuleSpecifier', - NewExpression: 'NewExpression', - ObjectExpression: 'ObjectExpression', - ObjectPattern: 'ObjectPattern', - Program: 'Program', - Property: 'Property', - ReturnStatement: 'ReturnStatement', - SequenceExpression: 'SequenceExpression', - SpreadElement: 'SpreadElement', - SwitchCase: 'SwitchCase', - SwitchStatement: 'SwitchStatement', - TaggedTemplateExpression: 'TaggedTemplateExpression', - TemplateElement: 'TemplateElement', - TemplateLiteral: 'TemplateLiteral', - ThisExpression: 'ThisExpression', - ThrowStatement: 'ThrowStatement', - TryStatement: 'TryStatement', - UnaryExpression: 'UnaryExpression', - UpdateExpression: 'UpdateExpression', - VariableDeclaration: 'VariableDeclaration', - VariableDeclarator: 'VariableDeclarator', - WhileStatement: 'WhileStatement', - WithStatement: 'WithStatement', - YieldExpression: 'YieldExpression' - }; - - PropertyKind = { - Data: 1, - Get: 2, - Set: 4 - }; - - ClassPropertyType = { - 'static': 'static', - prototype: 'prototype' - }; - - // Error messages should be identical to V8. - Messages = { - UnexpectedToken: 'Unexpected token %0', - UnexpectedNumber: 'Unexpected number', - UnexpectedString: 'Unexpected string', - UnexpectedIdentifier: 'Unexpected identifier', - UnexpectedReserved: 'Unexpected reserved word', - UnexpectedTemplate: 'Unexpected quasi %0', - UnexpectedEOS: 'Unexpected end of input', - NewlineAfterThrow: 'Illegal newline after throw', - InvalidRegExp: 'Invalid regular expression', - UnterminatedRegExp: 'Invalid regular expression: missing /', - InvalidLHSInAssignment: 'Invalid left-hand side in assignment', - InvalidLHSInFormalsList: 'Invalid left-hand side in formals list', - InvalidLHSInForIn: 'Invalid left-hand side in for-in', - MultipleDefaultsInSwitch: 'More than one default clause in switch statement', - NoCatchOrFinally: 'Missing catch or finally after try', - UnknownLabel: 'Undefined label \'%0\'', - Redeclaration: '%0 \'%1\' has already been declared', - IllegalContinue: 'Illegal continue statement', - IllegalBreak: 'Illegal break statement', - IllegalDuplicateClassProperty: 'Illegal duplicate property in class definition', - IllegalReturn: 'Illegal return statement', - IllegalYield: 'Illegal yield expression', - IllegalSpread: 'Illegal spread element', - StrictModeWith: 'Strict mode code may not include a with statement', - StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode', - StrictVarName: 'Variable name may not be eval or arguments in strict mode', - StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode', - StrictParamDupe: 'Strict mode function may not have duplicate parameter names', - ParameterAfterRestParameter: 'Rest parameter must be final parameter of an argument list', - DefaultRestParameter: 'Rest parameter can not have a default value', - ElementAfterSpreadElement: 'Spread must be the final element of an element list', - ObjectPatternAsRestParameter: 'Invalid rest parameter', - ObjectPatternAsSpread: 'Invalid spread argument', - StrictFunctionName: 'Function name may not be eval or arguments in strict mode', - StrictOctalLiteral: 'Octal literals are not allowed in strict mode.', - StrictDelete: 'Delete of an unqualified identifier in strict mode.', - StrictDuplicateProperty: 'Duplicate data property in object literal not allowed in strict mode', - AccessorDataProperty: 'Object literal may not have data and accessor property with the same name', - AccessorGetSet: 'Object literal may not have multiple get/set accessors with the same name', - StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode', - StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode', - StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode', - StrictReservedWord: 'Use of future reserved word in strict mode', - MissingFromClause: 'Missing from clause', - NoAsAfterImportNamespace: 'Missing as after import *', - InvalidModuleSpecifier: 'Invalid module specifier', - NoUnintializedConst: 'Const must be initialized', - ComprehensionRequiresBlock: 'Comprehension must have at least one block', - ComprehensionError: 'Comprehension Error', - EachNotAllowed: 'Each is not supported' - }; - - // See also tools/generate-unicode-regex.py. - Regex = { - NonAsciiIdentifierStart: new RegExp('[\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]'), - NonAsciiIdentifierPart: new RegExp('[\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0300-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u0483-\u0487\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u05d0-\u05ea\u05f0-\u05f2\u0610-\u061a\u0620-\u0669\u066e-\u06d3\u06d5-\u06dc\u06df-\u06e8\u06ea-\u06fc\u06ff\u0710-\u074a\u074d-\u07b1\u07c0-\u07f5\u07fa\u0800-\u082d\u0840-\u085b\u08a0\u08a2-\u08ac\u08e4-\u08fe\u0900-\u0963\u0966-\u096f\u0971-\u0977\u0979-\u097f\u0981-\u0983\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bc-\u09c4\u09c7\u09c8\u09cb-\u09ce\u09d7\u09dc\u09dd\u09df-\u09e3\u09e6-\u09f1\u0a01-\u0a03\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a59-\u0a5c\u0a5e\u0a66-\u0a75\u0a81-\u0a83\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abc-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ad0\u0ae0-\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3c-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b5c\u0b5d\u0b5f-\u0b63\u0b66-\u0b6f\u0b71\u0b82\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd0\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c58\u0c59\u0c60-\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbc-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0cde\u0ce0-\u0ce3\u0ce6-\u0cef\u0cf1\u0cf2\u0d02\u0d03\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d-\u0d44\u0d46-\u0d48\u0d4a-\u0d4e\u0d57\u0d60-\u0d63\u0d66-\u0d6f\u0d7a-\u0d7f\u0d82\u0d83\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e01-\u0e3a\u0e40-\u0e4e\u0e50-\u0e59\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb9\u0ebb-\u0ebd\u0ec0-\u0ec4\u0ec6\u0ec8-\u0ecd\u0ed0-\u0ed9\u0edc-\u0edf\u0f00\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e-\u0f47\u0f49-\u0f6c\u0f71-\u0f84\u0f86-\u0f97\u0f99-\u0fbc\u0fc6\u1000-\u1049\u1050-\u109d\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u135d-\u135f\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176c\u176e-\u1770\u1772\u1773\u1780-\u17d3\u17d7\u17dc\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u1820-\u1877\u1880-\u18aa\u18b0-\u18f5\u1900-\u191c\u1920-\u192b\u1930-\u193b\u1946-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u19d0-\u19d9\u1a00-\u1a1b\u1a20-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1aa7\u1b00-\u1b4b\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1bf3\u1c00-\u1c37\u1c40-\u1c49\u1c4d-\u1c7d\u1cd0-\u1cd2\u1cd4-\u1cf6\u1d00-\u1de6\u1dfc-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u200c\u200d\u203f\u2040\u2054\u2071\u207f\u2090-\u209c\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d7f-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2de0-\u2dff\u2e2f\u3005-\u3007\u3021-\u302f\u3031-\u3035\u3038-\u303c\u3041-\u3096\u3099\u309a\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua62b\ua640-\ua66f\ua674-\ua67d\ua67f-\ua697\ua69f-\ua6f1\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua827\ua840-\ua873\ua880-\ua8c4\ua8d0-\ua8d9\ua8e0-\ua8f7\ua8fb\ua900-\ua92d\ua930-\ua953\ua960-\ua97c\ua980-\ua9c0\ua9cf-\ua9d9\uaa00-\uaa36\uaa40-\uaa4d\uaa50-\uaa59\uaa60-\uaa76\uaa7a\uaa7b\uaa80-\uaac2\uaadb-\uaadd\uaae0-\uaaef\uaaf2-\uaaf6\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabea\uabec\uabed\uabf0-\uabf9\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\ufe70-\ufe74\ufe76-\ufefc\uff10-\uff19\uff21-\uff3a\uff3f\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]') - }; - - // Ensure the condition is true, otherwise throw an error. - // This is only to have a better contract semantic, i.e. another safety net - // to catch a logic error. The condition shall be fulfilled in normal case. - // Do NOT use this to enforce a certain condition on any user input. - - function assert(condition, message) { - /* istanbul ignore if */ - if (!condition) { - throw new Error('ASSERT: ' + message); - } - } - - function StringMap() { - this.$data = {}; - } - - StringMap.prototype.get = function (key) { - key = '$' + key; - return this.$data[key]; - }; - - StringMap.prototype.set = function (key, value) { - key = '$' + key; - this.$data[key] = value; - return this; - }; - - StringMap.prototype.has = function (key) { - key = '$' + key; - return Object.prototype.hasOwnProperty.call(this.$data, key); - }; - - StringMap.prototype['delete'] = function (key) { - key = '$' + key; - return delete this.$data[key]; - }; - - function isDecimalDigit(ch) { - return (ch >= 48 && ch <= 57); // 0..9 - } - - function isHexDigit(ch) { - return '0123456789abcdefABCDEF'.indexOf(ch) >= 0; - } - - function isOctalDigit(ch) { - return '01234567'.indexOf(ch) >= 0; - } - - - // 7.2 White Space - - function isWhiteSpace(ch) { - return (ch === 32) || // space - (ch === 9) || // tab - (ch === 0xB) || - (ch === 0xC) || - (ch === 0xA0) || - (ch >= 0x1680 && '\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\uFEFF'.indexOf(String.fromCharCode(ch)) > 0); - } - - // 7.3 Line Terminators - - function isLineTerminator(ch) { - return (ch === 10) || (ch === 13) || (ch === 0x2028) || (ch === 0x2029); - } - - // 7.6 Identifier Names and Identifiers - - function isIdentifierStart(ch) { - return (ch === 36) || (ch === 95) || // $ (dollar) and _ (underscore) - (ch >= 65 && ch <= 90) || // A..Z - (ch >= 97 && ch <= 122) || // a..z - (ch === 92) || // \ (backslash) - ((ch >= 0x80) && Regex.NonAsciiIdentifierStart.test(String.fromCharCode(ch))); - } - - function isIdentifierPart(ch) { - return (ch === 36) || (ch === 95) || // $ (dollar) and _ (underscore) - (ch >= 65 && ch <= 90) || // A..Z - (ch >= 97 && ch <= 122) || // a..z - (ch >= 48 && ch <= 57) || // 0..9 - (ch === 92) || // \ (backslash) - ((ch >= 0x80) && Regex.NonAsciiIdentifierPart.test(String.fromCharCode(ch))); - } - - // 7.6.1.2 Future Reserved Words - - function isFutureReservedWord(id) { - switch (id) { - case 'class': - case 'enum': - case 'export': - case 'extends': - case 'import': - case 'super': - return true; - default: - return false; - } - } - - function isStrictModeReservedWord(id) { - switch (id) { - case 'implements': - case 'interface': - case 'package': - case 'private': - case 'protected': - case 'public': - case 'static': - case 'yield': - case 'let': - return true; - default: - return false; - } - } - - function isRestrictedWord(id) { - return id === 'eval' || id === 'arguments'; - } - - // 7.6.1.1 Keywords - - function isKeyword(id) { - if (strict && isStrictModeReservedWord(id)) { - return true; - } - - // 'const' is specialized as Keyword in V8. - // 'yield' is only treated as a keyword in strict mode. - // 'let' is for compatiblity with SpiderMonkey and ES.next. - // Some others are from future reserved words. - - switch (id.length) { - case 2: - return (id === 'if') || (id === 'in') || (id === 'do'); - case 3: - return (id === 'var') || (id === 'for') || (id === 'new') || - (id === 'try') || (id === 'let'); - case 4: - return (id === 'this') || (id === 'else') || (id === 'case') || - (id === 'void') || (id === 'with') || (id === 'enum'); - case 5: - return (id === 'while') || (id === 'break') || (id === 'catch') || - (id === 'throw') || (id === 'const') || - (id === 'class') || (id === 'super'); - case 6: - return (id === 'return') || (id === 'typeof') || (id === 'delete') || - (id === 'switch') || (id === 'export') || (id === 'import'); - case 7: - return (id === 'default') || (id === 'finally') || (id === 'extends'); - case 8: - return (id === 'function') || (id === 'continue') || (id === 'debugger'); - case 10: - return (id === 'instanceof'); - default: - return false; - } - } - - // 7.4 Comments - - function skipComment() { - var ch, blockComment, lineComment; - - blockComment = false; - lineComment = false; - - while (index < length) { - ch = source.charCodeAt(index); - - if (lineComment) { - ++index; - if (isLineTerminator(ch)) { - lineComment = false; - if (ch === 13 && source.charCodeAt(index) === 10) { - ++index; - } - ++lineNumber; - lineStart = index; - } - } else if (blockComment) { - if (isLineTerminator(ch)) { - if (ch === 13 && source.charCodeAt(index + 1) === 10) { - ++index; - } - ++lineNumber; - ++index; - lineStart = index; - if (index >= length) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - } else { - ch = source.charCodeAt(index++); - if (index >= length) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - // Block comment ends with '*/' (char #42, char #47). - if (ch === 42) { - ch = source.charCodeAt(index); - if (ch === 47) { - ++index; - blockComment = false; - } - } - } - } else if (ch === 47) { - ch = source.charCodeAt(index + 1); - // Line comment starts with '//' (char #47, char #47). - if (ch === 47) { - index += 2; - lineComment = true; - } else if (ch === 42) { - // Block comment starts with '/*' (char #47, char #42). - index += 2; - blockComment = true; - if (index >= length) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - } else { - break; - } - } else if (isWhiteSpace(ch)) { - ++index; - } else if (isLineTerminator(ch)) { - ++index; - if (ch === 13 && source.charCodeAt(index) === 10) { - ++index; - } - ++lineNumber; - lineStart = index; - } else { - break; - } - } - } - - function scanHexEscape(prefix) { - var i, len, ch, code = 0; - - len = (prefix === 'u') ? 4 : 2; - for (i = 0; i < len; ++i) { - if (index < length && isHexDigit(source[index])) { - ch = source[index++]; - code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase()); - } else { - return ''; - } - } - return String.fromCharCode(code); - } - - function scanUnicodeCodePointEscape() { - var ch, code, cu1, cu2; - - ch = source[index]; - code = 0; - - // At least, one hex digit is required. - if (ch === '}') { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - while (index < length) { - ch = source[index++]; - if (!isHexDigit(ch)) { - break; - } - code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase()); - } - - if (code > 0x10FFFF || ch !== '}') { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - // UTF-16 Encoding - if (code <= 0xFFFF) { - return String.fromCharCode(code); - } - cu1 = ((code - 0x10000) >> 10) + 0xD800; - cu2 = ((code - 0x10000) & 1023) + 0xDC00; - return String.fromCharCode(cu1, cu2); - } - - function getEscapedIdentifier() { - var ch, id; - - ch = source.charCodeAt(index++); - id = String.fromCharCode(ch); - - // '\u' (char #92, char #117) denotes an escaped character. - if (ch === 92) { - if (source.charCodeAt(index) !== 117) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - ++index; - ch = scanHexEscape('u'); - if (!ch || ch === '\\' || !isIdentifierStart(ch.charCodeAt(0))) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - id = ch; - } - - while (index < length) { - ch = source.charCodeAt(index); - if (!isIdentifierPart(ch)) { - break; - } - ++index; - id += String.fromCharCode(ch); - - // '\u' (char #92, char #117) denotes an escaped character. - if (ch === 92) { - id = id.substr(0, id.length - 1); - if (source.charCodeAt(index) !== 117) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - ++index; - ch = scanHexEscape('u'); - if (!ch || ch === '\\' || !isIdentifierPart(ch.charCodeAt(0))) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - id += ch; - } - } - - return id; - } - - function getIdentifier() { - var start, ch; - - start = index++; - while (index < length) { - ch = source.charCodeAt(index); - if (ch === 92) { - // Blackslash (char #92) marks Unicode escape sequence. - index = start; - return getEscapedIdentifier(); - } - if (isIdentifierPart(ch)) { - ++index; - } else { - break; - } - } - - return source.slice(start, index); - } - - function scanIdentifier() { - var start, id, type; - - start = index; - - // Backslash (char #92) starts an escaped character. - id = (source.charCodeAt(index) === 92) ? getEscapedIdentifier() : getIdentifier(); - - // There is no keyword or literal with only one character. - // Thus, it must be an identifier. - if (id.length === 1) { - type = Token.Identifier; - } else if (isKeyword(id)) { - type = Token.Keyword; - } else if (id === 'null') { - type = Token.NullLiteral; - } else if (id === 'true' || id === 'false') { - type = Token.BooleanLiteral; - } else { - type = Token.Identifier; - } - - return { - type: type, - value: id, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - - // 7.7 Punctuators - - function scanPunctuator() { - var start = index, - code = source.charCodeAt(index), - code2, - ch1 = source[index], - ch2, - ch3, - ch4; - - switch (code) { - // Check for most common single-character punctuators. - case 40: // ( open bracket - case 41: // ) close bracket - case 59: // ; semicolon - case 44: // , comma - case 123: // { open curly brace - case 125: // } close curly brace - case 91: // [ - case 93: // ] - case 58: // : - case 63: // ? - case 126: // ~ - ++index; - if (extra.tokenize) { - if (code === 40) { - extra.openParenToken = extra.tokens.length; - } else if (code === 123) { - extra.openCurlyToken = extra.tokens.length; - } - } - return { - type: Token.Punctuator, - value: String.fromCharCode(code), - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - - default: - code2 = source.charCodeAt(index + 1); - - // '=' (char #61) marks an assignment or comparison operator. - if (code2 === 61) { - switch (code) { - case 37: // % - case 38: // & - case 42: // *: - case 43: // + - case 45: // - - case 47: // / - case 60: // < - case 62: // > - case 94: // ^ - case 124: // | - index += 2; - return { - type: Token.Punctuator, - value: String.fromCharCode(code) + String.fromCharCode(code2), - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - - case 33: // ! - case 61: // = - index += 2; - - // !== and === - if (source.charCodeAt(index) === 61) { - ++index; - } - return { - type: Token.Punctuator, - value: source.slice(start, index), - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - default: - break; - } - } - break; - } - - // Peek more characters. - - ch2 = source[index + 1]; - ch3 = source[index + 2]; - ch4 = source[index + 3]; - - // 4-character punctuator: >>>= - - if (ch1 === '>' && ch2 === '>' && ch3 === '>') { - if (ch4 === '=') { - index += 4; - return { - type: Token.Punctuator, - value: '>>>=', - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - } - - // 3-character punctuators: === !== >>> <<= >>= - - if (ch1 === '>' && ch2 === '>' && ch3 === '>') { - index += 3; - return { - type: Token.Punctuator, - value: '>>>', - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - if (ch1 === '<' && ch2 === '<' && ch3 === '=') { - index += 3; - return { - type: Token.Punctuator, - value: '<<=', - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - if (ch1 === '>' && ch2 === '>' && ch3 === '=') { - index += 3; - return { - type: Token.Punctuator, - value: '>>=', - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - if (ch1 === '.' && ch2 === '.' && ch3 === '.') { - index += 3; - return { - type: Token.Punctuator, - value: '...', - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - // Other 2-character punctuators: ++ -- << >> && || - - if (ch1 === ch2 && ('+-<>&|'.indexOf(ch1) >= 0)) { - index += 2; - return { - type: Token.Punctuator, - value: ch1 + ch2, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - if (ch1 === '=' && ch2 === '>') { - index += 2; - return { - type: Token.Punctuator, - value: '=>', - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) { - ++index; - return { - type: Token.Punctuator, - value: ch1, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - if (ch1 === '.') { - ++index; - return { - type: Token.Punctuator, - value: ch1, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - // 7.8.3 Numeric Literals - - function scanHexLiteral(start) { - var number = ''; - - while (index < length) { - if (!isHexDigit(source[index])) { - break; - } - number += source[index++]; - } - - if (number.length === 0) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - if (isIdentifierStart(source.charCodeAt(index))) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - return { - type: Token.NumericLiteral, - value: parseInt('0x' + number, 16), - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - function scanOctalLiteral(prefix, start) { - var number, octal; - - if (isOctalDigit(prefix)) { - octal = true; - number = '0' + source[index++]; - } else { - octal = false; - ++index; - number = ''; - } - - while (index < length) { - if (!isOctalDigit(source[index])) { - break; - } - number += source[index++]; - } - - if (!octal && number.length === 0) { - // only 0o or 0O - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - if (isIdentifierStart(source.charCodeAt(index)) || isDecimalDigit(source.charCodeAt(index))) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - return { - type: Token.NumericLiteral, - value: parseInt(number, 8), - octal: octal, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - function scanNumericLiteral() { - var number, start, ch, octal; - - ch = source[index]; - assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'), - 'Numeric literal must start with a decimal digit or a decimal point'); - - start = index; - number = ''; - if (ch !== '.') { - number = source[index++]; - ch = source[index]; - - // Hex number starts with '0x'. - // Octal number starts with '0'. - // Octal number in ES6 starts with '0o'. - // Binary number in ES6 starts with '0b'. - if (number === '0') { - if (ch === 'x' || ch === 'X') { - ++index; - return scanHexLiteral(start); - } - if (ch === 'b' || ch === 'B') { - ++index; - number = ''; - - while (index < length) { - ch = source[index]; - if (ch !== '0' && ch !== '1') { - break; - } - number += source[index++]; - } - - if (number.length === 0) { - // only 0b or 0B - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - if (index < length) { - ch = source.charCodeAt(index); - /* istanbul ignore else */ - if (isIdentifierStart(ch) || isDecimalDigit(ch)) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - } - return { - type: Token.NumericLiteral, - value: parseInt(number, 2), - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - if (ch === 'o' || ch === 'O' || isOctalDigit(ch)) { - return scanOctalLiteral(ch, start); - } - // decimal number starts with '0' such as '09' is illegal. - if (ch && isDecimalDigit(ch.charCodeAt(0))) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - } - - while (isDecimalDigit(source.charCodeAt(index))) { - number += source[index++]; - } - ch = source[index]; - } - - if (ch === '.') { - number += source[index++]; - while (isDecimalDigit(source.charCodeAt(index))) { - number += source[index++]; - } - ch = source[index]; - } - - if (ch === 'e' || ch === 'E') { - number += source[index++]; - - ch = source[index]; - if (ch === '+' || ch === '-') { - number += source[index++]; - } - if (isDecimalDigit(source.charCodeAt(index))) { - while (isDecimalDigit(source.charCodeAt(index))) { - number += source[index++]; - } - } else { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - } - - if (isIdentifierStart(source.charCodeAt(index))) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - return { - type: Token.NumericLiteral, - value: parseFloat(number), - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - // 7.8.4 String Literals - - function scanStringLiteral() { - var str = '', quote, start, ch, code, unescaped, restore, octal = false; - - quote = source[index]; - assert((quote === '\'' || quote === '"'), - 'String literal must starts with a quote'); - - start = index; - ++index; - - while (index < length) { - ch = source[index++]; - - if (ch === quote) { - quote = ''; - break; - } else if (ch === '\\') { - ch = source[index++]; - if (!ch || !isLineTerminator(ch.charCodeAt(0))) { - switch (ch) { - case 'n': - str += '\n'; - break; - case 'r': - str += '\r'; - break; - case 't': - str += '\t'; - break; - case 'u': - case 'x': - if (source[index] === '{') { - ++index; - str += scanUnicodeCodePointEscape(); - } else { - restore = index; - unescaped = scanHexEscape(ch); - if (unescaped) { - str += unescaped; - } else { - index = restore; - str += ch; - } - } - break; - case 'b': - str += '\b'; - break; - case 'f': - str += '\f'; - break; - case 'v': - str += '\x0B'; - break; - - default: - if (isOctalDigit(ch)) { - code = '01234567'.indexOf(ch); - - // \0 is not octal escape sequence - if (code !== 0) { - octal = true; - } - - /* istanbul ignore else */ - if (index < length && isOctalDigit(source[index])) { - octal = true; - code = code * 8 + '01234567'.indexOf(source[index++]); - - // 3 digits are only allowed when string starts - // with 0, 1, 2, 3 - if ('0123'.indexOf(ch) >= 0 && - index < length && - isOctalDigit(source[index])) { - code = code * 8 + '01234567'.indexOf(source[index++]); - } - } - str += String.fromCharCode(code); - } else { - str += ch; - } - break; - } - } else { - ++lineNumber; - if (ch === '\r' && source[index] === '\n') { - ++index; - } - lineStart = index; - } - } else if (isLineTerminator(ch.charCodeAt(0))) { - break; - } else { - str += ch; - } - } - - if (quote !== '') { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - return { - type: Token.StringLiteral, - value: str, - octal: octal, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - function scanTemplate() { - var cooked = '', ch, start, terminated, tail, restore, unescaped, code, octal; - - terminated = false; - tail = false; - start = index; - - ++index; - - while (index < length) { - ch = source[index++]; - if (ch === '`') { - tail = true; - terminated = true; - break; - } else if (ch === '$') { - if (source[index] === '{') { - ++index; - terminated = true; - break; - } - cooked += ch; - } else if (ch === '\\') { - ch = source[index++]; - if (!isLineTerminator(ch.charCodeAt(0))) { - switch (ch) { - case 'n': - cooked += '\n'; - break; - case 'r': - cooked += '\r'; - break; - case 't': - cooked += '\t'; - break; - case 'u': - case 'x': - if (source[index] === '{') { - ++index; - cooked += scanUnicodeCodePointEscape(); - } else { - restore = index; - unescaped = scanHexEscape(ch); - if (unescaped) { - cooked += unescaped; - } else { - index = restore; - cooked += ch; - } - } - break; - case 'b': - cooked += '\b'; - break; - case 'f': - cooked += '\f'; - break; - case 'v': - cooked += '\v'; - break; - - default: - if (isOctalDigit(ch)) { - code = '01234567'.indexOf(ch); - - // \0 is not octal escape sequence - if (code !== 0) { - octal = true; - } - - /* istanbul ignore else */ - if (index < length && isOctalDigit(source[index])) { - octal = true; - code = code * 8 + '01234567'.indexOf(source[index++]); - - // 3 digits are only allowed when string starts - // with 0, 1, 2, 3 - if ('0123'.indexOf(ch) >= 0 && - index < length && - isOctalDigit(source[index])) { - code = code * 8 + '01234567'.indexOf(source[index++]); - } - } - cooked += String.fromCharCode(code); - } else { - cooked += ch; - } - break; - } - } else { - ++lineNumber; - if (ch === '\r' && source[index] === '\n') { - ++index; - } - lineStart = index; - } - } else if (isLineTerminator(ch.charCodeAt(0))) { - ++lineNumber; - if (ch === '\r' && source[index] === '\n') { - ++index; - } - lineStart = index; - cooked += '\n'; - } else { - cooked += ch; - } - } - - if (!terminated) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - return { - type: Token.Template, - value: { - cooked: cooked, - raw: source.slice(start + 1, index - ((tail) ? 1 : 2)) - }, - tail: tail, - octal: octal, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - function scanTemplateElement(option) { - var startsWith, template; - - lookahead = null; - skipComment(); - - startsWith = (option.head) ? '`' : '}'; - - if (source[index] !== startsWith) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - template = scanTemplate(); - - peek(); - - return template; - } - - function scanRegExp() { - var str, ch, start, pattern, flags, value, classMarker = false, restore, terminated = false, tmp; - - lookahead = null; - skipComment(); - - start = index; - ch = source[index]; - assert(ch === '/', 'Regular expression literal must start with a slash'); - str = source[index++]; - - while (index < length) { - ch = source[index++]; - str += ch; - if (classMarker) { - if (ch === ']') { - classMarker = false; - } - } else { - if (ch === '\\') { - ch = source[index++]; - // ECMA-262 7.8.5 - if (isLineTerminator(ch.charCodeAt(0))) { - throwError({}, Messages.UnterminatedRegExp); - } - str += ch; - } else if (ch === '/') { - terminated = true; - break; - } else if (ch === '[') { - classMarker = true; - } else if (isLineTerminator(ch.charCodeAt(0))) { - throwError({}, Messages.UnterminatedRegExp); - } - } - } - - if (!terminated) { - throwError({}, Messages.UnterminatedRegExp); - } - - // Exclude leading and trailing slash. - pattern = str.substr(1, str.length - 2); - - flags = ''; - while (index < length) { - ch = source[index]; - if (!isIdentifierPart(ch.charCodeAt(0))) { - break; - } - - ++index; - if (ch === '\\' && index < length) { - ch = source[index]; - if (ch === 'u') { - ++index; - restore = index; - ch = scanHexEscape('u'); - /* istanbul ignore else */ - if (ch) { - flags += ch; - for (str += '\\u'; restore < index; ++restore) { - str += source[restore]; - } - } else { - index = restore; - flags += 'u'; - str += '\\u'; - } - } else { - str += '\\'; - } - } else { - flags += ch; - str += ch; - } - } - - tmp = pattern; - if (flags.indexOf('u') >= 0) { - // Replace each astral symbol and every Unicode code point - // escape sequence that represents such a symbol with a single - // ASCII symbol to avoid throwing on regular expressions that - // are only valid in combination with the `/u` flag. - tmp = tmp - .replace(/\\u\{([0-9a-fA-F]{5,6})\}/g, 'x') - .replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, 'x'); - } - - // First, detect invalid regular expressions. - try { - value = new RegExp(tmp); - } catch (e) { - throwError({}, Messages.InvalidRegExp); - } - - // Return a regular expression object for this pattern-flag pair, or - // `null` in case the current environment doesn't support the flags it - // uses. - try { - value = new RegExp(pattern, flags); - } catch (exception) { - value = null; - } - - peek(); - - if (extra.tokenize) { - return { - type: Token.RegularExpression, - value: value, - regex: { - pattern: pattern, - flags: flags - }, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - return { - literal: str, - value: value, - regex: { - pattern: pattern, - flags: flags - }, - range: [start, index] - }; - } - - function isIdentifierName(token) { - return token.type === Token.Identifier || - token.type === Token.Keyword || - token.type === Token.BooleanLiteral || - token.type === Token.NullLiteral; - } - - function advanceSlash() { - var prevToken, - checkToken; - // Using the following algorithm: - // https://github.com/mozilla/sweet.js/wiki/design - prevToken = extra.tokens[extra.tokens.length - 1]; - if (!prevToken) { - // Nothing before that: it cannot be a division. - return scanRegExp(); - } - if (prevToken.type === 'Punctuator') { - if (prevToken.value === ')') { - checkToken = extra.tokens[extra.openParenToken - 1]; - if (checkToken && - checkToken.type === 'Keyword' && - (checkToken.value === 'if' || - checkToken.value === 'while' || - checkToken.value === 'for' || - checkToken.value === 'with')) { - return scanRegExp(); - } - return scanPunctuator(); - } - if (prevToken.value === '}') { - // Dividing a function by anything makes little sense, - // but we have to check for that. - if (extra.tokens[extra.openCurlyToken - 3] && - extra.tokens[extra.openCurlyToken - 3].type === 'Keyword') { - // Anonymous function. - checkToken = extra.tokens[extra.openCurlyToken - 4]; - if (!checkToken) { - return scanPunctuator(); - } - } else if (extra.tokens[extra.openCurlyToken - 4] && - extra.tokens[extra.openCurlyToken - 4].type === 'Keyword') { - // Named function. - checkToken = extra.tokens[extra.openCurlyToken - 5]; - if (!checkToken) { - return scanRegExp(); - } - } else { - return scanPunctuator(); - } - // checkToken determines whether the function is - // a declaration or an expression. - if (FnExprTokens.indexOf(checkToken.value) >= 0) { - // It is an expression. - return scanPunctuator(); - } - // It is a declaration. - return scanRegExp(); - } - return scanRegExp(); - } - if (prevToken.type === 'Keyword') { - return scanRegExp(); - } - return scanPunctuator(); - } - - function advance() { - var ch; - - skipComment(); - - if (index >= length) { - return { - type: Token.EOF, - lineNumber: lineNumber, - lineStart: lineStart, - range: [index, index] - }; - } - - ch = source.charCodeAt(index); - - // Very common: ( and ) and ; - if (ch === 40 || ch === 41 || ch === 58) { - return scanPunctuator(); - } - - // String literal starts with single quote (#39) or double quote (#34). - if (ch === 39 || ch === 34) { - return scanStringLiteral(); - } - - if (ch === 96) { - return scanTemplate(); - } - if (isIdentifierStart(ch)) { - return scanIdentifier(); - } - - // Dot (.) char #46 can also start a floating-point number, hence the need - // to check the next character. - if (ch === 46) { - if (isDecimalDigit(source.charCodeAt(index + 1))) { - return scanNumericLiteral(); - } - return scanPunctuator(); - } - - if (isDecimalDigit(ch)) { - return scanNumericLiteral(); - } - - // Slash (/) char #47 can also start a regex. - if (extra.tokenize && ch === 47) { - return advanceSlash(); - } - - return scanPunctuator(); - } - - function lex() { - var token; - - token = lookahead; - index = token.range[1]; - lineNumber = token.lineNumber; - lineStart = token.lineStart; - - lookahead = advance(); - - index = token.range[1]; - lineNumber = token.lineNumber; - lineStart = token.lineStart; - - return token; - } - - function peek() { - var pos, line, start; - - pos = index; - line = lineNumber; - start = lineStart; - lookahead = advance(); - index = pos; - lineNumber = line; - lineStart = start; - } - - function lookahead2() { - var adv, pos, line, start, result; - - // If we are collecting the tokens, don't grab the next one yet. - /* istanbul ignore next */ - adv = (typeof extra.advance === 'function') ? extra.advance : advance; - - pos = index; - line = lineNumber; - start = lineStart; - - // Scan for the next immediate token. - /* istanbul ignore if */ - if (lookahead === null) { - lookahead = adv(); - } - index = lookahead.range[1]; - lineNumber = lookahead.lineNumber; - lineStart = lookahead.lineStart; - - // Grab the token right after. - result = adv(); - index = pos; - lineNumber = line; - lineStart = start; - - return result; - } - - function markerCreate() { - if (!extra.loc && !extra.range) { - return undefined; - } - skipComment(); - return {offset: index, line: lineNumber, col: index - lineStart}; - } - - function processComment(node) { - var lastChild, - trailingComments, - bottomRight = extra.bottomRightStack, - last = bottomRight[bottomRight.length - 1]; - - if (node.type === Syntax.Program) { - /* istanbul ignore else */ - if (node.body.length > 0) { - return; - } - } - - if (extra.trailingComments.length > 0) { - if (extra.trailingComments[0].range[0] >= node.range[1]) { - trailingComments = extra.trailingComments; - extra.trailingComments = []; - } else { - extra.trailingComments.length = 0; - } - } else { - if (last && last.trailingComments && last.trailingComments[0].range[0] >= node.range[1]) { - trailingComments = last.trailingComments; - delete last.trailingComments; - } - } - - // Eating the stack. - if (last) { - while (last && last.range[0] >= node.range[0]) { - lastChild = last; - last = bottomRight.pop(); - } - } - - if (lastChild) { - if (lastChild.leadingComments && lastChild.leadingComments[lastChild.leadingComments.length - 1].range[1] <= node.range[0]) { - node.leadingComments = lastChild.leadingComments; - delete lastChild.leadingComments; - } - } else if (extra.leadingComments.length > 0 && extra.leadingComments[extra.leadingComments.length - 1].range[1] <= node.range[0]) { - node.leadingComments = extra.leadingComments; - extra.leadingComments = []; - } - - if (trailingComments) { - node.trailingComments = trailingComments; - } - - bottomRight.push(node); - } - - function markerApply(marker, node) { - if (extra.range) { - node.range = [marker.offset, index]; - } - if (extra.loc) { - node.loc = { - start: { - line: marker.line, - column: marker.col - }, - end: { - line: lineNumber, - column: index - lineStart - } - }; - node = delegate.postProcess(node); - } - if (extra.attachComment) { - processComment(node); - } - return node; - } - - SyntaxTreeDelegate = { - - name: 'SyntaxTree', - - postProcess: function (node) { - return node; - }, - - createArrayExpression: function (elements) { - return { - type: Syntax.ArrayExpression, - elements: elements - }; - }, - - createAssignmentExpression: function (operator, left, right) { - return { - type: Syntax.AssignmentExpression, - operator: operator, - left: left, - right: right - }; - }, - - createBinaryExpression: function (operator, left, right) { - var type = (operator === '||' || operator === '&&') ? Syntax.LogicalExpression : - Syntax.BinaryExpression; - return { - type: type, - operator: operator, - left: left, - right: right - }; - }, - - createBlockStatement: function (body) { - return { - type: Syntax.BlockStatement, - body: body - }; - }, - - createBreakStatement: function (label) { - return { - type: Syntax.BreakStatement, - label: label - }; - }, - - createCallExpression: function (callee, args) { - return { - type: Syntax.CallExpression, - callee: callee, - 'arguments': args - }; - }, - - createCatchClause: function (param, body) { - return { - type: Syntax.CatchClause, - param: param, - body: body - }; - }, - - createConditionalExpression: function (test, consequent, alternate) { - return { - type: Syntax.ConditionalExpression, - test: test, - consequent: consequent, - alternate: alternate - }; - }, - - createContinueStatement: function (label) { - return { - type: Syntax.ContinueStatement, - label: label - }; - }, - - createDebuggerStatement: function () { - return { - type: Syntax.DebuggerStatement - }; - }, - - createDoWhileStatement: function (body, test) { - return { - type: Syntax.DoWhileStatement, - body: body, - test: test - }; - }, - - createEmptyStatement: function () { - return { - type: Syntax.EmptyStatement - }; - }, - - createExpressionStatement: function (expression) { - return { - type: Syntax.ExpressionStatement, - expression: expression - }; - }, - - createForStatement: function (init, test, update, body) { - return { - type: Syntax.ForStatement, - init: init, - test: test, - update: update, - body: body - }; - }, - - createForInStatement: function (left, right, body) { - return { - type: Syntax.ForInStatement, - left: left, - right: right, - body: body, - each: false - }; - }, - - createForOfStatement: function (left, right, body) { - return { - type: Syntax.ForOfStatement, - left: left, - right: right, - body: body - }; - }, - - createFunctionDeclaration: function (id, params, defaults, body, rest, generator, expression) { - return { - type: Syntax.FunctionDeclaration, - id: id, - params: params, - defaults: defaults, - body: body, - rest: rest, - generator: generator, - expression: expression - }; - }, - - createFunctionExpression: function (id, params, defaults, body, rest, generator, expression) { - return { - type: Syntax.FunctionExpression, - id: id, - params: params, - defaults: defaults, - body: body, - rest: rest, - generator: generator, - expression: expression - }; - }, - - createIdentifier: function (name) { - return { - type: Syntax.Identifier, - name: name - }; - }, - - createIfStatement: function (test, consequent, alternate) { - return { - type: Syntax.IfStatement, - test: test, - consequent: consequent, - alternate: alternate - }; - }, - - createLabeledStatement: function (label, body) { - return { - type: Syntax.LabeledStatement, - label: label, - body: body - }; - }, - - createLiteral: function (token) { - var object = { - type: Syntax.Literal, - value: token.value, - raw: source.slice(token.range[0], token.range[1]) - }; - if (token.regex) { - object.regex = token.regex; - } - return object; - }, - - createMemberExpression: function (accessor, object, property) { - return { - type: Syntax.MemberExpression, - computed: accessor === '[', - object: object, - property: property - }; - }, - - createNewExpression: function (callee, args) { - return { - type: Syntax.NewExpression, - callee: callee, - 'arguments': args - }; - }, - - createObjectExpression: function (properties) { - return { - type: Syntax.ObjectExpression, - properties: properties - }; - }, - - createPostfixExpression: function (operator, argument) { - return { - type: Syntax.UpdateExpression, - operator: operator, - argument: argument, - prefix: false - }; - }, - - createProgram: function (body) { - return { - type: Syntax.Program, - body: body - }; - }, - - createProperty: function (kind, key, value, method, shorthand, computed) { - return { - type: Syntax.Property, - key: key, - value: value, - kind: kind, - method: method, - shorthand: shorthand, - computed: computed - }; - }, - - createReturnStatement: function (argument) { - return { - type: Syntax.ReturnStatement, - argument: argument - }; - }, - - createSequenceExpression: function (expressions) { - return { - type: Syntax.SequenceExpression, - expressions: expressions - }; - }, - - createSwitchCase: function (test, consequent) { - return { - type: Syntax.SwitchCase, - test: test, - consequent: consequent - }; - }, - - createSwitchStatement: function (discriminant, cases) { - return { - type: Syntax.SwitchStatement, - discriminant: discriminant, - cases: cases - }; - }, - - createThisExpression: function () { - return { - type: Syntax.ThisExpression - }; - }, - - createThrowStatement: function (argument) { - return { - type: Syntax.ThrowStatement, - argument: argument - }; - }, - - createTryStatement: function (block, handler, finalizer) { - return { - type: Syntax.TryStatement, - block: block, - handler: handler, - finalizer: finalizer - }; - }, - - createUnaryExpression: function (operator, argument) { - if (operator === '++' || operator === '--') { - return { - type: Syntax.UpdateExpression, - operator: operator, - argument: argument, - prefix: true - }; - } - return { - type: Syntax.UnaryExpression, - operator: operator, - argument: argument, - prefix: true - }; - }, - - createVariableDeclaration: function (declarations, kind) { - return { - type: Syntax.VariableDeclaration, - declarations: declarations, - kind: kind - }; - }, - - createVariableDeclarator: function (id, init) { - return { - type: Syntax.VariableDeclarator, - id: id, - init: init - }; - }, - - createWhileStatement: function (test, body) { - return { - type: Syntax.WhileStatement, - test: test, - body: body - }; - }, - - createWithStatement: function (object, body) { - return { - type: Syntax.WithStatement, - object: object, - body: body - }; - }, - - createTemplateElement: function (value, tail) { - return { - type: Syntax.TemplateElement, - value: value, - tail: tail - }; - }, - - createTemplateLiteral: function (quasis, expressions) { - return { - type: Syntax.TemplateLiteral, - quasis: quasis, - expressions: expressions - }; - }, - - createSpreadElement: function (argument) { - return { - type: Syntax.SpreadElement, - argument: argument - }; - }, - - createTaggedTemplateExpression: function (tag, quasi) { - return { - type: Syntax.TaggedTemplateExpression, - tag: tag, - quasi: quasi - }; - }, - - createArrowFunctionExpression: function (params, defaults, body, rest, expression) { - return { - type: Syntax.ArrowFunctionExpression, - id: null, - params: params, - defaults: defaults, - body: body, - rest: rest, - generator: false, - expression: expression - }; - }, - - createMethodDefinition: function (propertyType, kind, key, value, computed) { - return { - type: Syntax.MethodDefinition, - key: key, - value: value, - kind: kind, - 'static': propertyType === ClassPropertyType.static, - computed: computed - }; - }, - - createClassBody: function (body) { - return { - type: Syntax.ClassBody, - body: body - }; - }, - - createClassExpression: function (id, superClass, body) { - return { - type: Syntax.ClassExpression, - id: id, - superClass: superClass, - body: body - }; - }, - - createClassDeclaration: function (id, superClass, body) { - return { - type: Syntax.ClassDeclaration, - id: id, - superClass: superClass, - body: body - }; - }, - - createModuleSpecifier: function (token) { - return { - type: Syntax.ModuleSpecifier, - value: token.value, - raw: source.slice(token.range[0], token.range[1]) - }; - }, - - createExportSpecifier: function (id, name) { - return { - type: Syntax.ExportSpecifier, - id: id, - name: name - }; - }, - - createExportBatchSpecifier: function () { - return { - type: Syntax.ExportBatchSpecifier - }; - }, - - createImportDefaultSpecifier: function (id) { - return { - type: Syntax.ImportDefaultSpecifier, - id: id - }; - }, - - createImportNamespaceSpecifier: function (id) { - return { - type: Syntax.ImportNamespaceSpecifier, - id: id - }; - }, - - createExportDeclaration: function (isDefault, declaration, specifiers, source) { - return { - type: Syntax.ExportDeclaration, - 'default': !!isDefault, - declaration: declaration, - specifiers: specifiers, - source: source - }; - }, - - createImportSpecifier: function (id, name) { - return { - type: Syntax.ImportSpecifier, - id: id, - name: name - }; - }, - - createImportDeclaration: function (specifiers, source) { - return { - type: Syntax.ImportDeclaration, - specifiers: specifiers, - source: source - }; - }, - - createYieldExpression: function (argument, delegate) { - return { - type: Syntax.YieldExpression, - argument: argument, - delegate: delegate - }; - }, - - createComprehensionExpression: function (filter, blocks, body) { - return { - type: Syntax.ComprehensionExpression, - filter: filter, - blocks: blocks, - body: body - }; - } - - }; - - // Return true if there is a line terminator before the next token. - - function peekLineTerminator() { - var pos, line, start, found; - - pos = index; - line = lineNumber; - start = lineStart; - skipComment(); - found = lineNumber !== line; - index = pos; - lineNumber = line; - lineStart = start; - - return found; - } - - // Throw an exception - - function throwError(token, messageFormat) { - var error, - args = Array.prototype.slice.call(arguments, 2), - msg = messageFormat.replace( - /%(\d)/g, - function (whole, index) { - assert(index < args.length, 'Message reference must be in range'); - return args[index]; - } - ); - - if (typeof token.lineNumber === 'number') { - error = new Error('Line ' + token.lineNumber + ': ' + msg); - error.index = token.range[0]; - error.lineNumber = token.lineNumber; - error.column = token.range[0] - lineStart + 1; - } else { - error = new Error('Line ' + lineNumber + ': ' + msg); - error.index = index; - error.lineNumber = lineNumber; - error.column = index - lineStart + 1; - } - - error.description = msg; - throw error; - } - - function throwErrorTolerant() { - try { - throwError.apply(null, arguments); - } catch (e) { - if (extra.errors) { - extra.errors.push(e); - } else { - throw e; - } - } - } - - - // Throw an exception because of the token. - - function throwUnexpected(token) { - if (token.type === Token.EOF) { - throwError(token, Messages.UnexpectedEOS); - } - - if (token.type === Token.NumericLiteral) { - throwError(token, Messages.UnexpectedNumber); - } - - if (token.type === Token.StringLiteral) { - throwError(token, Messages.UnexpectedString); - } - - if (token.type === Token.Identifier) { - throwError(token, Messages.UnexpectedIdentifier); - } - - if (token.type === Token.Keyword) { - if (isFutureReservedWord(token.value)) { - throwError(token, Messages.UnexpectedReserved); - } else if (strict && isStrictModeReservedWord(token.value)) { - throwErrorTolerant(token, Messages.StrictReservedWord); - return; - } - throwError(token, Messages.UnexpectedToken, token.value); - } - - if (token.type === Token.Template) { - throwError(token, Messages.UnexpectedTemplate, token.value.raw); - } - - // BooleanLiteral, NullLiteral, or Punctuator. - throwError(token, Messages.UnexpectedToken, token.value); - } - - // Expect the next token to match the specified punctuator. - // If not, an exception will be thrown. - - function expect(value) { - var token = lex(); - if (token.type !== Token.Punctuator || token.value !== value) { - throwUnexpected(token); - } - } - - // Expect the next token to match the specified keyword. - // If not, an exception will be thrown. - - function expectKeyword(keyword) { - var token = lex(); - if (token.type !== Token.Keyword || token.value !== keyword) { - throwUnexpected(token); - } - } - - // Return true if the next token matches the specified punctuator. - - function match(value) { - return lookahead.type === Token.Punctuator && lookahead.value === value; - } - - // Return true if the next token matches the specified keyword - - function matchKeyword(keyword) { - return lookahead.type === Token.Keyword && lookahead.value === keyword; - } - - - // Return true if the next token matches the specified contextual keyword - - function matchContextualKeyword(keyword) { - return lookahead.type === Token.Identifier && lookahead.value === keyword; - } - - // Return true if the next token is an assignment operator - - function matchAssign() { - var op; - - if (lookahead.type !== Token.Punctuator) { - return false; - } - op = lookahead.value; - return op === '=' || - op === '*=' || - op === '/=' || - op === '%=' || - op === '+=' || - op === '-=' || - op === '<<=' || - op === '>>=' || - op === '>>>=' || - op === '&=' || - op === '^=' || - op === '|='; - } - - function consumeSemicolon() { - var line, oldIndex = index, oldLineNumber = lineNumber, - oldLineStart = lineStart, oldLookahead = lookahead; - - // Catch the very common case first: immediately a semicolon (char #59). - if (source.charCodeAt(index) === 59) { - lex(); - return; - } - - line = lineNumber; - skipComment(); - if (lineNumber !== line) { - index = oldIndex; - lineNumber = oldLineNumber; - lineStart = oldLineStart; - lookahead = oldLookahead; - return; - } - - if (match(';')) { - lex(); - return; - } - - if (lookahead.type !== Token.EOF && !match('}')) { - throwUnexpected(lookahead); - } - } - - // Return true if provided expression is LeftHandSideExpression - - function isLeftHandSide(expr) { - return expr.type === Syntax.Identifier || expr.type === Syntax.MemberExpression; - } - - function isAssignableLeftHandSide(expr) { - return isLeftHandSide(expr) || expr.type === Syntax.ObjectPattern || expr.type === Syntax.ArrayPattern; - } - - // 11.1.4 Array Initialiser - - function parseArrayInitialiser() { - var elements = [], blocks = [], filter = null, tmp, possiblecomprehension = true, body, - marker = markerCreate(); - - expect('['); - while (!match(']')) { - if (lookahead.value === 'for' && - lookahead.type === Token.Keyword) { - if (!possiblecomprehension) { - throwError({}, Messages.ComprehensionError); - } - matchKeyword('for'); - tmp = parseForStatement({ignoreBody: true}); - tmp.of = tmp.type === Syntax.ForOfStatement; - tmp.type = Syntax.ComprehensionBlock; - if (tmp.left.kind) { // can't be let or const - throwError({}, Messages.ComprehensionError); - } - blocks.push(tmp); - } else if (lookahead.value === 'if' && - lookahead.type === Token.Keyword) { - if (!possiblecomprehension) { - throwError({}, Messages.ComprehensionError); - } - expectKeyword('if'); - expect('('); - filter = parseExpression(); - expect(')'); - } else if (lookahead.value === ',' && - lookahead.type === Token.Punctuator) { - possiblecomprehension = false; // no longer allowed. - lex(); - elements.push(null); - } else { - tmp = parseSpreadOrAssignmentExpression(); - elements.push(tmp); - if (tmp && tmp.type === Syntax.SpreadElement) { - if (!match(']')) { - throwError({}, Messages.ElementAfterSpreadElement); - } - } else if (!(match(']') || matchKeyword('for') || matchKeyword('if'))) { - expect(','); // this lexes. - possiblecomprehension = false; - } - } - } - - expect(']'); - - if (filter && !blocks.length) { - throwError({}, Messages.ComprehensionRequiresBlock); - } - - if (blocks.length) { - if (elements.length !== 1) { - throwError({}, Messages.ComprehensionError); - } - return markerApply(marker, delegate.createComprehensionExpression(filter, blocks, elements[0])); - } - return markerApply(marker, delegate.createArrayExpression(elements)); - } - - // 11.1.5 Object Initialiser - - function parsePropertyFunction(options) { - var previousStrict, previousYieldAllowed, params, defaults, body, - marker = markerCreate(); - - previousStrict = strict; - previousYieldAllowed = state.yieldAllowed; - state.yieldAllowed = options.generator; - params = options.params || []; - defaults = options.defaults || []; - - body = parseConciseBody(); - if (options.name && strict && isRestrictedWord(params[0].name)) { - throwErrorTolerant(options.name, Messages.StrictParamName); - } - strict = previousStrict; - state.yieldAllowed = previousYieldAllowed; - - return markerApply(marker, delegate.createFunctionExpression( - null, - params, - defaults, - body, - options.rest || null, - options.generator, - body.type !== Syntax.BlockStatement - )); - } - - - function parsePropertyMethodFunction(options) { - var previousStrict, tmp, method; - - previousStrict = strict; - strict = true; - - tmp = parseParams(); - - if (tmp.stricted) { - throwErrorTolerant(tmp.stricted, tmp.message); - } - - - method = parsePropertyFunction({ - params: tmp.params, - defaults: tmp.defaults, - rest: tmp.rest, - generator: options.generator - }); - - strict = previousStrict; - - return method; - } - - - function parseObjectPropertyKey() { - var marker = markerCreate(), - token = lex(), - propertyKey, - result; - - // Note: This function is called only from parseObjectProperty(), where - // EOF and Punctuator tokens are already filtered out. - - if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) { - if (strict && token.octal) { - throwErrorTolerant(token, Messages.StrictOctalLiteral); - } - return markerApply(marker, delegate.createLiteral(token)); - } - - if (token.type === Token.Punctuator && token.value === '[') { - // For computed properties we should skip the [ and ], and - // capture in marker only the assignment expression itself. - marker = markerCreate(); - propertyKey = parseAssignmentExpression(); - result = markerApply(marker, propertyKey); - expect(']'); - return result; - } - - return markerApply(marker, delegate.createIdentifier(token.value)); - } - - function parseObjectProperty() { - var token, key, id, value, param, expr, computed, - marker = markerCreate(); - - token = lookahead; - computed = (token.value === '[' && token.type === Token.Punctuator); - - if (token.type === Token.Identifier || computed) { - - id = parseObjectPropertyKey(); - - // Property Assignment: Getter and Setter. - - if (token.value === 'get' && !(match(':') || match('('))) { - computed = (lookahead.value === '['); - key = parseObjectPropertyKey(); - expect('('); - expect(')'); - return markerApply(marker, delegate.createProperty('get', key, parsePropertyFunction({ generator: false }), false, false, computed)); - } - if (token.value === 'set' && !(match(':') || match('('))) { - computed = (lookahead.value === '['); - key = parseObjectPropertyKey(); - expect('('); - token = lookahead; - param = [ parseVariableIdentifier() ]; - expect(')'); - return markerApply(marker, delegate.createProperty('set', key, parsePropertyFunction({ params: param, generator: false, name: token }), false, false, computed)); - } - if (match(':')) { - lex(); - return markerApply(marker, delegate.createProperty('init', id, parseAssignmentExpression(), false, false, computed)); - } - if (match('(')) { - return markerApply(marker, delegate.createProperty('init', id, parsePropertyMethodFunction({ generator: false }), true, false, computed)); - } - if (computed) { - // Computed properties can only be used with full notation. - throwUnexpected(lookahead); - } - return markerApply(marker, delegate.createProperty('init', id, id, false, true, false)); - } - if (token.type === Token.EOF || token.type === Token.Punctuator) { - if (!match('*')) { - throwUnexpected(token); - } - lex(); - - computed = (lookahead.type === Token.Punctuator && lookahead.value === '['); - - id = parseObjectPropertyKey(); - - if (!match('(')) { - throwUnexpected(lex()); - } - - return markerApply(marker, delegate.createProperty('init', id, parsePropertyMethodFunction({ generator: true }), true, false, computed)); - } - key = parseObjectPropertyKey(); - if (match(':')) { - lex(); - return markerApply(marker, delegate.createProperty('init', key, parseAssignmentExpression(), false, false, false)); - } - if (match('(')) { - return markerApply(marker, delegate.createProperty('init', key, parsePropertyMethodFunction({ generator: false }), true, false, false)); - } - throwUnexpected(lex()); - } - - function getFieldName(key) { - var toString = String; - if (key.type === Syntax.Identifier) { - return key.name; - } - return toString(key.value); - } - - function parseObjectInitialiser() { - var properties = [], property, name, kind, storedKind, map = new StringMap(), - marker = markerCreate(); - - expect('{'); - - while (!match('}')) { - property = parseObjectProperty(); - - if (!property.computed) { - name = getFieldName(property.key); - kind = (property.kind === 'init') ? PropertyKind.Data : (property.kind === 'get') ? PropertyKind.Get : PropertyKind.Set; - - if (map.has(name)) { - storedKind = map.get(name); - if (storedKind === PropertyKind.Data) { - if (strict && kind === PropertyKind.Data) { - throwErrorTolerant({}, Messages.StrictDuplicateProperty); - } else if (kind !== PropertyKind.Data) { - throwErrorTolerant({}, Messages.AccessorDataProperty); - } - } else { - if (kind === PropertyKind.Data) { - throwErrorTolerant({}, Messages.AccessorDataProperty); - } else if (storedKind & kind) { - throwErrorTolerant({}, Messages.AccessorGetSet); - } - } - map.set(name, storedKind | kind); - } else { - map.set(name, kind); - } - } - - properties.push(property); - - if (!match('}')) { - expect(','); - } - } - - expect('}'); - - return markerApply(marker, delegate.createObjectExpression(properties)); - } - - function parseTemplateElement(option) { - var marker = markerCreate(), - token = scanTemplateElement(option); - if (strict && token.octal) { - throwError(token, Messages.StrictOctalLiteral); - } - return markerApply(marker, delegate.createTemplateElement({ raw: token.value.raw, cooked: token.value.cooked }, token.tail)); - } - - function parseTemplateLiteral() { - var quasi, quasis, expressions, marker = markerCreate(); - - quasi = parseTemplateElement({ head: true }); - quasis = [ quasi ]; - expressions = []; - - while (!quasi.tail) { - expressions.push(parseExpression()); - quasi = parseTemplateElement({ head: false }); - quasis.push(quasi); - } - - return markerApply(marker, delegate.createTemplateLiteral(quasis, expressions)); - } - - // 11.1.6 The Grouping Operator - - function parseGroupExpression() { - var expr; - - expect('('); - - ++state.parenthesizedCount; - - expr = parseExpression(); - - expect(')'); - - return expr; - } - - - // 11.1 Primary Expressions - - function parsePrimaryExpression() { - var marker, type, token, expr; - - type = lookahead.type; - - if (type === Token.Identifier) { - marker = markerCreate(); - return markerApply(marker, delegate.createIdentifier(lex().value)); - } - - if (type === Token.StringLiteral || type === Token.NumericLiteral) { - if (strict && lookahead.octal) { - throwErrorTolerant(lookahead, Messages.StrictOctalLiteral); - } - marker = markerCreate(); - return markerApply(marker, delegate.createLiteral(lex())); - } - - if (type === Token.Keyword) { - if (matchKeyword('this')) { - marker = markerCreate(); - lex(); - return markerApply(marker, delegate.createThisExpression()); - } - - if (matchKeyword('function')) { - return parseFunctionExpression(); - } - - if (matchKeyword('class')) { - return parseClassExpression(); - } - - if (matchKeyword('super')) { - marker = markerCreate(); - lex(); - return markerApply(marker, delegate.createIdentifier('super')); - } - } - - if (type === Token.BooleanLiteral) { - marker = markerCreate(); - token = lex(); - token.value = (token.value === 'true'); - return markerApply(marker, delegate.createLiteral(token)); - } - - if (type === Token.NullLiteral) { - marker = markerCreate(); - token = lex(); - token.value = null; - return markerApply(marker, delegate.createLiteral(token)); - } - - if (match('[')) { - return parseArrayInitialiser(); - } - - if (match('{')) { - return parseObjectInitialiser(); - } - - if (match('(')) { - return parseGroupExpression(); - } - - if (match('/') || match('/=')) { - marker = markerCreate(); - return markerApply(marker, delegate.createLiteral(scanRegExp())); - } - - if (type === Token.Template) { - return parseTemplateLiteral(); - } - - throwUnexpected(lex()); - } - - // 11.2 Left-Hand-Side Expressions - - function parseArguments() { - var args = [], arg; - - expect('('); - - if (!match(')')) { - while (index < length) { - arg = parseSpreadOrAssignmentExpression(); - args.push(arg); - - if (match(')')) { - break; - } else if (arg.type === Syntax.SpreadElement) { - throwError({}, Messages.ElementAfterSpreadElement); - } - - expect(','); - } - } - - expect(')'); - - return args; - } - - function parseSpreadOrAssignmentExpression() { - if (match('...')) { - var marker = markerCreate(); - lex(); - return markerApply(marker, delegate.createSpreadElement(parseAssignmentExpression())); - } - return parseAssignmentExpression(); - } - - function parseNonComputedProperty() { - var marker = markerCreate(), - token = lex(); - - if (!isIdentifierName(token)) { - throwUnexpected(token); - } - - return markerApply(marker, delegate.createIdentifier(token.value)); - } - - function parseNonComputedMember() { - expect('.'); - - return parseNonComputedProperty(); - } - - function parseComputedMember() { - var expr; - - expect('['); - - expr = parseExpression(); - - expect(']'); - - return expr; - } - - function parseNewExpression() { - var callee, args, marker = markerCreate(); - - expectKeyword('new'); - callee = parseLeftHandSideExpression(); - args = match('(') ? parseArguments() : []; - - return markerApply(marker, delegate.createNewExpression(callee, args)); - } - - function parseLeftHandSideExpressionAllowCall() { - var expr, args, marker = markerCreate(); - - expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression(); - - while (match('.') || match('[') || match('(') || lookahead.type === Token.Template) { - if (match('(')) { - args = parseArguments(); - expr = markerApply(marker, delegate.createCallExpression(expr, args)); - } else if (match('[')) { - expr = markerApply(marker, delegate.createMemberExpression('[', expr, parseComputedMember())); - } else if (match('.')) { - expr = markerApply(marker, delegate.createMemberExpression('.', expr, parseNonComputedMember())); - } else { - expr = markerApply(marker, delegate.createTaggedTemplateExpression(expr, parseTemplateLiteral())); - } - } - - return expr; - } - - function parseLeftHandSideExpression() { - var expr, marker = markerCreate(); - - expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression(); - - while (match('.') || match('[') || lookahead.type === Token.Template) { - if (match('[')) { - expr = markerApply(marker, delegate.createMemberExpression('[', expr, parseComputedMember())); - } else if (match('.')) { - expr = markerApply(marker, delegate.createMemberExpression('.', expr, parseNonComputedMember())); - } else { - expr = markerApply(marker, delegate.createTaggedTemplateExpression(expr, parseTemplateLiteral())); - } - } - - return expr; - } - - // 11.3 Postfix Expressions - - function parsePostfixExpression() { - var marker = markerCreate(), - expr = parseLeftHandSideExpressionAllowCall(), - token; - - if (lookahead.type !== Token.Punctuator) { - return expr; - } - - if ((match('++') || match('--')) && !peekLineTerminator()) { - // 11.3.1, 11.3.2 - if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) { - throwErrorTolerant({}, Messages.StrictLHSPostfix); - } - - if (!isLeftHandSide(expr)) { - throwError({}, Messages.InvalidLHSInAssignment); - } - - token = lex(); - expr = markerApply(marker, delegate.createPostfixExpression(token.value, expr)); - } - - return expr; - } - - // 11.4 Unary Operators - - function parseUnaryExpression() { - var marker, token, expr; - - if (lookahead.type !== Token.Punctuator && lookahead.type !== Token.Keyword) { - return parsePostfixExpression(); - } - - if (match('++') || match('--')) { - marker = markerCreate(); - token = lex(); - expr = parseUnaryExpression(); - // 11.4.4, 11.4.5 - if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) { - throwErrorTolerant({}, Messages.StrictLHSPrefix); - } - - if (!isLeftHandSide(expr)) { - throwError({}, Messages.InvalidLHSInAssignment); - } - - return markerApply(marker, delegate.createUnaryExpression(token.value, expr)); - } - - if (match('+') || match('-') || match('~') || match('!')) { - marker = markerCreate(); - token = lex(); - expr = parseUnaryExpression(); - return markerApply(marker, delegate.createUnaryExpression(token.value, expr)); - } - - if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) { - marker = markerCreate(); - token = lex(); - expr = parseUnaryExpression(); - expr = markerApply(marker, delegate.createUnaryExpression(token.value, expr)); - if (strict && expr.operator === 'delete' && expr.argument.type === Syntax.Identifier) { - throwErrorTolerant({}, Messages.StrictDelete); - } - return expr; - } - - return parsePostfixExpression(); - } - - function binaryPrecedence(token, allowIn) { - var prec = 0; - - if (token.type !== Token.Punctuator && token.type !== Token.Keyword) { - return 0; - } - - switch (token.value) { - case '||': - prec = 1; - break; - - case '&&': - prec = 2; - break; - - case '|': - prec = 3; - break; - - case '^': - prec = 4; - break; - - case '&': - prec = 5; - break; - - case '==': - case '!=': - case '===': - case '!==': - prec = 6; - break; - - case '<': - case '>': - case '<=': - case '>=': - case 'instanceof': - prec = 7; - break; - - case 'in': - prec = allowIn ? 7 : 0; - break; - - case '<<': - case '>>': - case '>>>': - prec = 8; - break; - - case '+': - case '-': - prec = 9; - break; - - case '*': - case '/': - case '%': - prec = 11; - break; - - default: - break; - } - - return prec; - } - - // 11.5 Multiplicative Operators - // 11.6 Additive Operators - // 11.7 Bitwise Shift Operators - // 11.8 Relational Operators - // 11.9 Equality Operators - // 11.10 Binary Bitwise Operators - // 11.11 Binary Logical Operators - - function parseBinaryExpression() { - var expr, token, prec, previousAllowIn, stack, right, operator, left, i, - marker, markers; - - previousAllowIn = state.allowIn; - state.allowIn = true; - - marker = markerCreate(); - left = parseUnaryExpression(); - - token = lookahead; - prec = binaryPrecedence(token, previousAllowIn); - if (prec === 0) { - return left; - } - token.prec = prec; - lex(); - - markers = [marker, markerCreate()]; - right = parseUnaryExpression(); - - stack = [left, token, right]; - - while ((prec = binaryPrecedence(lookahead, previousAllowIn)) > 0) { - - // Reduce: make a binary expression from the three topmost entries. - while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) { - right = stack.pop(); - operator = stack.pop().value; - left = stack.pop(); - expr = delegate.createBinaryExpression(operator, left, right); - markers.pop(); - marker = markers.pop(); - markerApply(marker, expr); - stack.push(expr); - markers.push(marker); - } - - // Shift. - token = lex(); - token.prec = prec; - stack.push(token); - markers.push(markerCreate()); - expr = parseUnaryExpression(); - stack.push(expr); - } - - state.allowIn = previousAllowIn; - - // Final reduce to clean-up the stack. - i = stack.length - 1; - expr = stack[i]; - markers.pop(); - while (i > 1) { - expr = delegate.createBinaryExpression(stack[i - 1].value, stack[i - 2], expr); - i -= 2; - marker = markers.pop(); - markerApply(marker, expr); - } - - return expr; - } - - - // 11.12 Conditional Operator - - function parseConditionalExpression() { - var expr, previousAllowIn, consequent, alternate, marker = markerCreate(); - expr = parseBinaryExpression(); - - if (match('?')) { - lex(); - previousAllowIn = state.allowIn; - state.allowIn = true; - consequent = parseAssignmentExpression(); - state.allowIn = previousAllowIn; - expect(':'); - alternate = parseAssignmentExpression(); - - expr = markerApply(marker, delegate.createConditionalExpression(expr, consequent, alternate)); - } - - return expr; - } - - // 11.13 Assignment Operators - - // 12.14.5 AssignmentPattern - - function reinterpretAsAssignmentBindingPattern(expr) { - var i, len, property, element; - - if (expr.type === Syntax.ObjectExpression) { - expr.type = Syntax.ObjectPattern; - for (i = 0, len = expr.properties.length; i < len; i += 1) { - property = expr.properties[i]; - if (property.kind !== 'init') { - throwError({}, Messages.InvalidLHSInAssignment); - } - reinterpretAsAssignmentBindingPattern(property.value); - } - } else if (expr.type === Syntax.ArrayExpression) { - expr.type = Syntax.ArrayPattern; - for (i = 0, len = expr.elements.length; i < len; i += 1) { - element = expr.elements[i]; - /* istanbul ignore else */ - if (element) { - reinterpretAsAssignmentBindingPattern(element); - } - } - } else if (expr.type === Syntax.Identifier) { - if (isRestrictedWord(expr.name)) { - throwError({}, Messages.InvalidLHSInAssignment); - } - } else if (expr.type === Syntax.SpreadElement) { - reinterpretAsAssignmentBindingPattern(expr.argument); - if (expr.argument.type === Syntax.ObjectPattern) { - throwError({}, Messages.ObjectPatternAsSpread); - } - } else { - /* istanbul ignore else */ - if (expr.type !== Syntax.MemberExpression && expr.type !== Syntax.CallExpression && expr.type !== Syntax.NewExpression) { - throwError({}, Messages.InvalidLHSInAssignment); - } - } - } - - // 13.2.3 BindingPattern - - function reinterpretAsDestructuredParameter(options, expr) { - var i, len, property, element; - - if (expr.type === Syntax.ObjectExpression) { - expr.type = Syntax.ObjectPattern; - for (i = 0, len = expr.properties.length; i < len; i += 1) { - property = expr.properties[i]; - if (property.kind !== 'init') { - throwError({}, Messages.InvalidLHSInFormalsList); - } - reinterpretAsDestructuredParameter(options, property.value); - } - } else if (expr.type === Syntax.ArrayExpression) { - expr.type = Syntax.ArrayPattern; - for (i = 0, len = expr.elements.length; i < len; i += 1) { - element = expr.elements[i]; - if (element) { - reinterpretAsDestructuredParameter(options, element); - } - } - } else if (expr.type === Syntax.Identifier) { - validateParam(options, expr, expr.name); - } else if (expr.type === Syntax.SpreadElement) { - // BindingRestElement only allows BindingIdentifier - if (expr.argument.type !== Syntax.Identifier) { - throwError({}, Messages.InvalidLHSInFormalsList); - } - validateParam(options, expr.argument, expr.argument.name); - } else { - throwError({}, Messages.InvalidLHSInFormalsList); - } - } - - function reinterpretAsCoverFormalsList(expressions) { - var i, len, param, params, defaults, defaultCount, options, rest; - - params = []; - defaults = []; - defaultCount = 0; - rest = null; - options = { - paramSet: new StringMap() - }; - - for (i = 0, len = expressions.length; i < len; i += 1) { - param = expressions[i]; - if (param.type === Syntax.Identifier) { - params.push(param); - defaults.push(null); - validateParam(options, param, param.name); - } else if (param.type === Syntax.ObjectExpression || param.type === Syntax.ArrayExpression) { - reinterpretAsDestructuredParameter(options, param); - params.push(param); - defaults.push(null); - } else if (param.type === Syntax.SpreadElement) { - assert(i === len - 1, 'It is guaranteed that SpreadElement is last element by parseExpression'); - if (param.argument.type !== Syntax.Identifier) { - throwError({}, Messages.InvalidLHSInFormalsList); - } - reinterpretAsDestructuredParameter(options, param.argument); - rest = param.argument; - } else if (param.type === Syntax.AssignmentExpression) { - params.push(param.left); - defaults.push(param.right); - ++defaultCount; - validateParam(options, param.left, param.left.name); - } else { - return null; - } - } - - if (options.message === Messages.StrictParamDupe) { - throwError( - strict ? options.stricted : options.firstRestricted, - options.message - ); - } - - if (defaultCount === 0) { - defaults = []; - } - - return { - params: params, - defaults: defaults, - rest: rest, - stricted: options.stricted, - firstRestricted: options.firstRestricted, - message: options.message - }; - } - - function parseArrowFunctionExpression(options, marker) { - var previousStrict, previousYieldAllowed, body; - - expect('=>'); - - previousStrict = strict; - previousYieldAllowed = state.yieldAllowed; - state.yieldAllowed = false; - body = parseConciseBody(); - - if (strict && options.firstRestricted) { - throwError(options.firstRestricted, options.message); - } - if (strict && options.stricted) { - throwErrorTolerant(options.stricted, options.message); - } - - strict = previousStrict; - state.yieldAllowed = previousYieldAllowed; - - return markerApply(marker, delegate.createArrowFunctionExpression( - options.params, - options.defaults, - body, - options.rest, - body.type !== Syntax.BlockStatement - )); - } - - function parseAssignmentExpression() { - var marker, expr, token, params, oldParenthesizedCount; - - // Note that 'yield' is treated as a keyword in strict mode, but a - // contextual keyword (identifier) in non-strict mode, so we need - // to use matchKeyword and matchContextualKeyword appropriately. - if ((state.yieldAllowed && matchContextualKeyword('yield')) || (strict && matchKeyword('yield'))) { - return parseYieldExpression(); - } - - oldParenthesizedCount = state.parenthesizedCount; - - marker = markerCreate(); - - if (match('(')) { - token = lookahead2(); - if ((token.type === Token.Punctuator && token.value === ')') || token.value === '...') { - params = parseParams(); - if (!match('=>')) { - throwUnexpected(lex()); - } - return parseArrowFunctionExpression(params, marker); - } - } - - token = lookahead; - expr = parseConditionalExpression(); - - if (match('=>') && - (state.parenthesizedCount === oldParenthesizedCount || - state.parenthesizedCount === (oldParenthesizedCount + 1))) { - if (expr.type === Syntax.Identifier) { - params = reinterpretAsCoverFormalsList([ expr ]); - } else if (expr.type === Syntax.SequenceExpression) { - params = reinterpretAsCoverFormalsList(expr.expressions); - } - if (params) { - return parseArrowFunctionExpression(params, marker); - } - } - - if (matchAssign()) { - // 11.13.1 - if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) { - throwErrorTolerant(token, Messages.StrictLHSAssignment); - } - - // ES.next draf 11.13 Runtime Semantics step 1 - if (match('=') && (expr.type === Syntax.ObjectExpression || expr.type === Syntax.ArrayExpression)) { - reinterpretAsAssignmentBindingPattern(expr); - } else if (!isLeftHandSide(expr)) { - throwError({}, Messages.InvalidLHSInAssignment); - } - - expr = markerApply(marker, delegate.createAssignmentExpression(lex().value, expr, parseAssignmentExpression())); - } - - return expr; - } - - // 11.14 Comma Operator - - function parseExpression() { - var marker, expr, expressions, sequence, coverFormalsList, spreadFound, oldParenthesizedCount; - - oldParenthesizedCount = state.parenthesizedCount; - - marker = markerCreate(); - expr = parseAssignmentExpression(); - expressions = [ expr ]; - - if (match(',')) { - while (index < length) { - if (!match(',')) { - break; - } - - lex(); - expr = parseSpreadOrAssignmentExpression(); - expressions.push(expr); - - if (expr.type === Syntax.SpreadElement) { - spreadFound = true; - if (!match(')')) { - throwError({}, Messages.ElementAfterSpreadElement); - } - break; - } - } - - sequence = markerApply(marker, delegate.createSequenceExpression(expressions)); - } - - if (match('=>')) { - // Do not allow nested parentheses on the LHS of the =>. - if (state.parenthesizedCount === oldParenthesizedCount || state.parenthesizedCount === (oldParenthesizedCount + 1)) { - expr = expr.type === Syntax.SequenceExpression ? expr.expressions : expressions; - coverFormalsList = reinterpretAsCoverFormalsList(expr); - if (coverFormalsList) { - return parseArrowFunctionExpression(coverFormalsList, marker); - } - } - throwUnexpected(lex()); - } - - if (spreadFound && lookahead2().value !== '=>') { - throwError({}, Messages.IllegalSpread); - } - - return sequence || expr; - } - - // 12.1 Block - - function parseStatementList() { - var list = [], - statement; - - while (index < length) { - if (match('}')) { - break; - } - statement = parseSourceElement(); - if (typeof statement === 'undefined') { - break; - } - list.push(statement); - } - - return list; - } - - function parseBlock() { - var block, marker = markerCreate(); - - expect('{'); - - block = parseStatementList(); - - expect('}'); - - return markerApply(marker, delegate.createBlockStatement(block)); - } - - // 12.2 Variable Statement - - function parseVariableIdentifier() { - var marker = markerCreate(), - token = lex(); - - if (token.type !== Token.Identifier) { - throwUnexpected(token); - } - - return markerApply(marker, delegate.createIdentifier(token.value)); - } - - function parseVariableDeclaration(kind) { - var id, - marker = markerCreate(), - init = null; - if (match('{')) { - id = parseObjectInitialiser(); - reinterpretAsAssignmentBindingPattern(id); - } else if (match('[')) { - id = parseArrayInitialiser(); - reinterpretAsAssignmentBindingPattern(id); - } else { - /* istanbul ignore next */ - id = state.allowKeyword ? parseNonComputedProperty() : parseVariableIdentifier(); - // 12.2.1 - if (strict && isRestrictedWord(id.name)) { - throwErrorTolerant({}, Messages.StrictVarName); - } - } - - if (kind === 'const') { - if (!match('=')) { - throwError({}, Messages.NoUnintializedConst); - } - expect('='); - init = parseAssignmentExpression(); - } else if (match('=')) { - lex(); - init = parseAssignmentExpression(); - } - - return markerApply(marker, delegate.createVariableDeclarator(id, init)); - } - - function parseVariableDeclarationList(kind) { - var list = []; - - do { - list.push(parseVariableDeclaration(kind)); - if (!match(',')) { - break; - } - lex(); - } while (index < length); - - return list; - } - - function parseVariableStatement() { - var declarations, marker = markerCreate(); - - expectKeyword('var'); - - declarations = parseVariableDeclarationList(); - - consumeSemicolon(); - - return markerApply(marker, delegate.createVariableDeclaration(declarations, 'var')); - } - - // kind may be `const` or `let` - // Both are experimental and not in the specification yet. - // see http://wiki.ecmascript.org/doku.php?id=harmony:const - // and http://wiki.ecmascript.org/doku.php?id=harmony:let - function parseConstLetDeclaration(kind) { - var declarations, marker = markerCreate(); - - expectKeyword(kind); - - declarations = parseVariableDeclarationList(kind); - - consumeSemicolon(); - - return markerApply(marker, delegate.createVariableDeclaration(declarations, kind)); - } - - // people.mozilla.org/~jorendorff/es6-draft.html - - function parseModuleSpecifier() { - var marker = markerCreate(), - specifier; - - if (lookahead.type !== Token.StringLiteral) { - throwError({}, Messages.InvalidModuleSpecifier); - } - specifier = delegate.createModuleSpecifier(lookahead); - lex(); - return markerApply(marker, specifier); - } - - function parseExportBatchSpecifier() { - var marker = markerCreate(); - expect('*'); - return markerApply(marker, delegate.createExportBatchSpecifier()); - } - - function parseExportSpecifier() { - var id, name = null, marker = markerCreate(), from; - if (matchKeyword('default')) { - lex(); - id = markerApply(marker, delegate.createIdentifier('default')); - // export {default} from "something"; - } else { - id = parseVariableIdentifier(); - } - if (matchContextualKeyword('as')) { - lex(); - name = parseNonComputedProperty(); - } - - return markerApply(marker, delegate.createExportSpecifier(id, name)); - } - - function parseExportDeclaration() { - var backtrackToken, id, previousAllowKeyword, declaration = null, - isExportFromIdentifier, - src = null, specifiers = [], - marker = markerCreate(); - - function rewind(token) { - index = token.range[0]; - lineNumber = token.lineNumber; - lineStart = token.lineStart; - lookahead = token; - } - - expectKeyword('export'); - - if (matchKeyword('default')) { - // covers: - // export default ... - lex(); - if (matchKeyword('function') || matchKeyword('class')) { - backtrackToken = lookahead; - lex(); - if (isIdentifierName(lookahead)) { - // covers: - // export default function foo () {} - // export default class foo {} - id = parseNonComputedProperty(); - rewind(backtrackToken); - return markerApply(marker, delegate.createExportDeclaration(true, parseSourceElement(), [id], null)); - } - // covers: - // export default function () {} - // export default class {} - rewind(backtrackToken); - switch (lookahead.value) { - case 'class': - return markerApply(marker, delegate.createExportDeclaration(true, parseClassExpression(), [], null)); - case 'function': - return markerApply(marker, delegate.createExportDeclaration(true, parseFunctionExpression(), [], null)); - } - } - - if (matchContextualKeyword('from')) { - throwError({}, Messages.UnexpectedToken, lookahead.value); - } - - // covers: - // export default {}; - // export default []; - if (match('{')) { - declaration = parseObjectInitialiser(); - } else if (match('[')) { - declaration = parseArrayInitialiser(); - } else { - declaration = parseAssignmentExpression(); - } - consumeSemicolon(); - return markerApply(marker, delegate.createExportDeclaration(true, declaration, [], null)); - } - - // non-default export - if (lookahead.type === Token.Keyword) { - // covers: - // export var f = 1; - switch (lookahead.value) { - case 'let': - case 'const': - case 'var': - case 'class': - case 'function': - return markerApply(marker, delegate.createExportDeclaration(false, parseSourceElement(), specifiers, null)); - } - } - - if (match('*')) { - // covers: - // export * from "foo"; - specifiers.push(parseExportBatchSpecifier()); - - if (!matchContextualKeyword('from')) { - throwError({}, lookahead.value ? - Messages.UnexpectedToken : Messages.MissingFromClause, lookahead.value); - } - lex(); - src = parseModuleSpecifier(); - consumeSemicolon(); - - return markerApply(marker, delegate.createExportDeclaration(false, null, specifiers, src)); - } - - expect('{'); - do { - isExportFromIdentifier = isExportFromIdentifier || matchKeyword('default'); - specifiers.push(parseExportSpecifier()); - } while (match(',') && lex()); - expect('}'); - - if (matchContextualKeyword('from')) { - // covering: - // export {default} from "foo"; - // export {foo} from "foo"; - lex(); - src = parseModuleSpecifier(); - consumeSemicolon(); - } else if (isExportFromIdentifier) { - // covering: - // export {default}; // missing fromClause - throwError({}, lookahead.value ? - Messages.UnexpectedToken : Messages.MissingFromClause, lookahead.value); - } else { - // cover - // export {foo}; - consumeSemicolon(); - } - return markerApply(marker, delegate.createExportDeclaration(false, declaration, specifiers, src)); - } - - - function parseImportSpecifier() { - // import {} ...; - var id, name = null, marker = markerCreate(); - - id = parseNonComputedProperty(); - if (matchContextualKeyword('as')) { - lex(); - name = parseVariableIdentifier(); - } - - return markerApply(marker, delegate.createImportSpecifier(id, name)); - } - - function parseNamedImports() { - var specifiers = []; - // {foo, bar as bas} - expect('{'); - do { - specifiers.push(parseImportSpecifier()); - } while (match(',') && lex()); - expect('}'); - return specifiers; - } - - function parseImportDefaultSpecifier() { - // import ...; - var id, marker = markerCreate(); - - id = parseNonComputedProperty(); - - return markerApply(marker, delegate.createImportDefaultSpecifier(id)); - } - - function parseImportNamespaceSpecifier() { - // import <* as foo> ...; - var id, marker = markerCreate(); - - expect('*'); - if (!matchContextualKeyword('as')) { - throwError({}, Messages.NoAsAfterImportNamespace); - } - lex(); - id = parseNonComputedProperty(); - - return markerApply(marker, delegate.createImportNamespaceSpecifier(id)); - } - - function parseImportDeclaration() { - var specifiers, src, marker = markerCreate(); - - expectKeyword('import'); - specifiers = []; - - if (lookahead.type === Token.StringLiteral) { - // covers: - // import "foo"; - src = parseModuleSpecifier(); - consumeSemicolon(); - return markerApply(marker, delegate.createImportDeclaration(specifiers, src)); - } - - if (!matchKeyword('default') && isIdentifierName(lookahead)) { - // covers: - // import foo - // import foo, ... - specifiers.push(parseImportDefaultSpecifier()); - if (match(',')) { - lex(); - } - } - if (match('*')) { - // covers: - // import foo, * as foo - // import * as foo - specifiers.push(parseImportNamespaceSpecifier()); - } else if (match('{')) { - // covers: - // import foo, {bar} - // import {bar} - specifiers = specifiers.concat(parseNamedImports()); - } - - if (!matchContextualKeyword('from')) { - throwError({}, lookahead.value ? - Messages.UnexpectedToken : Messages.MissingFromClause, lookahead.value); - } - lex(); - src = parseModuleSpecifier(); - consumeSemicolon(); - - return markerApply(marker, delegate.createImportDeclaration(specifiers, src)); - } - - // 12.3 Empty Statement - - function parseEmptyStatement() { - var marker = markerCreate(); - expect(';'); - return markerApply(marker, delegate.createEmptyStatement()); - } - - // 12.4 Expression Statement - - function parseExpressionStatement() { - var marker = markerCreate(), expr = parseExpression(); - consumeSemicolon(); - return markerApply(marker, delegate.createExpressionStatement(expr)); - } - - // 12.5 If statement - - function parseIfStatement() { - var test, consequent, alternate, marker = markerCreate(); - - expectKeyword('if'); - - expect('('); - - test = parseExpression(); - - expect(')'); - - consequent = parseStatement(); - - if (matchKeyword('else')) { - lex(); - alternate = parseStatement(); - } else { - alternate = null; - } - - return markerApply(marker, delegate.createIfStatement(test, consequent, alternate)); - } - - // 12.6 Iteration Statements - - function parseDoWhileStatement() { - var body, test, oldInIteration, marker = markerCreate(); - - expectKeyword('do'); - - oldInIteration = state.inIteration; - state.inIteration = true; - - body = parseStatement(); - - state.inIteration = oldInIteration; - - expectKeyword('while'); - - expect('('); - - test = parseExpression(); - - expect(')'); - - if (match(';')) { - lex(); - } - - return markerApply(marker, delegate.createDoWhileStatement(body, test)); - } - - function parseWhileStatement() { - var test, body, oldInIteration, marker = markerCreate(); - - expectKeyword('while'); - - expect('('); - - test = parseExpression(); - - expect(')'); - - oldInIteration = state.inIteration; - state.inIteration = true; - - body = parseStatement(); - - state.inIteration = oldInIteration; - - return markerApply(marker, delegate.createWhileStatement(test, body)); - } - - function parseForVariableDeclaration() { - var marker = markerCreate(), - token = lex(), - declarations = parseVariableDeclarationList(); - - return markerApply(marker, delegate.createVariableDeclaration(declarations, token.value)); - } - - function parseForStatement(opts) { - var init, test, update, left, right, body, operator, oldInIteration, - marker = markerCreate(); - init = test = update = null; - expectKeyword('for'); - - // http://wiki.ecmascript.org/doku.php?id=proposals:iterators_and_generators&s=each - if (matchContextualKeyword('each')) { - throwError({}, Messages.EachNotAllowed); - } - - expect('('); - - if (match(';')) { - lex(); - } else { - if (matchKeyword('var') || matchKeyword('let') || matchKeyword('const')) { - state.allowIn = false; - init = parseForVariableDeclaration(); - state.allowIn = true; - - if (init.declarations.length === 1) { - if (matchKeyword('in') || matchContextualKeyword('of')) { - operator = lookahead; - if (!((operator.value === 'in' || init.kind !== 'var') && init.declarations[0].init)) { - lex(); - left = init; - right = parseExpression(); - init = null; - } - } - } - } else { - state.allowIn = false; - init = parseExpression(); - state.allowIn = true; - - if (matchContextualKeyword('of')) { - operator = lex(); - left = init; - right = parseExpression(); - init = null; - } else if (matchKeyword('in')) { - // LeftHandSideExpression - if (!isAssignableLeftHandSide(init)) { - throwError({}, Messages.InvalidLHSInForIn); - } - operator = lex(); - left = init; - right = parseExpression(); - init = null; - } - } - - if (typeof left === 'undefined') { - expect(';'); - } - } - - if (typeof left === 'undefined') { - - if (!match(';')) { - test = parseExpression(); - } - expect(';'); - - if (!match(')')) { - update = parseExpression(); - } - } - - expect(')'); - - oldInIteration = state.inIteration; - state.inIteration = true; - - if (!(opts !== undefined && opts.ignoreBody)) { - body = parseStatement(); - } - - state.inIteration = oldInIteration; - - if (typeof left === 'undefined') { - return markerApply(marker, delegate.createForStatement(init, test, update, body)); - } - - if (operator.value === 'in') { - return markerApply(marker, delegate.createForInStatement(left, right, body)); - } - return markerApply(marker, delegate.createForOfStatement(left, right, body)); - } - - // 12.7 The continue statement - - function parseContinueStatement() { - var label = null, marker = markerCreate(); - - expectKeyword('continue'); - - // Optimize the most common form: 'continue;'. - if (source.charCodeAt(index) === 59) { - lex(); - - if (!state.inIteration) { - throwError({}, Messages.IllegalContinue); - } - - return markerApply(marker, delegate.createContinueStatement(null)); - } - - if (peekLineTerminator()) { - if (!state.inIteration) { - throwError({}, Messages.IllegalContinue); - } - - return markerApply(marker, delegate.createContinueStatement(null)); - } - - if (lookahead.type === Token.Identifier) { - label = parseVariableIdentifier(); - - if (!state.labelSet.has(label.name)) { - throwError({}, Messages.UnknownLabel, label.name); - } - } - - consumeSemicolon(); - - if (label === null && !state.inIteration) { - throwError({}, Messages.IllegalContinue); - } - - return markerApply(marker, delegate.createContinueStatement(label)); - } - - // 12.8 The break statement - - function parseBreakStatement() { - var label = null, marker = markerCreate(); - - expectKeyword('break'); - - // Catch the very common case first: immediately a semicolon (char #59). - if (source.charCodeAt(index) === 59) { - lex(); - - if (!(state.inIteration || state.inSwitch)) { - throwError({}, Messages.IllegalBreak); - } - - return markerApply(marker, delegate.createBreakStatement(null)); - } - - if (peekLineTerminator()) { - if (!(state.inIteration || state.inSwitch)) { - throwError({}, Messages.IllegalBreak); - } - - return markerApply(marker, delegate.createBreakStatement(null)); - } - - if (lookahead.type === Token.Identifier) { - label = parseVariableIdentifier(); - - if (!state.labelSet.has(label.name)) { - throwError({}, Messages.UnknownLabel, label.name); - } - } - - consumeSemicolon(); - - if (label === null && !(state.inIteration || state.inSwitch)) { - throwError({}, Messages.IllegalBreak); - } - - return markerApply(marker, delegate.createBreakStatement(label)); - } - - // 12.9 The return statement - - function parseReturnStatement() { - var argument = null, marker = markerCreate(); - - expectKeyword('return'); - - if (!state.inFunctionBody) { - throwErrorTolerant({}, Messages.IllegalReturn); - } - - // 'return' followed by a space and an identifier is very common. - if (source.charCodeAt(index) === 32) { - if (isIdentifierStart(source.charCodeAt(index + 1))) { - argument = parseExpression(); - consumeSemicolon(); - return markerApply(marker, delegate.createReturnStatement(argument)); - } - } - - if (peekLineTerminator()) { - return markerApply(marker, delegate.createReturnStatement(null)); - } - - if (!match(';')) { - if (!match('}') && lookahead.type !== Token.EOF) { - argument = parseExpression(); - } - } - - consumeSemicolon(); - - return markerApply(marker, delegate.createReturnStatement(argument)); - } - - // 12.10 The with statement - - function parseWithStatement() { - var object, body, marker = markerCreate(); - - if (strict) { - throwErrorTolerant({}, Messages.StrictModeWith); - } - - expectKeyword('with'); - - expect('('); - - object = parseExpression(); - - expect(')'); - - body = parseStatement(); - - return markerApply(marker, delegate.createWithStatement(object, body)); - } - - // 12.10 The swith statement - - function parseSwitchCase() { - var test, - consequent = [], - sourceElement, - marker = markerCreate(); - - if (matchKeyword('default')) { - lex(); - test = null; - } else { - expectKeyword('case'); - test = parseExpression(); - } - expect(':'); - - while (index < length) { - if (match('}') || matchKeyword('default') || matchKeyword('case')) { - break; - } - sourceElement = parseSourceElement(); - if (typeof sourceElement === 'undefined') { - break; - } - consequent.push(sourceElement); - } - - return markerApply(marker, delegate.createSwitchCase(test, consequent)); - } - - function parseSwitchStatement() { - var discriminant, cases, clause, oldInSwitch, defaultFound, marker = markerCreate(); - - expectKeyword('switch'); - - expect('('); - - discriminant = parseExpression(); - - expect(')'); - - expect('{'); - - cases = []; - - if (match('}')) { - lex(); - return markerApply(marker, delegate.createSwitchStatement(discriminant, cases)); - } - - oldInSwitch = state.inSwitch; - state.inSwitch = true; - defaultFound = false; - - while (index < length) { - if (match('}')) { - break; - } - clause = parseSwitchCase(); - if (clause.test === null) { - if (defaultFound) { - throwError({}, Messages.MultipleDefaultsInSwitch); - } - defaultFound = true; - } - cases.push(clause); - } - - state.inSwitch = oldInSwitch; - - expect('}'); - - return markerApply(marker, delegate.createSwitchStatement(discriminant, cases)); - } - - // 12.13 The throw statement - - function parseThrowStatement() { - var argument, marker = markerCreate(); - - expectKeyword('throw'); - - if (peekLineTerminator()) { - throwError({}, Messages.NewlineAfterThrow); - } - - argument = parseExpression(); - - consumeSemicolon(); - - return markerApply(marker, delegate.createThrowStatement(argument)); - } - - // 12.14 The try statement - - function parseCatchClause() { - var param, body, marker = markerCreate(); - - expectKeyword('catch'); - - expect('('); - if (match(')')) { - throwUnexpected(lookahead); - } - - param = parseExpression(); - // 12.14.1 - if (strict && param.type === Syntax.Identifier && isRestrictedWord(param.name)) { - throwErrorTolerant({}, Messages.StrictCatchVariable); - } - - expect(')'); - body = parseBlock(); - return markerApply(marker, delegate.createCatchClause(param, body)); - } - - function parseTryStatement() { - var block, handler = null, finalizer = null, marker = markerCreate(); - - expectKeyword('try'); - - block = parseBlock(); - - if (matchKeyword('catch')) { - handler = parseCatchClause(); - } - - if (matchKeyword('finally')) { - lex(); - finalizer = parseBlock(); - } - - if (!handler && !finalizer) { - throwError({}, Messages.NoCatchOrFinally); - } - - return markerApply(marker, delegate.createTryStatement(block, handler, finalizer)); - } - - // 12.15 The debugger statement - - function parseDebuggerStatement() { - var marker = markerCreate(); - expectKeyword('debugger'); - - consumeSemicolon(); - - return markerApply(marker, delegate.createDebuggerStatement()); - } - - // 12 Statements - - function parseStatement() { - var type = lookahead.type, - marker, - expr, - labeledBody; - - if (type === Token.EOF) { - throwUnexpected(lookahead); - } - - if (type === Token.Punctuator) { - switch (lookahead.value) { - case ';': - return parseEmptyStatement(); - case '{': - return parseBlock(); - case '(': - return parseExpressionStatement(); - default: - break; - } - } - - if (type === Token.Keyword) { - switch (lookahead.value) { - case 'break': - return parseBreakStatement(); - case 'continue': - return parseContinueStatement(); - case 'debugger': - return parseDebuggerStatement(); - case 'do': - return parseDoWhileStatement(); - case 'for': - return parseForStatement(); - case 'function': - return parseFunctionDeclaration(); - case 'class': - return parseClassDeclaration(); - case 'if': - return parseIfStatement(); - case 'return': - return parseReturnStatement(); - case 'switch': - return parseSwitchStatement(); - case 'throw': - return parseThrowStatement(); - case 'try': - return parseTryStatement(); - case 'var': - return parseVariableStatement(); - case 'while': - return parseWhileStatement(); - case 'with': - return parseWithStatement(); - default: - break; - } - } - - marker = markerCreate(); - expr = parseExpression(); - - // 12.12 Labelled Statements - if ((expr.type === Syntax.Identifier) && match(':')) { - lex(); - - if (state.labelSet.has(expr.name)) { - throwError({}, Messages.Redeclaration, 'Label', expr.name); - } - - state.labelSet.set(expr.name, true); - labeledBody = parseStatement(); - state.labelSet['delete'](expr.name); - return markerApply(marker, delegate.createLabeledStatement(expr, labeledBody)); - } - - consumeSemicolon(); - - return markerApply(marker, delegate.createExpressionStatement(expr)); - } - - // 13 Function Definition - - function parseConciseBody() { - if (match('{')) { - return parseFunctionSourceElements(); - } - return parseAssignmentExpression(); - } - - function parseFunctionSourceElements() { - var sourceElement, sourceElements = [], token, directive, firstRestricted, - oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody, oldParenthesizedCount, - marker = markerCreate(); - - expect('{'); - - while (index < length) { - if (lookahead.type !== Token.StringLiteral) { - break; - } - token = lookahead; - - sourceElement = parseSourceElement(); - sourceElements.push(sourceElement); - if (sourceElement.expression.type !== Syntax.Literal) { - // this is not directive - break; - } - directive = source.slice(token.range[0] + 1, token.range[1] - 1); - if (directive === 'use strict') { - strict = true; - if (firstRestricted) { - throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral); - } - } else { - if (!firstRestricted && token.octal) { - firstRestricted = token; - } - } - } - - oldLabelSet = state.labelSet; - oldInIteration = state.inIteration; - oldInSwitch = state.inSwitch; - oldInFunctionBody = state.inFunctionBody; - oldParenthesizedCount = state.parenthesizedCount; - - state.labelSet = new StringMap(); - state.inIteration = false; - state.inSwitch = false; - state.inFunctionBody = true; - state.parenthesizedCount = 0; - - while (index < length) { - if (match('}')) { - break; - } - sourceElement = parseSourceElement(); - if (typeof sourceElement === 'undefined') { - break; - } - sourceElements.push(sourceElement); - } - - expect('}'); - - state.labelSet = oldLabelSet; - state.inIteration = oldInIteration; - state.inSwitch = oldInSwitch; - state.inFunctionBody = oldInFunctionBody; - state.parenthesizedCount = oldParenthesizedCount; - - return markerApply(marker, delegate.createBlockStatement(sourceElements)); - } - - function validateParam(options, param, name) { - if (strict) { - if (isRestrictedWord(name)) { - options.stricted = param; - options.message = Messages.StrictParamName; - } - if (options.paramSet.has(name)) { - options.stricted = param; - options.message = Messages.StrictParamDupe; - } - } else if (!options.firstRestricted) { - if (isRestrictedWord(name)) { - options.firstRestricted = param; - options.message = Messages.StrictParamName; - } else if (isStrictModeReservedWord(name)) { - options.firstRestricted = param; - options.message = Messages.StrictReservedWord; - } else if (options.paramSet.has(name)) { - options.firstRestricted = param; - options.message = Messages.StrictParamDupe; - } - } - options.paramSet.set(name, true); - } - - function parseParam(options) { - var token, rest, param, def; - - token = lookahead; - if (token.value === '...') { - token = lex(); - rest = true; - } - - if (match('[')) { - param = parseArrayInitialiser(); - reinterpretAsDestructuredParameter(options, param); - } else if (match('{')) { - if (rest) { - throwError({}, Messages.ObjectPatternAsRestParameter); - } - param = parseObjectInitialiser(); - reinterpretAsDestructuredParameter(options, param); - } else { - param = parseVariableIdentifier(); - validateParam(options, token, token.value); - } - - if (match('=')) { - if (rest) { - throwErrorTolerant(lookahead, Messages.DefaultRestParameter); - } - lex(); - def = parseAssignmentExpression(); - ++options.defaultCount; - } - - if (rest) { - if (!match(')')) { - throwError({}, Messages.ParameterAfterRestParameter); - } - options.rest = param; - return false; - } - - options.params.push(param); - options.defaults.push(def); - return !match(')'); - } - - function parseParams(firstRestricted) { - var options, marker = markerCreate(); - - options = { - params: [], - defaultCount: 0, - defaults: [], - rest: null, - firstRestricted: firstRestricted - }; - - expect('('); - - if (!match(')')) { - options.paramSet = new StringMap(); - while (index < length) { - if (!parseParam(options)) { - break; - } - expect(','); - } - } - - expect(')'); - - if (options.defaultCount === 0) { - options.defaults = []; - } - - return markerApply(marker, options); - } - - function parseFunctionDeclaration() { - var id, body, token, tmp, firstRestricted, message, previousStrict, previousYieldAllowed, generator, - marker = markerCreate(); - - expectKeyword('function'); - - generator = false; - if (match('*')) { - lex(); - generator = true; - } - - token = lookahead; - - id = parseVariableIdentifier(); - - if (strict) { - if (isRestrictedWord(token.value)) { - throwErrorTolerant(token, Messages.StrictFunctionName); - } - } else { - if (isRestrictedWord(token.value)) { - firstRestricted = token; - message = Messages.StrictFunctionName; - } else if (isStrictModeReservedWord(token.value)) { - firstRestricted = token; - message = Messages.StrictReservedWord; - } - } - - tmp = parseParams(firstRestricted); - firstRestricted = tmp.firstRestricted; - if (tmp.message) { - message = tmp.message; - } - - previousStrict = strict; - previousYieldAllowed = state.yieldAllowed; - state.yieldAllowed = generator; - - body = parseFunctionSourceElements(); - - if (strict && firstRestricted) { - throwError(firstRestricted, message); - } - if (strict && tmp.stricted) { - throwErrorTolerant(tmp.stricted, message); - } - strict = previousStrict; - state.yieldAllowed = previousYieldAllowed; - - return markerApply(marker, delegate.createFunctionDeclaration(id, tmp.params, tmp.defaults, body, tmp.rest, generator, false)); - } - - function parseFunctionExpression() { - var token, id = null, firstRestricted, message, tmp, body, previousStrict, previousYieldAllowed, generator, - marker = markerCreate(); - - expectKeyword('function'); - - generator = false; - - if (match('*')) { - lex(); - generator = true; - } - - if (!match('(')) { - token = lookahead; - id = parseVariableIdentifier(); - if (strict) { - if (isRestrictedWord(token.value)) { - throwErrorTolerant(token, Messages.StrictFunctionName); - } - } else { - if (isRestrictedWord(token.value)) { - firstRestricted = token; - message = Messages.StrictFunctionName; - } else if (isStrictModeReservedWord(token.value)) { - firstRestricted = token; - message = Messages.StrictReservedWord; - } - } - } - - tmp = parseParams(firstRestricted); - firstRestricted = tmp.firstRestricted; - if (tmp.message) { - message = tmp.message; - } - - previousStrict = strict; - previousYieldAllowed = state.yieldAllowed; - state.yieldAllowed = generator; - - body = parseFunctionSourceElements(); - - if (strict && firstRestricted) { - throwError(firstRestricted, message); - } - if (strict && tmp.stricted) { - throwErrorTolerant(tmp.stricted, message); - } - strict = previousStrict; - state.yieldAllowed = previousYieldAllowed; - - return markerApply(marker, delegate.createFunctionExpression(id, tmp.params, tmp.defaults, body, tmp.rest, generator, false)); - } - - function parseYieldExpression() { - var yieldToken, delegateFlag, expr, marker = markerCreate(); - - yieldToken = lex(); - assert(yieldToken.value === 'yield', 'Called parseYieldExpression with non-yield lookahead.'); - - if (!state.yieldAllowed) { - throwErrorTolerant({}, Messages.IllegalYield); - } - - delegateFlag = false; - if (match('*')) { - lex(); - delegateFlag = true; - } - - expr = parseAssignmentExpression(); - - return markerApply(marker, delegate.createYieldExpression(expr, delegateFlag)); - } - - // 14 Classes - - function validateDuplicateProp(propMap, key, accessor) { - var propInfo, reversed, name, isValidDuplicateProp; - - name = getFieldName(key); - - if (propMap.has(name)) { - propInfo = propMap.get(name); - if (accessor === 'data') { - isValidDuplicateProp = false; - } else { - if (accessor === 'get') { - reversed = 'set'; - } else { - reversed = 'get'; - } - - isValidDuplicateProp = - // There isn't already a specified accessor for this prop - propInfo[accessor] === undefined - // There isn't already a data prop by this name - && propInfo.data === undefined - // The only existing prop by this name is a reversed accessor - && propInfo[reversed] !== undefined; - } - if (!isValidDuplicateProp) { - throwError(key, Messages.IllegalDuplicateClassProperty); - } - } else { - propInfo = { - get: undefined, - set: undefined, - data: undefined - }; - propMap.set(name, propInfo); - } - propInfo[accessor] = true; - } - - function parseMethodDefinition(existingPropNames) { - var token, key, param, propType, computed, propMap, - marker = markerCreate(); - - if (lookahead.value === 'static') { - propType = ClassPropertyType.static; - lex(); - } else { - propType = ClassPropertyType.prototype; - } - - propMap = existingPropNames[propType]; - - if (match('*')) { - lex(); - computed = (lookahead.value === '['); - return markerApply(marker, delegate.createMethodDefinition( - propType, - '', - parseObjectPropertyKey(), - parsePropertyMethodFunction({ generator: true }), - computed - )); - } - - token = lookahead; - key = parseObjectPropertyKey(); - - if (token.value === 'get' && !match('(')) { - computed = (lookahead.value === '['); - key = parseObjectPropertyKey(); - - // It is a syntax error if any other properties have a name - // duplicating this one unless they are a setter - if (!computed) { - validateDuplicateProp(propMap, key, 'get'); - } - - expect('('); - expect(')'); - return markerApply(marker, delegate.createMethodDefinition( - propType, - 'get', - key, - parsePropertyFunction({ generator: false }), - computed - )); - } - if (token.value === 'set' && !match('(')) { - computed = (lookahead.value === '['); - key = parseObjectPropertyKey(); - - // It is a syntax error if any other properties have a name - // duplicating this one unless they are a getter - if (!computed) { - validateDuplicateProp(propMap, key, 'set'); - } - - expect('('); - token = lookahead; - param = [ parseVariableIdentifier() ]; - expect(')'); - return markerApply(marker, delegate.createMethodDefinition( - propType, - 'set', - key, - parsePropertyFunction({ params: param, generator: false, name: token }), - computed - )); - } - - computed = (token.value === '['); - - // It is a syntax error if any other properties have the same name as a - // non-getter, non-setter method - if (!computed) { - validateDuplicateProp(propMap, key, 'data'); - } - - return markerApply(marker, delegate.createMethodDefinition( - propType, - '', - key, - parsePropertyMethodFunction({ generator: false }), - computed - )); - } - - function parseClassElement(existingProps) { - if (match(';')) { - lex(); - return; - } - return parseMethodDefinition(existingProps); - } - - function parseClassBody() { - var classElement, classElements = [], existingProps = {}, marker = markerCreate(); - - existingProps[ClassPropertyType.static] = new StringMap(); - existingProps[ClassPropertyType.prototype] = new StringMap(); - - expect('{'); - - while (index < length) { - if (match('}')) { - break; - } - classElement = parseClassElement(existingProps); - - if (typeof classElement !== 'undefined') { - classElements.push(classElement); - } - } - - expect('}'); - - return markerApply(marker, delegate.createClassBody(classElements)); - } - - function parseClassExpression() { - var id, previousYieldAllowed, superClass = null, marker = markerCreate(); - - expectKeyword('class'); - - if (!matchKeyword('extends') && !match('{')) { - id = parseVariableIdentifier(); - } - - if (matchKeyword('extends')) { - expectKeyword('extends'); - previousYieldAllowed = state.yieldAllowed; - state.yieldAllowed = false; - superClass = parseAssignmentExpression(); - state.yieldAllowed = previousYieldAllowed; - } - - return markerApply(marker, delegate.createClassExpression(id, superClass, parseClassBody())); - } - - function parseClassDeclaration() { - var id, previousYieldAllowed, superClass = null, marker = markerCreate(); - - expectKeyword('class'); - - id = parseVariableIdentifier(); - - if (matchKeyword('extends')) { - expectKeyword('extends'); - previousYieldAllowed = state.yieldAllowed; - state.yieldAllowed = false; - superClass = parseAssignmentExpression(); - state.yieldAllowed = previousYieldAllowed; - } - - return markerApply(marker, delegate.createClassDeclaration(id, superClass, parseClassBody())); - } - - // 15 Program - - function parseSourceElement() { - if (lookahead.type === Token.Keyword) { - switch (lookahead.value) { - case 'const': - case 'let': - return parseConstLetDeclaration(lookahead.value); - case 'function': - return parseFunctionDeclaration(); - default: - return parseStatement(); - } - } - - if (lookahead.type !== Token.EOF) { - return parseStatement(); - } - } - - function parseProgramElement() { - if (extra.isModule && lookahead.type === Token.Keyword) { - switch (lookahead.value) { - case 'export': - return parseExportDeclaration(); - case 'import': - return parseImportDeclaration(); - } - } - - return parseSourceElement(); - } - - function parseProgramElements() { - var sourceElement, sourceElements = [], token, directive, firstRestricted; - - while (index < length) { - token = lookahead; - if (token.type !== Token.StringLiteral) { - break; - } - - sourceElement = parseProgramElement(); - sourceElements.push(sourceElement); - if (sourceElement.expression.type !== Syntax.Literal) { - // this is not directive - break; - } - directive = source.slice(token.range[0] + 1, token.range[1] - 1); - if (directive === 'use strict') { - strict = true; - if (firstRestricted) { - throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral); - } - } else { - if (!firstRestricted && token.octal) { - firstRestricted = token; - } - } - } - - while (index < length) { - sourceElement = parseProgramElement(); - if (typeof sourceElement === 'undefined') { - break; - } - sourceElements.push(sourceElement); - } - return sourceElements; - } - - function parseProgram() { - var body, marker = markerCreate(); - strict = !!extra.isModule; - peek(); - body = parseProgramElements(); - return markerApply(marker, delegate.createProgram(body)); - } - - // The following functions are needed only when the option to preserve - // the comments is active. - - function addComment(type, value, start, end, loc) { - var comment; - - assert(typeof start === 'number', 'Comment must have valid position'); - - // Because the way the actual token is scanned, often the comments - // (if any) are skipped twice during the lexical analysis. - // Thus, we need to skip adding a comment if the comment array already - // handled it. - if (state.lastCommentStart >= start) { - return; - } - state.lastCommentStart = start; - - comment = { - type: type, - value: value - }; - if (extra.range) { - comment.range = [start, end]; - } - if (extra.loc) { - comment.loc = loc; - } - extra.comments.push(comment); - if (extra.attachComment) { - extra.leadingComments.push(comment); - extra.trailingComments.push(comment); - } - } - - function scanComment() { - var comment, ch, loc, start, blockComment, lineComment; - - comment = ''; - blockComment = false; - lineComment = false; - - while (index < length) { - ch = source[index]; - - if (lineComment) { - ch = source[index++]; - if (isLineTerminator(ch.charCodeAt(0))) { - loc.end = { - line: lineNumber, - column: index - lineStart - 1 - }; - lineComment = false; - addComment('Line', comment, start, index - 1, loc); - if (ch === '\r' && source[index] === '\n') { - ++index; - } - ++lineNumber; - lineStart = index; - comment = ''; - } else if (index >= length) { - lineComment = false; - comment += ch; - loc.end = { - line: lineNumber, - column: length - lineStart - }; - addComment('Line', comment, start, length, loc); - } else { - comment += ch; - } - } else if (blockComment) { - if (isLineTerminator(ch.charCodeAt(0))) { - if (ch === '\r' && source[index + 1] === '\n') { - ++index; - comment += '\r\n'; - } else { - comment += ch; - } - ++lineNumber; - ++index; - lineStart = index; - if (index >= length) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - } else { - ch = source[index++]; - if (index >= length) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - comment += ch; - if (ch === '*') { - ch = source[index]; - if (ch === '/') { - comment = comment.substr(0, comment.length - 1); - blockComment = false; - ++index; - loc.end = { - line: lineNumber, - column: index - lineStart - }; - addComment('Block', comment, start, index, loc); - comment = ''; - } - } - } - } else if (ch === '/') { - ch = source[index + 1]; - if (ch === '/') { - loc = { - start: { - line: lineNumber, - column: index - lineStart - } - }; - start = index; - index += 2; - lineComment = true; - if (index >= length) { - loc.end = { - line: lineNumber, - column: index - lineStart - }; - lineComment = false; - addComment('Line', comment, start, index, loc); - } - } else if (ch === '*') { - start = index; - index += 2; - blockComment = true; - loc = { - start: { - line: lineNumber, - column: index - lineStart - 2 - } - }; - if (index >= length) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - } else { - break; - } - } else if (isWhiteSpace(ch.charCodeAt(0))) { - ++index; - } else if (isLineTerminator(ch.charCodeAt(0))) { - ++index; - if (ch === '\r' && source[index] === '\n') { - ++index; - } - ++lineNumber; - lineStart = index; - } else { - break; - } - } - } - - function collectToken() { - var start, loc, token, range, value, entry; - - skipComment(); - start = index; - loc = { - start: { - line: lineNumber, - column: index - lineStart - } - }; - - token = extra.advance(); - loc.end = { - line: lineNumber, - column: index - lineStart - }; - - if (token.type !== Token.EOF) { - range = [token.range[0], token.range[1]]; - value = source.slice(token.range[0], token.range[1]); - entry = { - type: TokenName[token.type], - value: value, - range: range, - loc: loc - }; - if (token.regex) { - entry.regex = { - pattern: token.regex.pattern, - flags: token.regex.flags - }; - } - extra.tokens.push(entry); - } - - return token; - } - - function collectRegex() { - var pos, loc, regex, token; - - skipComment(); - - pos = index; - loc = { - start: { - line: lineNumber, - column: index - lineStart - } - }; - - regex = extra.scanRegExp(); - loc.end = { - line: lineNumber, - column: index - lineStart - }; - - if (!extra.tokenize) { - /* istanbul ignore next */ - // Pop the previous token, which is likely '/' or '/=' - if (extra.tokens.length > 0) { - token = extra.tokens[extra.tokens.length - 1]; - if (token.range[0] === pos && token.type === 'Punctuator') { - if (token.value === '/' || token.value === '/=') { - extra.tokens.pop(); - } - } - } - - extra.tokens.push({ - type: 'RegularExpression', - value: regex.literal, - regex: regex.regex, - range: [pos, index], - loc: loc - }); - } - - return regex; - } - - function filterTokenLocation() { - var i, entry, token, tokens = []; - - for (i = 0; i < extra.tokens.length; ++i) { - entry = extra.tokens[i]; - token = { - type: entry.type, - value: entry.value - }; - if (entry.regex) { - token.regex = { - pattern: entry.regex.pattern, - flags: entry.regex.flags - }; - } - if (extra.range) { - token.range = entry.range; - } - if (extra.loc) { - token.loc = entry.loc; - } - tokens.push(token); - } - - extra.tokens = tokens; - } - - function patch() { - if (extra.comments) { - extra.skipComment = skipComment; - skipComment = scanComment; - } - - if (typeof extra.tokens !== 'undefined') { - extra.advance = advance; - extra.scanRegExp = scanRegExp; - - advance = collectToken; - scanRegExp = collectRegex; - } - } - - function unpatch() { - if (typeof extra.skipComment === 'function') { - skipComment = extra.skipComment; - } - - if (typeof extra.scanRegExp === 'function') { - advance = extra.advance; - scanRegExp = extra.scanRegExp; - } - } - - // This is used to modify the delegate. - - function extend(object, properties) { - var entry, result = {}; - - for (entry in object) { - /* istanbul ignore else */ - if (object.hasOwnProperty(entry)) { - result[entry] = object[entry]; - } - } - - for (entry in properties) { - /* istanbul ignore else */ - if (properties.hasOwnProperty(entry)) { - result[entry] = properties[entry]; - } - } - - return result; - } - - function tokenize(code, options) { - var toString, - token, - tokens; - - toString = String; - if (typeof code !== 'string' && !(code instanceof String)) { - code = toString(code); - } - - delegate = SyntaxTreeDelegate; - source = code; - index = 0; - lineNumber = (source.length > 0) ? 1 : 0; - lineStart = 0; - length = source.length; - lookahead = null; - state = { - allowKeyword: true, - allowIn: true, - labelSet: new StringMap(), - inFunctionBody: false, - inIteration: false, - inSwitch: false, - lastCommentStart: -1 - }; - - extra = {}; - - // Options matching. - options = options || {}; - - // Of course we collect tokens here. - options.tokens = true; - extra.tokens = []; - extra.tokenize = true; - // The following two fields are necessary to compute the Regex tokens. - extra.openParenToken = -1; - extra.openCurlyToken = -1; - - extra.range = (typeof options.range === 'boolean') && options.range; - extra.loc = (typeof options.loc === 'boolean') && options.loc; - - if (typeof options.comment === 'boolean' && options.comment) { - extra.comments = []; - } - if (typeof options.tolerant === 'boolean' && options.tolerant) { - extra.errors = []; - } - - patch(); - - try { - peek(); - if (lookahead.type === Token.EOF) { - return extra.tokens; - } - - token = lex(); - while (lookahead.type !== Token.EOF) { - try { - token = lex(); - } catch (lexError) { - token = lookahead; - if (extra.errors) { - extra.errors.push(lexError); - // We have to break on the first error - // to avoid infinite loops. - break; - } else { - throw lexError; - } - } - } - - filterTokenLocation(); - tokens = extra.tokens; - if (typeof extra.comments !== 'undefined') { - tokens.comments = extra.comments; - } - if (typeof extra.errors !== 'undefined') { - tokens.errors = extra.errors; - } - } catch (e) { - throw e; - } finally { - unpatch(); - extra = {}; - } - return tokens; - } - - function parse(code, options) { - var program, toString; - - toString = String; - if (typeof code !== 'string' && !(code instanceof String)) { - code = toString(code); - } - - delegate = SyntaxTreeDelegate; - source = code; - index = 0; - lineNumber = (source.length > 0) ? 1 : 0; - lineStart = 0; - length = source.length; - lookahead = null; - state = { - allowKeyword: false, - allowIn: true, - labelSet: new StringMap(), - parenthesizedCount: 0, - inFunctionBody: false, - inIteration: false, - inSwitch: false, - lastCommentStart: -1, - yieldAllowed: false - }; - - extra = {}; - if (typeof options !== 'undefined') { - extra.range = (typeof options.range === 'boolean') && options.range; - extra.loc = (typeof options.loc === 'boolean') && options.loc; - extra.attachComment = (typeof options.attachComment === 'boolean') && options.attachComment; - - if (extra.loc && options.source !== null && options.source !== undefined) { - delegate = extend(delegate, { - 'postProcess': function (node) { - node.loc.source = toString(options.source); - return node; - } - }); - } - - if (options.sourceType === 'module') { - extra.isModule = true; - } - if (typeof options.tokens === 'boolean' && options.tokens) { - extra.tokens = []; - } - if (typeof options.comment === 'boolean' && options.comment) { - extra.comments = []; - } - if (typeof options.tolerant === 'boolean' && options.tolerant) { - extra.errors = []; - } - if (extra.attachComment) { - extra.range = true; - extra.comments = []; - extra.bottomRightStack = []; - extra.trailingComments = []; - extra.leadingComments = []; - } - } - - patch(); - try { - program = parseProgram(); - if (typeof extra.comments !== 'undefined') { - program.comments = extra.comments; - } - if (typeof extra.tokens !== 'undefined') { - filterTokenLocation(); - program.tokens = extra.tokens; - } - if (typeof extra.errors !== 'undefined') { - program.errors = extra.errors; - } - } catch (e) { - throw e; - } finally { - unpatch(); - extra = {}; - } - - return program; - } - - // Sync with *.json manifests. - exports.version = '1.1.0-dev-harmony'; - - exports.tokenize = tokenize; - - exports.parse = parse; - - // Deep copy. - /* istanbul ignore next */ - exports.Syntax = (function () { - var name, types = {}; - - if (typeof Object.create === 'function') { - types = Object.create(null); - } - - for (name in Syntax) { - if (Syntax.hasOwnProperty(name)) { - types[name] = Syntax[name]; - } - } - - if (typeof Object.freeze === 'function') { - Object.freeze(types); - } - - return types; - }()); - -})); -/* vim: set sw=4 ts=4 et tw=80 : */ From aa35e20d2a625af0e4874f0d7503615c12919bc2 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Sun, 26 Apr 2020 16:58:22 +0800 Subject: [PATCH 09/24] - npm: use author/contributors --- package.json | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index f734e71..522db89 100644 --- a/package.json +++ b/package.json @@ -11,13 +11,12 @@ "engines": { "node": ">=4.0" }, - "maintainers": [ - { - "name": "Yusuke Suzuki", - "email": "utatane.tea@gmail.com", - "web": "http://github.com/Constellation" - } - ], + "author": { + "name": "Yusuke Suzuki", + "email": "utatane.tea@gmail.com", + "web": "http://github.com/Constellation" + }, + "contributors": [], "keywords": ["scope", "analysis"], "repository": { "type": "git", From f56266a178e1234ebb6b40b03236ee573b0d9919 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Sun, 26 Apr 2020 17:00:28 +0800 Subject: [PATCH 10/24] - Travis: Drop pre Node 10 versions --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 003a69b..6a408a8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,6 @@ sudo: false language: node_js node_js: - - 4 - - 6 - - 7 - - 8.0 - - 8.1 - 10 - 12 - 14 From 3e57002e3a83aa4365aec473c0f6a7c4e8528f15 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Sun, 26 Apr 2020 17:00:46 +0800 Subject: [PATCH 11/24] - Set coverage for now to pass as is --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 522db89..1d79058 100644 --- a/package.json +++ b/package.json @@ -49,10 +49,10 @@ }, "license": "BSD-2-Clause", "nyc": { - "branches": 100, - "lines": 100, - "functions": 100, - "statements": 100, + "branches": 14, + "lines": 53, + "functions": 57, + "statements": 50, "reporter": [ "html", "text" From d0147102f323ffe186d3855931ce966057bfcce3 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Sun, 26 Apr 2020 17:09:27 +0800 Subject: [PATCH 12/24] - npm: Provide tentative `browserify` script - npm: Remove gulpfile (including its bump functionality which has not currently been replaced) --- gulpfile.js | 77 ---------------------------------------------------- package.json | 15 ++++------ 2 files changed, 6 insertions(+), 86 deletions(-) delete mode 100644 gulpfile.js diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index f001f2e..0000000 --- a/gulpfile.js +++ /dev/null @@ -1,77 +0,0 @@ -/* - Copyright (C) 2014 Yusuke Suzuki - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -'use strict'; - -const gulp = require('gulp'), - git = require('gulp-git'), - bump = require('gulp-bump'), - filter = require('gulp-filter'), - tagVersion = require('gulp-tag-version'), - source = require('vinyl-source-stream'), - browserify = require('browserify'); - -gulp.task('browserify', [ 'build' ], function () { - return browserify({ - entries: [ './lib/index.js' ] - }) - .bundle() - .pipe(source('bundle.js')) - .pipe(gulp.dest('build')); -}); - -/** - * Bumping version number and tagging the repository with it. - * Please read http://semver.org/ - * - * You can use the commands - * - * gulp patch # makes v0.1.0 -> v0.1.1 - * gulp feature # makes v0.1.1 -> v0.2.0 - * gulp release # makes v0.2.1 -> v1.0.0 - * - * To bump the version numbers accordingly after you did a patch, - * introduced a feature or made a backwards-incompatible release. - */ - -function inc(importance) { - // get all the files to bump version in - return gulp.src(['./package.json']) - // bump the version number in those files - .pipe(bump({ type: importance })) - // save it back to filesystem - .pipe(gulp.dest('./')) - // commit the changed version number - .pipe(git.commit('Bumps package version')) - // read only one file to get the version number - .pipe(filter('package.json')) - // **tag it in the repository** - .pipe(tagVersion({ - prefix: '' - })); -} - -gulp.task('patch', [ 'build' ], function () { return inc('patch'); }); -gulp.task('minor', [ 'build' ], function () { return inc('minor'); }); -gulp.task('major', [ 'build' ], function () { return inc('major'); }); diff --git a/package.json b/package.json index 1d79058..80800f1 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,10 @@ "web": "http://github.com/Constellation" }, "contributors": [], - "keywords": ["scope", "analysis"], + "keywords": [ + "scope", + "analysis" + ], "repository": { "type": "git", "url": "https://github.com/estools/escope.git" @@ -36,16 +39,9 @@ "eslint": "^6.8.0", "espree": "^6.2.1", "esprima": "^4.0.1", - "gulp": "^4.0.2", - "gulp-bump": "^3.1.3", - "gulp-espower": "^1.1.0", - "gulp-filter": "^6.0.0", - "gulp-git": "^2.10.1", - "gulp-tag-version": "^1.3.1", "jsdoc": "^3.6.4", "mocha": "^7.1.2", - "nyc": "^15.0.1", - "vinyl-source-stream": "^2.0.0" + "nyc": "^15.0.1" }, "license": "BSD-2-Clause", "nyc": { @@ -63,6 +59,7 @@ ] }, "scripts": { + "browserify": "npm run build && browserify -e ./lib/index.js -o lib/bundle.js --standalone escope", "build-watch": "babel src/**/*.js --out-dir lib --source-maps --watch", "build": "babel src/**/*.js --out-dir lib --source-maps", "unit-test": "nyc mocha --require @babel/register test/*.js --timeout 100000", From 65b06973733e39f20bb1256e28225b0effbb049a Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Sun, 26 Apr 2020 17:14:20 +0800 Subject: [PATCH 13/24] - Linting: Remove old jslint directive --- src/index.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/index.js b/src/index.js index 39a6630..65e6413 100644 --- a/src/index.js +++ b/src/index.js @@ -46,8 +46,6 @@ * @module escope */ -/*jslint bitwise:true */ - import assert from 'assert'; import ScopeManager from './scope-manager'; From 99d15025f62e7112b028ffdb64e3e4388a5fb802 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Sun, 26 Apr 2020 18:29:40 +0800 Subject: [PATCH 14/24] - Babel: Target Node 4+ for Babel (to avoid needing to polyfill features only needed in earlier versions) --- .babelrc.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.babelrc.json b/.babelrc.json index 1320b9a..625789e 100644 --- a/.babelrc.json +++ b/.babelrc.json @@ -1,3 +1,9 @@ { - "presets": ["@babel/preset-env"] + "presets": [ + ["@babel/preset-env", { + "targets": { + "node": "4.0.0" + } + }] + ] } From 41d1d78f599a8eb68096be687708b0ee44b04ea9 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Sun, 26 Apr 2020 18:37:07 +0800 Subject: [PATCH 15/24] - Linting: Ignore jsdoc folder --- .eslintignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.eslintignore b/.eslintignore index 44f17c7..352ed20 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,3 +3,6 @@ lib !.eslintrc.js coverage + +# jsdoc +out From c5a48bcb65625529107654575bc1ed1b92b177cb Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Sun, 26 Apr 2020 18:37:14 +0800 Subject: [PATCH 16/24] - Linting: Remove formerly disabled rules --- .eslintrc.js | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 55f0344..113004b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -23,16 +23,6 @@ module.exports = { } }], rules: { - eqeqeq: 0, - 'no-use-before-define': 0, - 'no-shadow': 0, - 'no-new': 0, - 'no-underscore-dangle': 0, - 'no-multi-spaces': 0, - 'no-native-reassign': 0, - 'no-loop-func': 0, - 'no-lone-blocks': 0, - semi: ['error'], indent: ['error', 4, { SwitchCase: 1 }], 'prefer-const': ['error'], From 724377e529e7f12f6276c09caa9b537ba8ba5285 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Sun, 26 Apr 2020 22:09:16 +0800 Subject: [PATCH 17/24] - Testing: Use ESM fully in `third_party` and `test` --- test/es6-new-target.js | 3 +-- third_party/espree.js | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/test/es6-new-target.js b/test/es6-new-target.js index 2358343..8eb0cd5 100644 --- a/test/es6-new-target.js +++ b/test/es6-new-target.js @@ -23,8 +23,7 @@ import { expect } from 'chai'; import { analyze } from '..'; - -const parse = require('../third_party/espree'); +import parse from '../third_party/espree'; describe('ES6 new.target', function() { it('should not make references of new.target', function() { diff --git a/third_party/espree.js b/third_party/espree.js index c6d5323..1d95502 100644 --- a/third_party/espree.js +++ b/third_party/espree.js @@ -22,9 +22,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -const espree = require('espree'); +import espree from 'espree'; -module.exports = function (code) { +export default function (code) { return espree.parse(code, { // attach range information to each node @@ -51,6 +51,6 @@ module.exports = function (code) { ecmaVersion: 6, sourceType: 'module' }); -}; +} /* vim: set sw=4 ts=4 et tw=80 : */ From 54c6f41855ece8441e030e8517ae633fc3a2c022 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Sun, 26 Apr 2020 22:29:12 +0800 Subject: [PATCH 18/24] - Build: Replace browserify with Rollup - Build enhancement: Provide ESM build - npm: Point to browser and ESM builds in package.json fields --- package.json | 14 +++++++++--- rollup.config.js | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 rollup.config.js diff --git a/package.json b/package.json index 80800f1..df4bd88 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,8 @@ "homepage": "http://github.com/estools/escope", "bugs": "http://github.com/estools/escope/issues", "main": "lib/index.js", + "module": "lib/bundle.esm.js", + "browser": "lib/bundle.min.js", "files": [ "lib" ], @@ -34,14 +36,20 @@ "@babel/core": "^7.9.0", "@babel/preset-env": "^7.9.5", "@babel/register": "^7.9.0", - "browserify": "^14.4.0", + "@rollup/plugin-commonjs": "^11.1.0", + "@rollup/plugin-json": "^4.0.3", + "@rollup/plugin-node-resolve": "^7.1.3", "chai": "^4.2.0", "eslint": "^6.8.0", "espree": "^6.2.1", "esprima": "^4.0.1", "jsdoc": "^3.6.4", "mocha": "^7.1.2", - "nyc": "^15.0.1" + "nyc": "^15.0.1", + "rollup": "^2.7.2", + "rollup-plugin-babel": "^4.4.0", + "rollup-plugin-node-polyfills": "^0.2.1", + "rollup-plugin-terser": "^5.3.0" }, "license": "BSD-2-Clause", "nyc": { @@ -59,7 +67,7 @@ ] }, "scripts": { - "browserify": "npm run build && browserify -e ./lib/index.js -o lib/bundle.js --standalone escope", + "build-browser": "rollup -c", "build-watch": "babel src/**/*.js --out-dir lib --source-maps --watch", "build": "babel src/**/*.js --out-dir lib --source-maps", "unit-test": "nyc mocha --require @babel/register test/*.js --timeout 100000", diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 0000000..d06362c --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,56 @@ +import { terser } from 'rollup-plugin-terser'; + +import nodeResolve from '@rollup/plugin-node-resolve'; +import commonjs from '@rollup/plugin-commonjs'; +import json from '@rollup/plugin-json'; +import polyfills from 'rollup-plugin-node-polyfills'; + +import babel from 'rollup-plugin-babel'; + +/** + * @external RollupConfig + * @type {PlainObject} + * @see {@link https://rollupjs.org/guide/en#big-list-of-options} + */ + +/** + * @param {PlainObject} [config= {}] + * @param {boolean} [config.minifying=false] + * @param {string} [config.format='umd'] + * @returns {external:RollupConfig} + */ +function getRollupObject ({ minifying, format = 'umd' } = {}) { + const nonMinified = { + input: 'src/index.js', + output: { + format, + sourcemap: minifying, + file: `lib/bundle${ + format === 'umd' ? '' : `.${format}` + }${minifying ? '.min' : ''}.js`, + name: 'escope' + }, + plugins: [ + json(), + polyfills(), + nodeResolve(), + commonjs({ + namedExports: { + 'estraverse/estraverse.js': ['Syntax'] + } + }), + babel() + ] + }; + if (minifying) { + nonMinified.plugins.push(terser()); + } + return nonMinified; +} + +export default [ + getRollupObject({ minifying: true, format: 'umd' }), + getRollupObject({ minifying: false, format: 'umd' }), + getRollupObject({ minifying: true, format: 'esm' }), + getRollupObject({ minifying: false, format: 'esm' }) +]; From c0b1de31ad9ba880714fcc736c3d26093a86f059 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Mon, 27 Apr 2020 07:42:38 +0800 Subject: [PATCH 19/24] - Testing: Minor coverage improvement --- src/index.js | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/index.js b/src/index.js index 65e6413..95f1644 100644 --- a/src/index.js +++ b/src/index.js @@ -73,18 +73,16 @@ function updateDeeply(target, override) { return typeof target === 'object' && target instanceof Object && !(target instanceof Array) && !(target instanceof RegExp); } - for (const key in override) { - if (Object.hasOwnProperty.call(override, key)) { - const val = override[key]; - if (isHashObject(val)) { - if (isHashObject(target[key])) { - updateDeeply(target[key], val); - } else { - target[key] = updateDeeply({}, val); - } + for (const [key, val] of Object.entries(override || {})) { + if (isHashObject(val)) { + // istanbul ignore if + if (isHashObject(target[key])) { + updateDeeply(target[key], val); } else { - target[key] = val; + target[key] = updateDeeply({}, val); } + } else { + target[key] = val; } } return target; From d9b24f2af6f3fea0388ca9e4f0349f5afc0d884e Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Thu, 30 Apr 2020 15:51:18 +0800 Subject: [PATCH 20/24] - Use file extensions --- src/definition.js | 2 +- src/index.js | 10 +++++----- src/referencer.js | 8 ++++---- src/scope-manager.js | 2 +- src/scope.js | 6 +++--- test/arguments.js | 2 +- test/catch-scope.js | 2 +- test/child-visitor-keys.js | 2 +- test/es6-arrow-function-expression.js | 2 +- test/es6-block-scope.js | 2 +- test/es6-catch.js | 2 +- test/es6-class.js | 2 +- test/es6-default-parameters.js | 4 ++-- test/es6-destructuring-assignments.js | 4 ++-- test/es6-export.js | 4 ++-- test/es6-import.js | 4 ++-- test/es6-iteration-scope.js | 2 +- test/es6-new-target.js | 4 ++-- test/es6-object.js | 2 +- test/es6-rest-args.js | 4 ++-- test/es6-super.js | 2 +- test/es6-switch.js | 2 +- test/es6-template-literal.js | 2 +- test/fallback.js | 2 +- test/function-expression-name.js | 2 +- test/get-declared-variables.js | 4 ++-- test/global-increment.js | 2 +- test/implicit-global-reference.js | 2 +- test/implied-strict.js | 2 +- test/label.js | 2 +- test/nodejs-scope.js | 2 +- test/object-expression.js | 2 +- test/optimistic.js | 2 +- test/references.js | 4 ++-- test/with-scope.js | 2 +- 35 files changed, 52 insertions(+), 52 deletions(-) diff --git a/src/definition.js b/src/definition.js index a178009..2614657 100644 --- a/src/definition.js +++ b/src/definition.js @@ -22,7 +22,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import Variable from './variable'; +import Variable from './variable.js'; /** * @class Definition diff --git a/src/index.js b/src/index.js index 95f1644..6995d33 100644 --- a/src/index.js +++ b/src/index.js @@ -48,11 +48,11 @@ import assert from 'assert'; -import ScopeManager from './scope-manager'; -import Referencer from './referencer'; -import Reference from './reference'; -import Variable from './variable'; -import Scope from './scope'; +import ScopeManager from './scope-manager.js'; +import Referencer from './referencer.js'; +import Reference from './reference.js'; +import Variable from './variable.js'; +import Scope from './scope.js'; import { version } from '../package.json'; function defaultOptions() { diff --git a/src/referencer.js b/src/referencer.js index 9af33df..7845784 100644 --- a/src/referencer.js +++ b/src/referencer.js @@ -23,10 +23,10 @@ */ import { Syntax } from 'estraverse'; import esrecurse from 'esrecurse'; -import Reference from './reference'; -import Variable from './variable'; -import PatternVisitor from './pattern-visitor'; -import { ParameterDefinition, Definition } from './definition'; +import Reference from './reference.js'; +import Variable from './variable.js'; +import PatternVisitor from './pattern-visitor.js'; +import { ParameterDefinition, Definition } from './definition.js'; import assert from 'assert'; function traverseIdentifierInPattern(options, rootPattern, referencer, callback) { diff --git a/src/scope-manager.js b/src/scope-manager.js index b1d0a33..3b142b5 100644 --- a/src/scope-manager.js +++ b/src/scope-manager.js @@ -22,7 +22,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// import Scope from './scope'; +// import Scope from './scope.js'; import assert from 'assert'; import { diff --git a/src/scope.js b/src/scope.js index b71378b..cd69c39 100644 --- a/src/scope.js +++ b/src/scope.js @@ -24,9 +24,9 @@ import { Syntax } from 'estraverse'; -import Reference from './reference'; -import Variable from './variable'; -import Definition from './definition'; +import Reference from './reference.js'; +import Variable from './variable.js'; +import Definition from './definition.js'; import assert from 'assert'; function isStrictScope(scope, block, isMethodDefinition, useDirective) { diff --git a/test/arguments.js b/test/arguments.js index 31d7f36..281a4a0 100644 --- a/test/arguments.js +++ b/test/arguments.js @@ -23,7 +23,7 @@ import { expect } from 'chai'; import * as esprima from 'esprima'; -import { analyze } from '..'; +import { analyze } from '../src/index.js'; describe('arguments', function() { it('arguments are correctly materialized', function() { diff --git a/test/catch-scope.js b/test/catch-scope.js index 61e4290..c895f03 100644 --- a/test/catch-scope.js +++ b/test/catch-scope.js @@ -23,7 +23,7 @@ import { expect } from 'chai'; import * as esprima from 'esprima'; -import { analyze } from '..'; +import { analyze } from '../src/index.js'; describe('catch', function() { it('creates scope', function() { diff --git a/test/child-visitor-keys.js b/test/child-visitor-keys.js index 9cbee11..2034130 100644 --- a/test/child-visitor-keys.js +++ b/test/child-visitor-keys.js @@ -23,7 +23,7 @@ import { expect } from 'chai'; import * as esprima from 'esprima'; -import { analyze } from '..'; +import { analyze } from '../src/index.js'; describe('childVisitorKeys option', function() { it('should handle as a known node if the childVisitorKeys option was given.', function() { diff --git a/test/es6-arrow-function-expression.js b/test/es6-arrow-function-expression.js index 2ee7561..c632b8e 100644 --- a/test/es6-arrow-function-expression.js +++ b/test/es6-arrow-function-expression.js @@ -23,7 +23,7 @@ import { expect } from 'chai'; import { parse } from 'esprima'; -import { analyze } from '..'; +import { analyze } from '../src/index.js'; describe('ES6 arrow function expression', function() { it('materialize scope for arrow function expression', function() { diff --git a/test/es6-block-scope.js b/test/es6-block-scope.js index 528cd50..8497cda 100644 --- a/test/es6-block-scope.js +++ b/test/es6-block-scope.js @@ -23,7 +23,7 @@ import { expect } from 'chai'; import { parse } from 'esprima'; -import { analyze } from '..'; +import { analyze } from '../src/index.js'; describe('ES6 block scope', function() { it('let is materialized in ES6 block scope#1', function() { diff --git a/test/es6-catch.js b/test/es6-catch.js index 6e8abf5..8ab71cd 100644 --- a/test/es6-catch.js +++ b/test/es6-catch.js @@ -22,7 +22,7 @@ // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import { expect } from 'chai'; import { parse } from 'esprima'; -import { analyze } from '..'; +import { analyze } from '../src/index.js'; describe('ES6 catch', function() { it('takes binding pattern', function() { diff --git a/test/es6-class.js b/test/es6-class.js index a2bb0f3..0cacd7e 100644 --- a/test/es6-class.js +++ b/test/es6-class.js @@ -23,7 +23,7 @@ import { expect } from 'chai'; import { parse } from 'esprima'; -import { analyze } from '..'; +import { analyze } from '../src/index.js'; describe('ES6 class', function() { it('declaration name creates class scope', function() { diff --git a/test/es6-default-parameters.js b/test/es6-default-parameters.js index e645595..6a07fcc 100644 --- a/test/es6-default-parameters.js +++ b/test/es6-default-parameters.js @@ -22,8 +22,8 @@ // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import { expect } from 'chai'; -import espree from '../third_party/espree'; -import { analyze } from '..'; +import espree from '../third_party/espree.js'; +import { analyze } from '../src/index.js'; describe('ES6 default parameters:', function() { describe('a default parameter creates a writable reference for its initialization:', function() { diff --git a/test/es6-destructuring-assignments.js b/test/es6-destructuring-assignments.js index f827c2b..1dda1de 100644 --- a/test/es6-destructuring-assignments.js +++ b/test/es6-destructuring-assignments.js @@ -23,8 +23,8 @@ import { expect } from 'chai'; import * as harmony from 'esprima'; -import espree from '../third_party/espree'; -import { analyze } from '..'; +import espree from '../third_party/espree.js'; +import { analyze } from '../src/index.js'; describe('ES6 destructuring assignments', function() { it('Pattern in var in ForInStatement', function() { diff --git a/test/es6-export.js b/test/es6-export.js index 52f6cd4..aa55d2b 100644 --- a/test/es6-export.js +++ b/test/es6-export.js @@ -22,8 +22,8 @@ // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import { expect } from 'chai'; -import espree from '../third_party/espree'; -import { analyze } from '..'; +import espree from '../third_party/espree.js'; +import { analyze } from '../src/index.js'; describe('export declaration', function() { // http://people.mozilla.org/~jorendorff/es6-draft.html#sec-static-and-runtme-semantics-module-records diff --git a/test/es6-import.js b/test/es6-import.js index 59d331d..89d768c 100644 --- a/test/es6-import.js +++ b/test/es6-import.js @@ -22,8 +22,8 @@ // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import { expect } from 'chai'; -import espree from '../third_party/espree'; -import { analyze } from '..'; +import espree from '../third_party/espree.js'; +import { analyze } from '../src/index.js'; describe('import declaration', function() { // http://people.mozilla.org/~jorendorff/es6-draft.html#sec-static-and-runtme-semantics-module-records diff --git a/test/es6-iteration-scope.js b/test/es6-iteration-scope.js index 2e95481..43c677f 100644 --- a/test/es6-iteration-scope.js +++ b/test/es6-iteration-scope.js @@ -23,7 +23,7 @@ import { expect } from 'chai'; import { parse } from 'esprima'; -import { analyze } from '..'; +import { analyze } from '../src/index.js'; describe('ES6 iteration scope', function() { it('let materialize iteration scope for ForInStatement#1', function() { diff --git a/test/es6-new-target.js b/test/es6-new-target.js index 8eb0cd5..a43ed5f 100644 --- a/test/es6-new-target.js +++ b/test/es6-new-target.js @@ -22,8 +22,8 @@ // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import { expect } from 'chai'; -import { analyze } from '..'; -import parse from '../third_party/espree'; +import { analyze } from '../src/index.js'; +import parse from '../third_party/espree.js'; describe('ES6 new.target', function() { it('should not make references of new.target', function() { diff --git a/test/es6-object.js b/test/es6-object.js index d3db05a..74558ea 100644 --- a/test/es6-object.js +++ b/test/es6-object.js @@ -23,7 +23,7 @@ import { expect } from 'chai'; import { parse } from 'esprima'; -import { analyze } from '..'; +import { analyze } from '../src/index.js'; describe('ES6 object', function() { it('method definition', function() { diff --git a/test/es6-rest-args.js b/test/es6-rest-args.js index e75c814..54386ab 100644 --- a/test/es6-rest-args.js +++ b/test/es6-rest-args.js @@ -23,8 +23,8 @@ import { expect } from 'chai'; import { parse as esprima } from 'esprima'; -import espree from '../third_party/espree'; -import { analyze } from '..'; +import espree from '../third_party/espree.js'; +import { analyze } from '../src/index.js'; describe('ES6 rest arguments', function() { it('materialize rest argument in scope (esprima: rest property of FunctionDeclaration)', function() { diff --git a/test/es6-super.js b/test/es6-super.js index f612200..5af916c 100644 --- a/test/es6-super.js +++ b/test/es6-super.js @@ -23,7 +23,7 @@ import { expect } from 'chai'; import { parse } from 'esprima'; -import { analyze } from '..'; +import { analyze } from '../src/index.js'; describe('ES6 super', function() { it('is not handled as reference', function() { diff --git a/test/es6-switch.js b/test/es6-switch.js index 8b3571e..8401c68 100644 --- a/test/es6-switch.js +++ b/test/es6-switch.js @@ -23,7 +23,7 @@ import { expect } from 'chai'; import { parse } from 'esprima'; -import { analyze } from '..'; +import { analyze } from '../src/index.js'; describe('ES6 switch', function() { it('materialize scope', function() { diff --git a/test/es6-template-literal.js b/test/es6-template-literal.js index 123b098..29d48f2 100644 --- a/test/es6-template-literal.js +++ b/test/es6-template-literal.js @@ -23,7 +23,7 @@ import { expect } from 'chai'; import { parse } from 'esprima'; -import { analyze } from '..'; +import { analyze } from '../src/index.js'; describe('ES6 template literal', function() { it('refer variables', function() { diff --git a/test/fallback.js b/test/fallback.js index 5ce5b69..5859f84 100644 --- a/test/fallback.js +++ b/test/fallback.js @@ -23,7 +23,7 @@ import { expect } from 'chai'; import * as esprima from 'esprima'; -import { analyze } from '..'; +import { analyze } from '../src/index.js'; describe('fallback option', function() { it('should raise an error when it encountered an unknown node if no fallback.', function() { diff --git a/test/function-expression-name.js b/test/function-expression-name.js index a64792d..4d01f75 100644 --- a/test/function-expression-name.js +++ b/test/function-expression-name.js @@ -23,7 +23,7 @@ import { expect } from 'chai'; import { parse as parse } from 'esprima'; -import { analyze } from '..'; +import { analyze } from '../src/index.js'; describe('function name', function() { it('should create its special scope', function() { diff --git a/test/get-declared-variables.js b/test/get-declared-variables.js index 62ffdb8..cbff76f 100644 --- a/test/get-declared-variables.js +++ b/test/get-declared-variables.js @@ -23,8 +23,8 @@ import { expect } from 'chai'; import { visit } from 'esrecurse'; -import espree from '../third_party/espree'; -import { analyze } from '..'; +import espree from '../third_party/espree.js'; +import { analyze } from '../src/index.js'; describe('ScopeManager.prototype.getDeclaredVariables', function() { const verify = (ast, type, expectedNamesList) => { diff --git a/test/global-increment.js b/test/global-increment.js index e97a86c..befbe52 100644 --- a/test/global-increment.js +++ b/test/global-increment.js @@ -23,7 +23,7 @@ import { expect } from 'chai'; import { parse } from 'esprima'; -import { analyze } from '..'; +import { analyze } from '../src/index.js'; describe('global increment', function() { it('becomes read/write', function() { diff --git a/test/implicit-global-reference.js b/test/implicit-global-reference.js index 291560b..36af0ef 100644 --- a/test/implicit-global-reference.js +++ b/test/implicit-global-reference.js @@ -22,7 +22,7 @@ import { expect } from 'chai'; -import { analyze } from '..'; +import { analyze } from '../src/index.js'; import { parse } from 'esprima'; describe('implicit global reference', function() { diff --git a/test/implied-strict.js b/test/implied-strict.js index e4c68ab..94a2bda 100644 --- a/test/implied-strict.js +++ b/test/implied-strict.js @@ -23,7 +23,7 @@ import { expect } from 'chai'; import { parse } from 'esprima'; -import { analyze } from '..'; +import { analyze } from '../src/index.js'; describe('impliedStrict option', function() { it('ensures all user scopes are strict if ecmaVersion >= 5', function() { diff --git a/test/label.js b/test/label.js index e2dd7d5..936ebc9 100644 --- a/test/label.js +++ b/test/label.js @@ -23,7 +23,7 @@ import { expect } from 'chai'; import { parse } from 'esprima'; -import { analyze } from '..'; +import { analyze } from '../src/index.js'; describe('label', function() { it('should not create variables', function() { diff --git a/test/nodejs-scope.js b/test/nodejs-scope.js index 4f5e23f..a002ba5 100644 --- a/test/nodejs-scope.js +++ b/test/nodejs-scope.js @@ -23,7 +23,7 @@ import { expect } from 'chai'; import { parse } from 'esprima'; -import { analyze } from '..'; +import { analyze } from '../src/index.js'; describe('nodejsScope option', function() { it('creates a function scope following the global scope immediately', function() { diff --git a/test/object-expression.js b/test/object-expression.js index c962a4f..d8c7601 100644 --- a/test/object-expression.js +++ b/test/object-expression.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { analyze } from '..'; +import { analyze } from '../src/index.js'; describe('object expression', function() { it('doesn\'t require property type', function() { diff --git a/test/optimistic.js b/test/optimistic.js index 6793cda..5ba05d3 100644 --- a/test/optimistic.js +++ b/test/optimistic.js @@ -22,7 +22,7 @@ import { expect } from 'chai'; -import { analyze } from '..'; +import { analyze } from '../src/index.js'; import { parse } from 'esprima'; describe('optimistic', function() { diff --git a/test/references.js b/test/references.js index 94626c1..8aad1c3 100644 --- a/test/references.js +++ b/test/references.js @@ -22,8 +22,8 @@ // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import { expect } from 'chai'; -import espree from '../third_party/espree'; -import { analyze } from '..'; +import espree from '../third_party/espree.js'; +import { analyze } from '../src/index.js'; describe('References:', function() { describe('When there is a `let` declaration on global,', function() { diff --git a/test/with-scope.js b/test/with-scope.js index a42be9f..331aa81 100644 --- a/test/with-scope.js +++ b/test/with-scope.js @@ -23,7 +23,7 @@ import { expect } from 'chai'; import { parse } from 'esprima'; -import { analyze } from '..'; +import { analyze } from '../src/index.js'; describe('with', function() { it('creates scope', function() { From c4f8cfad294ac8dcb0855e62acb8da5fadf14e53 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Thu, 30 Apr 2020 19:07:31 +0800 Subject: [PATCH 21/24] - Refactoring: Prefer for-of --- src/pattern-visitor.js | 3 +-- src/referencer.js | 4 ++-- src/scope-manager.js | 3 +-- src/scope.js | 25 +++++++++---------------- 4 files changed, 13 insertions(+), 22 deletions(-) diff --git a/src/pattern-visitor.js b/src/pattern-visitor.js index dfa8768..f19c398 100644 --- a/src/pattern-visitor.js +++ b/src/pattern-visitor.js @@ -73,8 +73,7 @@ export default class PatternVisitor extends esrecurse.Visitor { } ArrayPattern(pattern) { - for (let i = 0, iz = pattern.elements.length; i < iz; ++i) { - const element = pattern.elements[i]; + for (const element of pattern.elements) { this.visit(element); } } diff --git a/src/referencer.js b/src/referencer.js index 7845784..c050697 100644 --- a/src/referencer.js +++ b/src/referencer.js @@ -508,8 +508,8 @@ export default class Referencer extends esrecurse.Visitor { this.scopeManager.__nestSwitchScope(node); } - for (let i = 0, iz = node.cases.length; i < iz; ++i) { - this.visit(node.cases[i]); + for (const cse of node.cases) { + this.visit(cse); } this.close(node); diff --git a/src/scope-manager.js b/src/scope-manager.js index 3b142b5..8642837 100644 --- a/src/scope-manager.js +++ b/src/scope-manager.js @@ -136,8 +136,7 @@ export default class ScopeManager { } } } else { - for (let i = 0, iz = scopes.length; i < iz; ++i) { - const scope = scopes[i]; + for (const scope of scopes) { if (predicate(scope)) { return scope; } diff --git a/src/scope.js b/src/scope.js index cd69c39..b093d4a 100644 --- a/src/scope.js +++ b/src/scope.js @@ -67,8 +67,7 @@ function isStrictScope(scope, block, isMethodDefinition, useDirective) { // Search 'use strict' directive. if (useDirective) { - for (let i = 0, iz = body.body.length; i < iz; ++i) { - const stmt = body.body[i]; + for (const stmt of body.body) { if (stmt.type !== Syntax.DirectiveStatement) { break; } @@ -77,8 +76,7 @@ function isStrictScope(scope, block, isMethodDefinition, useDirective) { } } } else { - for (let i = 0, iz = body.body.length; i < iz; ++i) { - const stmt = body.body[i]; + for (const stmt of body.body) { if (stmt.type !== Syntax.ExpressionStatement) { break; } @@ -280,8 +278,7 @@ export default class Scope { } // Try Resolving all references in this scope. - for (let i = 0, iz = this.__left.length; i < iz; ++i) { - const ref = this.__left[i]; + for (const ref of this.__left) { closeRef.call(this, ref); } this.__left = null; @@ -403,8 +400,7 @@ export default class Scope { resolve(ident) { assert(this.__isClosed(), 'Scope should be closed.'); assert(ident.type === Syntax.Identifier, 'Target should be identifier.'); - for (let i = 0, iz = this.references.length; i < iz; ++i) { - const ref = this.references[i]; + for (const ref of this.references) { if (ref.identifier === ident) { return ref; } @@ -443,8 +439,8 @@ export default class Scope { if (this.set.has(name)) { return true; } - for (let i = 0, iz = this.through.length; i < iz; ++i) { - if (this.through[i].identifier.name === name) { + for (const thrgh of this.through) { + if (thrgh.identifier.name === name) { return true; } } @@ -469,16 +465,14 @@ export class GlobalScope extends Scope { __close(scopeManager) { const implicit = []; - for (let i = 0, iz = this.__left.length; i < iz; ++i) { - const ref = this.__left[i]; + for (const ref of this.__left) { if (ref.__maybeImplicitGlobal && !this.set.has(ref.identifier.name)) { implicit.push(ref.__maybeImplicitGlobal); } } // create an implicit global variable from assignment expression - for (let i = 0, iz = implicit.length; i < iz; ++i) { - const info = implicit[i]; + for (const info of implicit) { this.__defineImplicit(info.pattern, new Definition( Variable.ImplicitGlobalVariable, @@ -546,8 +540,7 @@ export class WithScope extends Scope { return super.__close(scopeManager); } - for (let i = 0, iz = this.__left.length; i < iz; ++i) { - const ref = this.__left[i]; + for (const ref of this.__left) { ref.tainted = true; this.__delegateToUpperScope(ref); } From bd191fb10364f4bb93e40677e5b2e8ab523279fb Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Thu, 30 Apr 2020 19:59:05 +0800 Subject: [PATCH 22/24] - Add `Object.entries` polyfill --- .babelrc.json | 3 +++ package.json | 1 + 2 files changed, 4 insertions(+) diff --git a/.babelrc.json b/.babelrc.json index 625789e..941e381 100644 --- a/.babelrc.json +++ b/.babelrc.json @@ -5,5 +5,8 @@ "node": "4.0.0" } }] + ], + "plugins": [ + ["transform-es2017-object-entries"] ] } diff --git a/package.json b/package.json index df4bd88..00eb7e6 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "@rollup/plugin-commonjs": "^11.1.0", "@rollup/plugin-json": "^4.0.3", "@rollup/plugin-node-resolve": "^7.1.3", + "babel-plugin-transform-es2017-object-entries": "0.0.5", "chai": "^4.2.0", "eslint": "^6.8.0", "espree": "^6.2.1", From 0858bdfb5a78a895c660368c65ebb49d4cd0f021 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Sun, 10 May 2020 16:24:57 +0800 Subject: [PATCH 23/24] - npm: Update devDeps. - npm: Use rollup/plugin-babel over deprecated rollup-plugin-babel --- package.json | 12 ++++++------ rollup.config.js | 6 ++++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 00eb7e6..fa4b871 100644 --- a/package.json +++ b/package.json @@ -33,22 +33,22 @@ }, "devDependencies": { "@babel/cli": "^7.8.4", - "@babel/core": "^7.9.0", - "@babel/preset-env": "^7.9.5", + "@babel/core": "^7.9.6", + "@babel/preset-env": "^7.9.6", "@babel/register": "^7.9.0", + "@rollup/plugin-babel": "^5.0.0", "@rollup/plugin-commonjs": "^11.1.0", "@rollup/plugin-json": "^4.0.3", "@rollup/plugin-node-resolve": "^7.1.3", "babel-plugin-transform-es2017-object-entries": "0.0.5", "chai": "^4.2.0", - "eslint": "^6.8.0", - "espree": "^6.2.1", + "eslint": "^7.0.0", + "espree": "^7.0.0", "esprima": "^4.0.1", "jsdoc": "^3.6.4", "mocha": "^7.1.2", "nyc": "^15.0.1", - "rollup": "^2.7.2", - "rollup-plugin-babel": "^4.4.0", + "rollup": "^2.8.2", "rollup-plugin-node-polyfills": "^0.2.1", "rollup-plugin-terser": "^5.3.0" }, diff --git a/rollup.config.js b/rollup.config.js index d06362c..277a4df 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -5,7 +5,7 @@ import commonjs from '@rollup/plugin-commonjs'; import json from '@rollup/plugin-json'; import polyfills from 'rollup-plugin-node-polyfills'; -import babel from 'rollup-plugin-babel'; +import babel from '@rollup/plugin-babel'; /** * @external RollupConfig @@ -39,7 +39,9 @@ function getRollupObject ({ minifying, format = 'umd' } = {}) { 'estraverse/estraverse.js': ['Syntax'] } }), - babel() + babel({ + babelHelpers: 'bundled' + }) ] }; if (minifying) { From 99ffe18984549f41c5ce2d43c30d78e0b0f806d6 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Mon, 29 Jun 2020 14:35:00 +0800 Subject: [PATCH 24/24] - npm: Update devDeps. --- package.json | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index fa4b871..094c018 100644 --- a/package.json +++ b/package.json @@ -32,25 +32,25 @@ "estraverse": "^5.1.0" }, "devDependencies": { - "@babel/cli": "^7.8.4", - "@babel/core": "^7.9.6", - "@babel/preset-env": "^7.9.6", - "@babel/register": "^7.9.0", - "@rollup/plugin-babel": "^5.0.0", - "@rollup/plugin-commonjs": "^11.1.0", - "@rollup/plugin-json": "^4.0.3", - "@rollup/plugin-node-resolve": "^7.1.3", + "@babel/cli": "^7.10.3", + "@babel/core": "^7.10.3", + "@babel/preset-env": "^7.10.3", + "@babel/register": "^7.10.3", + "@rollup/plugin-babel": "^5.0.4", + "@rollup/plugin-commonjs": "^13.0.0", + "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-node-resolve": "^8.1.0", "babel-plugin-transform-es2017-object-entries": "0.0.5", "chai": "^4.2.0", - "eslint": "^7.0.0", - "espree": "^7.0.0", + "eslint": "^7.3.1", + "espree": "^7.1.0", "esprima": "^4.0.1", "jsdoc": "^3.6.4", - "mocha": "^7.1.2", - "nyc": "^15.0.1", - "rollup": "^2.8.2", + "mocha": "^8.0.1", + "nyc": "^15.1.0", + "rollup": "^2.18.1", "rollup-plugin-node-polyfills": "^0.2.1", - "rollup-plugin-terser": "^5.3.0" + "rollup-plugin-terser": "^6.1.0" }, "license": "BSD-2-Clause", "nyc": { @@ -72,7 +72,7 @@ "build-watch": "babel src/**/*.js --out-dir lib --source-maps --watch", "build": "babel src/**/*.js --out-dir lib --source-maps", "unit-test": "nyc mocha --require @babel/register test/*.js --timeout 100000", - "test": "npm run build && npm run unit-test", + "test": "npm run build && npm run unit-test && npm run lint", "lint": "eslint .", "jsdoc": "jsdoc src/*.js README.md" }