-
-
Notifications
You must be signed in to change notification settings - Fork 222
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implemented transform-regexp-constructors plugin.
Changes RegExp constructors into literals.
- Loading branch information
Shine Wang
committed
Oct 18, 2016
1 parent
a7a890a
commit 5d82d65
Showing
4 changed files
with
146 additions
and
0 deletions.
There are no files selected for viewing
4 changes: 4 additions & 0 deletions
4
packages/babel-plugin-transform-regexp-constructors/.npmignore
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
src | ||
__tests__ | ||
node_modules | ||
*.log |
52 changes: 52 additions & 0 deletions
52
packages/babel-plugin-transform-regexp-constructors/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
# babel-plugin-transform-regexp-constructors | ||
|
||
This changes RegExp constructors into literals if and only if the RegExp | ||
arguments are string literals. | ||
|
||
## Example | ||
|
||
**In** | ||
|
||
```javascript | ||
const foo = 'ab+'; | ||
var a = new RegExp(foo+'c', 'i'); | ||
``` | ||
|
||
**Out** | ||
|
||
```javascript | ||
const foo = 'ab+'; | ||
var a = /ab+c/i; | ||
``` | ||
|
||
## Installation | ||
|
||
```sh | ||
$ npm install babel-plugin-transform-regexp-constructors | ||
``` | ||
|
||
## Usage | ||
|
||
### Via `.babelrc` (Recommended) | ||
|
||
**.babelrc** | ||
|
||
```json | ||
{ | ||
"plugins": ["transform-regexp-constructors"] | ||
} | ||
``` | ||
|
||
### Via CLI | ||
|
||
```sh | ||
$ babel --plugins transform-regexp-constructors script.js | ||
``` | ||
|
||
### Via Node API | ||
|
||
```javascript | ||
require("babel-core").transform("code", { | ||
plugins: ["transform-regexp-constructors"] | ||
}); | ||
``` |
62 changes: 62 additions & 0 deletions
62
...abel-plugin-transform-regexp-constructors/__tests__/transform-regexp-constructors-test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
jest.autoMockOff(); | ||
|
||
const babel = require("babel-core"); | ||
const plugin = require("../src/index"); | ||
|
||
function transform(code) { | ||
return babel.transform(code, { | ||
plugins: [plugin], | ||
}).code; | ||
} | ||
|
||
describe("transform-regexp-constructors-plugin", () => { | ||
it("should transform RegExp constructors with string literals", () => { | ||
const source = "var x = new RegExp('ab+c');"; | ||
const expected = "var x = /ab+c/;"; | ||
expect(transform(source)).toBe(expected); | ||
}); | ||
|
||
it("should transform RegExp constructors with flags", () => { | ||
const source = "var x = new RegExp('ab+c', 'gimuy');"; | ||
const expected = "var x = /ab+c/gimuy;"; | ||
expect(transform(source)).toBe(expected); | ||
}); | ||
|
||
it("should transform RegExp escapes", () => { | ||
const source = String.raw`var x = new RegExp('\\w+\\s');`; | ||
const expected = String.raw`var x = /\w+\s/;`; | ||
expect(transform(source)).toBe(expected); | ||
}); | ||
|
||
it("should not transform RegExp constructors with expressions", () => { | ||
const source = "var x = new RegExp(foo(), 'g');"; | ||
const expected = source; | ||
expect(transform(source)).toBe(expected); | ||
}); | ||
|
||
it("should transform empty RegExp constructor", () => { | ||
const source = "var x = new RegExp();"; | ||
const expected = "var x = /(?:)/;"; | ||
expect(transform(source)).toBe(expected); | ||
}); | ||
|
||
it("should transform RegExp constructor with empty string", () => { | ||
const source = "var x = new RegExp('');"; | ||
const expected = "var x = /(?:)/;"; | ||
expect(transform(source)).toBe(expected); | ||
}); | ||
|
||
it("should resolve expressions and const references", () => { | ||
const source = ` | ||
const foo = "ab+"; | ||
const bar = "c\\\\w"; | ||
const flags = "g"; | ||
const ret = new RegExp(foo + bar + "d", flags);`; | ||
const expected = ` | ||
const foo = "ab+"; | ||
const bar = "c\\\\w"; | ||
const flags = "g"; | ||
const ret = /ab+c\\wd/g;`; | ||
expect(transform(source)).toBe(expected); | ||
}); | ||
}); |
28 changes: 28 additions & 0 deletions
28
packages/babel-plugin-transform-regexp-constructors/src/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
"use strict"; | ||
|
||
module.exports = function({ types: t }) { | ||
return { | ||
name: "transform-regexp-constructors", | ||
visitor: { | ||
NewExpression(path) { | ||
if (!t.isIdentifier(path.node.callee, {name: "RegExp"})) { | ||
return; | ||
} | ||
const evaluatedArgs = path.get("arguments") | ||
.map((a) => a.evaluate()); | ||
if (!evaluatedArgs.every((a) => a.confident === true && | ||
typeof a.value === "string")) { | ||
return; | ||
} | ||
const pattern = (evaluatedArgs.length >= 1 && | ||
evaluatedArgs[0].value !== "") ? | ||
evaluatedArgs[0].value : | ||
"(?:)"; | ||
const flags = evaluatedArgs.length >= 2 ? | ||
evaluatedArgs[1].value : | ||
""; | ||
path.replaceWith(t.regExpLiteral(pattern, flags)); | ||
} | ||
}, | ||
}; | ||
}; |