Add transform to rename variables that are ES3 reserved words (#6479)

* Initial version

* Replace .includes with .indexOf and better node set to visit

* Alphabetically sort es3 reserved words and make difference helper for readability

* Fix second Array.include error that was not polyfilled

* Move es3 keywords into separate babel-types helper and use in all es3 transforms

* Reference local plugin build directly for tests

* Try relative import for babel-types

* Update to scoped package name and beta 3

* Fix unscoped package import

* Replace local plugin reference with proper plugin name
This commit is contained in:
Mauro Bringolf
2017-10-19 00:00:58 +02:00
committed by Logan Smyth
parent e6d44fd68e
commit 2311ddbe67
12 changed files with 81 additions and 3 deletions

View File

@@ -7,7 +7,7 @@ export default function({ types: t }) {
if (
!node.computed &&
t.isIdentifier(prop) &&
!t.isValidIdentifier(prop.name)
!t.isValidES3Identifier(prop.name)
) {
// foo.default -> foo["default"]
node.property = t.stringLiteral(prop.name);

View File

@@ -7,7 +7,7 @@ export default function({ types: t }) {
if (
!node.computed &&
t.isIdentifier(key) &&
!t.isValidIdentifier(key.name)
!t.isValidES3Identifier(key.name)
) {
// default: "bar" -> "default": "bar"
node.key = t.stringLiteral(key.name);

View File

@@ -0,0 +1,3 @@
src
test
*.log

View File

@@ -0,0 +1,14 @@
{
"name": "@babel/plugin-transform-es3-reserved-words",
"version": "7.0.0-beta.3",
"description": "Ensure that no reserved words are used.",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es3-reserved-words",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
],
"devDependencies": {
"@babel/helper-plugin-test-runner": "7.0.0-beta.3"
}
}

View File

@@ -0,0 +1,11 @@
export default function({ types: t }) {
return {
visitor: {
"BindingIdentifier|ReferencedIdentifier"(path) {
if (!t.isValidES3Identifier(path.node.name)) {
path.scope.rename(path.node.name);
}
},
},
};
}

View File

@@ -0,0 +1,4 @@
function utf8CheckByte(byte) {
if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4;
return -1;
}

View File

@@ -0,0 +1,4 @@
function utf8CheckByte(_byte) {
if (_byte <= 0x7F) return 0;else if (_byte >> 5 === 0x06) return 2;else if (_byte >> 4 === 0x0E) return 3;else if (_byte >> 3 === 0x1E) return 4;
return -1;
}

View File

@@ -0,0 +1,3 @@
{
"plugins": ["transform-es3-reserved-words"]
}

View File

@@ -0,0 +1,3 @@
import runner from "@babel/helper-plugin-test-runner";
runner(__dirname);

View File

@@ -62,3 +62,30 @@ export const BLOCK_SCOPED_SYMBOL = Symbol.for("var used to be block scoped");
export const NOT_LOCAL_BINDING = Symbol.for(
"should not be considered a local binding",
);
export const RESERVED_WORDS_ES3_ONLY = new Set([
"abstract",
"boolean",
"byte",
"char",
"double",
"enum",
"final",
"float",
"goto",
"implements",
"int",
"interface",
"long",
"native",
"package",
"private",
"protected",
"public",
"short",
"static",
"synchronized",
"throws",
"transient",
"volatile",
]);

View File

@@ -580,6 +580,7 @@ export {
isBinding,
isReferenced,
isValidIdentifier,
isValidES3Identifier,
isLet,
isBlockScoped,
isVar,

View File

@@ -1,7 +1,7 @@
import { getBindingIdentifiers } from "./retrievers";
import esutils from "esutils";
import * as t from "./index";
import { BLOCK_SCOPED_SYMBOL } from "./constants";
import { BLOCK_SCOPED_SYMBOL, RESERVED_WORDS_ES3_ONLY } from "./constants";
/**
* Check if the input `node` is a binding identifier.
@@ -177,6 +177,14 @@ export function isValidIdentifier(name: string): boolean {
return esutils.keyword.isIdentifierNameES6(name);
}
}
/**
* Check if the input `name` is a valid identifier name according to the ES3 specification.
*
* Additional ES3 reserved words are
*/
export function isValidES3Identifier(name: string): boolean {
return isValidIdentifier(name, true) && !RESERVED_WORDS_ES3_ONLY.has(name);
}
/**
* Check if the input `node` is a `let` variable declaration.