diff --git a/package-lock.json b/package-lock.json index dbe63ca..ecc0ed8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,13 @@ { "name": "wc-compiler", - "version": "0.10.0", + "version": "0.11.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "wc-compiler", - "version": "0.10.0", + "version": "0.11.0", + "hasInstallScript": true, "license": "MIT", "dependencies": { "acorn": "^8.7.0", @@ -32,6 +33,7 @@ "livereload": "^0.9.3", "mocha": "^9.2.2", "nodemon": "^2.0.15", + "patch-package": "^8.0.0", "prismjs": "^1.28.0", "rehype-autolink-headings": "^6.1.1", "rehype-raw": "^6.1.1", @@ -427,6 +429,12 @@ "dev": true, "license": "ISC" }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true + }, "node_modules/abab": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", @@ -657,6 +665,15 @@ "dev": true, "license": "MIT" }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", @@ -933,14 +950,18 @@ } }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.6.tgz", + "integrity": "sha512-Mj50FLHtlsoVfRfnHaZvyrooHcrlceNZdL/QBvJJVd9Ta55qCQK0gs4ss2oZDeV9zFCs6ewzYgVE5yfVmfFpVg==", "dev": true, - "license": "MIT", "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.3", + "set-function-length": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -1587,6 +1608,21 @@ "dev": true, "license": "MIT" }, + "node_modules/define-data-property": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.2.tgz", + "integrity": "sha512-SRtsSqsDbgpJBbW3pABMCOt6rQyeM8s8RiyeSN8jYG8sYmt/kGJejbydttUsnDs1tadr19tvhT4ShwMyoqAm4g==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.2", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1716,6 +1752,15 @@ "once": "^1.4.0" } }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -2279,6 +2324,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/find-yarn-workspace-root": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", + "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", + "dev": true, + "dependencies": { + "micromatch": "^4.0.2" + } + }, "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", @@ -2407,11 +2461,13 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, - "license": "MIT" + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/functional-red-black-tree": { "version": "1.0.1", @@ -2441,15 +2497,19 @@ } }, "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, - "license": "MIT", "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2576,6 +2636,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/got": { "version": "9.6.0", "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", @@ -2675,6 +2747,30 @@ "node": ">=8" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", @@ -2698,6 +2794,18 @@ "node": ">=8" } }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/hast-to-hyperscript": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/hast-to-hyperscript/-/hast-to-hyperscript-10.0.1.tgz", @@ -3347,6 +3455,21 @@ "node": ">=0.10.0" } }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", @@ -3546,6 +3669,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-yarn-global": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", @@ -3553,6 +3688,12 @@ "dev": true, "license": "MIT" }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -3693,6 +3834,24 @@ "dev": true, "license": "MIT" }, + "node_modules/json-stable-stringify": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.1.1.tgz", + "integrity": "sha512-SU/971Kt5qVQfJpyDveVhQ/vya+5hvrjClFOcr8c0Fq5aODJjMwutrOfCU+eCnVD5gpx1Q3fEqkyom77zH1iIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "isarray": "^2.0.5", + "jsonify": "^0.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", @@ -3710,6 +3869,15 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsonify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", + "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/keyv": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", @@ -3720,6 +3888,15 @@ "json-buffer": "3.0.0" } }, + "node_modules/klaw-sync": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", + "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.11" + } + }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -5353,6 +5530,19 @@ ], "license": "MIT" }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/middleearth-names": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/middleearth-names/-/middleearth-names-1.1.0.tgz", @@ -6019,6 +6209,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -6045,6 +6244,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/open": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", + "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/opener": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", @@ -6314,6 +6529,132 @@ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "license": "MIT" }, + "node_modules/patch-package": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.0.0.tgz", + "integrity": "sha512-da8BVIhzjtgScwDJ2TtKsfT5JFWz1hYoBl9rUQ1f38MC2HwnEIkK8VN3dKMKcP7P7bvvgzNDbfNHtx3MsQb5vA==", + "dev": true, + "dependencies": { + "@yarnpkg/lockfile": "^1.1.0", + "chalk": "^4.1.2", + "ci-info": "^3.7.0", + "cross-spawn": "^7.0.3", + "find-yarn-workspace-root": "^2.0.0", + "fs-extra": "^9.0.0", + "json-stable-stringify": "^1.0.2", + "klaw-sync": "^6.0.0", + "minimist": "^1.2.6", + "open": "^7.4.2", + "rimraf": "^2.6.3", + "semver": "^7.5.3", + "slash": "^2.0.0", + "tmp": "^0.0.33", + "yaml": "^2.2.2" + }, + "bin": { + "patch-package": "index.js" + }, + "engines": { + "node": ">=14", + "npm": ">5" + } + }, + "node_modules/patch-package/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/patch-package/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/patch-package/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/patch-package/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/patch-package/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/patch-package/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/patch-package/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/patch-package/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -7066,6 +7407,23 @@ "dev": true, "license": "ISC" }, + "node_modules/set-function-length": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", + "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.2", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -7125,6 +7483,15 @@ "dev": true, "license": "MIT" }, + "node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/smpltmpl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/smpltmpl/-/smpltmpl-1.0.2.tgz", @@ -8200,11 +8567,10 @@ "license": "ISC" }, "node_modules/yaml": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.0.1.tgz", - "integrity": "sha512-1NpAYQ3wjzIlMs0mgdBmYzLkFgWBIWrzYVDYfrixhoFNNgJ444/jT2kUT2sicRbJES3oQYRZugjB6Ro8SjKeFg==", + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", + "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", "dev": true, - "license": "ISC", "engines": { "node": ">= 14" } @@ -8615,6 +8981,12 @@ "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", "dev": true }, + "@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true + }, "abab": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", @@ -8772,6 +9144,12 @@ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true + }, "babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", @@ -8974,13 +9352,15 @@ } }, "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.6.tgz", + "integrity": "sha512-Mj50FLHtlsoVfRfnHaZvyrooHcrlceNZdL/QBvJJVd9Ta55qCQK0gs4ss2oZDeV9zFCs6ewzYgVE5yfVmfFpVg==", "dev": true, "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.3", + "set-function-length": "^1.2.0" } }, "callsites": { @@ -9429,6 +9809,18 @@ "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", "dev": true }, + "define-data-property": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.2.tgz", + "integrity": "sha512-SRtsSqsDbgpJBbW3pABMCOt6rQyeM8s8RiyeSN8jYG8sYmt/kGJejbydttUsnDs1tadr19tvhT4ShwMyoqAm4g==", + "dev": true, + "requires": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.2", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.1" + } + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -9519,6 +9911,12 @@ "once": "^1.4.0" } }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -9911,6 +10309,15 @@ "path-exists": "^4.0.0" } }, + "find-yarn-workspace-root": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", + "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", + "dev": true, + "requires": { + "micromatch": "^4.0.2" + } + }, "flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", @@ -9991,9 +10398,9 @@ "optional": true }, "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true }, "functional-red-black-tree": { @@ -10015,14 +10422,16 @@ "dev": true }, "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" } }, "get-stream": { @@ -10107,6 +10516,15 @@ "type-fest": "^0.20.2" } }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3" + } + }, "got": { "version": "9.6.0", "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", @@ -10179,6 +10597,21 @@ "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==", "dev": true }, + "has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dev": true, + "requires": { + "get-intrinsic": "^1.2.2" + } + }, + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true + }, "has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", @@ -10191,6 +10624,15 @@ "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", "dev": true }, + "hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, + "requires": { + "function-bind": "^1.1.2" + } + }, "hast-to-hyperscript": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/hast-to-hyperscript/-/hast-to-hyperscript-10.0.1.tgz", @@ -10639,6 +11081,12 @@ "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", "dev": true }, + "is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true + }, "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", @@ -10763,12 +11211,27 @@ "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "requires": { + "is-docker": "^2.0.0" + } + }, "is-yarn-global": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", "dev": true }, + "isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -10872,6 +11335,18 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, + "json-stable-stringify": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.1.1.tgz", + "integrity": "sha512-SU/971Kt5qVQfJpyDveVhQ/vya+5hvrjClFOcr8c0Fq5aODJjMwutrOfCU+eCnVD5gpx1Q3fEqkyom77zH1iIg==", + "dev": true, + "requires": { + "call-bind": "^1.0.5", + "isarray": "^2.0.5", + "jsonify": "^0.0.1", + "object-keys": "^1.1.1" + } + }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", @@ -10887,6 +11362,12 @@ "graceful-fs": "^4.1.6" } }, + "jsonify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", + "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", + "dev": true + }, "keyv": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", @@ -10896,6 +11377,15 @@ "json-buffer": "3.0.0" } }, + "klaw-sync": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", + "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11" + } + }, "kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -11981,6 +12471,16 @@ "integrity": "sha512-DCfg/T8fcrhrRKTPjRrw/5LLvdGV7BHySf/1LOZx7TzWZdYRjogNtyNq885z3nNallwr3QUKARjqvHqX1/7t+w==", "dev": true }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, "middleearth-names": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/middleearth-names/-/middleearth-names-1.1.0.tgz", @@ -12451,6 +12951,12 @@ "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", "dev": true }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -12469,6 +12975,16 @@ "mimic-fn": "^2.1.0" } }, + "open": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", + "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "dev": true, + "requires": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + } + }, "opener": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", @@ -12653,6 +13169,98 @@ "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" }, + "patch-package": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.0.0.tgz", + "integrity": "sha512-da8BVIhzjtgScwDJ2TtKsfT5JFWz1hYoBl9rUQ1f38MC2HwnEIkK8VN3dKMKcP7P7bvvgzNDbfNHtx3MsQb5vA==", + "dev": true, + "requires": { + "@yarnpkg/lockfile": "^1.1.0", + "chalk": "^4.1.2", + "ci-info": "^3.7.0", + "cross-spawn": "^7.0.3", + "find-yarn-workspace-root": "^2.0.0", + "fs-extra": "^9.0.0", + "json-stable-stringify": "^1.0.2", + "klaw-sync": "^6.0.0", + "minimist": "^1.2.6", + "open": "^7.4.2", + "rimraf": "^2.6.3", + "semver": "^7.5.3", + "slash": "^2.0.0", + "tmp": "^0.0.33", + "yaml": "^2.2.2" + }, + "dependencies": { + "ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true + }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -13182,6 +13790,20 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, + "set-function-length": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", + "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", + "dev": true, + "requires": { + "define-data-property": "^1.1.2", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.1" + } + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -13226,6 +13848,12 @@ "integrity": "sha1-iJ5+NeaQ2JAQjvnznY81gtbX9OA=", "dev": true }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + }, "smpltmpl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/smpltmpl/-/smpltmpl-1.0.2.tgz", @@ -13959,9 +14587,9 @@ "dev": true }, "yaml": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.0.1.tgz", - "integrity": "sha512-1NpAYQ3wjzIlMs0mgdBmYzLkFgWBIWrzYVDYfrixhoFNNgJ444/jT2kUT2sicRbJES3oQYRZugjB6Ro8SjKeFg==", + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", + "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", "dev": true }, "yargs": { diff --git a/package.json b/package.json index 3e54be9..d05273f 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,8 @@ "test:tdd": "npm run test -- --watch", "test:tdd:exp": "npm run test:exp -- --watch", "dist": "rollup -c rollup.config.js", - "prepublishOnly": "npm run clean && npm run dist" + "prepublishOnly": "npm run clean && npm run dist", + "postinstall": "patch-package" }, "dependencies": { "acorn": "^8.7.0", @@ -65,6 +66,7 @@ "livereload": "^0.9.3", "mocha": "^9.2.2", "nodemon": "^2.0.15", + "patch-package": "^8.0.0", "prismjs": "^1.28.0", "rehype-autolink-headings": "^6.1.1", "rehype-raw": "^6.1.1", diff --git a/patches/escodegen+2.0.0.patch b/patches/escodegen+2.0.0.patch new file mode 100644 index 0000000..8073893 --- /dev/null +++ b/patches/escodegen+2.0.0.patch @@ -0,0 +1,4792 @@ +diff --git a/node_modules/escodegen/escodegen.js b/node_modules/escodegen/escodegen.js +index 847fc37..dfe80e3 100644 +--- a/node_modules/escodegen/escodegen.js ++++ b/node_modules/escodegen/escodegen.js +@@ -33,1219 +33,1376 @@ + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +-/*global exports:true, require:true, global:true*/ +-(function () { +- 'use strict'; +- +- var Syntax, +- Precedence, +- BinaryPrecedence, +- SourceNode, +- estraverse, +- esutils, +- base, +- indent, +- json, +- renumber, +- hexadecimal, +- quotes, +- escapeless, +- newline, +- space, +- parentheses, +- semicolons, +- safeConcatenation, +- directive, +- extra, +- parse, +- sourceMap, +- sourceCode, +- preserveBlankLines, +- FORMAT_MINIFY, +- FORMAT_DEFAULTS; +- +- estraverse = require('estraverse'); +- esutils = require('esutils'); +- +- Syntax = estraverse.Syntax; +- +- // Generation is done by generateExpression. +- function isExpression(node) { +- return CodeGenerator.Expression.hasOwnProperty(node.type); +- } +- +- // Generation is done by generateStatement. +- function isStatement(node) { +- return CodeGenerator.Statement.hasOwnProperty(node.type); +- } +- +- Precedence = { +- Sequence: 0, +- Yield: 1, +- 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, +- OptionalChaining: 16, +- Call: 17, +- New: 18, +- TaggedTemplate: 19, +- Member: 20, +- Primary: 21 ++import * as estraverse from 'estraverse'; ++import * as esutils from 'esutils'; ++// import packageJson from './package.json' assert { type: 'json' }; ++ ++var Syntax, ++ Precedence, ++ BinaryPrecedence, ++ SourceNode, ++ base, ++ indent, ++ json, ++ renumber, ++ hexadecimal, ++ quotes, ++ escapeless, ++ newline, ++ space, ++ parentheses, ++ semicolons, ++ safeConcatenation, ++ directive, ++ extra, ++ parse, ++ sourceMap, ++ sourceCode, ++ preserveBlankLines, ++ FORMAT_MINIFY, ++ FORMAT_DEFAULTS; ++ ++Syntax = estraverse.Syntax; ++ ++// Generation is done by generateExpression. ++function isExpression(node) { ++ return CodeGenerator.Expression.hasOwnProperty(node.type); ++} ++ ++// Generation is done by generateStatement. ++function isStatement(node) { ++ return CodeGenerator.Statement.hasOwnProperty(node.type); ++} ++ ++Precedence = { ++ Sequence: 0, ++ Yield: 1, ++ 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, ++ OptionalChaining: 16, ++ Call: 17, ++ New: 18, ++ TaggedTemplate: 19, ++ Member: 20, ++ Primary: 21 ++}; ++ ++BinaryPrecedence = { ++ '||': Precedence.LogicalOR, ++ '&&': Precedence.LogicalAND, ++ '|': Precedence.BitwiseOR, ++ '^': Precedence.BitwiseXOR, ++ '&': Precedence.BitwiseAND, ++ '==': Precedence.Equality, ++ '!=': Precedence.Equality, ++ '===': Precedence.Equality, ++ '!==': Precedence.Equality, ++ 'is': Precedence.Equality, ++ 'isnt': Precedence.Equality, ++ '<': Precedence.Relational, ++ '>': Precedence.Relational, ++ '<=': Precedence.Relational, ++ '>=': Precedence.Relational, ++ 'in': Precedence.Relational, ++ 'instanceof': Precedence.Relational, ++ '<<': Precedence.BitwiseSHIFT, ++ '>>': Precedence.BitwiseSHIFT, ++ '>>>': Precedence.BitwiseSHIFT, ++ '+': Precedence.Additive, ++ '-': Precedence.Additive, ++ '*': Precedence.Multiplicative, ++ '%': Precedence.Multiplicative, ++ '/': Precedence.Multiplicative, ++ '**': Precedence.Exponentiation ++}; ++ ++//Flags ++var F_ALLOW_IN = 1, ++ F_ALLOW_CALL = 1 << 1, ++ F_ALLOW_UNPARATH_NEW = 1 << 2, ++ F_FUNC_BODY = 1 << 3, ++ F_DIRECTIVE_CTX = 1 << 4, ++ F_SEMICOLON_OPT = 1 << 5; ++ ++//Expression flag sets ++//NOTE: Flag order: ++// F_ALLOW_IN ++// F_ALLOW_CALL ++// F_ALLOW_UNPARATH_NEW ++var E_FTT = F_ALLOW_CALL | F_ALLOW_UNPARATH_NEW, ++ E_TTF = F_ALLOW_IN | F_ALLOW_CALL, ++ E_TTT = F_ALLOW_IN | F_ALLOW_CALL | F_ALLOW_UNPARATH_NEW, ++ E_TFF = F_ALLOW_IN, ++ E_FFT = F_ALLOW_UNPARATH_NEW, ++ E_TFT = F_ALLOW_IN | F_ALLOW_UNPARATH_NEW; ++ ++//Statement flag sets ++//NOTE: Flag order: ++// F_ALLOW_IN ++// F_FUNC_BODY ++// F_DIRECTIVE_CTX ++// F_SEMICOLON_OPT ++var S_TFFF = F_ALLOW_IN, ++ S_TFFT = F_ALLOW_IN | F_SEMICOLON_OPT, ++ S_FFFF = 0x00, ++ S_TFTF = F_ALLOW_IN | F_DIRECTIVE_CTX, ++ S_TTFF = F_ALLOW_IN | F_FUNC_BODY; ++ ++function getDefaultOptions() { ++ // default options ++ return { ++ indent: null, ++ base: null, ++ parse: null, ++ comment: false, ++ format: { ++ indent: { ++ style: ' ', ++ base: 0, ++ adjustMultilineComment: false ++ }, ++ newline: '\n', ++ space: ' ', ++ json: false, ++ renumber: false, ++ hexadecimal: false, ++ quotes: 'single', ++ escapeless: false, ++ compact: false, ++ parentheses: true, ++ semicolons: true, ++ safeConcatenation: false, ++ preserveBlankLines: false ++ }, ++ moz: { ++ comprehensionExpressionStartsWithAssignment: false, ++ starlessGenerator: false ++ }, ++ sourceMap: null, ++ sourceMapRoot: null, ++ sourceMapWithCode: false, ++ directive: false, ++ raw: true, ++ verbatim: null, ++ sourceCode: null + }; ++} + +- BinaryPrecedence = { +- '||': Precedence.LogicalOR, +- '&&': Precedence.LogicalAND, +- '|': Precedence.BitwiseOR, +- '^': Precedence.BitwiseXOR, +- '&': Precedence.BitwiseAND, +- '==': Precedence.Equality, +- '!=': Precedence.Equality, +- '===': Precedence.Equality, +- '!==': Precedence.Equality, +- 'is': Precedence.Equality, +- 'isnt': Precedence.Equality, +- '<': Precedence.Relational, +- '>': Precedence.Relational, +- '<=': Precedence.Relational, +- '>=': Precedence.Relational, +- 'in': Precedence.Relational, +- 'instanceof': Precedence.Relational, +- '<<': Precedence.BitwiseSHIFT, +- '>>': Precedence.BitwiseSHIFT, +- '>>>': Precedence.BitwiseSHIFT, +- '+': Precedence.Additive, +- '-': Precedence.Additive, +- '*': Precedence.Multiplicative, +- '%': Precedence.Multiplicative, +- '/': Precedence.Multiplicative, +- '**': Precedence.Exponentiation +- }; ++function stringRepeat(str, num) { ++ var result = ''; + +- //Flags +- var F_ALLOW_IN = 1, +- F_ALLOW_CALL = 1 << 1, +- F_ALLOW_UNPARATH_NEW = 1 << 2, +- F_FUNC_BODY = 1 << 3, +- F_DIRECTIVE_CTX = 1 << 4, +- F_SEMICOLON_OPT = 1 << 5; +- +- //Expression flag sets +- //NOTE: Flag order: +- // F_ALLOW_IN +- // F_ALLOW_CALL +- // F_ALLOW_UNPARATH_NEW +- var E_FTT = F_ALLOW_CALL | F_ALLOW_UNPARATH_NEW, +- E_TTF = F_ALLOW_IN | F_ALLOW_CALL, +- E_TTT = F_ALLOW_IN | F_ALLOW_CALL | F_ALLOW_UNPARATH_NEW, +- E_TFF = F_ALLOW_IN, +- E_FFT = F_ALLOW_UNPARATH_NEW, +- E_TFT = F_ALLOW_IN | F_ALLOW_UNPARATH_NEW; +- +- //Statement flag sets +- //NOTE: Flag order: +- // F_ALLOW_IN +- // F_FUNC_BODY +- // F_DIRECTIVE_CTX +- // F_SEMICOLON_OPT +- var S_TFFF = F_ALLOW_IN, +- S_TFFT = F_ALLOW_IN | F_SEMICOLON_OPT, +- S_FFFF = 0x00, +- S_TFTF = F_ALLOW_IN | F_DIRECTIVE_CTX, +- S_TTFF = F_ALLOW_IN | F_FUNC_BODY; +- +- function getDefaultOptions() { +- // default options +- return { +- indent: null, +- base: null, +- parse: null, +- comment: false, +- format: { +- indent: { +- style: ' ', +- base: 0, +- adjustMultilineComment: false +- }, +- newline: '\n', +- space: ' ', +- json: false, +- renumber: false, +- hexadecimal: false, +- quotes: 'single', +- escapeless: false, +- compact: false, +- parentheses: true, +- semicolons: true, +- safeConcatenation: false, +- preserveBlankLines: false +- }, +- moz: { +- comprehensionExpressionStartsWithAssignment: false, +- starlessGenerator: false +- }, +- sourceMap: null, +- sourceMapRoot: null, +- sourceMapWithCode: false, +- directive: false, +- raw: true, +- verbatim: null, +- sourceCode: null +- }; +- } +- +- function stringRepeat(str, num) { +- var result = ''; +- +- for (num |= 0; num > 0; num >>>= 1, str += str) { +- if (num & 1) { +- result += str; +- } ++ for (num |= 0; num > 0; num >>>= 1, str += str) { ++ if (num & 1) { ++ result += str; + } +- +- return result; + } + +- function hasLineTerminator(str) { +- return (/[\r\n]/g).test(str); +- } ++ return result; ++} + +- function endsWithLineTerminator(str) { +- var len = str.length; +- return len && esutils.code.isLineTerminator(str.charCodeAt(len - 1)); +- } ++function hasLineTerminator(str) { ++ return (/[\r\n]/g).test(str); ++} + +- function merge(target, override) { +- var key; +- for (key in override) { +- if (override.hasOwnProperty(key)) { +- target[key] = override[key]; +- } ++function endsWithLineTerminator(str) { ++ var len = str.length; ++ return len && esutils.code.isLineTerminator(str.charCodeAt(len - 1)); ++} ++ ++function merge(target, override) { ++ var key; ++ for (key in override) { ++ if (override.hasOwnProperty(key)) { ++ target[key] = override[key]; + } +- return target; + } ++ return target; ++} + +- function updateDeeply(target, override) { +- var key, val; ++function updateDeeply(target, override) { ++ var key, val; + +- function isHashObject(target) { +- return typeof target === 'object' && target instanceof Object && !(target instanceof RegExp); +- } ++ function isHashObject(target) { ++ return typeof target === 'object' && target instanceof Object && !(target instanceof RegExp); ++ } + +- for (key in override) { +- if (override.hasOwnProperty(key)) { +- val = override[key]; +- if (isHashObject(val)) { +- if (isHashObject(target[key])) { +- updateDeeply(target[key], val); +- } else { +- target[key] = updateDeeply({}, val); +- } ++ for (key in override) { ++ if (override.hasOwnProperty(key)) { ++ val = override[key]; ++ if (isHashObject(val)) { ++ if (isHashObject(target[key])) { ++ updateDeeply(target[key], val); + } else { +- target[key] = val; ++ target[key] = updateDeeply({}, val); + } ++ } else { ++ target[key] = val; + } + } +- return target; + } ++ return target; ++} + +- function generateNumber(value) { +- var result, point, temp, exponent, pos; ++function generateNumber(value) { ++ var result, point, temp, exponent, pos; + +- if (value !== value) { +- throw new Error('Numeric literal whose value is NaN'); +- } +- if (value < 0 || (value === 0 && 1 / value < 0)) { +- throw new Error('Numeric literal whose value is negative'); +- } +- +- if (value === 1 / 0) { +- return json ? 'null' : renumber ? '1e400' : '1e+400'; +- } +- +- result = '' + value; +- if (!renumber || result.length < 3) { +- return result; +- } ++ if (value !== value) { ++ throw new Error('Numeric literal whose value is NaN'); ++ } ++ if (value < 0 || (value === 0 && 1 / value < 0)) { ++ throw new Error('Numeric literal whose value is negative'); ++ } + +- point = result.indexOf('.'); +- if (!json && result.charCodeAt(0) === 0x30 /* 0 */ && point === 1) { +- point = 0; +- result = result.slice(1); +- } +- temp = result; +- result = result.replace('e+', 'e'); +- exponent = 0; +- if ((pos = temp.indexOf('e')) > 0) { +- exponent = +temp.slice(pos + 1); +- temp = temp.slice(0, pos); +- } +- if (point >= 0) { +- exponent -= temp.length - point - 1; +- temp = +(temp.slice(0, point) + temp.slice(point + 1)) + ''; +- } +- pos = 0; +- while (temp.charCodeAt(temp.length + pos - 1) === 0x30 /* 0 */) { +- --pos; +- } +- if (pos !== 0) { +- exponent -= pos; +- temp = temp.slice(0, pos); +- } +- if (exponent !== 0) { +- temp += 'e' + exponent; +- } +- if ((temp.length < result.length || +- (hexadecimal && value > 1e12 && Math.floor(value) === value && (temp = '0x' + value.toString(16)).length < result.length)) && +- +temp === value) { +- result = temp; +- } ++ if (value === 1 / 0) { ++ return json ? 'null' : renumber ? '1e400' : '1e+400'; ++ } + ++ result = '' + value; ++ if (!renumber || result.length < 3) { + return result; + } + +- // Generate valid RegExp expression. +- // This function is based on https://github.com/Constellation/iv Engine ++ point = result.indexOf('.'); ++ if (!json && result.charCodeAt(0) === 0x30 /* 0 */ && point === 1) { ++ point = 0; ++ result = result.slice(1); ++ } ++ temp = result; ++ result = result.replace('e+', 'e'); ++ exponent = 0; ++ if ((pos = temp.indexOf('e')) > 0) { ++ exponent = +temp.slice(pos + 1); ++ temp = temp.slice(0, pos); ++ } ++ if (point >= 0) { ++ exponent -= temp.length - point - 1; ++ temp = +(temp.slice(0, point) + temp.slice(point + 1)) + ''; ++ } ++ pos = 0; ++ while (temp.charCodeAt(temp.length + pos - 1) === 0x30 /* 0 */) { ++ --pos; ++ } ++ if (pos !== 0) { ++ exponent -= pos; ++ temp = temp.slice(0, pos); ++ } ++ if (exponent !== 0) { ++ temp += 'e' + exponent; ++ } ++ if ((temp.length < result.length || ++ (hexadecimal && value > 1e12 && Math.floor(value) === value && (temp = '0x' + value.toString(16)).length < result.length)) && ++ +temp === value) { ++ result = temp; ++ } ++ ++ return result; ++} + +- function escapeRegExpCharacter(ch, previousIsBackslash) { +- // not handling '\' and handling \u2028 or \u2029 to unicode escape sequence +- if ((ch & ~1) === 0x2028) { +- return (previousIsBackslash ? 'u' : '\\u') + ((ch === 0x2028) ? '2028' : '2029'); +- } else if (ch === 10 || ch === 13) { // \n, \r +- return (previousIsBackslash ? '' : '\\') + ((ch === 10) ? 'n' : 'r'); +- } +- return String.fromCharCode(ch); ++// Generate valid RegExp expression. ++// This function is based on https://github.com/Constellation/iv Engine ++ ++function escapeRegExpCharacter(ch, previousIsBackslash) { ++ // not handling '\' and handling \u2028 or \u2029 to unicode escape sequence ++ if ((ch & ~1) === 0x2028) { ++ return (previousIsBackslash ? 'u' : '\\u') + ((ch === 0x2028) ? '2028' : '2029'); ++ } else if (ch === 10 || ch === 13) { // \n, \r ++ return (previousIsBackslash ? '' : '\\') + ((ch === 10) ? 'n' : 'r'); + } ++ return String.fromCharCode(ch); ++} + +- function generateRegExp(reg) { +- var match, result, flags, i, iz, ch, characterInBrack, previousIsBackslash; ++function generateRegExp(reg) { ++ var match, result, flags, i, iz, ch, characterInBrack, previousIsBackslash; + +- result = reg.toString(); ++ result = reg.toString(); + +- if (reg.source) { +- // extract flag from toString result +- match = result.match(/\/([^/]*)$/); +- if (!match) { +- return result; +- } ++ if (reg.source) { ++ // extract flag from toString result ++ match = result.match(/\/([^/]*)$/); ++ if (!match) { ++ return result; ++ } + +- flags = match[1]; +- result = ''; ++ flags = match[1]; ++ result = ''; + +- characterInBrack = false; +- previousIsBackslash = false; +- for (i = 0, iz = reg.source.length; i < iz; ++i) { +- ch = reg.source.charCodeAt(i); ++ characterInBrack = false; ++ previousIsBackslash = false; ++ for (i = 0, iz = reg.source.length; i < iz; ++i) { ++ ch = reg.source.charCodeAt(i); + +- if (!previousIsBackslash) { +- if (characterInBrack) { +- if (ch === 93) { // ] +- characterInBrack = false; +- } +- } else { +- if (ch === 47) { // / +- result += '\\'; +- } else if (ch === 91) { // [ +- characterInBrack = true; +- } ++ if (!previousIsBackslash) { ++ if (characterInBrack) { ++ if (ch === 93) { // ] ++ characterInBrack = false; + } +- result += escapeRegExpCharacter(ch, previousIsBackslash); +- previousIsBackslash = ch === 92; // \ + } else { +- // if new RegExp("\\\n') is provided, create /\n/ +- result += escapeRegExpCharacter(ch, previousIsBackslash); +- // prevent like /\\[/]/ +- previousIsBackslash = false; ++ if (ch === 47) { // / ++ result += '\\'; ++ } else if (ch === 91) { // [ ++ characterInBrack = true; ++ } + } ++ result += escapeRegExpCharacter(ch, previousIsBackslash); ++ previousIsBackslash = ch === 92; // \ ++ } else { ++ // if new RegExp("\\\n') is provided, create /\n/ ++ result += escapeRegExpCharacter(ch, previousIsBackslash); ++ // prevent like /\\[/]/ ++ previousIsBackslash = false; + } +- +- return '/' + result + '/' + flags; + } + +- return result; ++ return '/' + result + '/' + flags; + } + +- function escapeAllowedCharacter(code, next) { +- var hex; +- +- if (code === 0x08 /* \b */) { +- return '\\b'; +- } +- +- if (code === 0x0C /* \f */) { +- return '\\f'; +- } ++ return result; ++} + +- if (code === 0x09 /* \t */) { +- return '\\t'; +- } ++function escapeAllowedCharacter(code, next) { ++ var hex; + +- hex = code.toString(16).toUpperCase(); +- if (json || code > 0xFF) { +- return '\\u' + '0000'.slice(hex.length) + hex; +- } else if (code === 0x0000 && !esutils.code.isDecimalDigit(next)) { +- return '\\0'; +- } else if (code === 0x000B /* \v */) { // '\v' +- return '\\x0B'; +- } else { +- return '\\x' + '00'.slice(hex.length) + hex; +- } ++ if (code === 0x08 /* \b */) { ++ return '\\b'; + } + +- function escapeDisallowedCharacter(code) { +- if (code === 0x5C /* \ */) { +- return '\\\\'; +- } +- +- if (code === 0x0A /* \n */) { +- return '\\n'; +- } +- +- if (code === 0x0D /* \r */) { +- return '\\r'; +- } ++ if (code === 0x0C /* \f */) { ++ return '\\f'; ++ } + +- if (code === 0x2028) { +- return '\\u2028'; +- } ++ if (code === 0x09 /* \t */) { ++ return '\\t'; ++ } + +- if (code === 0x2029) { +- return '\\u2029'; +- } ++ hex = code.toString(16).toUpperCase(); ++ if (json || code > 0xFF) { ++ return '\\u' + '0000'.slice(hex.length) + hex; ++ } else if (code === 0x0000 && !esutils.code.isDecimalDigit(next)) { ++ return '\\0'; ++ } else if (code === 0x000B /* \v */) { // '\v' ++ return '\\x0B'; ++ } else { ++ return '\\x' + '00'.slice(hex.length) + hex; ++ } ++} + +- throw new Error('Incorrectly classified character'); ++function escapeDisallowedCharacter(code) { ++ if (code === 0x5C /* \ */) { ++ return '\\\\'; + } + +- function escapeDirective(str) { +- var i, iz, code, quote; ++ if (code === 0x0A /* \n */) { ++ return '\\n'; ++ } + +- quote = quotes === 'double' ? '"' : '\''; +- for (i = 0, iz = str.length; i < iz; ++i) { +- code = str.charCodeAt(i); +- if (code === 0x27 /* ' */) { +- quote = '"'; +- break; +- } else if (code === 0x22 /* " */) { +- quote = '\''; +- break; +- } else if (code === 0x5C /* \ */) { +- ++i; +- } +- } ++ if (code === 0x0D /* \r */) { ++ return '\\r'; ++ } + +- return quote + str + quote; ++ if (code === 0x2028) { ++ return '\\u2028'; + } + +- function escapeString(str) { +- var result = '', i, len, code, singleQuotes = 0, doubleQuotes = 0, single, quote; ++ if (code === 0x2029) { ++ return '\\u2029'; ++ } + +- for (i = 0, len = str.length; i < len; ++i) { +- code = str.charCodeAt(i); +- if (code === 0x27 /* ' */) { +- ++singleQuotes; +- } else if (code === 0x22 /* " */) { +- ++doubleQuotes; +- } else if (code === 0x2F /* / */ && json) { +- result += '\\'; +- } else if (esutils.code.isLineTerminator(code) || code === 0x5C /* \ */) { +- result += escapeDisallowedCharacter(code); +- continue; +- } else if (!esutils.code.isIdentifierPartES5(code) && (json && code < 0x20 /* SP */ || !json && !escapeless && (code < 0x20 /* SP */ || code > 0x7E /* ~ */))) { +- result += escapeAllowedCharacter(code, str.charCodeAt(i + 1)); +- continue; +- } +- result += String.fromCharCode(code); +- } ++ throw new Error('Incorrectly classified character'); ++} + +- single = !(quotes === 'double' || (quotes === 'auto' && doubleQuotes < singleQuotes)); +- quote = single ? '\'' : '"'; ++function escapeDirective(str) { ++ var i, iz, code, quote; + +- if (!(single ? singleQuotes : doubleQuotes)) { +- return quote + result + quote; ++ quote = quotes === 'double' ? '"' : '\''; ++ for (i = 0, iz = str.length; i < iz; ++i) { ++ code = str.charCodeAt(i); ++ if (code === 0x27 /* ' */) { ++ quote = '"'; ++ break; ++ } else if (code === 0x22 /* " */) { ++ quote = '\''; ++ break; ++ } else if (code === 0x5C /* \ */) { ++ ++i; + } ++ } + +- str = result; +- result = quote; ++ return quote + str + quote; ++} ++ ++function escapeString(str) { ++ var result = '', i, len, code, singleQuotes = 0, doubleQuotes = 0, single, quote; ++ ++ for (i = 0, len = str.length; i < len; ++i) { ++ code = str.charCodeAt(i); ++ if (code === 0x27 /* ' */) { ++ ++singleQuotes; ++ } else if (code === 0x22 /* " */) { ++ ++doubleQuotes; ++ } else if (code === 0x2F /* / */ && json) { ++ result += '\\'; ++ } else if (esutils.code.isLineTerminator(code) || code === 0x5C /* \ */) { ++ result += escapeDisallowedCharacter(code); ++ continue; ++ } else if (!esutils.code.isIdentifierPartES5(code) && (json && code < 0x20 /* SP */ || !json && !escapeless && (code < 0x20 /* SP */ || code > 0x7E /* ~ */))) { ++ result += escapeAllowedCharacter(code, str.charCodeAt(i + 1)); ++ continue; ++ } ++ result += String.fromCharCode(code); ++ } + +- for (i = 0, len = str.length; i < len; ++i) { +- code = str.charCodeAt(i); +- if ((code === 0x27 /* ' */ && single) || (code === 0x22 /* " */ && !single)) { +- result += '\\'; +- } +- result += String.fromCharCode(code); +- } ++ single = !(quotes === 'double' || (quotes === 'auto' && doubleQuotes < singleQuotes)); ++ quote = single ? '\'' : '"'; + +- return result + quote; ++ if (!(single ? singleQuotes : doubleQuotes)) { ++ return quote + result + quote; + } + +- /** +- * flatten an array to a string, where the array can contain +- * either strings or nested arrays +- */ +- function flattenToString(arr) { +- var i, iz, elem, result = ''; +- for (i = 0, iz = arr.length; i < iz; ++i) { +- elem = arr[i]; +- result += Array.isArray(elem) ? flattenToString(elem) : elem; ++ str = result; ++ result = quote; ++ ++ for (i = 0, len = str.length; i < len; ++i) { ++ code = str.charCodeAt(i); ++ if ((code === 0x27 /* ' */ && single) || (code === 0x22 /* " */ && !single)) { ++ result += '\\'; + } +- return result; ++ result += String.fromCharCode(code); + } + +- /** +- * convert generated to a SourceNode when source maps are enabled. +- */ +- function toSourceNodeWhenNeeded(generated, node) { +- if (!sourceMap) { +- // with no source maps, generated is either an +- // array or a string. if an array, flatten it. +- // if a string, just return it +- if (Array.isArray(generated)) { +- return flattenToString(generated); +- } else { +- return generated; +- } +- } +- if (node == null) { +- if (generated instanceof SourceNode) { +- return generated; +- } else { +- node = {}; +- } ++ return result + quote; ++} ++ ++/** ++ * flatten an array to a string, where the array can contain ++ * either strings or nested arrays ++ */ ++function flattenToString(arr) { ++ var i, iz, elem, result = ''; ++ for (i = 0, iz = arr.length; i < iz; ++i) { ++ elem = arr[i]; ++ result += Array.isArray(elem) ? flattenToString(elem) : elem; ++ } ++ return result; ++} ++ ++/** ++ * convert generated to a SourceNode when source maps are enabled. ++ */ ++function toSourceNodeWhenNeeded(generated, node) { ++ if (!sourceMap) { ++ // with no source maps, generated is either an ++ // array or a string. if an array, flatten it. ++ // if a string, just return it ++ if (Array.isArray(generated)) { ++ return flattenToString(generated); ++ } else { ++ return generated; + } +- if (node.loc == null) { +- return new SourceNode(null, null, sourceMap, generated, node.name || null); ++ } ++ if (node == null) { ++ if (generated instanceof SourceNode) { ++ return generated; ++ } else { ++ node = {}; + } +- return new SourceNode(node.loc.start.line, node.loc.start.column, (sourceMap === true ? node.loc.source || null : sourceMap), generated, node.name || null); ++ } ++ if (node.loc == null) { ++ return new SourceNode(null, null, sourceMap, generated, node.name || null); ++ } ++ return new SourceNode(node.loc.start.line, node.loc.start.column, (sourceMap === true ? node.loc.source || null : sourceMap), generated, node.name || null); ++} ++ ++function noEmptySpace() { ++ return (space) ? space : ' '; ++} ++ ++function join(left, right) { ++ var leftSource, ++ rightSource, ++ leftCharCode, ++ rightCharCode; ++ ++ leftSource = toSourceNodeWhenNeeded(left).toString(); ++ if (leftSource.length === 0) { ++ return [right]; + } + +- function noEmptySpace() { +- return (space) ? space : ' '; ++ rightSource = toSourceNodeWhenNeeded(right).toString(); ++ if (rightSource.length === 0) { ++ return [left]; + } + +- function join(left, right) { +- var leftSource, +- rightSource, +- leftCharCode, +- rightCharCode; ++ leftCharCode = leftSource.charCodeAt(leftSource.length - 1); ++ rightCharCode = rightSource.charCodeAt(0); + +- leftSource = toSourceNodeWhenNeeded(left).toString(); +- if (leftSource.length === 0) { +- return [right]; ++ if ((leftCharCode === 0x2B /* + */ || leftCharCode === 0x2D /* - */) && leftCharCode === rightCharCode || ++ esutils.code.isIdentifierPartES5(leftCharCode) && esutils.code.isIdentifierPartES5(rightCharCode) || ++ leftCharCode === 0x2F /* / */ && rightCharCode === 0x69 /* i */) { // infix word operators all start with `i` ++ return [left, noEmptySpace(), right]; ++ } else if (esutils.code.isWhiteSpace(leftCharCode) || esutils.code.isLineTerminator(leftCharCode) || ++ esutils.code.isWhiteSpace(rightCharCode) || esutils.code.isLineTerminator(rightCharCode)) { ++ return [left, right]; ++ } ++ return [left, space, right]; ++} ++ ++function addIndent(stmt) { ++ return [base, stmt]; ++} ++ ++function withIndent(fn) { ++ var previousBase; ++ previousBase = base; ++ base += indent; ++ fn(base); ++ base = previousBase; ++} ++ ++function calculateSpaces(str) { ++ var i; ++ for (i = str.length - 1; i >= 0; --i) { ++ if (esutils.code.isLineTerminator(str.charCodeAt(i))) { ++ break; + } ++ } ++ return (str.length - 1) - i; ++} + +- rightSource = toSourceNodeWhenNeeded(right).toString(); +- if (rightSource.length === 0) { +- return [left]; +- } ++function adjustMultilineComment(value, specialBase) { ++ var array, i, len, line, j, spaces, previousBase, sn; + +- leftCharCode = leftSource.charCodeAt(leftSource.length - 1); +- rightCharCode = rightSource.charCodeAt(0); ++ array = value.split(/\r\n|[\r\n]/); ++ spaces = Number.MAX_VALUE; + +- if ((leftCharCode === 0x2B /* + */ || leftCharCode === 0x2D /* - */) && leftCharCode === rightCharCode || +- esutils.code.isIdentifierPartES5(leftCharCode) && esutils.code.isIdentifierPartES5(rightCharCode) || +- leftCharCode === 0x2F /* / */ && rightCharCode === 0x69 /* i */) { // infix word operators all start with `i` +- return [left, noEmptySpace(), right]; +- } else if (esutils.code.isWhiteSpace(leftCharCode) || esutils.code.isLineTerminator(leftCharCode) || +- esutils.code.isWhiteSpace(rightCharCode) || esutils.code.isLineTerminator(rightCharCode)) { +- return [left, right]; ++ // first line doesn't have indentation ++ for (i = 1, len = array.length; i < len; ++i) { ++ line = array[i]; ++ j = 0; ++ while (j < line.length && esutils.code.isWhiteSpace(line.charCodeAt(j))) { ++ ++j; ++ } ++ if (spaces > j) { ++ spaces = j; + } +- return [left, space, right]; +- } +- +- function addIndent(stmt) { +- return [base, stmt]; + } + +- function withIndent(fn) { +- var previousBase; ++ if (typeof specialBase !== 'undefined') { ++ // pattern like ++ // { ++ // var t = 20; /* ++ // * this is comment ++ // */ ++ // } + previousBase = base; +- base += indent; +- fn(base); +- base = previousBase; +- } +- +- function calculateSpaces(str) { +- var i; +- for (i = str.length - 1; i >= 0; --i) { +- if (esutils.code.isLineTerminator(str.charCodeAt(i))) { +- break; +- } ++ if (array[1][spaces] === '*') { ++ specialBase += ' '; ++ } ++ base = specialBase; ++ } else { ++ if (spaces & 1) { ++ // /* ++ // * ++ // */ ++ // If spaces are odd number, above pattern is considered. ++ // We waste 1 space. ++ --spaces; + } +- return (str.length - 1) - i; ++ previousBase = base; + } + +- function adjustMultilineComment(value, specialBase) { +- var array, i, len, line, j, spaces, previousBase, sn; ++ for (i = 1, len = array.length; i < len; ++i) { ++ sn = toSourceNodeWhenNeeded(addIndent(array[i].slice(spaces))); ++ array[i] = sourceMap ? sn.join('') : sn; ++ } + +- array = value.split(/\r\n|[\r\n]/); +- spaces = Number.MAX_VALUE; ++ base = previousBase; + +- // first line doesn't have indentation +- for (i = 1, len = array.length; i < len; ++i) { +- line = array[i]; +- j = 0; +- while (j < line.length && esutils.code.isWhiteSpace(line.charCodeAt(j))) { +- ++j; +- } +- if (spaces > j) { +- spaces = j; +- } +- } ++ return array.join('\n'); ++} + +- if (typeof specialBase !== 'undefined') { +- // pattern like +- // { +- // var t = 20; /* +- // * this is comment +- // */ +- // } +- previousBase = base; +- if (array[1][spaces] === '*') { +- specialBase += ' '; +- } +- base = specialBase; ++function generateComment(comment, specialBase) { ++ if (comment.type === 'Line') { ++ if (endsWithLineTerminator(comment.value)) { ++ return '//' + comment.value; + } else { +- if (spaces & 1) { +- // /* +- // * +- // */ +- // If spaces are odd number, above pattern is considered. +- // We waste 1 space. +- --spaces; ++ // Always use LineTerminator ++ var result = '//' + comment.value; ++ if (!preserveBlankLines) { ++ result += '\n'; + } +- previousBase = base; ++ return result; + } ++ } ++ if (extra.format.indent.adjustMultilineComment && /[\n\r]/.test(comment.value)) { ++ return adjustMultilineComment('/*' + comment.value + '*/', specialBase); ++ } ++ return '/*' + comment.value + '*/'; ++} + +- for (i = 1, len = array.length; i < len; ++i) { +- sn = toSourceNodeWhenNeeded(addIndent(array[i].slice(spaces))); +- array[i] = sourceMap ? sn.join('') : sn; +- } ++function addComments(stmt, result) { ++ var i, len, comment, save, tailingToStatement, specialBase, fragment, ++ extRange, range, prevRange, prefix, infix, suffix, count; + +- base = previousBase; ++ if (stmt.leadingComments && stmt.leadingComments.length > 0) { ++ save = result; + +- return array.join('\n'); +- } ++ if (preserveBlankLines) { ++ comment = stmt.leadingComments[0]; ++ result = []; ++ ++ extRange = comment.extendedRange; ++ range = comment.range; + +- function generateComment(comment, specialBase) { +- if (comment.type === 'Line') { +- if (endsWithLineTerminator(comment.value)) { +- return '//' + comment.value; ++ prefix = sourceCode.substring(extRange[0], range[0]); ++ count = (prefix.match(/\n/g) || []).length; ++ if (count > 0) { ++ result.push(stringRepeat('\n', count)); ++ result.push(addIndent(generateComment(comment))); + } else { +- // Always use LineTerminator +- var result = '//' + comment.value; +- if (!preserveBlankLines) { +- result += '\n'; +- } +- return result; ++ result.push(prefix); ++ result.push(generateComment(comment)); + } +- } +- if (extra.format.indent.adjustMultilineComment && /[\n\r]/.test(comment.value)) { +- return adjustMultilineComment('/*' + comment.value + '*/', specialBase); +- } +- return '/*' + comment.value + '*/'; +- } +- +- function addComments(stmt, result) { +- var i, len, comment, save, tailingToStatement, specialBase, fragment, +- extRange, range, prevRange, prefix, infix, suffix, count; +- +- if (stmt.leadingComments && stmt.leadingComments.length > 0) { +- save = result; + +- if (preserveBlankLines) { +- comment = stmt.leadingComments[0]; +- result = []; ++ prevRange = range; + +- extRange = comment.extendedRange; ++ for (i = 1, len = stmt.leadingComments.length; i < len; i++) { ++ comment = stmt.leadingComments[i]; + range = comment.range; + +- prefix = sourceCode.substring(extRange[0], range[0]); +- count = (prefix.match(/\n/g) || []).length; +- if (count > 0) { +- result.push(stringRepeat('\n', count)); +- result.push(addIndent(generateComment(comment))); +- } else { +- result.push(prefix); +- result.push(generateComment(comment)); +- } ++ infix = sourceCode.substring(prevRange[1], range[0]); ++ count = (infix.match(/\n/g) || []).length; ++ result.push(stringRepeat('\n', count)); ++ result.push(addIndent(generateComment(comment))); + + prevRange = range; ++ } + +- for (i = 1, len = stmt.leadingComments.length; i < len; i++) { +- comment = stmt.leadingComments[i]; +- range = comment.range; +- +- infix = sourceCode.substring(prevRange[1], range[0]); +- count = (infix.match(/\n/g) || []).length; +- result.push(stringRepeat('\n', count)); +- result.push(addIndent(generateComment(comment))); +- +- prevRange = range; +- } +- +- suffix = sourceCode.substring(range[1], extRange[1]); +- count = (suffix.match(/\n/g) || []).length; +- result.push(stringRepeat('\n', count)); +- } else { +- comment = stmt.leadingComments[0]; +- result = []; +- if (safeConcatenation && stmt.type === Syntax.Program && stmt.body.length === 0) { +- result.push('\n'); +- } +- result.push(generateComment(comment)); +- if (!endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) { +- result.push('\n'); +- } ++ suffix = sourceCode.substring(range[1], extRange[1]); ++ count = (suffix.match(/\n/g) || []).length; ++ result.push(stringRepeat('\n', count)); ++ } else { ++ comment = stmt.leadingComments[0]; ++ result = []; ++ if (safeConcatenation && stmt.type === Syntax.Program && stmt.body.length === 0) { ++ result.push('\n'); ++ } ++ result.push(generateComment(comment)); ++ if (!endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) { ++ result.push('\n'); ++ } + +- for (i = 1, len = stmt.leadingComments.length; i < len; ++i) { +- comment = stmt.leadingComments[i]; +- fragment = [generateComment(comment)]; +- if (!endsWithLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) { +- fragment.push('\n'); +- } +- result.push(addIndent(fragment)); ++ for (i = 1, len = stmt.leadingComments.length; i < len; ++i) { ++ comment = stmt.leadingComments[i]; ++ fragment = [generateComment(comment)]; ++ if (!endsWithLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) { ++ fragment.push('\n'); + } ++ result.push(addIndent(fragment)); + } +- +- result.push(addIndent(save)); + } + +- if (stmt.trailingComments) { ++ result.push(addIndent(save)); ++ } + +- if (preserveBlankLines) { +- comment = stmt.trailingComments[0]; +- extRange = comment.extendedRange; +- range = comment.range; ++ if (stmt.trailingComments) { + +- prefix = sourceCode.substring(extRange[0], range[0]); +- count = (prefix.match(/\n/g) || []).length; ++ if (preserveBlankLines) { ++ comment = stmt.trailingComments[0]; ++ extRange = comment.extendedRange; ++ range = comment.range; + +- if (count > 0) { +- result.push(stringRepeat('\n', count)); +- result.push(addIndent(generateComment(comment))); +- } else { +- result.push(prefix); +- result.push(generateComment(comment)); +- } ++ prefix = sourceCode.substring(extRange[0], range[0]); ++ count = (prefix.match(/\n/g) || []).length; ++ ++ if (count > 0) { ++ result.push(stringRepeat('\n', count)); ++ result.push(addIndent(generateComment(comment))); + } else { +- tailingToStatement = !endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString()); +- specialBase = stringRepeat(' ', calculateSpaces(toSourceNodeWhenNeeded([base, result, indent]).toString())); +- for (i = 0, len = stmt.trailingComments.length; i < len; ++i) { +- comment = stmt.trailingComments[i]; +- if (tailingToStatement) { +- // We assume target like following script +- // +- // var t = 20; /** +- // * This is comment of t +- // */ +- if (i === 0) { +- // first case +- result = [result, indent]; +- } else { +- result = [result, specialBase]; +- } +- result.push(generateComment(comment, specialBase)); ++ result.push(prefix); ++ result.push(generateComment(comment)); ++ } ++ } else { ++ tailingToStatement = !endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString()); ++ specialBase = stringRepeat(' ', calculateSpaces(toSourceNodeWhenNeeded([base, result, indent]).toString())); ++ for (i = 0, len = stmt.trailingComments.length; i < len; ++i) { ++ comment = stmt.trailingComments[i]; ++ if (tailingToStatement) { ++ // We assume target like following script ++ // ++ // var t = 20; /** ++ // * This is comment of t ++ // */ ++ if (i === 0) { ++ // first case ++ result = [result, indent]; + } else { +- result = [result, addIndent(generateComment(comment))]; +- } +- if (i !== len - 1 && !endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) { +- result = [result, '\n']; ++ result = [result, specialBase]; + } ++ result.push(generateComment(comment, specialBase)); ++ } else { ++ result = [result, addIndent(generateComment(comment))]; ++ } ++ if (i !== len - 1 && !endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) { ++ result = [result, '\n']; + } + } + } +- +- return result; + } + +- function generateBlankLines(start, end, result) { +- var j, newlineCount = 0; ++ return result; ++} + +- for (j = start; j < end; j++) { +- if (sourceCode[j] === '\n') { +- newlineCount++; +- } +- } ++function generateBlankLines(start, end, result) { ++ var j, newlineCount = 0; + +- for (j = 1; j < newlineCount; j++) { +- result.push(newline); ++ for (j = start; j < end; j++) { ++ if (sourceCode[j] === '\n') { ++ newlineCount++; + } + } + +- function parenthesize(text, current, should) { +- if (current < should) { +- return ['(', text, ')']; +- } +- return text; ++ for (j = 1; j < newlineCount; j++) { ++ result.push(newline); + } ++} + +- function generateVerbatimString(string) { +- var i, iz, result; +- result = string.split(/\r\n|\n/); +- for (i = 1, iz = result.length; i < iz; i++) { +- result[i] = newline + base + result[i]; +- } +- return result; ++function parenthesize(text, current, should) { ++ if (current < should) { ++ return ['(', text, ')']; + } +- +- function generateVerbatim(expr, precedence) { +- var verbatim, result, prec; +- verbatim = expr[extra.verbatim]; +- +- if (typeof verbatim === 'string') { +- result = parenthesize(generateVerbatimString(verbatim), Precedence.Sequence, precedence); +- } else { +- // verbatim is object +- result = generateVerbatimString(verbatim.content); +- prec = (verbatim.precedence != null) ? verbatim.precedence : Precedence.Sequence; +- result = parenthesize(result, prec, precedence); +- } +- +- return toSourceNodeWhenNeeded(result, expr); ++ return text; ++} ++ ++function generateVerbatimString(string) { ++ var i, iz, result; ++ result = string.split(/\r\n|\n/); ++ for (i = 1, iz = result.length; i < iz; i++) { ++ result[i] = newline + base + result[i]; + } +- +- function CodeGenerator() { ++ return result; ++} ++ ++function generateVerbatim(expr, precedence) { ++ var verbatim, result, prec; ++ verbatim = expr[extra.verbatim]; ++ ++ if (typeof verbatim === 'string') { ++ result = parenthesize(generateVerbatimString(verbatim), Precedence.Sequence, precedence); ++ } else { ++ // verbatim is object ++ result = generateVerbatimString(verbatim.content); ++ prec = (verbatim.precedence != null) ? verbatim.precedence : Precedence.Sequence; ++ result = parenthesize(result, prec, precedence); + } + +- // Helpers. ++ return toSourceNodeWhenNeeded(result, expr); ++} + +- CodeGenerator.prototype.maybeBlock = function(stmt, flags) { +- var result, noLeadingComment, that = this; ++function CodeGenerator() { ++} + +- noLeadingComment = !extra.comment || !stmt.leadingComments; ++// Helpers. + +- if (stmt.type === Syntax.BlockStatement && noLeadingComment) { +- return [space, this.generateStatement(stmt, flags)]; +- } ++CodeGenerator.prototype.maybeBlock = function(stmt, flags) { ++ var result, noLeadingComment, that = this; + +- if (stmt.type === Syntax.EmptyStatement && noLeadingComment) { +- return ';'; +- } ++ noLeadingComment = !extra.comment || !stmt.leadingComments; + +- withIndent(function () { +- result = [ +- newline, +- addIndent(that.generateStatement(stmt, flags)) +- ]; +- }); ++ if (stmt.type === Syntax.BlockStatement && noLeadingComment) { ++ return [space, this.generateStatement(stmt, flags)]; ++ } + +- return result; +- }; ++ if (stmt.type === Syntax.EmptyStatement && noLeadingComment) { ++ return ';'; ++ } + +- CodeGenerator.prototype.maybeBlockSuffix = function (stmt, result) { +- var ends = endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString()); +- if (stmt.type === Syntax.BlockStatement && (!extra.comment || !stmt.leadingComments) && !ends) { +- return [result, space]; +- } +- if (ends) { +- return [result, base]; +- } +- return [result, newline, base]; +- }; ++ withIndent(function () { ++ result = [ ++ newline, ++ addIndent(that.generateStatement(stmt, flags)) ++ ]; ++ }); + +- function generateIdentifier(node) { +- return toSourceNodeWhenNeeded(node.name, node); +- } ++ return result; ++}; + +- function generateAsyncPrefix(node, spaceRequired) { +- return node.async ? 'async' + (spaceRequired ? noEmptySpace() : space) : ''; ++CodeGenerator.prototype.maybeBlockSuffix = function (stmt, result) { ++ var ends = endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString()); ++ if (stmt.type === Syntax.BlockStatement && (!extra.comment || !stmt.leadingComments) && !ends) { ++ return [result, space]; + } +- +- function generateStarSuffix(node) { +- var isGenerator = node.generator && !extra.moz.starlessGenerator; +- return isGenerator ? '*' + space : ''; ++ if (ends) { ++ return [result, base]; + } +- +- function generateMethodPrefix(prop) { +- var func = prop.value, prefix = ''; +- if (func.async) { +- prefix += generateAsyncPrefix(func, !prop.computed); +- } +- if (func.generator) { +- // avoid space before method name +- prefix += generateStarSuffix(func) ? '*' : ''; +- } +- return prefix; ++ return [result, newline, base]; ++}; ++ ++function generateIdentifier(node) { ++ return toSourceNodeWhenNeeded(node.name, node); ++} ++ ++function generateAsyncPrefix(node, spaceRequired) { ++ return node.async ? 'async' + (spaceRequired ? noEmptySpace() : space) : ''; ++} ++ ++function generateStarSuffix(node) { ++ var isGenerator = node.generator && !extra.moz.starlessGenerator; ++ return isGenerator ? '*' + space : ''; ++} ++ ++function generateMethodPrefix(prop) { ++ var func = prop.value, prefix = ''; ++ if (func.async) { ++ prefix += generateAsyncPrefix(func, !prop.computed); + } ++ if (func.generator) { ++ // avoid space before method name ++ prefix += generateStarSuffix(func) ? '*' : ''; ++ } ++ return prefix; ++} + +- CodeGenerator.prototype.generatePattern = function (node, precedence, flags) { +- if (node.type === Syntax.Identifier) { +- return generateIdentifier(node); +- } +- return this.generateExpression(node, precedence, flags); +- }; +- +- CodeGenerator.prototype.generateFunctionParams = function (node) { +- var i, iz, result, hasDefault; +- +- hasDefault = false; +- +- if (node.type === Syntax.ArrowFunctionExpression && +- !node.rest && (!node.defaults || node.defaults.length === 0) && +- node.params.length === 1 && node.params[0].type === Syntax.Identifier) { +- // arg => { } case +- result = [generateAsyncPrefix(node, true), generateIdentifier(node.params[0])]; +- } else { +- result = node.type === Syntax.ArrowFunctionExpression ? [generateAsyncPrefix(node, false)] : []; +- result.push('('); +- if (node.defaults) { +- hasDefault = true; ++CodeGenerator.prototype.generatePattern = function (node, precedence, flags) { ++ if (node.type === Syntax.Identifier) { ++ return generateIdentifier(node); ++ } ++ return this.generateExpression(node, precedence, flags); ++}; ++ ++CodeGenerator.prototype.generateFunctionParams = function (node) { ++ var i, iz, result, hasDefault; ++ ++ hasDefault = false; ++ ++ if (node.type === Syntax.ArrowFunctionExpression && ++ !node.rest && (!node.defaults || node.defaults.length === 0) && ++ node.params.length === 1 && node.params[0].type === Syntax.Identifier) { ++ // arg => { } case ++ result = [generateAsyncPrefix(node, true), generateIdentifier(node.params[0])]; ++ } else { ++ result = node.type === Syntax.ArrowFunctionExpression ? [generateAsyncPrefix(node, false)] : []; ++ result.push('('); ++ if (node.defaults) { ++ hasDefault = true; ++ } ++ for (i = 0, iz = node.params.length; i < iz; ++i) { ++ if (hasDefault && node.defaults[i]) { ++ // Handle default values. ++ result.push(this.generateAssignment(node.params[i], node.defaults[i], '=', Precedence.Assignment, E_TTT)); ++ } else { ++ result.push(this.generatePattern(node.params[i], Precedence.Assignment, E_TTT)); + } +- for (i = 0, iz = node.params.length; i < iz; ++i) { +- if (hasDefault && node.defaults[i]) { +- // Handle default values. +- result.push(this.generateAssignment(node.params[i], node.defaults[i], '=', Precedence.Assignment, E_TTT)); +- } else { +- result.push(this.generatePattern(node.params[i], Precedence.Assignment, E_TTT)); +- } +- if (i + 1 < iz) { +- result.push(',' + space); +- } ++ if (i + 1 < iz) { ++ result.push(',' + space); + } ++ } + +- if (node.rest) { +- if (node.params.length) { +- result.push(',' + space); +- } +- result.push('...'); +- result.push(generateIdentifier(node.rest)); ++ if (node.rest) { ++ if (node.params.length) { ++ result.push(',' + space); + } +- +- result.push(')'); ++ result.push('...'); ++ result.push(generateIdentifier(node.rest)); + } + +- return result; +- }; ++ result.push(')'); ++ } ++ ++ return result; ++}; + +- CodeGenerator.prototype.generateFunctionBody = function (node) { +- var result, expr; ++CodeGenerator.prototype.generateFunctionBody = function (node) { ++ var result, expr; + +- result = this.generateFunctionParams(node); ++ result = this.generateFunctionParams(node); ++ ++ if (node.type === Syntax.ArrowFunctionExpression) { ++ result.push(space); ++ result.push('=>'); ++ } + +- if (node.type === Syntax.ArrowFunctionExpression) { +- result.push(space); +- result.push('=>'); ++ if (node.expression) { ++ result.push(space); ++ expr = this.generateExpression(node.body, Precedence.Assignment, E_TTT); ++ if (expr.toString().charAt(0) === '{') { ++ expr = ['(', expr, ')']; + } ++ result.push(expr); ++ } else { ++ result.push(this.maybeBlock(node.body, S_TTFF)); ++ } + +- if (node.expression) { +- result.push(space); +- expr = this.generateExpression(node.body, Precedence.Assignment, E_TTT); +- if (expr.toString().charAt(0) === '{') { +- expr = ['(', expr, ')']; +- } +- result.push(expr); ++ return result; ++}; ++ ++CodeGenerator.prototype.generateIterationForStatement = function (operator, stmt, flags) { ++ var result = ['for' + (stmt.await ? noEmptySpace() + 'await' : '') + space + '('], that = this; ++ withIndent(function () { ++ if (stmt.left.type === Syntax.VariableDeclaration) { ++ withIndent(function () { ++ result.push(stmt.left.kind + noEmptySpace()); ++ result.push(that.generateStatement(stmt.left.declarations[0], S_FFFF)); ++ }); + } else { +- result.push(this.maybeBlock(node.body, S_TTFF)); ++ result.push(that.generateExpression(stmt.left, Precedence.Call, E_TTT)); + } + +- return result; +- }; ++ result = join(result, operator); ++ result = [join( ++ result, ++ that.generateExpression(stmt.right, Precedence.Assignment, E_TTT) ++ ), ')']; ++ }); ++ result.push(this.maybeBlock(stmt.body, flags)); ++ return result; ++}; + +- CodeGenerator.prototype.generateIterationForStatement = function (operator, stmt, flags) { +- var result = ['for' + (stmt.await ? noEmptySpace() + 'await' : '') + space + '('], that = this; +- withIndent(function () { +- if (stmt.left.type === Syntax.VariableDeclaration) { +- withIndent(function () { +- result.push(stmt.left.kind + noEmptySpace()); +- result.push(that.generateStatement(stmt.left.declarations[0], S_FFFF)); +- }); +- } else { +- result.push(that.generateExpression(stmt.left, Precedence.Call, E_TTT)); +- } ++CodeGenerator.prototype.generatePropertyKey = function (expr, computed) { ++ var result = []; + +- result = join(result, operator); +- result = [join( +- result, +- that.generateExpression(stmt.right, Precedence.Assignment, E_TTT) +- ), ')']; +- }); +- result.push(this.maybeBlock(stmt.body, flags)); +- return result; +- }; ++ if (computed) { ++ result.push('['); ++ } + +- CodeGenerator.prototype.generatePropertyKey = function (expr, computed) { +- var result = []; ++ result.push(this.generateExpression(expr, Precedence.Assignment, E_TTT)); + +- if (computed) { +- result.push('['); +- } ++ if (computed) { ++ result.push(']'); ++ } + +- result.push(this.generateExpression(expr, Precedence.Assignment, E_TTT)); ++ return result; ++}; + +- if (computed) { +- result.push(']'); +- } ++CodeGenerator.prototype.generateAssignment = function (left, right, operator, precedence, flags) { ++ if (Precedence.Assignment < precedence) { ++ flags |= F_ALLOW_IN; ++ } + +- return result; +- }; ++ return parenthesize( ++ [ ++ this.generateExpression(left, Precedence.Call, flags), ++ space + operator + space, ++ this.generateExpression(right, Precedence.Assignment, flags) ++ ], ++ Precedence.Assignment, ++ precedence ++ ); ++}; ++ ++CodeGenerator.prototype.semicolon = function (flags) { ++ if (!semicolons && flags & F_SEMICOLON_OPT) { ++ return ''; ++ } ++ return ';'; ++}; + +- CodeGenerator.prototype.generateAssignment = function (left, right, operator, precedence, flags) { +- if (Precedence.Assignment < precedence) { +- flags |= F_ALLOW_IN; +- } ++// Statements. + +- return parenthesize( +- [ +- this.generateExpression(left, Precedence.Call, flags), +- space + operator + space, +- this.generateExpression(right, Precedence.Assignment, flags) +- ], +- Precedence.Assignment, +- precedence +- ); +- }; ++CodeGenerator.Statement = { + +- CodeGenerator.prototype.semicolon = function (flags) { +- if (!semicolons && flags & F_SEMICOLON_OPT) { +- return ''; +- } +- return ';'; +- }; ++ BlockStatement: function (stmt, flags) { ++ var range, content, result = ['{', newline], that = this; + +- // Statements. +- +- CodeGenerator.Statement = { +- +- BlockStatement: function (stmt, flags) { +- var range, content, result = ['{', newline], that = this; +- +- withIndent(function () { +- // handle functions without any code +- if (stmt.body.length === 0 && preserveBlankLines) { +- range = stmt.range; +- if (range[1] - range[0] > 2) { +- content = sourceCode.substring(range[0] + 1, range[1] - 1); +- if (content[0] === '\n') { +- result = ['{']; +- } +- result.push(content); ++ withIndent(function () { ++ // handle functions without any code ++ if (stmt.body.length === 0 && preserveBlankLines) { ++ range = stmt.range; ++ if (range[1] - range[0] > 2) { ++ content = sourceCode.substring(range[0] + 1, range[1] - 1); ++ if (content[0] === '\n') { ++ result = ['{']; + } ++ result.push(content); + } ++ } + +- var i, iz, fragment, bodyFlags; +- bodyFlags = S_TFFF; +- if (flags & F_FUNC_BODY) { +- bodyFlags |= F_DIRECTIVE_CTX; +- } ++ var i, iz, fragment, bodyFlags; ++ bodyFlags = S_TFFF; ++ if (flags & F_FUNC_BODY) { ++ bodyFlags |= F_DIRECTIVE_CTX; ++ } + +- for (i = 0, iz = stmt.body.length; i < iz; ++i) { +- if (preserveBlankLines) { +- // handle spaces before the first line +- if (i === 0) { +- if (stmt.body[0].leadingComments) { +- range = stmt.body[0].leadingComments[0].extendedRange; +- content = sourceCode.substring(range[0], range[1]); +- if (content[0] === '\n') { +- result = ['{']; +- } +- } +- if (!stmt.body[0].leadingComments) { +- generateBlankLines(stmt.range[0], stmt.body[0].range[0], result); ++ for (i = 0, iz = stmt.body.length; i < iz; ++i) { ++ if (preserveBlankLines) { ++ // handle spaces before the first line ++ if (i === 0) { ++ if (stmt.body[0].leadingComments) { ++ range = stmt.body[0].leadingComments[0].extendedRange; ++ content = sourceCode.substring(range[0], range[1]); ++ if (content[0] === '\n') { ++ result = ['{']; + } + } +- +- // handle spaces between lines +- if (i > 0) { +- if (!stmt.body[i - 1].trailingComments && !stmt.body[i].leadingComments) { +- generateBlankLines(stmt.body[i - 1].range[1], stmt.body[i].range[0], result); +- } ++ if (!stmt.body[0].leadingComments) { ++ generateBlankLines(stmt.range[0], stmt.body[0].range[0], result); + } + } + +- if (i === iz - 1) { +- bodyFlags |= F_SEMICOLON_OPT; ++ // handle spaces between lines ++ if (i > 0) { ++ if (!stmt.body[i - 1].trailingComments && !stmt.body[i].leadingComments) { ++ generateBlankLines(stmt.body[i - 1].range[1], stmt.body[i].range[0], result); ++ } + } ++ } + +- if (stmt.body[i].leadingComments && preserveBlankLines) { +- fragment = that.generateStatement(stmt.body[i], bodyFlags); +- } else { +- fragment = addIndent(that.generateStatement(stmt.body[i], bodyFlags)); +- } ++ if (i === iz - 1) { ++ bodyFlags |= F_SEMICOLON_OPT; ++ } + +- result.push(fragment); +- if (!endsWithLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) { +- if (preserveBlankLines && i < iz - 1) { +- // don't add a new line if there are leading coments +- // in the next statement +- if (!stmt.body[i + 1].leadingComments) { +- result.push(newline); +- } +- } else { ++ if (stmt.body[i].leadingComments && preserveBlankLines) { ++ fragment = that.generateStatement(stmt.body[i], bodyFlags); ++ } else { ++ fragment = addIndent(that.generateStatement(stmt.body[i], bodyFlags)); ++ } ++ ++ result.push(fragment); ++ if (!endsWithLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) { ++ if (preserveBlankLines && i < iz - 1) { ++ // don't add a new line if there are leading coments ++ // in the next statement ++ if (!stmt.body[i + 1].leadingComments) { + result.push(newline); + } ++ } else { ++ result.push(newline); + } ++ } + +- if (preserveBlankLines) { +- // handle spaces after the last line +- if (i === iz - 1) { +- if (!stmt.body[i].trailingComments) { +- generateBlankLines(stmt.body[i].range[1], stmt.range[1], result); +- } ++ if (preserveBlankLines) { ++ // handle spaces after the last line ++ if (i === iz - 1) { ++ if (!stmt.body[i].trailingComments) { ++ generateBlankLines(stmt.body[i].range[1], stmt.range[1], result); + } + } + } +- }); ++ } ++ }); + +- result.push(addIndent('}')); +- return result; +- }, ++ result.push(addIndent('}')); ++ return result; ++ }, + +- BreakStatement: function (stmt, flags) { +- if (stmt.label) { +- return 'break ' + stmt.label.name + this.semicolon(flags); +- } +- return 'break' + this.semicolon(flags); +- }, ++ BreakStatement: function (stmt, flags) { ++ if (stmt.label) { ++ return 'break ' + stmt.label.name + this.semicolon(flags); ++ } ++ return 'break' + this.semicolon(flags); ++ }, + +- ContinueStatement: function (stmt, flags) { +- if (stmt.label) { +- return 'continue ' + stmt.label.name + this.semicolon(flags); +- } +- return 'continue' + this.semicolon(flags); +- }, ++ ContinueStatement: function (stmt, flags) { ++ if (stmt.label) { ++ return 'continue ' + stmt.label.name + this.semicolon(flags); ++ } ++ return 'continue' + this.semicolon(flags); ++ }, + +- ClassBody: function (stmt, flags) { +- var result = [ '{', newline], that = this; ++ ClassBody: function (stmt, flags) { ++ var result = [ '{', newline], that = this; + +- withIndent(function (indent) { +- var i, iz; ++ withIndent(function (indent) { ++ var i, iz; + +- for (i = 0, iz = stmt.body.length; i < iz; ++i) { +- result.push(indent); +- result.push(that.generateExpression(stmt.body[i], Precedence.Sequence, E_TTT)); +- if (i + 1 < iz) { +- result.push(newline); +- } ++ for (i = 0, iz = stmt.body.length; i < iz; ++i) { ++ result.push(indent); ++ result.push(that.generateExpression(stmt.body[i], Precedence.Sequence, E_TTT)); ++ if (i + 1 < iz) { ++ result.push(newline); + } +- }); +- +- if (!endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) { +- result.push(newline); + } +- result.push(base); +- result.push('}'); +- return result; +- }, ++ }); + +- ClassDeclaration: function (stmt, flags) { +- var result, fragment; +- result = ['class']; +- if (stmt.id) { +- result = join(result, this.generateExpression(stmt.id, Precedence.Sequence, E_TTT)); +- } +- if (stmt.superClass) { +- fragment = join('extends', this.generateExpression(stmt.superClass, Precedence.Unary, E_TTT)); +- result = join(result, fragment); +- } +- result.push(space); +- result.push(this.generateStatement(stmt.body, S_TFFT)); +- return result; +- }, ++ if (!endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) { ++ result.push(newline); ++ } ++ result.push(base); ++ result.push('}'); ++ return result; ++ }, ++ ++ ClassDeclaration: function (stmt, flags) { ++ var result, fragment; ++ result = ['class']; ++ if (stmt.id) { ++ result = join(result, this.generateExpression(stmt.id, Precedence.Sequence, E_TTT)); ++ } ++ if (stmt.superClass) { ++ fragment = join('extends', this.generateExpression(stmt.superClass, Precedence.Unary, E_TTT)); ++ result = join(result, fragment); ++ } ++ result.push(space); ++ result.push(this.generateStatement(stmt.body, S_TFFT)); ++ return result; ++ }, ++ ++ DirectiveStatement: function (stmt, flags) { ++ if (extra.raw && stmt.raw) { ++ return stmt.raw + this.semicolon(flags); ++ } ++ return escapeDirective(stmt.directive) + this.semicolon(flags); ++ }, ++ ++ DoWhileStatement: function (stmt, flags) { ++ // Because `do 42 while (cond)` is Syntax Error. We need semicolon. ++ var result = join('do', this.maybeBlock(stmt.body, S_TFFF)); ++ result = this.maybeBlockSuffix(stmt.body, result); ++ return join(result, [ ++ 'while' + space + '(', ++ this.generateExpression(stmt.test, Precedence.Sequence, E_TTT), ++ ')' + this.semicolon(flags) ++ ]); ++ }, ++ ++ CatchClause: function (stmt, flags) { ++ var result, that = this; ++ withIndent(function () { ++ var guard; ++ ++ if (stmt.param) { ++ result = [ ++ 'catch' + space + '(', ++ that.generateExpression(stmt.param, Precedence.Sequence, E_TTT), ++ ')' ++ ]; + +- DirectiveStatement: function (stmt, flags) { +- if (extra.raw && stmt.raw) { +- return stmt.raw + this.semicolon(flags); ++ if (stmt.guard) { ++ guard = that.generateExpression(stmt.guard, Precedence.Sequence, E_TTT); ++ result.splice(2, 0, ' if ', guard); ++ } ++ } else { ++ result = ['catch']; + } +- return escapeDirective(stmt.directive) + this.semicolon(flags); +- }, ++ }); ++ result.push(this.maybeBlock(stmt.body, S_TFFF)); ++ return result; ++ }, + +- DoWhileStatement: function (stmt, flags) { +- // Because `do 42 while (cond)` is Syntax Error. We need semicolon. +- var result = join('do', this.maybeBlock(stmt.body, S_TFFF)); +- result = this.maybeBlockSuffix(stmt.body, result); +- return join(result, [ +- 'while' + space + '(', +- this.generateExpression(stmt.test, Precedence.Sequence, E_TTT), +- ')' + this.semicolon(flags) +- ]); +- }, ++ DebuggerStatement: function (stmt, flags) { ++ return 'debugger' + this.semicolon(flags); ++ }, + +- CatchClause: function (stmt, flags) { +- var result, that = this; +- withIndent(function () { +- var guard; +- +- if (stmt.param) { +- result = [ +- 'catch' + space + '(', +- that.generateExpression(stmt.param, Precedence.Sequence, E_TTT), +- ')' +- ]; +- +- if (stmt.guard) { +- guard = that.generateExpression(stmt.guard, Precedence.Sequence, E_TTT); +- result.splice(2, 0, ' if ', guard); ++ EmptyStatement: function (stmt, flags) { ++ return ';'; ++ }, ++ ++ ExportDefaultDeclaration: function (stmt, flags) { ++ var result = [ 'export' ], bodyFlags; ++ ++ bodyFlags = (flags & F_SEMICOLON_OPT) ? S_TFFT : S_TFFF; ++ ++ // export default HoistableDeclaration[Default] ++ // export default AssignmentExpression[In] ; ++ result = join(result, 'default'); ++ if (isStatement(stmt.declaration)) { ++ result = join(result, this.generateStatement(stmt.declaration, bodyFlags)); ++ } else { ++ result = join(result, this.generateExpression(stmt.declaration, Precedence.Assignment, E_TTT) + this.semicolon(flags)); ++ } ++ return result; ++ }, ++ ++ ExportNamedDeclaration: function (stmt, flags) { ++ var result = [ 'export' ], bodyFlags, that = this; ++ ++ bodyFlags = (flags & F_SEMICOLON_OPT) ? S_TFFT : S_TFFF; ++ ++ // export VariableStatement ++ // export Declaration[Default] ++ if (stmt.declaration) { ++ return join(result, this.generateStatement(stmt.declaration, bodyFlags)); ++ } ++ ++ // export ExportClause[NoReference] FromClause ; ++ // export ExportClause ; ++ if (stmt.specifiers) { ++ if (stmt.specifiers.length === 0) { ++ result = join(result, '{' + space + '}'); ++ } else if (stmt.specifiers[0].type === Syntax.ExportBatchSpecifier) { ++ result = join(result, this.generateExpression(stmt.specifiers[0], Precedence.Sequence, E_TTT)); ++ } else { ++ result = join(result, '{'); ++ withIndent(function (indent) { ++ var i, iz; ++ result.push(newline); ++ for (i = 0, iz = stmt.specifiers.length; i < iz; ++i) { ++ result.push(indent); ++ result.push(that.generateExpression(stmt.specifiers[i], Precedence.Sequence, E_TTT)); ++ if (i + 1 < iz) { ++ result.push(',' + newline); ++ } + } +- } else { +- result = ['catch']; ++ }); ++ if (!endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) { ++ result.push(newline); + } +- }); +- result.push(this.maybeBlock(stmt.body, S_TFFF)); +- return result; +- }, ++ result.push(base + '}'); ++ } + +- DebuggerStatement: function (stmt, flags) { +- return 'debugger' + this.semicolon(flags); +- }, ++ if (stmt.source) { ++ result = join(result, [ ++ 'from' + space, ++ // ModuleSpecifier ++ this.generateExpression(stmt.source, Precedence.Sequence, E_TTT), ++ this.semicolon(flags) ++ ]); ++ } else { ++ result.push(this.semicolon(flags)); ++ } ++ } ++ return result; ++ }, + +- EmptyStatement: function (stmt, flags) { +- return ';'; +- }, ++ ExportAllDeclaration: function (stmt, flags) { ++ // export * FromClause ; ++ return [ ++ 'export' + space, ++ '*' + space, ++ 'from' + space, ++ // ModuleSpecifier ++ this.generateExpression(stmt.source, Precedence.Sequence, E_TTT), ++ this.semicolon(flags) ++ ]; ++ }, + +- ExportDefaultDeclaration: function (stmt, flags) { +- var result = [ 'export' ], bodyFlags; ++ ExpressionStatement: function (stmt, flags) { ++ var result, fragment; + +- bodyFlags = (flags & F_SEMICOLON_OPT) ? S_TFFT : S_TFFF; ++ function isClassPrefixed(fragment) { ++ var code; ++ if (fragment.slice(0, 5) !== 'class') { ++ return false; ++ } ++ code = fragment.charCodeAt(5); ++ return code === 0x7B /* '{' */ || esutils.code.isWhiteSpace(code) || esutils.code.isLineTerminator(code); ++ } + +- // export default HoistableDeclaration[Default] +- // export default AssignmentExpression[In] ; +- result = join(result, 'default'); +- if (isStatement(stmt.declaration)) { +- result = join(result, this.generateStatement(stmt.declaration, bodyFlags)); +- } else { +- result = join(result, this.generateExpression(stmt.declaration, Precedence.Assignment, E_TTT) + this.semicolon(flags)); ++ function isFunctionPrefixed(fragment) { ++ var code; ++ if (fragment.slice(0, 8) !== 'function') { ++ return false; + } +- return result; +- }, ++ code = fragment.charCodeAt(8); ++ return code === 0x28 /* '(' */ || esutils.code.isWhiteSpace(code) || code === 0x2A /* '*' */ || esutils.code.isLineTerminator(code); ++ } ++ ++ function isAsyncPrefixed(fragment) { ++ var code, i, iz; ++ if (fragment.slice(0, 5) !== 'async') { ++ return false; ++ } ++ if (!esutils.code.isWhiteSpace(fragment.charCodeAt(5))) { ++ return false; ++ } ++ for (i = 6, iz = fragment.length; i < iz; ++i) { ++ if (!esutils.code.isWhiteSpace(fragment.charCodeAt(i))) { ++ break; ++ } ++ } ++ if (i === iz) { ++ return false; ++ } ++ if (fragment.slice(i, i + 8) !== 'function') { ++ return false; ++ } ++ code = fragment.charCodeAt(i + 8); ++ return code === 0x28 /* '(' */ || esutils.code.isWhiteSpace(code) || code === 0x2A /* '*' */ || esutils.code.isLineTerminator(code); ++ } ++ ++ result = [this.generateExpression(stmt.expression, Precedence.Sequence, E_TTT)]; ++ // 12.4 '{', 'function', 'class' is not allowed in this position. ++ // wrap expression with parentheses ++ fragment = toSourceNodeWhenNeeded(result).toString(); ++ if (fragment.charCodeAt(0) === 0x7B /* '{' */ || // ObjectExpression ++ isClassPrefixed(fragment) || ++ isFunctionPrefixed(fragment) || ++ isAsyncPrefixed(fragment) || ++ (directive && (flags & F_DIRECTIVE_CTX) && stmt.expression.type === Syntax.Literal && typeof stmt.expression.value === 'string')) { ++ result = ['(', result, ')' + this.semicolon(flags)]; ++ } else { ++ result.push(this.semicolon(flags)); ++ } ++ return result; ++ }, ++ ++ ImportDeclaration: function (stmt, flags) { ++ // ES6: 15.2.1 valid import declarations: ++ // - import ImportClause FromClause ; ++ // - import ModuleSpecifier ; ++ var result, cursor, that = this; ++ ++ // If no ImportClause is present, ++ // this should be `import ModuleSpecifier` so skip `from` ++ // ModuleSpecifier is StringLiteral. ++ if (stmt.specifiers.length === 0) { ++ // import ModuleSpecifier ; ++ return [ ++ 'import', ++ space, ++ // ModuleSpecifier ++ this.generateExpression(stmt.source, Precedence.Sequence, E_TTT), ++ this.semicolon(flags) ++ ]; ++ } + +- ExportNamedDeclaration: function (stmt, flags) { +- var result = [ 'export' ], bodyFlags, that = this; ++ // import ImportClause FromClause ; ++ result = [ ++ 'import' ++ ]; ++ cursor = 0; + +- bodyFlags = (flags & F_SEMICOLON_OPT) ? S_TFFT : S_TFFF; ++ // ImportedBinding ++ if (stmt.specifiers[cursor].type === Syntax.ImportDefaultSpecifier) { ++ result = join(result, [ ++ this.generateExpression(stmt.specifiers[cursor], Precedence.Sequence, E_TTT) ++ ]); ++ ++cursor; ++ } + +- // export VariableStatement +- // export Declaration[Default] +- if (stmt.declaration) { +- return join(result, this.generateStatement(stmt.declaration, bodyFlags)); ++ if (stmt.specifiers[cursor]) { ++ if (cursor !== 0) { ++ result.push(','); + } + +- // export ExportClause[NoReference] FromClause ; +- // export ExportClause ; +- if (stmt.specifiers) { +- if (stmt.specifiers.length === 0) { +- result = join(result, '{' + space + '}'); +- } else if (stmt.specifiers[0].type === Syntax.ExportBatchSpecifier) { +- result = join(result, this.generateExpression(stmt.specifiers[0], Precedence.Sequence, E_TTT)); ++ if (stmt.specifiers[cursor].type === Syntax.ImportNamespaceSpecifier) { ++ // NameSpaceImport ++ result = join(result, [ ++ space, ++ this.generateExpression(stmt.specifiers[cursor], Precedence.Sequence, E_TTT) ++ ]); ++ } else { ++ // NamedImports ++ result.push(space + '{'); ++ ++ if ((stmt.specifiers.length - cursor) === 1) { ++ // import { ... } from "..."; ++ result.push(space); ++ result.push(this.generateExpression(stmt.specifiers[cursor], Precedence.Sequence, E_TTT)); ++ result.push(space + '}' + space); + } else { +- result = join(result, '{'); ++ // import { ++ // ..., ++ // ..., ++ // } from "..."; + withIndent(function (indent) { + var i, iz; + result.push(newline); +- for (i = 0, iz = stmt.specifiers.length; i < iz; ++i) { ++ for (i = cursor, iz = stmt.specifiers.length; i < iz; ++i) { + result.push(indent); + result.push(that.generateExpression(stmt.specifiers[i], Precedence.Sequence, E_TTT)); + if (i + 1 < iz) { +@@ -1256,1392 +1413,1244 @@ + if (!endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) { + result.push(newline); + } +- result.push(base + '}'); +- } +- +- if (stmt.source) { +- result = join(result, [ +- 'from' + space, +- // ModuleSpecifier +- this.generateExpression(stmt.source, Precedence.Sequence, E_TTT), +- this.semicolon(flags) +- ]); +- } else { +- result.push(this.semicolon(flags)); ++ result.push(base + '}' + space); + } + } +- return result; +- }, ++ } ++ ++ result = join(result, [ ++ 'from' + space, ++ // ModuleSpecifier ++ this.generateExpression(stmt.source, Precedence.Sequence, E_TTT), ++ this.semicolon(flags) ++ ]); ++ return result; ++ }, + +- ExportAllDeclaration: function (stmt, flags) { +- // export * FromClause ; ++ VariableDeclarator: function (stmt, flags) { ++ var itemFlags = (flags & F_ALLOW_IN) ? E_TTT : E_FTT; ++ if (stmt.init) { + return [ +- 'export' + space, +- '*' + space, +- 'from' + space, +- // ModuleSpecifier +- this.generateExpression(stmt.source, Precedence.Sequence, E_TTT), +- this.semicolon(flags) ++ this.generateExpression(stmt.id, Precedence.Assignment, itemFlags), ++ space, ++ '=', ++ space, ++ this.generateExpression(stmt.init, Precedence.Assignment, itemFlags) + ]; +- }, ++ } ++ return this.generatePattern(stmt.id, Precedence.Assignment, itemFlags); ++ }, + +- ExpressionStatement: function (stmt, flags) { +- var result, fragment; ++ VariableDeclaration: function (stmt, flags) { ++ // VariableDeclarator is typed as Statement, ++ // but joined with comma (not LineTerminator). ++ // So if comment is attached to target node, we should specialize. ++ var result, i, iz, node, bodyFlags, that = this; + +- function isClassPrefixed(fragment) { +- var code; +- if (fragment.slice(0, 5) !== 'class') { +- return false; +- } +- code = fragment.charCodeAt(5); +- return code === 0x7B /* '{' */ || esutils.code.isWhiteSpace(code) || esutils.code.isLineTerminator(code); ++ result = [ stmt.kind ]; ++ ++ bodyFlags = (flags & F_ALLOW_IN) ? S_TFFF : S_FFFF; ++ ++ function block() { ++ node = stmt.declarations[0]; ++ if (extra.comment && node.leadingComments) { ++ result.push('\n'); ++ result.push(addIndent(that.generateStatement(node, bodyFlags))); ++ } else { ++ result.push(noEmptySpace()); ++ result.push(that.generateStatement(node, bodyFlags)); + } + +- function isFunctionPrefixed(fragment) { +- var code; +- if (fragment.slice(0, 8) !== 'function') { +- return false; ++ for (i = 1, iz = stmt.declarations.length; i < iz; ++i) { ++ node = stmt.declarations[i]; ++ if (extra.comment && node.leadingComments) { ++ result.push(',' + newline); ++ result.push(addIndent(that.generateStatement(node, bodyFlags))); ++ } else { ++ result.push(',' + space); ++ result.push(that.generateStatement(node, bodyFlags)); + } +- code = fragment.charCodeAt(8); +- return code === 0x28 /* '(' */ || esutils.code.isWhiteSpace(code) || code === 0x2A /* '*' */ || esutils.code.isLineTerminator(code); + } ++ } ++ ++ if (stmt.declarations.length > 1) { ++ withIndent(block); ++ } else { ++ block(); ++ } + +- function isAsyncPrefixed(fragment) { +- var code, i, iz; +- if (fragment.slice(0, 5) !== 'async') { +- return false; ++ result.push(this.semicolon(flags)); ++ ++ return result; ++ }, ++ ++ ThrowStatement: function (stmt, flags) { ++ return [join( ++ 'throw', ++ this.generateExpression(stmt.argument, Precedence.Sequence, E_TTT) ++ ), this.semicolon(flags)]; ++ }, ++ ++ TryStatement: function (stmt, flags) { ++ var result, i, iz, guardedHandlers; ++ ++ result = ['try', this.maybeBlock(stmt.block, S_TFFF)]; ++ result = this.maybeBlockSuffix(stmt.block, result); ++ ++ if (stmt.handlers) { ++ // old interface ++ for (i = 0, iz = stmt.handlers.length; i < iz; ++i) { ++ result = join(result, this.generateStatement(stmt.handlers[i], S_TFFF)); ++ if (stmt.finalizer || i + 1 !== iz) { ++ result = this.maybeBlockSuffix(stmt.handlers[i].body, result); + } +- if (!esutils.code.isWhiteSpace(fragment.charCodeAt(5))) { +- return false; ++ } ++ } else { ++ guardedHandlers = stmt.guardedHandlers || []; ++ ++ for (i = 0, iz = guardedHandlers.length; i < iz; ++i) { ++ result = join(result, this.generateStatement(guardedHandlers[i], S_TFFF)); ++ if (stmt.finalizer || i + 1 !== iz) { ++ result = this.maybeBlockSuffix(guardedHandlers[i].body, result); + } +- for (i = 6, iz = fragment.length; i < iz; ++i) { +- if (!esutils.code.isWhiteSpace(fragment.charCodeAt(i))) { +- break; ++ } ++ ++ // new interface ++ if (stmt.handler) { ++ if (Array.isArray(stmt.handler)) { ++ for (i = 0, iz = stmt.handler.length; i < iz; ++i) { ++ result = join(result, this.generateStatement(stmt.handler[i], S_TFFF)); ++ if (stmt.finalizer || i + 1 !== iz) { ++ result = this.maybeBlockSuffix(stmt.handler[i].body, result); ++ } ++ } ++ } else { ++ result = join(result, this.generateStatement(stmt.handler, S_TFFF)); ++ if (stmt.finalizer) { ++ result = this.maybeBlockSuffix(stmt.handler.body, result); + } + } +- if (i === iz) { +- return false; ++ } ++ } ++ if (stmt.finalizer) { ++ result = join(result, ['finally', this.maybeBlock(stmt.finalizer, S_TFFF)]); ++ } ++ return result; ++ }, ++ ++ SwitchStatement: function (stmt, flags) { ++ var result, fragment, i, iz, bodyFlags, that = this; ++ withIndent(function () { ++ result = [ ++ 'switch' + space + '(', ++ that.generateExpression(stmt.discriminant, Precedence.Sequence, E_TTT), ++ ')' + space + '{' + newline ++ ]; ++ }); ++ if (stmt.cases) { ++ bodyFlags = S_TFFF; ++ for (i = 0, iz = stmt.cases.length; i < iz; ++i) { ++ if (i === iz - 1) { ++ bodyFlags |= F_SEMICOLON_OPT; + } +- if (fragment.slice(i, i + 8) !== 'function') { +- return false; ++ fragment = addIndent(this.generateStatement(stmt.cases[i], bodyFlags)); ++ result.push(fragment); ++ if (!endsWithLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) { ++ result.push(newline); + } +- code = fragment.charCodeAt(i + 8); +- return code === 0x28 /* '(' */ || esutils.code.isWhiteSpace(code) || code === 0x2A /* '*' */ || esutils.code.isLineTerminator(code); + } ++ } ++ result.push(addIndent('}')); ++ return result; ++ }, + +- result = [this.generateExpression(stmt.expression, Precedence.Sequence, E_TTT)]; +- // 12.4 '{', 'function', 'class' is not allowed in this position. +- // wrap expression with parentheses +- fragment = toSourceNodeWhenNeeded(result).toString(); +- if (fragment.charCodeAt(0) === 0x7B /* '{' */ || // ObjectExpression +- isClassPrefixed(fragment) || +- isFunctionPrefixed(fragment) || +- isAsyncPrefixed(fragment) || +- (directive && (flags & F_DIRECTIVE_CTX) && stmt.expression.type === Syntax.Literal && typeof stmt.expression.value === 'string')) { +- result = ['(', result, ')' + this.semicolon(flags)]; ++ SwitchCase: function (stmt, flags) { ++ var result, fragment, i, iz, bodyFlags, that = this; ++ withIndent(function () { ++ if (stmt.test) { ++ result = [ ++ join('case', that.generateExpression(stmt.test, Precedence.Sequence, E_TTT)), ++ ':' ++ ]; + } else { +- result.push(this.semicolon(flags)); ++ result = ['default:']; + } +- return result; +- }, +- +- ImportDeclaration: function (stmt, flags) { +- // ES6: 15.2.1 valid import declarations: +- // - import ImportClause FromClause ; +- // - import ModuleSpecifier ; +- var result, cursor, that = this; + +- // If no ImportClause is present, +- // this should be `import ModuleSpecifier` so skip `from` +- // ModuleSpecifier is StringLiteral. +- if (stmt.specifiers.length === 0) { +- // import ModuleSpecifier ; +- return [ +- 'import', +- space, +- // ModuleSpecifier +- this.generateExpression(stmt.source, Precedence.Sequence, E_TTT), +- this.semicolon(flags) +- ]; ++ i = 0; ++ iz = stmt.consequent.length; ++ if (iz && stmt.consequent[0].type === Syntax.BlockStatement) { ++ fragment = that.maybeBlock(stmt.consequent[0], S_TFFF); ++ result.push(fragment); ++ i = 1; + } + +- // import ImportClause FromClause ; +- result = [ +- 'import' +- ]; +- cursor = 0; +- +- // ImportedBinding +- if (stmt.specifiers[cursor].type === Syntax.ImportDefaultSpecifier) { +- result = join(result, [ +- this.generateExpression(stmt.specifiers[cursor], Precedence.Sequence, E_TTT) +- ]); +- ++cursor; ++ if (i !== iz && !endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) { ++ result.push(newline); + } + +- if (stmt.specifiers[cursor]) { +- if (cursor !== 0) { +- result.push(','); ++ bodyFlags = S_TFFF; ++ for (; i < iz; ++i) { ++ if (i === iz - 1 && flags & F_SEMICOLON_OPT) { ++ bodyFlags |= F_SEMICOLON_OPT; + } +- +- if (stmt.specifiers[cursor].type === Syntax.ImportNamespaceSpecifier) { +- // NameSpaceImport +- result = join(result, [ +- space, +- this.generateExpression(stmt.specifiers[cursor], Precedence.Sequence, E_TTT) +- ]); +- } else { +- // NamedImports +- result.push(space + '{'); +- +- if ((stmt.specifiers.length - cursor) === 1) { +- // import { ... } from "..."; +- result.push(space); +- result.push(this.generateExpression(stmt.specifiers[cursor], Precedence.Sequence, E_TTT)); +- result.push(space + '}' + space); +- } else { +- // import { +- // ..., +- // ..., +- // } from "..."; +- withIndent(function (indent) { +- var i, iz; +- result.push(newline); +- for (i = cursor, iz = stmt.specifiers.length; i < iz; ++i) { +- result.push(indent); +- result.push(that.generateExpression(stmt.specifiers[i], Precedence.Sequence, E_TTT)); +- if (i + 1 < iz) { +- result.push(',' + newline); +- } +- } +- }); +- if (!endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) { +- result.push(newline); +- } +- result.push(base + '}' + space); +- } ++ fragment = addIndent(that.generateStatement(stmt.consequent[i], bodyFlags)); ++ result.push(fragment); ++ if (i + 1 !== iz && !endsWithLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) { ++ result.push(newline); + } + } ++ }); ++ return result; ++ }, + +- result = join(result, [ +- 'from' + space, +- // ModuleSpecifier +- this.generateExpression(stmt.source, Precedence.Sequence, E_TTT), +- this.semicolon(flags) +- ]); +- return result; +- }, +- +- VariableDeclarator: function (stmt, flags) { +- var itemFlags = (flags & F_ALLOW_IN) ? E_TTT : E_FTT; +- if (stmt.init) { +- return [ +- this.generateExpression(stmt.id, Precedence.Assignment, itemFlags), +- space, +- '=', +- space, +- this.generateExpression(stmt.init, Precedence.Assignment, itemFlags) +- ]; ++ IfStatement: function (stmt, flags) { ++ var result, bodyFlags, semicolonOptional, that = this; ++ withIndent(function () { ++ result = [ ++ 'if' + space + '(', ++ that.generateExpression(stmt.test, Precedence.Sequence, E_TTT), ++ ')' ++ ]; ++ }); ++ semicolonOptional = flags & F_SEMICOLON_OPT; ++ bodyFlags = S_TFFF; ++ if (semicolonOptional) { ++ bodyFlags |= F_SEMICOLON_OPT; ++ } ++ if (stmt.alternate) { ++ result.push(this.maybeBlock(stmt.consequent, S_TFFF)); ++ result = this.maybeBlockSuffix(stmt.consequent, result); ++ if (stmt.alternate.type === Syntax.IfStatement) { ++ result = join(result, ['else ', this.generateStatement(stmt.alternate, bodyFlags)]); ++ } else { ++ result = join(result, join('else', this.maybeBlock(stmt.alternate, bodyFlags))); + } +- return this.generatePattern(stmt.id, Precedence.Assignment, itemFlags); +- }, +- +- VariableDeclaration: function (stmt, flags) { +- // VariableDeclarator is typed as Statement, +- // but joined with comma (not LineTerminator). +- // So if comment is attached to target node, we should specialize. +- var result, i, iz, node, bodyFlags, that = this; +- +- result = [ stmt.kind ]; +- +- bodyFlags = (flags & F_ALLOW_IN) ? S_TFFF : S_FFFF; ++ } else { ++ result.push(this.maybeBlock(stmt.consequent, bodyFlags)); ++ } ++ return result; ++ }, + +- function block() { +- node = stmt.declarations[0]; +- if (extra.comment && node.leadingComments) { +- result.push('\n'); +- result.push(addIndent(that.generateStatement(node, bodyFlags))); ++ ForStatement: function (stmt, flags) { ++ var result, that = this; ++ withIndent(function () { ++ result = ['for' + space + '(']; ++ if (stmt.init) { ++ if (stmt.init.type === Syntax.VariableDeclaration) { ++ result.push(that.generateStatement(stmt.init, S_FFFF)); + } else { +- result.push(noEmptySpace()); +- result.push(that.generateStatement(node, bodyFlags)); +- } +- +- for (i = 1, iz = stmt.declarations.length; i < iz; ++i) { +- node = stmt.declarations[i]; +- if (extra.comment && node.leadingComments) { +- result.push(',' + newline); +- result.push(addIndent(that.generateStatement(node, bodyFlags))); +- } else { +- result.push(',' + space); +- result.push(that.generateStatement(node, bodyFlags)); +- } ++ // F_ALLOW_IN becomes false. ++ result.push(that.generateExpression(stmt.init, Precedence.Sequence, E_FTT)); ++ result.push(';'); + } ++ } else { ++ result.push(';'); + } + +- if (stmt.declarations.length > 1) { +- withIndent(block); ++ if (stmt.test) { ++ result.push(space); ++ result.push(that.generateExpression(stmt.test, Precedence.Sequence, E_TTT)); ++ result.push(';'); + } else { +- block(); ++ result.push(';'); + } + +- result.push(this.semicolon(flags)); +- +- return result; +- }, +- +- ThrowStatement: function (stmt, flags) { +- return [join( +- 'throw', +- this.generateExpression(stmt.argument, Precedence.Sequence, E_TTT) +- ), this.semicolon(flags)]; +- }, +- +- TryStatement: function (stmt, flags) { +- var result, i, iz, guardedHandlers; +- +- result = ['try', this.maybeBlock(stmt.block, S_TFFF)]; +- result = this.maybeBlockSuffix(stmt.block, result); +- +- if (stmt.handlers) { +- // old interface +- for (i = 0, iz = stmt.handlers.length; i < iz; ++i) { +- result = join(result, this.generateStatement(stmt.handlers[i], S_TFFF)); +- if (stmt.finalizer || i + 1 !== iz) { +- result = this.maybeBlockSuffix(stmt.handlers[i].body, result); +- } +- } ++ if (stmt.update) { ++ result.push(space); ++ result.push(that.generateExpression(stmt.update, Precedence.Sequence, E_TTT)); ++ result.push(')'); + } else { +- guardedHandlers = stmt.guardedHandlers || []; ++ result.push(')'); ++ } ++ }); + +- for (i = 0, iz = guardedHandlers.length; i < iz; ++i) { +- result = join(result, this.generateStatement(guardedHandlers[i], S_TFFF)); +- if (stmt.finalizer || i + 1 !== iz) { +- result = this.maybeBlockSuffix(guardedHandlers[i].body, result); +- } +- } ++ result.push(this.maybeBlock(stmt.body, flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF)); ++ return result; ++ }, ++ ++ ForInStatement: function (stmt, flags) { ++ return this.generateIterationForStatement('in', stmt, flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF); ++ }, ++ ++ ForOfStatement: function (stmt, flags) { ++ return this.generateIterationForStatement('of', stmt, flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF); ++ }, ++ ++ LabeledStatement: function (stmt, flags) { ++ return [stmt.label.name + ':', this.maybeBlock(stmt.body, flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF)]; ++ }, ++ ++ Program: function (stmt, flags) { ++ var result, fragment, i, iz, bodyFlags; ++ iz = stmt.body.length; ++ result = [safeConcatenation && iz > 0 ? '\n' : '']; ++ bodyFlags = S_TFTF; ++ for (i = 0; i < iz; ++i) { ++ if (!safeConcatenation && i === iz - 1) { ++ bodyFlags |= F_SEMICOLON_OPT; ++ } + +- // new interface +- if (stmt.handler) { +- if (Array.isArray(stmt.handler)) { +- for (i = 0, iz = stmt.handler.length; i < iz; ++i) { +- result = join(result, this.generateStatement(stmt.handler[i], S_TFFF)); +- if (stmt.finalizer || i + 1 !== iz) { +- result = this.maybeBlockSuffix(stmt.handler[i].body, result); +- } +- } +- } else { +- result = join(result, this.generateStatement(stmt.handler, S_TFFF)); +- if (stmt.finalizer) { +- result = this.maybeBlockSuffix(stmt.handler.body, result); +- } ++ if (preserveBlankLines) { ++ // handle spaces before the first line ++ if (i === 0) { ++ if (!stmt.body[0].leadingComments) { ++ generateBlankLines(stmt.range[0], stmt.body[i].range[0], result); + } + } +- } +- if (stmt.finalizer) { +- result = join(result, ['finally', this.maybeBlock(stmt.finalizer, S_TFFF)]); +- } +- return result; +- }, + +- SwitchStatement: function (stmt, flags) { +- var result, fragment, i, iz, bodyFlags, that = this; +- withIndent(function () { +- result = [ +- 'switch' + space + '(', +- that.generateExpression(stmt.discriminant, Precedence.Sequence, E_TTT), +- ')' + space + '{' + newline +- ]; +- }); +- if (stmt.cases) { +- bodyFlags = S_TFFF; +- for (i = 0, iz = stmt.cases.length; i < iz; ++i) { +- if (i === iz - 1) { +- bodyFlags |= F_SEMICOLON_OPT; +- } +- fragment = addIndent(this.generateStatement(stmt.cases[i], bodyFlags)); +- result.push(fragment); +- if (!endsWithLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) { +- result.push(newline); ++ // handle spaces between lines ++ if (i > 0) { ++ if (!stmt.body[i - 1].trailingComments && !stmt.body[i].leadingComments) { ++ generateBlankLines(stmt.body[i - 1].range[1], stmt.body[i].range[0], result); + } + } + } +- result.push(addIndent('}')); +- return result; +- }, + +- SwitchCase: function (stmt, flags) { +- var result, fragment, i, iz, bodyFlags, that = this; +- withIndent(function () { +- if (stmt.test) { +- result = [ +- join('case', that.generateExpression(stmt.test, Precedence.Sequence, E_TTT)), +- ':' +- ]; +- } else { +- result = ['default:']; +- } +- +- i = 0; +- iz = stmt.consequent.length; +- if (iz && stmt.consequent[0].type === Syntax.BlockStatement) { +- fragment = that.maybeBlock(stmt.consequent[0], S_TFFF); +- result.push(fragment); +- i = 1; +- } +- +- if (i !== iz && !endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) { +- result.push(newline); +- } +- +- bodyFlags = S_TFFF; +- for (; i < iz; ++i) { +- if (i === iz - 1 && flags & F_SEMICOLON_OPT) { +- bodyFlags |= F_SEMICOLON_OPT; +- } +- fragment = addIndent(that.generateStatement(stmt.consequent[i], bodyFlags)); +- result.push(fragment); +- if (i + 1 !== iz && !endsWithLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) { ++ fragment = addIndent(this.generateStatement(stmt.body[i], bodyFlags)); ++ result.push(fragment); ++ if (i + 1 < iz && !endsWithLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) { ++ if (preserveBlankLines) { ++ if (!stmt.body[i + 1].leadingComments) { + result.push(newline); + } +- } +- }); +- return result; +- }, +- +- IfStatement: function (stmt, flags) { +- var result, bodyFlags, semicolonOptional, that = this; +- withIndent(function () { +- result = [ +- 'if' + space + '(', +- that.generateExpression(stmt.test, Precedence.Sequence, E_TTT), +- ')' +- ]; +- }); +- semicolonOptional = flags & F_SEMICOLON_OPT; +- bodyFlags = S_TFFF; +- if (semicolonOptional) { +- bodyFlags |= F_SEMICOLON_OPT; +- } +- if (stmt.alternate) { +- result.push(this.maybeBlock(stmt.consequent, S_TFFF)); +- result = this.maybeBlockSuffix(stmt.consequent, result); +- if (stmt.alternate.type === Syntax.IfStatement) { +- result = join(result, ['else ', this.generateStatement(stmt.alternate, bodyFlags)]); + } else { +- result = join(result, join('else', this.maybeBlock(stmt.alternate, bodyFlags))); ++ result.push(newline); + } +- } else { +- result.push(this.maybeBlock(stmt.consequent, bodyFlags)); + } +- return result; +- }, + +- ForStatement: function (stmt, flags) { +- var result, that = this; +- withIndent(function () { +- result = ['for' + space + '(']; +- if (stmt.init) { +- if (stmt.init.type === Syntax.VariableDeclaration) { +- result.push(that.generateStatement(stmt.init, S_FFFF)); +- } else { +- // F_ALLOW_IN becomes false. +- result.push(that.generateExpression(stmt.init, Precedence.Sequence, E_FTT)); +- result.push(';'); ++ if (preserveBlankLines) { ++ // handle spaces after the last line ++ if (i === iz - 1) { ++ if (!stmt.body[i].trailingComments) { ++ generateBlankLines(stmt.body[i].range[1], stmt.range[1], result); + } +- } else { +- result.push(';'); +- } +- +- if (stmt.test) { +- result.push(space); +- result.push(that.generateExpression(stmt.test, Precedence.Sequence, E_TTT)); +- result.push(';'); +- } else { +- result.push(';'); + } ++ } ++ } ++ return result; ++ }, ++ ++ FunctionDeclaration: function (stmt, flags) { ++ return [ ++ generateAsyncPrefix(stmt, true), ++ 'function', ++ generateStarSuffix(stmt) || noEmptySpace(), ++ stmt.id ? generateIdentifier(stmt.id) : '', ++ this.generateFunctionBody(stmt) ++ ]; ++ }, ++ ++ ReturnStatement: function (stmt, flags) { ++ if (stmt.argument) { ++ return [join( ++ 'return', ++ this.generateExpression(stmt.argument, Precedence.Sequence, E_TTT) ++ ), this.semicolon(flags)]; ++ } ++ return ['return' + this.semicolon(flags)]; ++ }, + +- if (stmt.update) { +- result.push(space); +- result.push(that.generateExpression(stmt.update, Precedence.Sequence, E_TTT)); +- result.push(')'); +- } else { +- result.push(')'); +- } +- }); ++ WhileStatement: function (stmt, flags) { ++ var result, that = this; ++ withIndent(function () { ++ result = [ ++ 'while' + space + '(', ++ that.generateExpression(stmt.test, Precedence.Sequence, E_TTT), ++ ')' ++ ]; ++ }); ++ result.push(this.maybeBlock(stmt.body, flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF)); ++ return result; ++ }, + +- result.push(this.maybeBlock(stmt.body, flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF)); +- return result; +- }, ++ WithStatement: function (stmt, flags) { ++ var result, that = this; ++ withIndent(function () { ++ result = [ ++ 'with' + space + '(', ++ that.generateExpression(stmt.object, Precedence.Sequence, E_TTT), ++ ')' ++ ]; ++ }); ++ result.push(this.maybeBlock(stmt.body, flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF)); ++ return result; ++ } + +- ForInStatement: function (stmt, flags) { +- return this.generateIterationForStatement('in', stmt, flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF); +- }, ++}; + +- ForOfStatement: function (stmt, flags) { +- return this.generateIterationForStatement('of', stmt, flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF); +- }, ++merge(CodeGenerator.prototype, CodeGenerator.Statement); + +- LabeledStatement: function (stmt, flags) { +- return [stmt.label.name + ':', this.maybeBlock(stmt.body, flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF)]; +- }, ++// Expressions. + +- Program: function (stmt, flags) { +- var result, fragment, i, iz, bodyFlags; +- iz = stmt.body.length; +- result = [safeConcatenation && iz > 0 ? '\n' : '']; +- bodyFlags = S_TFTF; +- for (i = 0; i < iz; ++i) { +- if (!safeConcatenation && i === iz - 1) { +- bodyFlags |= F_SEMICOLON_OPT; +- } ++CodeGenerator.Expression = { + +- if (preserveBlankLines) { +- // handle spaces before the first line +- if (i === 0) { +- if (!stmt.body[0].leadingComments) { +- generateBlankLines(stmt.range[0], stmt.body[i].range[0], result); +- } +- } +- +- // handle spaces between lines +- if (i > 0) { +- if (!stmt.body[i - 1].trailingComments && !stmt.body[i].leadingComments) { +- generateBlankLines(stmt.body[i - 1].range[1], stmt.body[i].range[0], result); +- } +- } +- } ++ SequenceExpression: function (expr, precedence, flags) { ++ var result, i, iz; ++ if (Precedence.Sequence < precedence) { ++ flags |= F_ALLOW_IN; ++ } ++ result = []; ++ for (i = 0, iz = expr.expressions.length; i < iz; ++i) { ++ result.push(this.generateExpression(expr.expressions[i], Precedence.Assignment, flags)); ++ if (i + 1 < iz) { ++ result.push(',' + space); ++ } ++ } ++ return parenthesize(result, Precedence.Sequence, precedence); ++ }, + +- fragment = addIndent(this.generateStatement(stmt.body[i], bodyFlags)); +- result.push(fragment); +- if (i + 1 < iz && !endsWithLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) { +- if (preserveBlankLines) { +- if (!stmt.body[i + 1].leadingComments) { +- result.push(newline); +- } +- } else { +- result.push(newline); +- } +- } ++ AssignmentExpression: function (expr, precedence, flags) { ++ return this.generateAssignment(expr.left, expr.right, expr.operator, precedence, flags); ++ }, + +- if (preserveBlankLines) { +- // handle spaces after the last line +- if (i === iz - 1) { +- if (!stmt.body[i].trailingComments) { +- generateBlankLines(stmt.body[i].range[1], stmt.range[1], result); +- } +- } +- } +- } +- return result; +- }, ++ ArrowFunctionExpression: function (expr, precedence, flags) { ++ return parenthesize(this.generateFunctionBody(expr), Precedence.ArrowFunction, precedence); ++ }, + +- FunctionDeclaration: function (stmt, flags) { +- return [ +- generateAsyncPrefix(stmt, true), +- 'function', +- generateStarSuffix(stmt) || noEmptySpace(), +- stmt.id ? generateIdentifier(stmt.id) : '', +- this.generateFunctionBody(stmt) +- ]; +- }, ++ ConditionalExpression: function (expr, precedence, flags) { ++ if (Precedence.Conditional < precedence) { ++ flags |= F_ALLOW_IN; ++ } ++ return parenthesize( ++ [ ++ this.generateExpression(expr.test, Precedence.LogicalOR, flags), ++ space + '?' + space, ++ this.generateExpression(expr.consequent, Precedence.Assignment, flags), ++ space + ':' + space, ++ this.generateExpression(expr.alternate, Precedence.Assignment, flags) ++ ], ++ Precedence.Conditional, ++ precedence ++ ); ++ }, + +- ReturnStatement: function (stmt, flags) { +- if (stmt.argument) { +- return [join( +- 'return', +- this.generateExpression(stmt.argument, Precedence.Sequence, E_TTT) +- ), this.semicolon(flags)]; +- } +- return ['return' + this.semicolon(flags)]; +- }, ++ LogicalExpression: function (expr, precedence, flags) { ++ return this.BinaryExpression(expr, precedence, flags); ++ }, + +- WhileStatement: function (stmt, flags) { +- var result, that = this; +- withIndent(function () { +- result = [ +- 'while' + space + '(', +- that.generateExpression(stmt.test, Precedence.Sequence, E_TTT), +- ')' +- ]; +- }); +- result.push(this.maybeBlock(stmt.body, flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF)); +- return result; +- }, ++ BinaryExpression: function (expr, precedence, flags) { ++ var result, leftPrecedence, rightPrecedence, currentPrecedence, fragment, leftSource; ++ currentPrecedence = BinaryPrecedence[expr.operator]; ++ leftPrecedence = expr.operator === '**' ? Precedence.Postfix : currentPrecedence; ++ rightPrecedence = expr.operator === '**' ? currentPrecedence : currentPrecedence + 1; + +- WithStatement: function (stmt, flags) { +- var result, that = this; +- withIndent(function () { +- result = [ +- 'with' + space + '(', +- that.generateExpression(stmt.object, Precedence.Sequence, E_TTT), +- ')' +- ]; +- }); +- result.push(this.maybeBlock(stmt.body, flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF)); +- return result; ++ if (currentPrecedence < precedence) { ++ flags |= F_ALLOW_IN; + } + +- }; ++ fragment = this.generateExpression(expr.left, leftPrecedence, flags); + +- merge(CodeGenerator.prototype, CodeGenerator.Statement); ++ leftSource = fragment.toString(); + +- // Expressions. ++ if (leftSource.charCodeAt(leftSource.length - 1) === 0x2F /* / */ && esutils.code.isIdentifierPartES5(expr.operator.charCodeAt(0))) { ++ result = [fragment, noEmptySpace(), expr.operator]; ++ } else { ++ result = join(fragment, expr.operator); ++ } + +- CodeGenerator.Expression = { ++ fragment = this.generateExpression(expr.right, rightPrecedence, flags); + +- SequenceExpression: function (expr, precedence, flags) { +- var result, i, iz; +- if (Precedence.Sequence < precedence) { +- flags |= F_ALLOW_IN; +- } +- result = []; +- for (i = 0, iz = expr.expressions.length; i < iz; ++i) { +- result.push(this.generateExpression(expr.expressions[i], Precedence.Assignment, flags)); +- if (i + 1 < iz) { +- result.push(',' + space); +- } +- } +- return parenthesize(result, Precedence.Sequence, precedence); +- }, +- +- AssignmentExpression: function (expr, precedence, flags) { +- return this.generateAssignment(expr.left, expr.right, expr.operator, precedence, flags); +- }, ++ if (expr.operator === '/' && fragment.toString().charAt(0) === '/' || ++ expr.operator.slice(-1) === '<' && fragment.toString().slice(0, 3) === '!--') { ++ // If '/' concats with '/' or `<` concats with `!--`, it is interpreted as comment start ++ result.push(noEmptySpace()); ++ result.push(fragment); ++ } else { ++ result = join(result, fragment); ++ } + +- ArrowFunctionExpression: function (expr, precedence, flags) { +- return parenthesize(this.generateFunctionBody(expr), Precedence.ArrowFunction, precedence); +- }, ++ if (expr.operator === 'in' && !(flags & F_ALLOW_IN)) { ++ return ['(', result, ')']; ++ } ++ return parenthesize(result, currentPrecedence, precedence); ++ }, + +- ConditionalExpression: function (expr, precedence, flags) { +- if (Precedence.Conditional < precedence) { +- flags |= F_ALLOW_IN; +- } +- return parenthesize( +- [ +- this.generateExpression(expr.test, Precedence.LogicalOR, flags), +- space + '?' + space, +- this.generateExpression(expr.consequent, Precedence.Assignment, flags), +- space + ':' + space, +- this.generateExpression(expr.alternate, Precedence.Assignment, flags) +- ], +- Precedence.Conditional, +- precedence +- ); +- }, ++ CallExpression: function (expr, precedence, flags) { ++ var result, i, iz; + +- LogicalExpression: function (expr, precedence, flags) { +- return this.BinaryExpression(expr, precedence, flags); +- }, ++ // F_ALLOW_UNPARATH_NEW becomes false. ++ result = [this.generateExpression(expr.callee, Precedence.Call, E_TTF)]; + +- BinaryExpression: function (expr, precedence, flags) { +- var result, leftPrecedence, rightPrecedence, currentPrecedence, fragment, leftSource; +- currentPrecedence = BinaryPrecedence[expr.operator]; +- leftPrecedence = expr.operator === '**' ? Precedence.Postfix : currentPrecedence; +- rightPrecedence = expr.operator === '**' ? currentPrecedence : currentPrecedence + 1; ++ if (expr.optional) { ++ result.push('?.'); ++ } + +- if (currentPrecedence < precedence) { +- flags |= F_ALLOW_IN; ++ result.push('('); ++ for (i = 0, iz = expr['arguments'].length; i < iz; ++i) { ++ result.push(this.generateExpression(expr['arguments'][i], Precedence.Assignment, E_TTT)); ++ if (i + 1 < iz) { ++ result.push(',' + space); + } ++ } ++ result.push(')'); + +- fragment = this.generateExpression(expr.left, leftPrecedence, flags); +- +- leftSource = fragment.toString(); ++ if (!(flags & F_ALLOW_CALL)) { ++ return ['(', result, ')']; ++ } + +- if (leftSource.charCodeAt(leftSource.length - 1) === 0x2F /* / */ && esutils.code.isIdentifierPartES5(expr.operator.charCodeAt(0))) { +- result = [fragment, noEmptySpace(), expr.operator]; +- } else { +- result = join(fragment, expr.operator); +- } ++ return parenthesize(result, Precedence.Call, precedence); ++ }, + +- fragment = this.generateExpression(expr.right, rightPrecedence, flags); ++ ChainExpression: function (expr, precedence, flags) { ++ if (Precedence.OptionalChaining < precedence) { ++ flags |= F_ALLOW_CALL; ++ } + +- if (expr.operator === '/' && fragment.toString().charAt(0) === '/' || +- expr.operator.slice(-1) === '<' && fragment.toString().slice(0, 3) === '!--') { +- // If '/' concats with '/' or `<` concats with `!--`, it is interpreted as comment start +- result.push(noEmptySpace()); +- result.push(fragment); +- } else { +- result = join(result, fragment); +- } ++ var result = this.generateExpression(expr.expression, Precedence.OptionalChaining, flags); + +- if (expr.operator === 'in' && !(flags & F_ALLOW_IN)) { +- return ['(', result, ')']; +- } +- return parenthesize(result, currentPrecedence, precedence); +- }, ++ return parenthesize(result, Precedence.OptionalChaining, precedence); ++ }, + +- CallExpression: function (expr, precedence, flags) { +- var result, i, iz; ++ NewExpression: function (expr, precedence, flags) { ++ var result, length, i, iz, itemFlags; ++ length = expr['arguments'].length; + +- // F_ALLOW_UNPARATH_NEW becomes false. +- result = [this.generateExpression(expr.callee, Precedence.Call, E_TTF)]; ++ // F_ALLOW_CALL becomes false. ++ // F_ALLOW_UNPARATH_NEW may become false. ++ itemFlags = (flags & F_ALLOW_UNPARATH_NEW && !parentheses && length === 0) ? E_TFT : E_TFF; + +- if (expr.optional) { +- result.push('?.'); +- } ++ result = join( ++ 'new', ++ this.generateExpression(expr.callee, Precedence.New, itemFlags) ++ ); + ++ if (!(flags & F_ALLOW_UNPARATH_NEW) || parentheses || length > 0) { + result.push('('); +- for (i = 0, iz = expr['arguments'].length; i < iz; ++i) { ++ for (i = 0, iz = length; i < iz; ++i) { + result.push(this.generateExpression(expr['arguments'][i], Precedence.Assignment, E_TTT)); + if (i + 1 < iz) { + result.push(',' + space); + } + } + result.push(')'); ++ } + +- if (!(flags & F_ALLOW_CALL)) { +- return ['(', result, ')']; +- } +- +- return parenthesize(result, Precedence.Call, precedence); +- }, +- +- ChainExpression: function (expr, precedence, flags) { +- if (Precedence.OptionalChaining < precedence) { +- flags |= F_ALLOW_CALL; +- } +- +- var result = this.generateExpression(expr.expression, Precedence.OptionalChaining, flags); +- +- return parenthesize(result, Precedence.OptionalChaining, precedence); +- }, +- +- NewExpression: function (expr, precedence, flags) { +- var result, length, i, iz, itemFlags; +- length = expr['arguments'].length; ++ return parenthesize(result, Precedence.New, precedence); ++ }, + +- // F_ALLOW_CALL becomes false. +- // F_ALLOW_UNPARATH_NEW may become false. +- itemFlags = (flags & F_ALLOW_UNPARATH_NEW && !parentheses && length === 0) ? E_TFT : E_TFF; ++ MemberExpression: function (expr, precedence, flags) { ++ var result, fragment; + +- result = join( +- 'new', +- this.generateExpression(expr.callee, Precedence.New, itemFlags) +- ); ++ // F_ALLOW_UNPARATH_NEW becomes false. ++ result = [this.generateExpression(expr.object, Precedence.Call, (flags & F_ALLOW_CALL) ? E_TTF : E_TFF)]; + +- if (!(flags & F_ALLOW_UNPARATH_NEW) || parentheses || length > 0) { +- result.push('('); +- for (i = 0, iz = length; i < iz; ++i) { +- result.push(this.generateExpression(expr['arguments'][i], Precedence.Assignment, E_TTT)); +- if (i + 1 < iz) { +- result.push(',' + space); +- } +- } +- result.push(')'); ++ if (expr.computed) { ++ if (expr.optional) { ++ result.push('?.'); + } + +- return parenthesize(result, Precedence.New, precedence); +- }, +- +- MemberExpression: function (expr, precedence, flags) { +- var result, fragment; +- +- // F_ALLOW_UNPARATH_NEW becomes false. +- 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.optional && expr.object.type === Syntax.Literal && typeof expr.object.value === 'number') { +- fragment = toSourceNodeWhenNeeded(result).toString(); +- // When the following conditions are all true, +- // 1. No floating point +- // 2. Don't have exponents +- // 3. The last character is a decimal digit +- // 4. Not hexadecimal OR octal number literal +- // we should add a floating point. +- if ( +- fragment.indexOf('.') < 0 && +- !/[eExX]/.test(fragment) && +- esutils.code.isDecimalDigit(fragment.charCodeAt(fragment.length - 1)) && +- !(fragment.length >= 2 && fragment.charCodeAt(0) === 48) // '0' +- ) { +- 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.optional && expr.object.type === Syntax.Literal && typeof expr.object.value === 'number') { ++ fragment = toSourceNodeWhenNeeded(result).toString(); ++ // When the following conditions are all true, ++ // 1. No floating point ++ // 2. Don't have exponents ++ // 3. The last character is a decimal digit ++ // 4. Not hexadecimal OR octal number literal ++ // we should add a floating point. ++ if ( ++ fragment.indexOf('.') < 0 && ++ !/[eExX]/.test(fragment) && ++ esutils.code.isDecimalDigit(fragment.charCodeAt(fragment.length - 1)) && ++ !(fragment.length >= 2 && fragment.charCodeAt(0) === 48) // '0' ++ ) { ++ result.push(' '); + } +- result.push(expr.optional ? '?.' : '.'); +- result.push(generateIdentifier(expr.property)); + } ++ result.push(expr.optional ? '?.' : '.'); ++ result.push(generateIdentifier(expr.property)); ++ } + +- return parenthesize(result, Precedence.Member, precedence); +- }, ++ return parenthesize(result, Precedence.Member, precedence); ++ }, + +- MetaProperty: function (expr, precedence, flags) { +- var result; +- result = []; +- result.push(typeof expr.meta === "string" ? expr.meta : generateIdentifier(expr.meta)); +- result.push('.'); +- result.push(typeof expr.property === "string" ? expr.property : generateIdentifier(expr.property)); +- return parenthesize(result, Precedence.Member, precedence); +- }, ++ MetaProperty: function (expr, precedence, flags) { ++ var result; ++ result = []; ++ result.push(typeof expr.meta === "string" ? expr.meta : generateIdentifier(expr.meta)); ++ result.push('.'); ++ result.push(typeof expr.property === "string" ? expr.property : generateIdentifier(expr.property)); ++ return parenthesize(result, Precedence.Member, precedence); ++ }, + +- UnaryExpression: function (expr, precedence, flags) { +- var result, fragment, rightCharCode, leftSource, leftCharCode; +- fragment = this.generateExpression(expr.argument, Precedence.Unary, E_TTT); ++ UnaryExpression: function (expr, precedence, flags) { ++ var result, fragment, rightCharCode, leftSource, leftCharCode; ++ fragment = this.generateExpression(expr.argument, Precedence.Unary, E_TTT); + +- if (space === '') { +- result = join(expr.operator, fragment); ++ if (space === '') { ++ result = join(expr.operator, fragment); ++ } else { ++ result = [expr.operator]; ++ if (expr.operator.length > 2) { ++ // delete, void, typeof ++ // get `typeof []`, not `typeof[]` ++ result = join(result, fragment); + } else { +- result = [expr.operator]; +- if (expr.operator.length > 2) { +- // delete, void, typeof +- // get `typeof []`, not `typeof[]` +- result = join(result, fragment); ++ // Prevent inserting spaces between operator and argument if it is unnecessary ++ // like, `!cond` ++ leftSource = toSourceNodeWhenNeeded(result).toString(); ++ leftCharCode = leftSource.charCodeAt(leftSource.length - 1); ++ rightCharCode = fragment.toString().charCodeAt(0); ++ ++ if (((leftCharCode === 0x2B /* + */ || leftCharCode === 0x2D /* - */) && leftCharCode === rightCharCode) || ++ (esutils.code.isIdentifierPartES5(leftCharCode) && esutils.code.isIdentifierPartES5(rightCharCode))) { ++ result.push(noEmptySpace()); ++ result.push(fragment); + } else { +- // Prevent inserting spaces between operator and argument if it is unnecessary +- // like, `!cond` +- leftSource = toSourceNodeWhenNeeded(result).toString(); +- leftCharCode = leftSource.charCodeAt(leftSource.length - 1); +- rightCharCode = fragment.toString().charCodeAt(0); +- +- if (((leftCharCode === 0x2B /* + */ || leftCharCode === 0x2D /* - */) && leftCharCode === rightCharCode) || +- (esutils.code.isIdentifierPartES5(leftCharCode) && esutils.code.isIdentifierPartES5(rightCharCode))) { +- result.push(noEmptySpace()); +- result.push(fragment); +- } else { +- result.push(fragment); +- } ++ result.push(fragment); + } + } +- return parenthesize(result, Precedence.Unary, precedence); +- }, +- +- YieldExpression: function (expr, precedence, flags) { +- var result; +- if (expr.delegate) { +- result = 'yield*'; +- } else { +- result = 'yield'; +- } +- if (expr.argument) { +- result = join( +- result, +- this.generateExpression(expr.argument, Precedence.Yield, E_TTT) +- ); +- } +- return parenthesize(result, Precedence.Yield, precedence); +- }, ++ } ++ return parenthesize(result, Precedence.Unary, precedence); ++ }, + +- AwaitExpression: function (expr, precedence, flags) { +- var result = join( +- expr.all ? 'await*' : 'await', +- this.generateExpression(expr.argument, Precedence.Await, E_TTT) ++ YieldExpression: function (expr, precedence, flags) { ++ var result; ++ if (expr.delegate) { ++ result = 'yield*'; ++ } else { ++ result = 'yield'; ++ } ++ if (expr.argument) { ++ result = join( ++ result, ++ this.generateExpression(expr.argument, Precedence.Yield, E_TTT) + ); +- return parenthesize(result, Precedence.Await, precedence); +- }, ++ } ++ return parenthesize(result, Precedence.Yield, precedence); ++ }, + +- UpdateExpression: function (expr, precedence, flags) { +- if (expr.prefix) { +- return parenthesize( +- [ +- expr.operator, +- this.generateExpression(expr.argument, Precedence.Unary, E_TTT) +- ], +- Precedence.Unary, +- precedence +- ); +- } ++ AwaitExpression: function (expr, precedence, flags) { ++ var result = join( ++ expr.all ? 'await*' : 'await', ++ this.generateExpression(expr.argument, Precedence.Await, E_TTT) ++ ); ++ return parenthesize(result, Precedence.Await, precedence); ++ }, ++ ++ UpdateExpression: function (expr, precedence, flags) { ++ if (expr.prefix) { + return parenthesize( + [ +- this.generateExpression(expr.argument, Precedence.Postfix, E_TTT), +- expr.operator ++ expr.operator, ++ this.generateExpression(expr.argument, Precedence.Unary, E_TTT) + ], +- Precedence.Postfix, ++ Precedence.Unary, + precedence + ); +- }, +- +- FunctionExpression: function (expr, precedence, flags) { +- var result = [ +- generateAsyncPrefix(expr, true), +- 'function' +- ]; +- if (expr.id) { +- result.push(generateStarSuffix(expr) || noEmptySpace()); +- result.push(generateIdentifier(expr.id)); +- } else { +- result.push(generateStarSuffix(expr) || space); +- } +- result.push(this.generateFunctionBody(expr)); +- return result; +- }, +- +- ArrayPattern: function (expr, precedence, flags) { +- return this.ArrayExpression(expr, precedence, flags, true); +- }, +- +- ArrayExpression: function (expr, precedence, flags, isPattern) { +- var result, multiline, that = this; +- if (!expr.elements.length) { +- return '[]'; +- } +- multiline = isPattern ? false : expr.elements.length > 1; +- result = ['[', multiline ? newline : '']; +- withIndent(function (indent) { +- var i, iz; +- for (i = 0, iz = expr.elements.length; i < iz; ++i) { +- if (!expr.elements[i]) { +- if (multiline) { +- result.push(indent); +- } +- if (i + 1 === iz) { +- result.push(','); +- } +- } else { +- result.push(multiline ? indent : ''); +- result.push(that.generateExpression(expr.elements[i], Precedence.Assignment, E_TTT)); ++ } ++ return parenthesize( ++ [ ++ this.generateExpression(expr.argument, Precedence.Postfix, E_TTT), ++ expr.operator ++ ], ++ Precedence.Postfix, ++ precedence ++ ); ++ }, ++ ++ FunctionExpression: function (expr, precedence, flags) { ++ var result = [ ++ generateAsyncPrefix(expr, true), ++ 'function' ++ ]; ++ if (expr.id) { ++ result.push(generateStarSuffix(expr) || noEmptySpace()); ++ result.push(generateIdentifier(expr.id)); ++ } else { ++ result.push(generateStarSuffix(expr) || space); ++ } ++ result.push(this.generateFunctionBody(expr)); ++ return result; ++ }, ++ ++ ArrayPattern: function (expr, precedence, flags) { ++ return this.ArrayExpression(expr, precedence, flags, true); ++ }, ++ ++ ArrayExpression: function (expr, precedence, flags, isPattern) { ++ var result, multiline, that = this; ++ if (!expr.elements.length) { ++ return '[]'; ++ } ++ multiline = isPattern ? false : expr.elements.length > 1; ++ result = ['[', multiline ? newline : '']; ++ withIndent(function (indent) { ++ var i, iz; ++ for (i = 0, iz = expr.elements.length; i < iz; ++i) { ++ if (!expr.elements[i]) { ++ if (multiline) { ++ result.push(indent); + } +- if (i + 1 < iz) { +- result.push(',' + (multiline ? newline : space)); ++ if (i + 1 === iz) { ++ result.push(','); + } ++ } else { ++ result.push(multiline ? indent : ''); ++ result.push(that.generateExpression(expr.elements[i], Precedence.Assignment, E_TTT)); ++ } ++ if (i + 1 < iz) { ++ result.push(',' + (multiline ? newline : space)); + } +- }); +- if (multiline && !endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) { +- result.push(newline); + } +- result.push(multiline ? base : ''); +- result.push(']'); +- return result; +- }, +- +- RestElement: function(expr, precedence, flags) { +- return '...' + this.generatePattern(expr.argument); +- }, ++ }); ++ if (multiline && !endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) { ++ result.push(newline); ++ } ++ result.push(multiline ? base : ''); ++ result.push(']'); ++ return result; ++ }, + +- ClassExpression: function (expr, precedence, flags) { +- var result, fragment; +- result = ['class']; +- if (expr.id) { +- result = join(result, this.generateExpression(expr.id, Precedence.Sequence, E_TTT)); +- } +- if (expr.superClass) { +- fragment = join('extends', this.generateExpression(expr.superClass, Precedence.Unary, E_TTT)); +- result = join(result, fragment); +- } +- result.push(space); +- result.push(this.generateStatement(expr.body, S_TFFT)); +- return result; +- }, ++ RestElement: function(expr, precedence, flags) { ++ return '...' + this.generatePattern(expr.argument); ++ }, + +- MethodDefinition: function (expr, precedence, flags) { +- var result, fragment; +- if (expr['static']) { +- result = ['static' + space]; +- } else { +- result = []; +- } +- if (expr.kind === 'get' || expr.kind === 'set') { +- fragment = [ +- join(expr.kind, this.generatePropertyKey(expr.key, expr.computed)), +- this.generateFunctionBody(expr.value) +- ]; +- } else { +- fragment = [ +- generateMethodPrefix(expr), +- this.generatePropertyKey(expr.key, expr.computed), +- this.generateFunctionBody(expr.value) +- ]; +- } +- return join(result, fragment); +- }, ++ ClassExpression: function (expr, precedence, flags) { ++ var result, fragment; ++ result = ['class']; ++ if (expr.id) { ++ result = join(result, this.generateExpression(expr.id, Precedence.Sequence, E_TTT)); ++ } ++ if (expr.superClass) { ++ fragment = join('extends', this.generateExpression(expr.superClass, Precedence.Unary, E_TTT)); ++ result = join(result, fragment); ++ } ++ result.push(space); ++ result.push(this.generateStatement(expr.body, S_TFFT)); ++ return result; ++ }, + +- Property: function (expr, precedence, flags) { +- if (expr.kind === 'get' || expr.kind === 'set') { +- return [ +- expr.kind, noEmptySpace(), +- this.generatePropertyKey(expr.key, expr.computed), +- this.generateFunctionBody(expr.value) +- ]; +- } ++ MethodDefinition: function (expr, precedence, flags) { ++ var result, fragment; ++ if (expr['static']) { ++ result = ['static' + space]; ++ } else { ++ result = []; ++ } ++ if (expr.kind === 'get' || expr.kind === 'set') { ++ fragment = [ ++ join(expr.kind, this.generatePropertyKey(expr.key, expr.computed)), ++ this.generateFunctionBody(expr.value) ++ ]; ++ } else { ++ fragment = [ ++ generateMethodPrefix(expr), ++ this.generatePropertyKey(expr.key, expr.computed), ++ this.generateFunctionBody(expr.value) ++ ]; ++ } ++ return join(result, fragment); ++ }, + +- if (expr.shorthand) { +- if (expr.value.type === "AssignmentPattern") { +- return this.AssignmentPattern(expr.value, Precedence.Sequence, E_TTT); +- } +- return this.generatePropertyKey(expr.key, expr.computed); +- } ++ Property: function (expr, precedence, flags) { ++ if (expr.kind === 'get' || expr.kind === 'set') { ++ return [ ++ expr.kind, noEmptySpace(), ++ this.generatePropertyKey(expr.key, expr.computed), ++ this.generateFunctionBody(expr.value) ++ ]; ++ } + +- if (expr.method) { +- return [ +- generateMethodPrefix(expr), +- this.generatePropertyKey(expr.key, expr.computed), +- this.generateFunctionBody(expr.value) +- ]; ++ if (expr.shorthand) { ++ if (expr.value.type === "AssignmentPattern") { ++ return this.AssignmentPattern(expr.value, Precedence.Sequence, E_TTT); + } ++ return this.generatePropertyKey(expr.key, expr.computed); ++ } + ++ if (expr.method) { + return [ ++ generateMethodPrefix(expr), + this.generatePropertyKey(expr.key, expr.computed), +- ':' + space, +- this.generateExpression(expr.value, Precedence.Assignment, E_TTT) ++ this.generateFunctionBody(expr.value) + ]; +- }, ++ } + +- ObjectExpression: function (expr, precedence, flags) { +- var multiline, result, fragment, that = this; ++ return [ ++ this.generatePropertyKey(expr.key, expr.computed), ++ ':' + space, ++ this.generateExpression(expr.value, Precedence.Assignment, E_TTT) ++ ]; ++ }, + +- if (!expr.properties.length) { +- return '{}'; +- } +- multiline = expr.properties.length > 1; ++ ObjectExpression: function (expr, precedence, flags) { ++ var multiline, result, fragment, that = this; + +- withIndent(function () { +- fragment = that.generateExpression(expr.properties[0], Precedence.Sequence, E_TTT); +- }); ++ if (!expr.properties.length) { ++ return '{}'; ++ } ++ multiline = expr.properties.length > 1; + +- if (!multiline) { +- // issues 4 +- // Do not transform from +- // dejavu.Class.declare({ +- // method2: function () {} +- // }); +- // to +- // dejavu.Class.declare({method2: function () { +- // }}); +- if (!hasLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) { +- return [ '{', space, fragment, space, '}' ]; +- } ++ withIndent(function () { ++ fragment = that.generateExpression(expr.properties[0], Precedence.Sequence, E_TTT); ++ }); ++ ++ if (!multiline) { ++ // issues 4 ++ // Do not transform from ++ // dejavu.Class.declare({ ++ // method2: function () {} ++ // }); ++ // to ++ // dejavu.Class.declare({method2: function () { ++ // }}); ++ if (!hasLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) { ++ return [ '{', space, fragment, space, '}' ]; + } ++ } + +- withIndent(function (indent) { +- var i, iz; +- result = [ '{', newline, indent, fragment ]; ++ withIndent(function (indent) { ++ var i, iz; ++ result = [ '{', newline, indent, fragment ]; + +- if (multiline) { +- result.push(',' + newline); +- for (i = 1, iz = expr.properties.length; i < iz; ++i) { +- result.push(indent); +- result.push(that.generateExpression(expr.properties[i], Precedence.Sequence, E_TTT)); +- if (i + 1 < iz) { +- result.push(',' + newline); +- } ++ if (multiline) { ++ result.push(',' + newline); ++ for (i = 1, iz = expr.properties.length; i < iz; ++i) { ++ result.push(indent); ++ result.push(that.generateExpression(expr.properties[i], Precedence.Sequence, E_TTT)); ++ if (i + 1 < iz) { ++ result.push(',' + newline); + } + } +- }); +- +- if (!endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) { +- result.push(newline); + } +- result.push(base); +- result.push('}'); +- return result; +- }, ++ }); + +- AssignmentPattern: function(expr, precedence, flags) { +- return this.generateAssignment(expr.left, expr.right, '=', precedence, flags); +- }, ++ if (!endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) { ++ result.push(newline); ++ } ++ result.push(base); ++ result.push('}'); ++ return result; ++ }, + +- ObjectPattern: function (expr, precedence, flags) { +- var result, i, iz, multiline, property, that = this; +- if (!expr.properties.length) { +- return '{}'; +- } ++ AssignmentPattern: function(expr, precedence, flags) { ++ return this.generateAssignment(expr.left, expr.right, '=', precedence, flags); ++ }, ++ ++ ObjectPattern: function (expr, precedence, flags) { ++ var result, i, iz, multiline, property, that = this; ++ if (!expr.properties.length) { ++ return '{}'; ++ } + +- multiline = false; +- if (expr.properties.length === 1) { +- property = expr.properties[0]; ++ multiline = false; ++ if (expr.properties.length === 1) { ++ property = expr.properties[0]; ++ if ( ++ property.type === Syntax.Property ++ && property.value.type !== Syntax.Identifier ++ ) { ++ multiline = true; ++ } ++ } else { ++ for (i = 0, iz = expr.properties.length; i < iz; ++i) { ++ property = expr.properties[i]; + if ( + property.type === Syntax.Property +- && property.value.type !== Syntax.Identifier ++ && !property.shorthand + ) { + multiline = true; +- } +- } else { +- for (i = 0, iz = expr.properties.length; i < iz; ++i) { +- property = expr.properties[i]; +- if ( +- property.type === Syntax.Property +- && !property.shorthand +- ) { +- multiline = true; +- break; +- } ++ break; + } + } +- result = ['{', multiline ? newline : '' ]; ++ } ++ result = ['{', multiline ? newline : '' ]; + +- withIndent(function (indent) { +- var i, iz; +- for (i = 0, iz = expr.properties.length; i < iz; ++i) { +- result.push(multiline ? indent : ''); +- result.push(that.generateExpression(expr.properties[i], Precedence.Sequence, E_TTT)); +- if (i + 1 < iz) { +- result.push(',' + (multiline ? newline : space)); +- } ++ withIndent(function (indent) { ++ var i, iz; ++ for (i = 0, iz = expr.properties.length; i < iz; ++i) { ++ result.push(multiline ? indent : ''); ++ result.push(that.generateExpression(expr.properties[i], Precedence.Sequence, E_TTT)); ++ if (i + 1 < iz) { ++ result.push(',' + (multiline ? newline : space)); + } +- }); +- +- if (multiline && !endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) { +- result.push(newline); + } +- result.push(multiline ? base : ''); +- result.push('}'); +- return result; +- }, ++ }); + +- ThisExpression: function (expr, precedence, flags) { +- return 'this'; +- }, ++ if (multiline && !endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) { ++ result.push(newline); ++ } ++ result.push(multiline ? base : ''); ++ result.push('}'); ++ return result; ++ }, + +- Super: function (expr, precedence, flags) { +- return 'super'; +- }, ++ ThisExpression: function (expr, precedence, flags) { ++ return 'this'; ++ }, + +- Identifier: function (expr, precedence, flags) { +- return generateIdentifier(expr); +- }, ++ Super: function (expr, precedence, flags) { ++ return 'super'; ++ }, + +- ImportDefaultSpecifier: function (expr, precedence, flags) { +- return generateIdentifier(expr.id || expr.local); +- }, ++ Identifier: function (expr, precedence, flags) { ++ return generateIdentifier(expr); ++ }, + +- ImportNamespaceSpecifier: function (expr, precedence, flags) { +- var result = ['*']; +- var id = expr.id || expr.local; +- if (id) { +- result.push(space + 'as' + noEmptySpace() + generateIdentifier(id)); +- } +- return result; +- }, ++ ImportDefaultSpecifier: function (expr, precedence, flags) { ++ return generateIdentifier(expr.id || expr.local); ++ }, + +- ImportSpecifier: function (expr, precedence, flags) { +- var imported = expr.imported; +- var result = [ imported.name ]; +- var local = expr.local; +- if (local && local.name !== imported.name) { +- result.push(noEmptySpace() + 'as' + noEmptySpace() + generateIdentifier(local)); +- } +- return result; +- }, ++ ImportNamespaceSpecifier: function (expr, precedence, flags) { ++ var result = ['*']; ++ var id = expr.id || expr.local; ++ if (id) { ++ result.push(space + 'as' + noEmptySpace() + generateIdentifier(id)); ++ } ++ return result; ++ }, + +- ExportSpecifier: function (expr, precedence, flags) { +- var local = expr.local; +- var result = [ local.name ]; +- var exported = expr.exported; +- if (exported && exported.name !== local.name) { +- result.push(noEmptySpace() + 'as' + noEmptySpace() + generateIdentifier(exported)); +- } +- return result; +- }, ++ ImportSpecifier: function (expr, precedence, flags) { ++ var imported = expr.imported; ++ var result = [ imported.name ]; ++ var local = expr.local; ++ if (local && local.name !== imported.name) { ++ result.push(noEmptySpace() + 'as' + noEmptySpace() + generateIdentifier(local)); ++ } ++ return result; ++ }, + +- Literal: function (expr, precedence, flags) { +- var raw; +- if (expr.hasOwnProperty('raw') && parse && extra.raw) { +- try { +- raw = parse(expr.raw).body[0].expression; +- if (raw.type === Syntax.Literal) { +- if (raw.value === expr.value) { +- return expr.raw; +- } ++ ExportSpecifier: function (expr, precedence, flags) { ++ var local = expr.local; ++ var result = [ local.name ]; ++ var exported = expr.exported; ++ if (exported && exported.name !== local.name) { ++ result.push(noEmptySpace() + 'as' + noEmptySpace() + generateIdentifier(exported)); ++ } ++ return result; ++ }, ++ ++ Literal: function (expr, precedence, flags) { ++ var raw; ++ if (expr.hasOwnProperty('raw') && parse && extra.raw) { ++ try { ++ raw = parse(expr.raw).body[0].expression; ++ if (raw.type === Syntax.Literal) { ++ if (raw.value === expr.value) { ++ return expr.raw; + } +- } catch (e) { +- // not use raw property + } ++ } catch (e) { ++ // not use raw property + } ++ } + +- if (expr.regex) { +- return '/' + expr.regex.pattern + '/' + expr.regex.flags; +- } ++ if (expr.regex) { ++ return '/' + expr.regex.pattern + '/' + expr.regex.flags; ++ } + +- if (expr.value === null) { +- return 'null'; +- } ++ if (expr.value === null) { ++ return 'null'; ++ } + +- if (typeof expr.value === 'string') { +- return escapeString(expr.value); +- } ++ if (typeof expr.value === 'string') { ++ return escapeString(expr.value); ++ } + +- if (typeof expr.value === 'number') { +- return generateNumber(expr.value); +- } ++ if (typeof expr.value === 'number') { ++ return generateNumber(expr.value); ++ } + +- if (typeof expr.value === 'boolean') { +- return expr.value ? 'true' : 'false'; +- } ++ if (typeof expr.value === 'boolean') { ++ return expr.value ? 'true' : 'false'; ++ } + +- return generateRegExp(expr.value); +- }, ++ return generateRegExp(expr.value); ++ }, + +- GeneratorExpression: function (expr, precedence, flags) { +- return this.ComprehensionExpression(expr, precedence, flags); +- }, ++ GeneratorExpression: function (expr, precedence, flags) { ++ return this.ComprehensionExpression(expr, precedence, flags); ++ }, + +- ComprehensionExpression: function (expr, precedence, flags) { +- // GeneratorExpression should be parenthesized with (...), ComprehensionExpression with [...] +- // Due to https://bugzilla.mozilla.org/show_bug.cgi?id=883468 position of expr.body can differ in Spidermonkey and ES6 ++ ComprehensionExpression: function (expr, precedence, flags) { ++ // GeneratorExpression should be parenthesized with (...), ComprehensionExpression with [...] ++ // Due to https://bugzilla.mozilla.org/show_bug.cgi?id=883468 position of expr.body can differ in Spidermonkey and ES6 + +- var result, i, iz, fragment, that = this; +- result = (expr.type === Syntax.GeneratorExpression) ? ['('] : ['[']; ++ var result, i, iz, fragment, that = this; ++ result = (expr.type === Syntax.GeneratorExpression) ? ['('] : ['[']; + +- if (extra.moz.comprehensionExpressionStartsWithAssignment) { +- fragment = this.generateExpression(expr.body, Precedence.Assignment, E_TTT); +- result.push(fragment); +- } ++ if (extra.moz.comprehensionExpressionStartsWithAssignment) { ++ fragment = this.generateExpression(expr.body, Precedence.Assignment, E_TTT); ++ result.push(fragment); ++ } + +- if (expr.blocks) { +- withIndent(function () { +- for (i = 0, iz = expr.blocks.length; i < iz; ++i) { +- fragment = that.generateExpression(expr.blocks[i], Precedence.Sequence, E_TTT); +- if (i > 0 || extra.moz.comprehensionExpressionStartsWithAssignment) { +- result = join(result, fragment); +- } else { +- result.push(fragment); +- } ++ if (expr.blocks) { ++ withIndent(function () { ++ for (i = 0, iz = expr.blocks.length; i < iz; ++i) { ++ fragment = that.generateExpression(expr.blocks[i], Precedence.Sequence, E_TTT); ++ if (i > 0 || extra.moz.comprehensionExpressionStartsWithAssignment) { ++ result = join(result, fragment); ++ } else { ++ result.push(fragment); + } +- }); +- } +- +- if (expr.filter) { +- result = join(result, 'if' + space); +- fragment = this.generateExpression(expr.filter, Precedence.Sequence, E_TTT); +- result = join(result, [ '(', fragment, ')' ]); +- } +- +- if (!extra.moz.comprehensionExpressionStartsWithAssignment) { +- fragment = this.generateExpression(expr.body, Precedence.Assignment, E_TTT); +- +- result = join(result, fragment); +- } +- +- result.push((expr.type === Syntax.GeneratorExpression) ? ')' : ']'); +- return result; +- }, +- +- ComprehensionBlock: function (expr, precedence, flags) { +- var fragment; +- if (expr.left.type === Syntax.VariableDeclaration) { +- fragment = [ +- expr.left.kind, noEmptySpace(), +- this.generateStatement(expr.left.declarations[0], S_FFFF) +- ]; +- } else { +- fragment = this.generateExpression(expr.left, Precedence.Call, E_TTT); +- } +- +- fragment = join(fragment, expr.of ? 'of' : 'in'); +- fragment = join(fragment, this.generateExpression(expr.right, Precedence.Sequence, E_TTT)); +- +- return [ 'for' + space + '(', fragment, ')' ]; +- }, +- +- SpreadElement: function (expr, precedence, flags) { +- return [ +- '...', +- this.generateExpression(expr.argument, Precedence.Assignment, E_TTT) +- ]; +- }, +- +- TaggedTemplateExpression: function (expr, precedence, flags) { +- var itemFlags = E_TTF; +- if (!(flags & F_ALLOW_CALL)) { +- itemFlags = E_TFF; +- } +- var result = [ +- this.generateExpression(expr.tag, Precedence.Call, itemFlags), +- this.generateExpression(expr.quasi, Precedence.Primary, E_FFT) +- ]; +- return parenthesize(result, Precedence.TaggedTemplate, precedence); +- }, +- +- TemplateElement: function (expr, precedence, flags) { +- // Don't use "cooked". Since tagged template can use raw template +- // representation. So if we do so, it breaks the script semantics. +- return expr.value.raw; +- }, +- +- TemplateLiteral: function (expr, precedence, flags) { +- var result, i, iz; +- result = [ '`' ]; +- for (i = 0, iz = expr.quasis.length; i < iz; ++i) { +- result.push(this.generateExpression(expr.quasis[i], Precedence.Primary, E_TTT)); +- if (i + 1 < iz) { +- result.push('${' + space); +- result.push(this.generateExpression(expr.expressions[i], Precedence.Sequence, E_TTT)); +- result.push(space + '}'); + } +- } +- result.push('`'); +- return result; +- }, +- +- ModuleSpecifier: function (expr, precedence, flags) { +- return this.Literal(expr, precedence, flags); +- }, ++ }); ++ } + +- ImportExpression: function(expr, precedence, flag) { +- return parenthesize([ +- 'import(', +- this.generateExpression(expr.source, Precedence.Assignment, E_TTT), +- ')' +- ], Precedence.Call, precedence); ++ if (expr.filter) { ++ result = join(result, 'if' + space); ++ fragment = this.generateExpression(expr.filter, Precedence.Sequence, E_TTT); ++ result = join(result, [ '(', fragment, ')' ]); + } +- }; + +- merge(CodeGenerator.prototype, CodeGenerator.Expression); ++ if (!extra.moz.comprehensionExpressionStartsWithAssignment) { ++ fragment = this.generateExpression(expr.body, Precedence.Assignment, E_TTT); + +- CodeGenerator.prototype.generateExpression = function (expr, precedence, flags) { +- var result, type; ++ result = join(result, fragment); ++ } + +- type = expr.type || Syntax.Property; ++ result.push((expr.type === Syntax.GeneratorExpression) ? ')' : ']'); ++ return result; ++ }, ++ ++ ComprehensionBlock: function (expr, precedence, flags) { ++ var fragment; ++ if (expr.left.type === Syntax.VariableDeclaration) { ++ fragment = [ ++ expr.left.kind, noEmptySpace(), ++ this.generateStatement(expr.left.declarations[0], S_FFFF) ++ ]; ++ } else { ++ fragment = this.generateExpression(expr.left, Precedence.Call, E_TTT); ++ } ++ ++ fragment = join(fragment, expr.of ? 'of' : 'in'); ++ fragment = join(fragment, this.generateExpression(expr.right, Precedence.Sequence, E_TTT)); ++ ++ return [ 'for' + space + '(', fragment, ')' ]; ++ }, ++ ++ SpreadElement: function (expr, precedence, flags) { ++ return [ ++ '...', ++ this.generateExpression(expr.argument, Precedence.Assignment, E_TTT) ++ ]; ++ }, ++ ++ TaggedTemplateExpression: function (expr, precedence, flags) { ++ var itemFlags = E_TTF; ++ if (!(flags & F_ALLOW_CALL)) { ++ itemFlags = E_TFF; ++ } ++ var result = [ ++ this.generateExpression(expr.tag, Precedence.Call, itemFlags), ++ this.generateExpression(expr.quasi, Precedence.Primary, E_FFT) ++ ]; ++ return parenthesize(result, Precedence.TaggedTemplate, precedence); ++ }, ++ ++ TemplateElement: function (expr, precedence, flags) { ++ // Don't use "cooked". Since tagged template can use raw template ++ // representation. So if we do so, it breaks the script semantics. ++ return expr.value.raw; ++ }, ++ ++ TemplateLiteral: function (expr, precedence, flags) { ++ var result, i, iz; ++ result = [ '`' ]; ++ for (i = 0, iz = expr.quasis.length; i < iz; ++i) { ++ result.push(this.generateExpression(expr.quasis[i], Precedence.Primary, E_TTT)); ++ if (i + 1 < iz) { ++ result.push('${' + space); ++ result.push(this.generateExpression(expr.expressions[i], Precedence.Sequence, E_TTT)); ++ result.push(space + '}'); ++ } ++ } ++ result.push('`'); ++ return result; ++ }, ++ ++ ModuleSpecifier: function (expr, precedence, flags) { ++ return this.Literal(expr, precedence, flags); ++ }, ++ ++ ImportExpression: function(expr, precedence, flag) { ++ return parenthesize([ ++ 'import(', ++ this.generateExpression(expr.source, Precedence.Assignment, E_TTT), ++ ')' ++ ], Precedence.Call, precedence); ++ } ++}; + +- if (extra.verbatim && expr.hasOwnProperty(extra.verbatim)) { +- return generateVerbatim(expr, precedence); +- } ++merge(CodeGenerator.prototype, CodeGenerator.Expression); + +- result = this[type](expr, precedence, flags); ++CodeGenerator.prototype.generateExpression = function (expr, precedence, flags) { ++ var result, type; + ++ type = expr.type || Syntax.Property; + +- if (extra.comment) { +- result = addComments(expr, result); +- } +- return toSourceNodeWhenNeeded(result, expr); +- }; ++ if (extra.verbatim && expr.hasOwnProperty(extra.verbatim)) { ++ return generateVerbatim(expr, precedence); ++ } + +- CodeGenerator.prototype.generateStatement = function (stmt, flags) { +- var result, +- fragment; ++ result = this[type](expr, precedence, flags); + +- result = this[stmt.type](stmt, flags); + +- // Attach comments ++ if (extra.comment) { ++ result = addComments(expr, result); ++ } ++ return toSourceNodeWhenNeeded(result, expr); ++}; + +- if (extra.comment) { +- result = addComments(stmt, result); +- } ++CodeGenerator.prototype.generateStatement = function (stmt, flags) { ++ var result, ++ fragment; + +- fragment = toSourceNodeWhenNeeded(result).toString(); +- if (stmt.type === Syntax.Program && !safeConcatenation && newline === '' && fragment.charAt(fragment.length - 1) === '\n') { +- result = sourceMap ? toSourceNodeWhenNeeded(result).replaceRight(/\s+$/, '') : fragment.replace(/\s+$/, ''); +- } ++ result = this[stmt.type](stmt, flags); + +- return toSourceNodeWhenNeeded(result, stmt); +- }; ++ // Attach comments + +- function generateInternal(node) { +- var codegen; ++ if (extra.comment) { ++ result = addComments(stmt, result); ++ } + +- codegen = new CodeGenerator(); +- if (isStatement(node)) { +- return codegen.generateStatement(node, S_TFFF); +- } ++ fragment = toSourceNodeWhenNeeded(result).toString(); ++ if (stmt.type === Syntax.Program && !safeConcatenation && newline === '' && fragment.charAt(fragment.length - 1) === '\n') { ++ result = sourceMap ? toSourceNodeWhenNeeded(result).replaceRight(/\s+$/, '') : fragment.replace(/\s+$/, ''); ++ } + +- if (isExpression(node)) { +- return codegen.generateExpression(node, Precedence.Sequence, E_TTT); +- } ++ return toSourceNodeWhenNeeded(result, stmt); ++}; + +- throw new Error('Unknown node type: ' + node.type); ++function generateInternal(node) { ++ var codegen; ++ ++ codegen = new CodeGenerator(); ++ if (isStatement(node)) { ++ return codegen.generateStatement(node, S_TFFF); + } + +- function generate(node, options) { +- var defaultOptions = getDefaultOptions(), result, pair; ++ if (isExpression(node)) { ++ return codegen.generateExpression(node, Precedence.Sequence, E_TTT); ++ } + +- if (options != null) { +- // Obsolete options +- // +- // `options.indent` +- // `options.base` +- // +- // Instead of them, we can use `option.format.indent`. +- if (typeof options.indent === 'string') { +- defaultOptions.format.indent.style = options.indent; +- } +- if (typeof options.base === 'number') { +- defaultOptions.format.indent.base = options.base; +- } +- options = updateDeeply(defaultOptions, options); +- indent = options.format.indent.style; +- if (typeof options.base === 'string') { +- base = options.base; +- } else { +- base = stringRepeat(indent, options.format.indent.base); +- } ++ throw new Error('Unknown node type: ' + node.type); ++} ++ ++function generate(node, options) { ++ var defaultOptions = getDefaultOptions(), result, pair; ++ ++ if (options != null) { ++ // Obsolete options ++ // ++ // `options.indent` ++ // `options.base` ++ // ++ // Instead of them, we can use `option.format.indent`. ++ if (typeof options.indent === 'string') { ++ defaultOptions.format.indent.style = options.indent; ++ } ++ if (typeof options.base === 'number') { ++ defaultOptions.format.indent.base = options.base; ++ } ++ options = updateDeeply(defaultOptions, options); ++ indent = options.format.indent.style; ++ if (typeof options.base === 'string') { ++ base = options.base; + } else { +- options = defaultOptions; +- indent = options.format.indent.style; + base = stringRepeat(indent, options.format.indent.base); + } +- json = options.format.json; +- renumber = options.format.renumber; +- hexadecimal = json ? false : options.format.hexadecimal; +- quotes = json ? 'double' : options.format.quotes; +- escapeless = options.format.escapeless; +- newline = options.format.newline; +- space = options.format.space; +- if (options.format.compact) { +- newline = space = indent = base = ''; +- } +- parentheses = options.format.parentheses; +- semicolons = options.format.semicolons; +- safeConcatenation = options.format.safeConcatenation; +- directive = options.directive; +- parse = json ? null : options.parse; +- sourceMap = options.sourceMap; +- sourceCode = options.sourceCode; +- preserveBlankLines = options.format.preserveBlankLines && sourceCode !== null; +- extra = options; +- +- if (sourceMap) { +- if (!exports.browser) { +- // We assume environment is node.js +- // And prevent from including source-map by browserify +- SourceNode = require('source-map').SourceNode; +- } else { +- SourceNode = global.sourceMap.SourceNode; +- } +- } +- +- result = generateInternal(node); +- +- if (!sourceMap) { +- pair = {code: result.toString(), map: null}; +- return options.sourceMapWithCode ? pair : pair.code; ++ } else { ++ options = defaultOptions; ++ indent = options.format.indent.style; ++ base = stringRepeat(indent, options.format.indent.base); ++ } ++ json = options.format.json; ++ renumber = options.format.renumber; ++ hexadecimal = json ? false : options.format.hexadecimal; ++ quotes = json ? 'double' : options.format.quotes; ++ escapeless = options.format.escapeless; ++ newline = options.format.newline; ++ space = options.format.space; ++ if (options.format.compact) { ++ newline = space = indent = base = ''; ++ } ++ parentheses = options.format.parentheses; ++ semicolons = options.format.semicolons; ++ safeConcatenation = options.format.safeConcatenation; ++ directive = options.directive; ++ parse = json ? null : options.parse; ++ sourceMap = options.sourceMap; ++ sourceCode = options.sourceCode; ++ preserveBlankLines = options.format.preserveBlankLines && sourceCode !== null; ++ extra = options; ++ ++ if (sourceMap) { ++ if (!exports.browser) { ++ // We assume environment is node.js ++ // And prevent from including source-map by browserify ++ SourceNode = require('source-map').SourceNode; ++ } else { ++ SourceNode = global.sourceMap.SourceNode; + } ++ } + ++ result = generateInternal(node); + +- pair = result.toStringWithSourceMap({ +- file: options.file, +- sourceRoot: options.sourceMapRoot +- }); ++ if (!sourceMap) { ++ pair = {code: result.toString(), map: null}; ++ return options.sourceMapWithCode ? pair : pair.code; ++ } + +- if (options.sourceContent) { +- pair.map.setSourceContent(options.sourceMap, +- options.sourceContent); +- } + +- if (options.sourceMapWithCode) { +- return pair; +- } ++ pair = result.toStringWithSourceMap({ ++ file: options.file, ++ sourceRoot: options.sourceMapRoot ++ }); + +- return pair.map.toString(); ++ if (options.sourceContent) { ++ pair.map.setSourceContent(options.sourceMap, ++ options.sourceContent); + } + +- FORMAT_MINIFY = { +- indent: { +- style: '', +- base: 0 +- }, +- renumber: true, +- hexadecimal: true, +- quotes: 'auto', +- escapeless: true, +- compact: true, +- parentheses: false, +- semicolons: false +- }; ++ if (options.sourceMapWithCode) { ++ return pair; ++ } + +- FORMAT_DEFAULTS = getDefaultOptions().format; ++ return pair.map.toString(); ++} ++ ++FORMAT_MINIFY = { ++ indent: { ++ style: '', ++ base: 0 ++ }, ++ renumber: true, ++ hexadecimal: true, ++ quotes: 'auto', ++ escapeless: true, ++ compact: true, ++ parentheses: false, ++ semicolons: false ++}; ++ ++FORMAT_DEFAULTS = getDefaultOptions().format; ++ ++var attachComments = estraverse.attachComments; ++var precedence = updateDeeply({}, Precedence); ++var browser = false; ++// var { version } = packageJson; ++ ++export { ++ // version, ++ generate, ++ attachComments, ++ precedence as Precedence, ++ browser, ++ FORMAT_MINIFY, ++ FORMAT_DEFAULTS ++} ++// // exports.version = require('./package.json').version; ++// exports.generate = generate; ++// exports.attachComments = estraverse.attachComments; ++// exports.Precedence = updateDeeply({}, Precedence); ++// exports.browser = false; ++// exports.FORMAT_MINIFY = FORMAT_MINIFY; ++// exports.FORMAT_DEFAULTS = FORMAT_DEFAULTS; + +- exports.version = require('./package.json').version; +- exports.generate = generate; +- exports.attachComments = estraverse.attachComments; +- exports.Precedence = updateDeeply({}, Precedence); +- exports.browser = false; +- exports.FORMAT_MINIFY = FORMAT_MINIFY; +- exports.FORMAT_DEFAULTS = FORMAT_DEFAULTS; +-}()); + /* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/rollup.config.js b/rollup.config.js index c8c8037..04ae486 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,6 +1,5 @@ import { nodeResolve } from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; -import json from '@rollup/plugin-json'; export default { input: 'src/wcc.js', @@ -9,7 +8,6 @@ export default { format: 'cjs' }, plugins: [ - json(), nodeResolve(), commonjs() ] diff --git a/src/jsx-loader.js b/src/jsx-loader.js index 370b945..2fffd8f 100644 --- a/src/jsx-loader.js +++ b/src/jsx-loader.js @@ -2,7 +2,7 @@ // https://nodejs.org/api/esm.html#esm_loaders import * as acorn from 'acorn'; import * as walk from 'acorn-walk'; -import escodegen from 'escodegen'; +import { generate } from 'escodegen'; import fs from 'fs'; import jsx from 'acorn-jsx'; import { parse, parseFragment, serialize } from 'parse5'; @@ -323,7 +323,7 @@ export function parseJsx(moduleURL) { } } - let newModuleContents = escodegen.generate(tree); + let newModuleContents = generate(tree); // TODO better way to determine value type? /* eslint-disable indent */ @@ -391,7 +391,7 @@ export async function load(url, context, defaultLoad) { return { format: 'module', - source: escodegen.generate(jsFromJsx), + source: generate(jsFromJsx), shortCircuit: true }; } diff --git a/src/wcc.js b/src/wcc.js index 887e0b6..990bc5f 100644 --- a/src/wcc.js +++ b/src/wcc.js @@ -4,7 +4,7 @@ import './dom-shim.js'; import * as acorn from 'acorn'; import * as walk from 'acorn-walk'; -import escodegen from 'escodegen'; +import { generate } from 'escodegen'; import { getParser, parseJsx } from './jsx-loader.js'; import { parse, parseFragment, serialize } from 'parse5'; import fs from 'fs'; @@ -94,7 +94,7 @@ function registerDependencies(moduleURL, definitions, depth = 0) { definitions[tagName] = { instanceName: args[1].name, moduleURL, - source: escodegen.generate(tree), + source: generate(tree), url: moduleURL, isEntry };