From f6ea090dac8d81b887d321e490fda6ae32f3a561 Mon Sep 17 00:00:00 2001 From: Brook Date: Tue, 16 Jul 2024 23:22:49 +0800 Subject: [PATCH 1/2] feat: Support class field declarations(and property without value). From https://github.com/estools/escodegen/pull/465/commits/694da5391bc0fb3ac4e596082064a84188f20e49 add support for property without value --- escodegen.js | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/escodegen.js b/escodegen.js index 82417cd7..e8eca21f 100644 --- a/escodegen.js +++ b/escodegen.js @@ -1130,7 +1130,8 @@ for (i = 0, iz = stmt.body.length; i < iz; ++i) { result.push(indent); - result.push(that.generateExpression(stmt.body[i], Precedence.Sequence, E_TTT)); + var flag = E_TTT | (i === iz - 1 ? F_SEMICOLON_OPT : 0) + result.push(that.generateExpression(stmt.body[i], Precedence.Sequence, flag)); if (i + 1 < iz) { result.push(newline); } @@ -2161,6 +2162,28 @@ return join(result, fragment); }, + PrivateIdentifier: function (expr, precedence, flags) { + return toSourceNodeWhenNeeded('#' + expr.name, expr); + }, + PropertyDefinition: function (expr, precedence, flags) { + var keywords = []; + if (expr.static) { + keywords.push('static'); + } + // null for property without value + var assign = expr.value !== null ? [ + space, + '=', + space, + this.generateExpression(expr.value, Precedence.Assignment, E_TTT) + ] : [] + return join(keywords, [].concat( + this.generatePropertyKey(expr.key, expr.computed), + assign, + this.semicolon(flags) + )); + }, + Property: function (expr, precedence, flags) { if (expr.kind === 'get' || expr.kind === 'set') { return [ From 81d0c456b8150bf1c675b50c23fc4bd858abc936 Mon Sep 17 00:00:00 2001 From: Brook Date: Wed, 17 Jul 2024 09:35:44 +0800 Subject: [PATCH 2/2] test: class fields --- test/compare-acorn-es2022.js | 99 +++++++++++++++++++ .../class-field-declarations.expected.js | 10 ++ .../class-field-declarations.expected.min.js | 1 + .../class-field-declarations.js | 13 +++ 4 files changed, 123 insertions(+) create mode 100644 test/compare-acorn-es2022.js create mode 100644 test/compare-acorn-es2022/class-field-declarations.expected.js create mode 100644 test/compare-acorn-es2022/class-field-declarations.expected.min.js create mode 100644 test/compare-acorn-es2022/class-field-declarations.js diff --git a/test/compare-acorn-es2022.js b/test/compare-acorn-es2022.js new file mode 100644 index 00000000..cdb85bc8 --- /dev/null +++ b/test/compare-acorn-es2022.js @@ -0,0 +1,99 @@ +/* + Copyright (C) 2012-2013 Yusuke Suzuki + 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: + + * 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'; + +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 expectedTree, actual, actualTree, options; + + options = { + ranges: false, + locations: false, + ecmaVersion: 2022, + }; + + expectedTree = acorn.parse(code, options); + + // for UNIX text comment + actual = escodegen.generate(expectedTree) + "\n"; + actualTree = acorn.parse(actual, options); + + console.dir(expectedTree, { depth: null }); + console.dir(actualTree, { depth: null }); + + expect(actual).to.be.equal(expected); + expect(actualTree).excludingEvery(['start', 'end', 'raw']).to.deep.equal(expectedTree); +} + +function testMin(code, expected) { + var expectedTree, actual, actualTree, options; + + options = { + ranges: false, + locations: false, + ecmaVersion: 2022, + }; + + expectedTree = acorn.parse(code, options); + + // for UNIX text comment + actual = escodegen.generate(expectedTree, { + format: escodegen.FORMAT_MINIFY, + raw: false + }).replace(/[\n\r]$/, '') + '\n'; + actualTree = acorn.parse(actual, options); + + expect(actual).to.be.equal(expected); + expect(actualTree).excludingEvery(['start', 'end', 'raw']).to.deep.equal(expectedTree); +} + +describe('compare acorn es2022 test', function () { + fs.readdirSync(__dirname + '/compare-acorn-es2022').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-es2022/' + file, 'utf-8'); + expected = fs.readFileSync(__dirname + '/compare-acorn-es2022/' + exp, 'utf-8'); + test(code, expected); + if (fs.existsSync(__dirname + '/compare-acorn-es2022/' + min)) { + expected = fs.readFileSync(__dirname + '/compare-acorn-es2022/' + min, 'utf-8'); + testMin(code, expected); + } + }); + } + }); +}); +/* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/test/compare-acorn-es2022/class-field-declarations.expected.js b/test/compare-acorn-es2022/class-field-declarations.expected.js new file mode 100644 index 00000000..37da0a32 --- /dev/null +++ b/test/compare-acorn-es2022/class-field-declarations.expected.js @@ -0,0 +1,10 @@ +class FieldDeclarations { + noValue; + member = 1; + ['non-identifier'] = 18; + [Symbol.iterator] = 10; + #privateMember = 2; + static #STATIC = 3; + static STATIC = 4; + static [1 + 2] = 4; +} diff --git a/test/compare-acorn-es2022/class-field-declarations.expected.min.js b/test/compare-acorn-es2022/class-field-declarations.expected.min.js new file mode 100644 index 00000000..55f7fe9a --- /dev/null +++ b/test/compare-acorn-es2022/class-field-declarations.expected.min.js @@ -0,0 +1 @@ +class FieldDeclarations{noValue;member=1;['non-identifier']=18;[Symbol.iterator]=10;#privateMember=2;static#STATIC=3;static STATIC=4;static[1+2]=4} diff --git a/test/compare-acorn-es2022/class-field-declarations.js b/test/compare-acorn-es2022/class-field-declarations.js new file mode 100644 index 00000000..48232387 --- /dev/null +++ b/test/compare-acorn-es2022/class-field-declarations.js @@ -0,0 +1,13 @@ +class FieldDeclarations{ + noValue + member = 1; + + ["non-identifier"] = 18; + [Symbol.iterator] = 10; + + #privateMember = 2 + + static #STATIC = 3 + static STATIC = 4 + static [1 + 2] = 4 +}