Skip to content

Commit

Permalink
INCOMPLETE: failling single SequenceExpressionAsKey test
Browse files Browse the repository at this point in the history
Merge branch 'eslint-npm' into eslint-npm-full

* eslint-npm:
  - npm: update estraverse - npm: update devDeps. - npm: Update package-lock version
  - npm: update devDeps. - npm: Update package-lock version
  - Linting: Temporarily disable most linting, with a few fixes
  - Breaking change: Remove bower-registry-client build (bower deprecated) - Update: Use new SourceMapConsumer API in test - Build: Provide browserified builds with npm package - Travis: Drop 4, 6, 8; Add 10, 12, 14; check build - Maintenance: Add `.editorconfig` - Docs: Use fenced code blocks in README (for syntax highlighting) - npm: Add `bugs`, `keywords`, change from `maintainers` to `authors`/`contributors` - npm: Restore `optionator` to a regular dep. (used in published binary file) - npm: Drop unused semver, minimist - npm: Bump deps. (estraverse, optionator, optional source-map potentially breaking) and devDeps. - npm: Drop bluebird in favor of ES Promises - npm: Use more recently maintained browserify + uglifyify - npm: Replace linting and testing scripts in Gulpfile with npm scripts
  Add more optional-chaining tests
  Test logical assignments
  Implement coalescing code generation
  Support BigInt syntax
  Update gulpfile and dependencies
  Version 2.0.0
  add support for optional chaining (estools#412)
  Update .gitattributes
  drop support for node <6 (estools#419)

# Conflicts:
#	.eslintignore
#	.eslintrc.js
#	.gitignore
#	escodegen.js.map
#	package-lock.json
#	package.json
#	src/escodegen.js
#	test/source-map.js
#	tools/release.js
  • Loading branch information
brettz9 committed Feb 9, 2021
2 parents 8d538ba + 77da34c commit 5653edd
Show file tree
Hide file tree
Showing 22 changed files with 11,872 additions and 2,444 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
test/3rdparty/**/* -crlf -diff
# don't collapse diffs of test expectations
test/compare-*/*.expected.min.js -linguist-generated
2 changes: 1 addition & 1 deletion escodegen.js.map

Large diffs are not rendered by default.

13,392 changes: 10,985 additions & 2,407 deletions package-lock.json

Large diffs are not rendered by default.

23 changes: 12 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
"escodegen.browser.js",
"package.json"
],
"version": "1.14.3",
"version": "2.0.0",
"engines": {
"node": ">=4.0"
"node": ">=6.0"
},
"author": {
"name": "Yusuke Suzuki",
Expand All @@ -37,7 +37,7 @@
},
"dependencies": {
"esprima": "^4.0.1",
"estraverse": "^5.1.0",
"estraverse": "^5.2.0",
"esutils": "^2.0.3",
"optionator": "^0.9.1"
},
Expand All @@ -47,14 +47,15 @@
"devDependencies": {
"@babel/cli": "^7.8.4",
"@babel/preset-env": "^7.9.5",
"acorn": "^7.3.1",
"acorn": "^8.0.5",
"babel-plugin-transform-es2017-object-entries": "0.0.5",
"browserify": "^16.5.1",
"chai": "^4.2.0",
"eslint": "^7.3.1",
"mocha": "^8.0.1",
"browserify": "^17.0.0",
"chai": "^4.3.0",
"chai-exclude": "^2.0.2",
"eslint": "^7.19.0",
"mocha": "^8.2.1",
"nyc": "^15.1.0",
"semver": "^7.3.2",
"source-map": "~0.7.3",
"uglifyify": "^5.0.2"
},
"license": "BSD-2-Clause",
Expand All @@ -76,9 +77,9 @@
"build": "babel src/escodegen.js --out-file escodegen.js --source-maps",
"browser-build-min": "browserify -t uglifyify -e tools/entry-point.js -o escodegen.browser.min.js",
"browser-build": "browserify -e tools/entry-point.js -o escodegen.browser.js",
"test": "npm run unit-test && npm run lint",
"unit-test": "nyc --require chai/register-expect mocha test/*.js --timeout 100000",
"lint": "eslint --rulesdir tools/rules/ .",
"unit-test": "nyc --require chai/register-expect mocha test/*.js --timeout 100000",
"test": "npm run unit-test && npm run lint",
"release": "node tools/release.js"
}
}
90 changes: 65 additions & 25 deletions src/escodegen.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
Copyright (C) 2012 Joost-Wim Boekesteijn <joost-wim@boekesteijn.nl>
Copyright (C) 2012 Kris Kowal <kris.kowal@cixar.com>
Copyright (C) 2012 Arpad Borsos <arpad.borsos@googlemail.com>
Copyright (C) 2020 Apple Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Expand Down Expand Up @@ -77,28 +78,31 @@
Assignment: 1,
Conditional: 2,
ArrowFunction: 2,
LogicalOR: 3,
LogicalAND: 4,
BitwiseOR: 5,
BitwiseXOR: 6,
BitwiseAND: 7,
Equality: 8,
Relational: 9,
BitwiseSHIFT: 10,
Additive: 11,
Multiplicative: 12,
Exponentiation: 13,
Await: 14,
Unary: 14,
Postfix: 15,
Call: 16,
New: 17,
TaggedTemplate: 18,
Member: 19,
Primary: 20
Coalesce: 3,
LogicalOR: 4,
LogicalAND: 5,
BitwiseOR: 6,
BitwiseXOR: 7,
BitwiseAND: 8,
Equality: 9,
Relational: 10,
BitwiseSHIFT: 11,
Additive: 12,
Multiplicative: 13,
Exponentiation: 14,
Await: 15,
Unary: 15,
Postfix: 16,
OptionalChaining: 17,
Call: 18,
New: 19,
TaggedTemplate: 20,
Member: 21,
Primary: 22
};

const BinaryPrecedence = {
'??': Precedence.Coalesce,
'||': Precedence.LogicalOR,
'&&': Precedence.LogicalAND,
'|': Precedence.BitwiseOR,
Expand Down Expand Up @@ -133,7 +137,8 @@
F_ALLOW_UNPARATH_NEW = 1 << 2,
F_FUNC_BODY = 1 << 3,
F_DIRECTIVE_CTX = 1 << 4,
F_SEMICOLON_OPT = 1 << 5;
F_SEMICOLON_OPT = 1 << 5,
F_FOUND_COALESCE = 1 << 6;

//Expression flag sets
//NOTE: Flag order:
Expand Down Expand Up @@ -1812,7 +1817,7 @@
}
return parenthesize(
[
this.generateExpression(expr.test, Precedence.LogicalOR, flags),
this.generateExpression(expr.test, Precedence.Coalesce, flags),
`${space}?${space}`,
this.generateExpression(expr.consequent, Precedence.Assignment, flags),
`${space}:${space}`,
Expand All @@ -1824,6 +1829,9 @@
},

LogicalExpression (expr, precedence, flags) {
if (expr.operator === '??') {
flags |= F_FOUND_COALESCE;
}
return this.BinaryExpression(expr, precedence, flags);
},

Expand Down Expand Up @@ -1861,12 +1869,20 @@
if (expr.operator === 'in' && !(flags & F_ALLOW_IN)) {
return ['(', result, ')'];
}
if ((expr.operator === '||' || expr.operator === '&&') && (flags & F_FOUND_COALESCE)) {
return ['(', result, ')'];
}
return parenthesize(result, currentPrecedence, precedence);
},

CallExpression (expr, precedence, flags) {
// F_ALLOW_UNPARATH_NEW becomes false.
const result = [this.generateExpression(expr.callee, Precedence.Call, E_TTF)];

if (expr.optional) {
result.push('?.');
}

result.push('(');
for (let i = 0, iz = expr['arguments'].length; i < iz; ++i) {
result.push(this.generateExpression(expr['arguments'][i], Precedence.Assignment, E_TTT));
Expand All @@ -1879,9 +1895,20 @@
if (!(flags & F_ALLOW_CALL)) {
return ['(', result, ')'];
}

return parenthesize(result, Precedence.Call, precedence);
},

ChainExpression (expr, precedence, flags) {
if (Precedence.OptionalChaining < precedence) {
flags |= F_ALLOW_CALL;
}

const result = this.generateExpression(expr.expression, Precedence.OptionalChaining, flags);

return parenthesize(result, Precedence.OptionalChaining, precedence);
},

NewExpression (expr, precedence, flags) {
const { length } = expr['arguments'];

Expand Down Expand Up @@ -1913,11 +1940,15 @@
const result = [this.generateExpression(expr.object, Precedence.Call, (flags & F_ALLOW_CALL) ? E_TTF : E_TFF)];

if (expr.computed) {
if (expr.optional) {
result.push('?.');
}

result.push('[');
result.push(this.generateExpression(expr.property, Precedence.Sequence, flags & F_ALLOW_CALL ? E_TTT : E_TFT));
result.push(']');
} else {
if (expr.object.type === Syntax.Literal && typeof expr.object.value === 'number') {
if (!expr.optional && expr.object.type === Syntax.Literal && typeof expr.object.value === 'number') {
const fragment = toSourceNodeWhenNeeded(result).toString();
// When the following conditions are all true,
// 1. No floating point
Expand All @@ -1934,7 +1965,7 @@
result.push(' ');
}
}
result.push('.');
result.push(expr.optional ? '?.' : '.');
result.push(generateIdentifier(expr.property));
}

Expand Down Expand Up @@ -2314,6 +2345,16 @@
return `/${expr.regex.pattern}/${expr.regex.flags}`;
}

if (typeof expr.value === 'bigint') {
return expr.value.toString() + 'n';
}

// `expr.value` can be null if `expr.bigint` exists. We need to check
// `expr.bigint` first.
if (expr.bigint) {
return expr.bigint + 'n';
}

if (expr.value === null) {
return 'null';
}
Expand Down Expand Up @@ -2445,8 +2486,7 @@
this.generateExpression(expr.source, Precedence.Assignment, E_TTT),
')'
], Precedence.Call, precedence);
},

}
};

merge(CodeGenerator.prototype, CodeGenerator.Expression);
Expand Down
95 changes: 95 additions & 0 deletions test/compare-acorn-es2020.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
Copyright (C) 2012-2013 Yusuke Suzuki <utatane.tea@gmail.com>
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 <COPYRIGHT HOLDER> 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';

var fs = require('fs'),
acorn = require('acorn'),
escodegen = require('./loader'),
chai = require('chai'),
chaiExclude = require('chai-exclude'),
expect = chai.expect;

chai.use(chaiExclude);

function test(code, expected) {
var tree, actual, actualTree, options;

options = {
ranges: false,
locations: false,
ecmaVersion: 11
};

tree = acorn.parse(code, options);

// for UNIX text comment
actual = escodegen.generate(tree);
actualTree = acorn.parse(actual, options);

expect(actual).to.be.equal(expected);
expect(tree).excludingEvery(['start', 'end', 'raw']).to.deep.equal(actualTree);
}

function testMin(code, expected) {
var tree, actual, actualTree, options;

options = {
ranges: false,
locations: false,
ecmaVersion: 11
};

tree = acorn.parse(code, options);

// for UNIX text comment
actual = escodegen.generate(tree, {
format: escodegen.FORMAT_MINIFY,
raw: false
}).replace(/[\n\r]$/, '') + '\n';
actualTree = acorn.parse(actual, options);

expect(actual).to.be.equal(expected);
expect(tree).excludingEvery(['start', 'end', 'raw']).to.deep.equal(actualTree);
}

describe('compare acorn es2020 test', function () {
fs.readdirSync(__dirname + '/compare-acorn-es2020').sort().forEach(function(file) {
var code, expected, exp, min;
if (/\.js$/.test(file) && !/expected\.js$/.test(file) && !/expected\.min\.js$/.test(file)) {
it(file, function () {
exp = file.replace(/\.js$/, '.expected.js');
min = file.replace(/\.js$/, '.expected.min.js');
code = fs.readFileSync(__dirname + '/compare-acorn-es2020/' + file, 'utf-8');
expected = fs.readFileSync(__dirname + '/compare-acorn-es2020/' + exp, 'utf-8');
test(code, expected);
if (fs.existsSync(__dirname + '/compare-acorn-es2020/' + min)) {
expected = fs.readFileSync(__dirname + '/compare-acorn-es2020/' + min, 'utf-8');
testMin(code, expected);
}
});
}
});
});
/* vim: set sw=4 ts=4 et tw=80 : */
3 changes: 3 additions & 0 deletions test/compare-acorn-es2020/bigint.expected.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
2000n + 30;
20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000n + 30;
-20000000000000000000000000000n;
1 change: 1 addition & 0 deletions test/compare-acorn-es2020/bigint.expected.min.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2000n+30;20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000n+30;-20000000000000000000000000000n
28 changes: 28 additions & 0 deletions test/compare-acorn-es2020/bigint.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (C) 2020 Apple Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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 APPLE INC. AND ITS 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 APPLE INC. OR ITS CONTRIBUTORS
* 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.
*/

2000n + 30;
20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000n + 30;
-20000000000000000000000000000n;
Loading

0 comments on commit 5653edd

Please sign in to comment.