Extracted babel-helper-annotate-as-pure (#6267)

This commit is contained in:
Mateusz Burzyński 2017-09-25 17:40:51 +02:00 committed by GitHub
parent 2374062bbd
commit 413ffe6639
8 changed files with 119 additions and 26 deletions

View File

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

View File

@ -0,0 +1,36 @@
# babel-helper-annotate-as-pure
## API
```js
declare export default annotateAsPure(nodeOrPath: Node | NodePath);
```
## Usage
```js
import traverse from "babel-traverse";
import annotateAsPure from "babel-helper-annotate-as-pure";
// ...
traverse(file, {
CallExpression(path) {
annotateAsPure(path);
},
});
```
## Caveat with UglifyJS pre v3.1.0
`babel-helper-annotate-as-pure` concatenates existing leading comments to the `#__PURE__` annotation, but versions of UglifyJS before v3.1.0 checks only the last leading comment for the annotation.
So for the example input when annotating all CallExpressions:
```js
const four = /* foo */ add(2, 2);
```
it produces:
```js
const four = /* #__PURE__ */ /* foo */ add(2, 2);
```
and such generated annotation will be ignored in those previous versions of the UglifyJS.

View File

@ -0,0 +1,11 @@
{
"name": "babel-helper-annotate-as-pure",
"version": "7.0.0-beta.1",
"description": "Helper function to annotate paths and nodes with #__PURE__ comment",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-annotate-as-pure",
"license": "MIT",
"main": "lib/index.js",
"dependencies": {
"babel-types": "7.0.0-beta.1"
}
}

View File

@ -0,0 +1,19 @@
import * as t from "babel-types";
const PURE_ANNOTATION = "#__PURE__";
const isPureAnnotated = node => {
const { leadingComments } = node;
if (leadingComments === undefined) {
return false;
}
return leadingComments.some(comment => /[@#]__PURE__/.test(comment.value));
};
export default function annotateAsPure(pathOrNode) {
const node = pathOrNode.node || pathOrNode;
if (isPureAnnotated(node)) {
return;
}
t.addComment(node, "leading", PURE_ANNOTATION);
}

View File

@ -6,6 +6,7 @@
"license": "MIT", "license": "MIT",
"main": "lib/index.js", "main": "lib/index.js",
"dependencies": { "dependencies": {
"babel-helper-annotate-as-pure": "7.0.0-beta.1",
"babel-helper-define-map": "7.0.0-beta.1", "babel-helper-define-map": "7.0.0-beta.1",
"babel-helper-function-name": "7.0.0-beta.1", "babel-helper-function-name": "7.0.0-beta.1",
"babel-helper-optimise-call-expression": "7.0.0-beta.1", "babel-helper-optimise-call-expression": "7.0.0-beta.1",

View File

@ -1,9 +1,8 @@
import LooseTransformer from "./loose"; import LooseTransformer from "./loose";
import VanillaTransformer from "./vanilla"; import VanillaTransformer from "./vanilla";
import annotateAsPure from "babel-helper-annotate-as-pure";
import nameFunction from "babel-helper-function-name"; import nameFunction from "babel-helper-function-name";
const PURE_ANNOTATION = "#__PURE__";
export default function({ types: t }) { export default function({ types: t }) {
// todo: investigate traversal requeueing // todo: investigate traversal requeueing
const VISITED = Symbol(); const VISITED = Symbol();
@ -57,7 +56,7 @@ export default function({ types: t }) {
path.replaceWith(new Constructor(path, state.file).run()); path.replaceWith(new Constructor(path, state.file).run());
if (path.isCallExpression()) { if (path.isCallExpression()) {
path.addComment("leading", PURE_ANNOTATION); annotateAsPure(path);
if (path.get("callee").isArrowFunctionExpression()) { if (path.get("callee").isArrowFunctionExpression()) {
path.get("callee").arrowFunctionToExpression(); path.get("callee").arrowFunctionToExpression();
} }

View File

@ -1,4 +1,5 @@
// This file contains methods responsible for dealing with comments. // This file contains methods responsible for dealing with comments.
import * as t from "babel-types";
/** /**
* Share comments amongst siblings. * Share comments amongst siblings.
@ -27,13 +28,8 @@ export function shareCommentsWithSiblings() {
} }
} }
export function addComment(type, content, line?) { export function addComment(type: string, content: string, line?: boolean) {
this.addComments(type, [ t.addComment(this.node, type, content, line);
{
type: line ? "CommentLine" : "CommentBlock",
value: content,
},
]);
} }
/** /**
@ -41,20 +37,5 @@ export function addComment(type, content, line?) {
*/ */
export function addComments(type: string, comments: Array) { export function addComments(type: string, comments: Array) {
if (!comments) return; t.addComments(this.node, type, comments);
const node = this.node;
if (!node) return;
const key = `${type}Comments`;
if (node[key]) {
if (type === "leading") {
node[key] = comments.concat(node[key]);
} else {
node[key] = node[key].concat(comments);
}
} else {
node[key] = comments;
}
} }

View File

@ -399,6 +399,49 @@ export function buildMatchMemberExpression(
}; };
} }
/**
* Add comment of certain type to a node.
*/
export function addComment(
node: Object,
type: string,
content: string,
line?: boolean,
): Object {
addComments(node, type, [
{
type: line ? "CommentLine" : "CommentBlock",
value: content,
},
]);
}
/**
* Add comments of certain type to a node.
*/
export function addComments(
node: Object,
type: string,
comments: Array,
): Object {
if (!comments || !node) return;
const key = `${type}Comments`;
if (node[key]) {
if (type === "leading") {
node[key] = comments.concat(node[key]);
} else {
node[key] = node[key].concat(comments);
}
} else {
node[key] = comments;
}
return node;
}
/** /**
* Remove comment properties from a node. * Remove comment properties from a node.
*/ */