Mark transpiled JSX elements as pure (#11126)

* Mark transpiled JSX elements as pure

* Avoid duble annotation

* Add "pure" option to the React preset

* Fix generator indentation

* Update tests

* Add tests for the "pure" option

* Update windows fixtures
This commit is contained in:
Nicolò Ribaudo 2020-03-19 15:43:54 +01:00 committed by GitHub
parent fa7ec81771
commit f3912ac08f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
246 changed files with 613 additions and 314 deletions

View File

@ -262,6 +262,8 @@ export default class Printer {
if (i + 1 === str.length) return; if (i + 1 === str.length) return;
const chaPost = str[i + 1]; const chaPost = str[i + 1];
if (chaPost !== "/" && chaPost !== "*") return; if (chaPost !== "/" && chaPost !== "*") return;
// We don't print newlines aroung /*#__PURE__*/ annotations
if (PURE_ANNOTATION_RE.test(str.slice(i + 2, str.length - 2))) return;
} }
this.token("("); this.token("(");
this.indent(); this.indent();

View File

@ -9,6 +9,7 @@
}, },
"main": "lib/index.js", "main": "lib/index.js",
"dependencies": { "dependencies": {
"@babel/helper-annotate-as-pure": "^7.8.3",
"@babel/helper-module-imports": "^7.8.3", "@babel/helper-module-imports": "^7.8.3",
"@babel/types": "^7.8.3", "@babel/types": "^7.8.3",
"esutils": "^2.0.0" "esutils": "^2.0.0"

View File

@ -1,6 +1,14 @@
import esutils from "esutils"; import esutils from "esutils";
import * as t from "@babel/types"; import * as t from "@babel/types";
import { addNamed, addNamespace, isModule } from "@babel/helper-module-imports"; import { addNamed, addNamespace, isModule } from "@babel/helper-module-imports";
import annotateAsPure from "@babel/helper-annotate-as-pure";
const DEFAULT = {
importSource: "react",
runtime: "automatic",
pragma: "React.createElement",
pragmaFrag: "React.Fragment",
};
export function helper(babel, options) { export function helper(babel, options) {
const FILE_NAME_VAR = "_jsxFileName"; const FILE_NAME_VAR = "_jsxFileName";
@ -17,10 +25,10 @@ export function helper(babel, options) {
const IMPORT_NAME_SIZE = options.development ? 3 : 4; const IMPORT_NAME_SIZE = options.development ? 3 : 4;
const { const {
importSource: IMPORT_SOURCE_DEFAULT = "react", importSource: IMPORT_SOURCE_DEFAULT = DEFAULT.importSource,
runtime: RUNTIME_DEFAULT = "automatic", runtime: RUNTIME_DEFAULT = DEFAULT.runtime,
pragma: PRAGMA_DEFAULT = "React.createElement", pragma: PRAGMA_DEFAULT = DEFAULT.pragma,
pragmaFrag: PRAGMA_FRAG_DEFAULT = "React.Fragment", pragmaFrag: PRAGMA_FRAG_DEFAULT = DEFAULT.pragmaFrag,
} = options; } = options;
return { return {
@ -142,8 +150,14 @@ You can set \`throwIfNamespace: false\` to bypass this warning.`,
createIdentifierParser(pragmaFrag), createIdentifierParser(pragmaFrag),
); );
state.set("@babel/plugin-react-jsx/usedFragment", false); state.set("@babel/plugin-react-jsx/usedFragment", false);
state.set("@babel/plugin-react-jsx/pragmaSet", pragmaSet); state.set(
state.set("@babel/plugin-react-jsx/pragmaFragSet", pragmaFragSet); "@babel/plugin-react-jsx/pragmaSet",
pragma !== DEFAULT.pragma,
);
state.set(
"@babel/plugin-react-jsx/pragmaFragSet",
pragmaFrag !== DEFAULT.pragmaFrag,
);
} else if (runtime === "automatic") { } else if (runtime === "automatic") {
if (pragmaSet || pragmaFragSet) { if (pragmaSet || pragmaFragSet) {
throw path.buildCodeFrameError( throw path.buildCodeFrameError(
@ -190,6 +204,11 @@ You can set \`throwIfNamespace: false\` to bypass this warning.`,
createIdentifierName(path, "Fragment", importName), createIdentifierName(path, "Fragment", importName),
), ),
); );
state.set(
"@babel/plugin-react-jsx/importSourceSet",
source !== DEFAULT.importSource,
);
} else { } else {
throw path.buildCodeFrameError( throw path.buildCodeFrameError(
`Runtime must be either "classic" or "automatic".`, `Runtime must be either "classic" or "automatic".`,
@ -505,6 +524,7 @@ You can set \`throwIfNamespace: false\` to bypass this warning.`,
tagExpr: tagExpr, tagExpr: tagExpr,
tagName: tagName, tagName: tagName,
args: args, args: args,
pure: false,
}; };
if (options.pre) { if (options.pre) {
@ -577,13 +597,15 @@ You can set \`throwIfNamespace: false\` to bypass this warning.`,
options.post(state, file); options.post(state, file);
} }
return ( const call =
state.call || state.call ||
t.callExpression( t.callExpression(
path.node.children.length > 1 ? state.jsxStaticCallee : state.jsxCallee, path.node.children.length > 1 ? state.jsxStaticCallee : state.jsxCallee,
args, args,
) );
); if (state.pure) annotateAsPure(call);
return call;
} }
// Builds props for React.jsx. This function adds children into the props // Builds props for React.jsx. This function adds children into the props
@ -633,6 +655,7 @@ You can set \`throwIfNamespace: false\` to bypass this warning.`,
tagExpr: tagExpr, tagExpr: tagExpr,
tagName: tagName, tagName: tagName,
args: args, args: args,
pure: false,
}; };
if (options.pre) { if (options.pre) {
@ -667,13 +690,15 @@ You can set \`throwIfNamespace: false\` to bypass this warning.`,
options.post(state, file); options.post(state, file);
} }
return ( const call =
state.call || state.call ||
t.callExpression( t.callExpression(
path.node.children.length > 1 ? state.jsxStaticCallee : state.jsxCallee, path.node.children.length > 1 ? state.jsxStaticCallee : state.jsxCallee,
args, args,
) );
); if (state.pure) annotateAsPure(call);
return call;
} }
function buildCreateElementFragmentCall(path, file) { function buildCreateElementFragmentCall(path, file) {
@ -692,6 +717,7 @@ You can set \`throwIfNamespace: false\` to bypass this warning.`,
tagExpr: tagExpr, tagExpr: tagExpr,
tagName: tagName, tagName: tagName,
args: args, args: args,
pure: false,
}; };
if (options.pre) { if (options.pre) {
@ -706,7 +732,12 @@ You can set \`throwIfNamespace: false\` to bypass this warning.`,
} }
file.set("@babel/plugin-react-jsx/usedFragment", true); file.set("@babel/plugin-react-jsx/usedFragment", true);
return state.call || t.callExpression(state.createElementCallee, args);
const call =
state.call || t.callExpression(state.createElementCallee, args);
if (state.pure) annotateAsPure(call);
return call;
} }
// Builds JSX into: // Builds JSX into:
@ -733,6 +764,7 @@ You can set \`throwIfNamespace: false\` to bypass this warning.`,
tagExpr: tagExpr, tagExpr: tagExpr,
tagName: tagName, tagName: tagName,
args: args, args: args,
pure: false,
}; };
if (options.pre) { if (options.pre) {
@ -751,7 +783,11 @@ You can set \`throwIfNamespace: false\` to bypass this warning.`,
options.post(state, file); options.post(state, file);
} }
return state.call || t.callExpression(state.createElementCallee, args); const call =
state.call || t.callExpression(state.createElementCallee, args);
if (state.pure) annotateAsPure(call);
return call;
} }
/** /**

View File

@ -9,6 +9,7 @@
}, },
"main": "lib/index.js", "main": "lib/index.js",
"dependencies": { "dependencies": {
"@babel/helper-annotate-as-pure": "^7.8.3",
"@babel/types": "^7.8.3", "@babel/types": "^7.8.3",
"esutils": "^2.0.0" "esutils": "^2.0.0"
} }

View File

@ -1,11 +1,13 @@
import esutils from "esutils"; import esutils from "esutils";
import * as t from "@babel/types"; import * as t from "@babel/types";
import annotateAsPure from "@babel/helper-annotate-as-pure";
type ElementState = { type ElementState = {
tagExpr: Object, // tag node tagExpr: Object, // tag node
tagName: ?string, // raw string tag name tagName: ?string, // raw string tag name
args: Array<Object>, // array of call arguments args: Array<Object>, // array of call arguments
call?: Object, // optional call property that can be set to override the call expression returned call?: Object, // optional call property that can be set to override the call expression returned
pure: boolean, // true if the element can be marked with a #__PURE__ annotation
}; };
export default function(opts) { export default function(opts) {
@ -134,6 +136,7 @@ You can set \`throwIfNamespace: false\` to bypass this warning.`,
tagExpr: tagExpr, tagExpr: tagExpr,
tagName: tagName, tagName: tagName,
args: args, args: args,
pure: false,
}; };
if (opts.pre) { if (opts.pre) {
@ -153,7 +156,10 @@ You can set \`throwIfNamespace: false\` to bypass this warning.`,
opts.post(state, file); opts.post(state, file);
} }
return state.call || t.callExpression(state.callee, args); const call = state.call || t.callExpression(state.callee, args);
if (state.pure) annotateAsPure(call);
return call;
} }
function pushProps(_props, objs) { function pushProps(_props, objs) {
@ -248,6 +254,7 @@ You can set \`throwIfNamespace: false\` to bypass this warning.`,
tagExpr: tagExpr, tagExpr: tagExpr,
tagName: tagName, tagName: tagName,
args: args, args: args,
pure: false,
}; };
if (opts.pre) { if (opts.pre) {
@ -262,6 +269,10 @@ You can set \`throwIfNamespace: false\` to bypass this warning.`,
} }
file.set("usedFragment", true); file.set("usedFragment", true);
return state.call || t.callExpression(state.callee, args);
const call = state.call || t.callExpression(state.callee, args);
if (state.pure) annotateAsPure(call);
return call;
} }
} }

View File

@ -2,5 +2,5 @@
var arr = []; var arr = [];
for (var i = 0; i < 4; ++i) { for (var i = 0; i < 4; ++i) {
arr.push(React.createElement("i", null)); arr.push( /*#__PURE__*/React.createElement("i", null));
} }

View File

@ -24,9 +24,9 @@ var RandomComponent = /*#__PURE__*/function (_Component) {
babelHelpers.createClass(RandomComponent, [{ babelHelpers.createClass(RandomComponent, [{
key: "render", key: "render",
value: function render() { value: function render() {
return _react["default"].createElement("div", { return /*#__PURE__*/_react["default"].createElement("div", {
className: "sui-RandomComponent" className: "sui-RandomComponent"
}, _react["default"].createElement("h2", null, "Hi there!")); }, /*#__PURE__*/_react["default"].createElement("h2", null, "Hi there!"));
} }
}]); }]);
return RandomComponent; return RandomComponent;

View File

@ -6,16 +6,15 @@ Object.defineProperty(exports, "__esModule", {
exports["default"] = _default; exports["default"] = _default;
function _default() { function _default() {
return (/*#__PURE__*/function () { return /*#__PURE__*/function () {
function Select() { function Select() {
babelHelpers.classCallCheck(this, Select); babelHelpers.classCallCheck(this, Select);
} }
babelHelpers.createClass(Select, [{ babelHelpers.createClass(Select, [{
key: "query", key: "query",
value: function query(_query) {} value: function query(_query) {}
}]); }]);
return Select; return Select;
}() }();
);
} }

View File

@ -7,7 +7,7 @@ exports["default"] = void 0;
var _default = function _default(_ref) { var _default = function _default(_ref) {
var _onClick = _ref.onClick; var _onClick = _ref.onClick;
return React.createElement("div", { return /*#__PURE__*/React.createElement("div", {
onClick: function onClick() { onClick: function onClick() {
return _onClick(); return _onClick();
} }

View File

@ -12,7 +12,6 @@
"babel-plugin" "babel-plugin"
], ],
"dependencies": { "dependencies": {
"@babel/helper-annotate-as-pure": "^7.8.3",
"@babel/helper-plugin-utils": "^7.8.3" "@babel/helper-plugin-utils": "^7.8.3"
}, },
"peerDependencies": { "peerDependencies": {

View File

@ -1,6 +1,5 @@
import { declare } from "@babel/helper-plugin-utils"; import { declare } from "@babel/helper-plugin-utils";
import { types as t } from "@babel/core"; import { types as t } from "@babel/core";
import annotateAsPure from "@babel/helper-annotate-as-pure";
export default declare((api, options) => { export default declare((api, options) => {
api.assertVersion(7); api.assertVersion(7);
@ -107,13 +106,7 @@ export default declare((api, options) => {
// Traverse all props passed to this element for immutability. // Traverse all props passed to this element for immutability.
path.traverse(immutabilityVisitor, state); path.traverse(immutabilityVisitor, state);
if (state.isImmutable) { if (state.isImmutable) path.hoist();
const hoisted = path.hoist();
if (hoisted) {
annotateAsPure(hoisted);
}
}
}, },
}, },
}; };

View File

@ -1,10 +1,10 @@
var _ref = /*#__PURE__*/<div>child</div>; var _ref = <div>child</div>;
const AppItem = () => { const AppItem = () => {
return _ref; return _ref;
}; };
var _ref2 = /*#__PURE__*/<div> var _ref2 = <div>
<p>Parent</p> <p>Parent</p>
<AppItem /> <AppItem />
</div>; </div>;

View File

@ -1,6 +1,6 @@
var _ref2 = /*#__PURE__*/<div>child</div>; var _ref2 = <div>child</div>;
var _ref3 = /*#__PURE__*/<p>Parent</p>; var _ref3 = <p>Parent</p>;
(function () { (function () {
class App extends React.Component { class App extends React.Component {
@ -13,7 +13,7 @@ var _ref3 = /*#__PURE__*/<p>Parent</p>;
const AppItem = () => { const AppItem = () => {
return _ref2; return _ref2;
}, },
_ref = /*#__PURE__*/<div> _ref = <div>
{_ref3} {_ref3}
<AppItem /> <AppItem />
</div>; </div>;

View File

@ -1,13 +1,13 @@
var _ref = /*#__PURE__*/<div>child</div>; var _ref = <div>child</div>;
var _ref3 = /*#__PURE__*/<p>Parent</p>; var _ref3 = <p>Parent</p>;
(function () { (function () {
const AppItem = () => { const AppItem = () => {
return _ref; return _ref;
}; };
var _ref2 = /*#__PURE__*/<div> var _ref2 = <div>
{_ref3} {_ref3}
<AppItem /> <AppItem />
</div>; </div>;

View File

@ -5,12 +5,12 @@ export default class App extends React.Component {
} }
var _ref2 = /*#__PURE__*/<div>child</div>; var _ref2 = <div>child</div>;
const AppItem = () => { const AppItem = () => {
return _ref2; return _ref2;
}, },
_ref = /*#__PURE__*/<div> _ref = <div>
<p>Parent</p> <p>Parent</p>
<AppItem /> <AppItem />
</div>; </div>;

View File

@ -1,4 +1,4 @@
var _ref = /*#__PURE__*/<span />; var _ref = <span />;
var Foo = React.createClass({ var Foo = React.createClass({
render: function () { render: function () {

View File

@ -1,6 +1,6 @@
import React from 'react'; // Regression test for https://github.com/babel/babel/issues/5552 import React from 'react'; // Regression test for https://github.com/babel/babel/issues/5552
var _ref = /*#__PURE__*/<div />; var _ref = <div />;
class BugReport extends React.Component { class BugReport extends React.Component {
constructor(...args) { constructor(...args) {

View File

@ -1,9 +1,9 @@
import React from 'react'; import React from 'react';
import Loader from 'loader'; import Loader from 'loader';
var _ref = /*#__PURE__*/<Loader className="full-height" />; var _ref = <Loader className="full-height" />;
var _ref2 = /*#__PURE__*/<Loader className="p-y-5" />; var _ref2 = <Loader className="p-y-5" />;
const errorComesHere = () => _ref, const errorComesHere = () => _ref,
thisWorksFine = () => _ref2; thisWorksFine = () => _ref2;

View File

@ -1,6 +1,6 @@
var Foo = require("Foo"); var Foo = require("Foo");
var _ref = /*#__PURE__*/<Foo />; var _ref = <Foo />;
function render() { function render() {
return _ref; return _ref;

View File

@ -1,6 +1,6 @@
var _ref = /*#__PURE__*/<b></b>; var _ref = <b></b>;
var _ref2 = /*#__PURE__*/<span></span>; var _ref2 = <span></span>;
function render() { function render() {
var children = _ref; var children = _ref;

View File

@ -4,11 +4,11 @@ const Parent = ({}) => _ref;
export default Parent; export default Parent;
var _ref2 = /*#__PURE__*/<div className="child"> var _ref2 = <div className="child">
ChildTextContent ChildTextContent
</div>; </div>;
let Child = () => _ref2, let Child = () => _ref2,
_ref = /*#__PURE__*/<div className="parent"> _ref = <div className="parent">
<Child /> <Child />
</div>; </div>;

View File

@ -1,6 +1,6 @@
function render() { function render() {
const bar = "bar", const bar = "bar",
_ref = /*#__PURE__*/<foo bar={bar} />, _ref = <foo bar={bar} />,
renderFoo = () => _ref; renderFoo = () => _ref;
return renderFoo(); return renderFoo();
@ -10,7 +10,7 @@ function render() {
const bar = "bar", const bar = "bar",
renderFoo = () => _ref2, renderFoo = () => _ref2,
baz = "baz", baz = "baz",
_ref2 = /*#__PURE__*/<foo bar={bar} baz={baz} />; _ref2 = <foo bar={bar} baz={baz} />;
return renderFoo(); return renderFoo();
} }

View File

@ -1,7 +1,7 @@
function render() { function render() {
var title = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; var title = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var _ref = /*#__PURE__*/<Component title={title} />; var _ref = <Component title={title} />;
return () => _ref; return () => _ref;
} }

View File

@ -1,6 +1,6 @@
function render(Component) { function render(Component) {
var text = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '', var text = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '',
_ref = /*#__PURE__*/<Component text={text} />; _ref = <Component text={text} />;
return function () { return function () {
return _ref; return _ref;

View File

@ -6,7 +6,7 @@ const Parent = ({}) => _ref;
export default Parent; export default Parent;
var _ref2 = /*#__PURE__*/<div className="child"> var _ref2 = <div className="child">
ChildTextContent ChildTextContent
</div>; </div>;
@ -14,6 +14,6 @@ let Child = () => _ref2;
Child = HOC(Child); Child = HOC(Child);
var _ref = /*#__PURE__*/<div className="parent"> var _ref = <div className="parent">
<Child /> <Child />
</div>; </div>;

View File

@ -1,5 +1,5 @@
function render(text) { function render(text) {
var _ref = /*#__PURE__*/<foo>{text}</foo>; var _ref = <foo>{text}</foo>;
return function () { return function () {
return _ref; return _ref;
@ -9,7 +9,7 @@ function render(text) {
var Foo2 = require("Foo"); var Foo2 = require("Foo");
function createComponent(text) { function createComponent(text) {
var _ref2 = /*#__PURE__*/<Foo2>{text}</Foo2>; var _ref2 = <Foo2>{text}</Foo2>;
return function render() { return function render() {
return _ref2; return _ref2;

View File

@ -1,4 +1,4 @@
var _ref = /*#__PURE__*/<div foo={notDeclared}></div>; var _ref = <div foo={notDeclared}></div>;
var Foo = React.createClass({ var Foo = React.createClass({
render: function render() { render: function render() {

View File

@ -1,10 +1,10 @@
var _ref = /*#__PURE__*/<foo />; var _ref = <foo />;
function render() { function render() {
return _ref; return _ref;
} }
var _ref2 = /*#__PURE__*/<div className="foo"><input type="checkbox" checked={true} /></div>; var _ref2 = <div className="foo"><input type="checkbox" checked={true} /></div>;
function render() { function render() {
return _ref2; return _ref2;

View File

@ -1,7 +1,7 @@
function render() { function render() {
var text = getText(); var text = getText();
var _ref = /*#__PURE__*/<foo>{text}</foo>; var _ref = <foo>{text}</foo>;
return function () { return function () {
return _ref; return _ref;

View File

@ -1,7 +1,7 @@
function render() { function render() {
this.component = "div"; this.component = "div";
var _ref = /*#__PURE__*/<this.component />; var _ref = <this.component />;
return () => _ref; return () => _ref;
} }

View File

@ -1,4 +1,4 @@
var _ref = /*#__PURE__*/<span>Sub Component</span>; var _ref = <span>Sub Component</span>;
class Component extends React.Component { class Component extends React.Component {
constructor(...args) { constructor(...args) {
@ -6,7 +6,7 @@ class Component extends React.Component {
this.subComponent = () => _ref; this.subComponent = () => _ref;
var _ref2 = /*#__PURE__*/<this.subComponent />; var _ref2 = <this.subComponent />;
this.render = () => _ref2; this.render = () => _ref2;
} }

View File

@ -1,10 +1,10 @@
var _ref = /*#__PURE__*/<span>Sub Component</span>; var _ref = <span>Sub Component</span>;
const els = { const els = {
subComponent: () => _ref subComponent: () => _ref
}; };
var _ref2 = /*#__PURE__*/<els.subComponent />; var _ref2 = <els.subComponent />;
class Component extends React.Component { class Component extends React.Component {
constructor(...args) { constructor(...args) {

View File

@ -1,6 +1,6 @@
function fn(Component, obj) { function fn(Component, obj) {
var data = obj.data, var data = obj.data,
_ref = /*#__PURE__*/<Component prop={data} />; _ref = <Component prop={data} />;
return () => _ref; return () => _ref;
} }

View File

@ -3,7 +3,7 @@ function render(_ref) {
className = _ref.className, className = _ref.className,
id = _ref.id; id = _ref.id;
var _ref2 = /*#__PURE__*/<Component text={text} className={className} id={id} />; var _ref2 = <Component text={text} className={className} id={id} />;
return () => _ref2; return () => _ref2;
} }

View File

@ -4,7 +4,7 @@ function render(_ref) {
id = _ref.id, id = _ref.id,
props = babelHelpers.objectWithoutProperties(_ref, ["text", "className", "id"]); props = babelHelpers.objectWithoutProperties(_ref, ["text", "className", "id"]);
var _ref2 = /*#__PURE__*/<Component text={text} className={className} id={id} />; var _ref2 = <Component text={text} className={className} id={id} />;
// intentionally ignoring props // intentionally ignoring props
return () => _ref2; return () => _ref2;

View File

@ -1,7 +1,7 @@
function render(_ref) { function render(_ref) {
let text = _ref.text; let text = _ref.text;
var _ref2 = /*#__PURE__*/<Component text={text} />; var _ref2 = <Component text={text} />;
return () => _ref2; return () => _ref2;
} }

View File

@ -1,5 +1,5 @@
function render(text) { function render(text) {
var _ref = /*#__PURE__*/<div>{text}</div>; var _ref = <div>{text}</div>;
return function () { return function () {
return _ref; return _ref;

View File

@ -1,5 +1,5 @@
function render(offset) { function render(offset) {
var _ref = /*#__PURE__*/<div tabIndex={offset + 1} />; var _ref = <div tabIndex={offset + 1} />;
return function () { return function () {
return _ref; return _ref;

View File

@ -1,6 +1,6 @@
const OFFSET = 3; const OFFSET = 3;
var _ref = /*#__PURE__*/<div tabIndex={OFFSET + 1} />; var _ref = <div tabIndex={OFFSET + 1} />;
var Foo = React.createClass({ var Foo = React.createClass({
render: function () { render: function () {

View File

@ -1,6 +1,6 @@
import Intl from 'react-intl'; import Intl from 'react-intl';
var _ref = /*#__PURE__*/<Intl.FormattedMessage id="someMessage.foo" defaultMessage={"Some text, " + "and some more too. {someValue}"} description="A test message for babel." values={{ var _ref = <Intl.FormattedMessage id="someMessage.foo" defaultMessage={"Some text, " + "and some more too. {someValue}"} description="A test message for babel." values={{
someValue: "A value." someValue: "A value."
}} />; }} />;

View File

@ -1,4 +1,4 @@
var _ref = /*#__PURE__*/<FormattedMessage id="someMessage.foo" defaultMessage={"Some text, " + "and some more too. {someValue}"} description="A test message for babel." values={{ var _ref = <FormattedMessage id="someMessage.foo" defaultMessage={"Some text, " + "and some more too. {someValue}"} description="A test message for babel." values={{
someValue: "A value." someValue: "A value."
}} />; }} />;

View File

@ -1,4 +1,4 @@
var _ref = /*#__PURE__*/<div data-text={"Some text, " + "and some more too."} />; var _ref = <div data-text={"Some text, " + "and some more too."} />;
var Foo = React.createClass({ var Foo = React.createClass({
render: function () { render: function () {

View File

@ -1,7 +1,7 @@
function render(text) { function render(text) {
text += "yes"; text += "yes";
var _ref = /*#__PURE__*/<div>{text}</div>; var _ref = <div>{text}</div>;
return function () { return function () {
return _ref; return _ref;

View File

@ -1,4 +1,4 @@
var _ref = /*#__PURE__*/<div className="class-name"> var _ref = <div className="class-name">
Text Text
</div>; </div>;

View File

@ -1,6 +1,6 @@
function fn(Component) { function fn(Component) {
var data = "prop", var data = "prop",
_ref = /*#__PURE__*/<Component prop={data} />; _ref = <Component prop={data} />;
return () => _ref; return () => _ref;
} }

View File

@ -62,6 +62,8 @@ export default declare(api => {
if (!hasKey && state.args.length > 2) { if (!hasKey && state.args.length > 2) {
state.args.splice(2, 0, t.unaryExpression("void", t.numericLiteral(0))); state.args.splice(2, 0, t.unaryExpression("void", t.numericLiteral(0)));
} }
state.pure = true;
}, },
}); });
return { return {

View File

@ -1,3 +1,4 @@
/*#__PURE__*/
babelHelpers.jsx("div", { babelHelpers.jsx("div", {
children: "foo" children: "foo"
}, void 0, "bar"); }, void 0, "bar");

View File

@ -1,3 +1,4 @@
/*#__PURE__*/
babelHelpers.jsx(Baz, { babelHelpers.jsx(Baz, {
foo: "bar" foo: "bar"
}); });

View File

@ -1 +1,2 @@
/*#__PURE__*/
babelHelpers.jsx(Baz, {}); babelHelpers.jsx(Baz, {});

View File

@ -1,6 +1,6 @@
var TestComponent = React.createClass({ var TestComponent = React.createClass({
render: function () { render: function () {
return babelHelpers.jsx("span", { return /*#__PURE__*/babelHelpers.jsx("span", {
className: this.props.someProp className: this.props.someProp
}); });
} }

View File

@ -1 +1,2 @@
React.createElement(React.Fragment, null, babelHelpers.jsx("span", {}), babelHelpers.jsx("div", {})); /*#__PURE__*/
React.createElement(React.Fragment, null, /*#__PURE__*/babelHelpers.jsx("span", {}), /*#__PURE__*/babelHelpers.jsx("div", {}));

View File

@ -1,3 +1,4 @@
/*#__PURE__*/
babelHelpers.jsx("foo", { babelHelpers.jsx("foo", {
bar: "foo" bar: "foo"
}); });

View File

@ -1 +1,2 @@
/*#__PURE__*/
babelHelpers.jsx("foo", {}); babelHelpers.jsx("foo", {});

View File

@ -1,3 +1,4 @@
/*#__PURE__*/
babelHelpers.jsx(Foo, { babelHelpers.jsx(Foo, {
"data-value": "bar" "data-value": "bar"
}, "foo" + "baz"); }, "foo" + "baz");

View File

@ -1,3 +1,4 @@
/*#__PURE__*/
babelHelpers.jsx(Foo, { babelHelpers.jsx(Foo, {
"data-value": "bar" "data-value": "bar"
}, "foo"); }, "foo");

View File

@ -4,5 +4,5 @@ var _export = require("./export");
//index.js file //index.js file
function ParentComponent() { function ParentComponent() {
return babelHelpers.jsx(_export.form.TestComponent, {}); return /*#__PURE__*/babelHelpers.jsx(_export.form.TestComponent, {});
} }

View File

@ -7,6 +7,6 @@ exports.default = void 0;
var _reactBootstrap = require("react-bootstrap"); var _reactBootstrap = require("react-bootstrap");
var _default = CustomModal = () => babelHelpers.jsx(_reactBootstrap.Modal.Header, {}, void 0, "foobar"); var _default = CustomModal = () => /*#__PURE__*/babelHelpers.jsx(_reactBootstrap.Modal.Header, {}, void 0, "foobar");
exports.default = _default; exports.default = _default;

View File

@ -1 +1,2 @@
/*#__PURE__*/
babelHelpers.jsx(Baz, {}); babelHelpers.jsx(Baz, {});

View File

@ -1,3 +1,4 @@
/*#__PURE__*/
babelHelpers.jsx(Foo, { babelHelpers.jsx(Foo, {
className: "foo" className: "foo"
}, void 0, bar, babelHelpers.jsx(Baz, {}, "baz")); }, void 0, bar, /*#__PURE__*/babelHelpers.jsx(Baz, {}, "baz"));

View File

@ -1,3 +1,4 @@
/*#__PURE__*/
babelHelpers.jsx("div", { babelHelpers.jsx("div", {
className: "foo" className: "foo"
}, void 0, bar); }, void 0, bar);

View File

@ -1,3 +1,4 @@
/*#__PURE__*/
babelHelpers.jsx("div", { babelHelpers.jsx("div", {
className: "foo" className: "foo"
}, void 0, bar, babelHelpers.jsx(Baz, {}, "baz")); }, void 0, bar, /*#__PURE__*/babelHelpers.jsx(Baz, {}, "baz"));

View File

@ -1,3 +1,4 @@
/*#__PURE__*/
React.createElement(Foo, { React.createElement(Foo, {
ref: "bar" ref: "bar"
}); });

View File

@ -1,3 +1,4 @@
/*#__PURE__*/
babelHelpers.jsx(Baz, { babelHelpers.jsx(Baz, {
foo: "bar" foo: "bar"
}); });

View File

@ -1 +1,2 @@
/*#__PURE__*/
babelHelpers.jsx(Baz, {}); babelHelpers.jsx(Baz, {});

View File

@ -1,3 +1,4 @@
/*#__PURE__*/
babelHelpers.jsx("foo", { babelHelpers.jsx("foo", {
bar: "foo" bar: "foo"
}); });

View File

@ -1 +1,2 @@
/*#__PURE__*/
babelHelpers.jsx("foo", {}); babelHelpers.jsx("foo", {});

View File

@ -1,3 +1,4 @@
/*#__PURE__*/
babelHelpers.jsx(Foo, { babelHelpers.jsx(Foo, {
bar: true bar: true
}); });

View File

@ -1 +1,2 @@
/*#__PURE__*/
React.createElement(Foo, bar); React.createElement(Foo, bar);

View File

@ -1,3 +1,3 @@
var test = babelHelpers.jsx(T, { var test = /*#__PURE__*/babelHelpers.jsx(T, {
default: " some string " default: " some string "
}); });

View File

@ -4,6 +4,8 @@ import { declare } from "@babel/helper-plugin-utils";
import { types as t } from "@babel/core"; import { types as t } from "@babel/core";
export default declare((api, options) => { export default declare((api, options) => {
const PURE_ANNOTATION = options.pure;
const visitor = helper(api, { const visitor = helper(api, {
pre(state) { pre(state) {
const tagName = state.tagName; const tagName = state.tagName;
@ -20,6 +22,9 @@ export default declare((api, options) => {
state.createElementCallee = pass.get( state.createElementCallee = pass.get(
"@babel/plugin-react-jsx/createElementIdentifier", "@babel/plugin-react-jsx/createElementIdentifier",
)(); )();
state.pure =
PURE_ANNOTATION ?? !pass.get("@babel/plugin-react-jsx/pragmaSet");
} else { } else {
state.jsxCallee = pass.get("@babel/plugin-react-jsx/jsxIdentifier")(); state.jsxCallee = pass.get("@babel/plugin-react-jsx/jsxIdentifier")();
state.jsxStaticCallee = pass.get( state.jsxStaticCallee = pass.get(
@ -28,6 +33,10 @@ export default declare((api, options) => {
state.createElementCallee = pass.get( state.createElementCallee = pass.get(
"@babel/plugin-react-jsx/createElementIdentifier", "@babel/plugin-react-jsx/createElementIdentifier",
)(); )();
state.pure =
PURE_ANNOTATION ??
!pass.get("@babel/plugin-react-jsx/importSourceSet");
} }
}, },

View File

@ -3,23 +3,23 @@ import { jsxDEV as _jsxDEV } from "react/jsx-dev-runtime";
import { Fragment as _Fragment } from "react/jsx-dev-runtime"; import { Fragment as _Fragment } from "react/jsx-dev-runtime";
var _jsxFileName = "<CWD>/packages/babel-plugin-transform-react-jsx-development/test/fixtures/linux/auto-import-dev/input.js"; var _jsxFileName = "<CWD>/packages/babel-plugin-transform-react-jsx-development/test/fixtures/linux/auto-import-dev/input.js";
var x = _jsxDEV(_Fragment, { var x = /*#__PURE__*/_jsxDEV(_Fragment, {
children: _jsxDEV("div", { children: /*#__PURE__*/_jsxDEV("div", {
children: [_jsxDEV("div", {}, "1", false, { children: [/*#__PURE__*/_jsxDEV("div", {}, "1", false, {
fileName: _jsxFileName, fileName: _jsxFileName,
lineNumber: 4, lineNumber: 4,
columnNumber: 7 columnNumber: 7
}, this), _jsxDEV("div", { }, this), /*#__PURE__*/_jsxDEV("div", {
meow: "wolf" meow: "wolf"
}, "2", false, { }, "2", false, {
fileName: _jsxFileName, fileName: _jsxFileName,
lineNumber: 5, lineNumber: 5,
columnNumber: 7 columnNumber: 7
}, this), _jsxDEV("div", {}, "3", false, { }, this), /*#__PURE__*/_jsxDEV("div", {}, "3", false, {
fileName: _jsxFileName, fileName: _jsxFileName,
lineNumber: 6, lineNumber: 6,
columnNumber: 7 columnNumber: 7
}, this), _createElement("div", { ...props, }, this), /*#__PURE__*/_createElement("div", { ...props,
key: "4", key: "4",
__source: { __source: {
fileName: _jsxFileName, fileName: _jsxFileName,

View File

@ -1,12 +1,12 @@
var _jsxFileName = "<CWD>/packages/babel-plugin-transform-react-jsx-development/test/fixtures/linux/classic-runtime/input.js"; var _jsxFileName = "<CWD>/packages/babel-plugin-transform-react-jsx-development/test/fixtures/linux/classic-runtime/input.js";
var x = React.createElement(React.Fragment, null, React.createElement("div", { var x = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
__source: { __source: {
fileName: _jsxFileName, fileName: _jsxFileName,
lineNumber: 3, lineNumber: 3,
columnNumber: 5 columnNumber: 5
}, },
__self: this __self: this
}, React.createElement("div", { }, /*#__PURE__*/React.createElement("div", {
key: "1", key: "1",
__source: { __source: {
fileName: _jsxFileName, fileName: _jsxFileName,
@ -14,7 +14,7 @@ var x = React.createElement(React.Fragment, null, React.createElement("div", {
columnNumber: 9 columnNumber: 9
}, },
__self: this __self: this
}), React.createElement("div", { }), /*#__PURE__*/React.createElement("div", {
key: "2", key: "2",
meow: "wolf", meow: "wolf",
__source: { __source: {
@ -23,7 +23,7 @@ var x = React.createElement(React.Fragment, null, React.createElement("div", {
columnNumber: 9 columnNumber: 9
}, },
__self: this __self: this
}), React.createElement("div", { }), /*#__PURE__*/React.createElement("div", {
key: "3", key: "3",
__source: { __source: {
fileName: _jsxFileName, fileName: _jsxFileName,
@ -31,7 +31,7 @@ var x = React.createElement(React.Fragment, null, React.createElement("div", {
columnNumber: 9 columnNumber: 9
}, },
__self: this __self: this
}), React.createElement("div", { ...props, }), /*#__PURE__*/React.createElement("div", { ...props,
key: "4", key: "4",
__source: { __source: {
fileName: _jsxFileName, fileName: _jsxFileName,

View File

@ -2,8 +2,8 @@ var _reactJsxDevRuntime = require("react/jsx-dev-runtime");
var _jsxFileName = "<CWD>/packages/babel-plugin-transform-react-jsx-development/test/fixtures/linux/fragments/input.js"; var _jsxFileName = "<CWD>/packages/babel-plugin-transform-react-jsx-development/test/fixtures/linux/fragments/input.js";
var x = _reactJsxDevRuntime.jsxDEV(_reactJsxDevRuntime.Fragment, { var x = /*#__PURE__*/_reactJsxDevRuntime.jsxDEV(_reactJsxDevRuntime.Fragment, {
children: _reactJsxDevRuntime.jsxDEV("div", {}, void 0, false, { children: /*#__PURE__*/_reactJsxDevRuntime.jsxDEV("div", {}, void 0, false, {
fileName: _jsxFileName, fileName: _jsxFileName,
lineNumber: 1, lineNumber: 1,
columnNumber: 11 columnNumber: 11

View File

@ -2,7 +2,7 @@ var _reactJsxDevRuntime = require("react/jsx-dev-runtime");
var _jsxFileName = "<CWD>/packages/babel-plugin-transform-react-jsx-development/test/fixtures/linux/handle-fragments-with-key/input.js"; var _jsxFileName = "<CWD>/packages/babel-plugin-transform-react-jsx-development/test/fixtures/linux/handle-fragments-with-key/input.js";
var x = _reactJsxDevRuntime.jsxDEV(React.Fragment, {}, "foo", false, { var x = /*#__PURE__*/_reactJsxDevRuntime.jsxDEV(React.Fragment, {}, "foo", false, {
fileName: _jsxFileName, fileName: _jsxFileName,
lineNumber: 1, lineNumber: 1,
columnNumber: 9 columnNumber: 9

View File

@ -2,12 +2,12 @@ var _reactJsxDevRuntime = require("react/jsx-dev-runtime");
var _jsxFileName = "<CWD>/packages/babel-plugin-transform-react-jsx-development/test/fixtures/linux/handle-nonstatic-children/input.js"; var _jsxFileName = "<CWD>/packages/babel-plugin-transform-react-jsx-development/test/fixtures/linux/handle-nonstatic-children/input.js";
var x = _reactJsxDevRuntime.jsxDEV("div", { var x = /*#__PURE__*/_reactJsxDevRuntime.jsxDEV("div", {
children: [_reactJsxDevRuntime.jsxDEV("span", {}, "0", false, { children: [/*#__PURE__*/_reactJsxDevRuntime.jsxDEV("span", {}, "0", false, {
fileName: _jsxFileName, fileName: _jsxFileName,
lineNumber: 1, lineNumber: 1,
columnNumber: 16 columnNumber: 16
}, this), _reactJsxDevRuntime.jsxDEV("span", {}, "1", false, { }, this), /*#__PURE__*/_reactJsxDevRuntime.jsxDEV("span", {}, "1", false, {
fileName: _jsxFileName, fileName: _jsxFileName,
lineNumber: 1, lineNumber: 1,
columnNumber: 36 columnNumber: 36

View File

@ -2,16 +2,16 @@ var _reactJsxDevRuntime = require("react/jsx-dev-runtime");
var _jsxFileName = "<CWD>/packages/babel-plugin-transform-react-jsx-development/test/fixtures/linux/handle-static-children/input.js"; var _jsxFileName = "<CWD>/packages/babel-plugin-transform-react-jsx-development/test/fixtures/linux/handle-static-children/input.js";
var x = _reactJsxDevRuntime.jsxDEV("div", { var x = /*#__PURE__*/_reactJsxDevRuntime.jsxDEV("div", {
children: [_reactJsxDevRuntime.jsxDEV("span", {}, void 0, false, { children: [/*#__PURE__*/_reactJsxDevRuntime.jsxDEV("span", {}, void 0, false, {
fileName: _jsxFileName, fileName: _jsxFileName,
lineNumber: 3, lineNumber: 3,
columnNumber: 5 columnNumber: 5
}, this), [_reactJsxDevRuntime.jsxDEV("span", {}, "0", false, { }, this), [/*#__PURE__*/_reactJsxDevRuntime.jsxDEV("span", {}, "0", false, {
fileName: _jsxFileName, fileName: _jsxFileName,
lineNumber: 4, lineNumber: 4,
columnNumber: 7 columnNumber: 7
}, this), _reactJsxDevRuntime.jsxDEV("span", {}, "1", false, { }, this), /*#__PURE__*/_reactJsxDevRuntime.jsxDEV("span", {}, "1", false, {
fileName: _jsxFileName, fileName: _jsxFileName,
lineNumber: 4, lineNumber: 4,
columnNumber: 27 columnNumber: 27

View File

@ -3,23 +3,23 @@ import { jsxDEV as _jsxDEV } from "react/jsx-dev-runtime";
import { Fragment as _Fragment } from "react/jsx-dev-runtime"; import { Fragment as _Fragment } from "react/jsx-dev-runtime";
var _jsxFileName = "C:\\Users\\travis\\build\\babel\\babel\\packages\\babel-plugin-transform-react-jsx-development\\test\\fixtures\\windows\\auto-import-dev-windows\\input.js"; var _jsxFileName = "C:\\Users\\travis\\build\\babel\\babel\\packages\\babel-plugin-transform-react-jsx-development\\test\\fixtures\\windows\\auto-import-dev-windows\\input.js";
var x = _jsxDEV(_Fragment, { var x = /*#__PURE__*/_jsxDEV(_Fragment, {
children: _jsxDEV("div", { children: /*#__PURE__*/_jsxDEV("div", {
children: [_jsxDEV("div", {}, "1", false, { children: [/*#__PURE__*/_jsxDEV("div", {}, "1", false, {
fileName: _jsxFileName, fileName: _jsxFileName,
lineNumber: 4, lineNumber: 4,
columnNumber: 7 columnNumber: 7
}, this), _jsxDEV("div", { }, this), /*#__PURE__*/_jsxDEV("div", {
meow: "wolf" meow: "wolf"
}, "2", false, { }, "2", false, {
fileName: _jsxFileName, fileName: _jsxFileName,
lineNumber: 5, lineNumber: 5,
columnNumber: 7 columnNumber: 7
}, this), _jsxDEV("div", {}, "3", false, { }, this), /*#__PURE__*/_jsxDEV("div", {}, "3", false, {
fileName: _jsxFileName, fileName: _jsxFileName,
lineNumber: 6, lineNumber: 6,
columnNumber: 7 columnNumber: 7
}, this), _createElement("div", { ...props, }, this), /*#__PURE__*/_createElement("div", { ...props,
key: "4", key: "4",
__source: { __source: {
fileName: _jsxFileName, fileName: _jsxFileName,

View File

@ -1,12 +1,12 @@
var _jsxFileName = "C:\\Users\\travis\\build\\babel\\babel\\packages\\babel-plugin-transform-react-jsx-development\\test\\fixtures\\windows\\classic-runtime-windows\\input.js"; var _jsxFileName = "C:\\Users\\travis\\build\\babel\\babel\\packages\\babel-plugin-transform-react-jsx-development\\test\\fixtures\\windows\\classic-runtime-windows\\input.js";
var x = React.createElement(React.Fragment, null, React.createElement("div", { var x = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
__source: { __source: {
fileName: _jsxFileName, fileName: _jsxFileName,
lineNumber: 3, lineNumber: 3,
columnNumber: 5 columnNumber: 5
}, },
__self: this __self: this
}, React.createElement("div", { }, /*#__PURE__*/React.createElement("div", {
key: "1", key: "1",
__source: { __source: {
fileName: _jsxFileName, fileName: _jsxFileName,
@ -14,7 +14,7 @@ var x = React.createElement(React.Fragment, null, React.createElement("div", {
columnNumber: 7 columnNumber: 7
}, },
__self: this __self: this
}), React.createElement("div", { }), /*#__PURE__*/React.createElement("div", {
key: "2", key: "2",
meow: "wolf", meow: "wolf",
__source: { __source: {
@ -23,7 +23,7 @@ var x = React.createElement(React.Fragment, null, React.createElement("div", {
columnNumber: 7 columnNumber: 7
}, },
__self: this __self: this
}), React.createElement("div", { }), /*#__PURE__*/React.createElement("div", {
key: "3", key: "3",
__source: { __source: {
fileName: _jsxFileName, fileName: _jsxFileName,
@ -31,7 +31,7 @@ var x = React.createElement(React.Fragment, null, React.createElement("div", {
columnNumber: 7 columnNumber: 7
}, },
__self: this __self: this
}), React.createElement("div", { ...props, }), /*#__PURE__*/React.createElement("div", { ...props,
key: "4", key: "4",
__source: { __source: {
fileName: _jsxFileName, fileName: _jsxFileName,

View File

@ -2,8 +2,8 @@ var _reactJsxDevRuntime = require("react/jsx-dev-runtime");
var _jsxFileName = "C:\\Users\\travis\\build\\babel\\babel\\packages\\babel-plugin-transform-react-jsx-development\\test\\fixtures\\windows\\fragments-windows\\input.js"; var _jsxFileName = "C:\\Users\\travis\\build\\babel\\babel\\packages\\babel-plugin-transform-react-jsx-development\\test\\fixtures\\windows\\fragments-windows\\input.js";
var x = _reactJsxDevRuntime.jsxDEV(_reactJsxDevRuntime.Fragment, { var x = /*#__PURE__*/_reactJsxDevRuntime.jsxDEV(_reactJsxDevRuntime.Fragment, {
children: _reactJsxDevRuntime.jsxDEV("div", {}, void 0, false, { children: /*#__PURE__*/_reactJsxDevRuntime.jsxDEV("div", {}, void 0, false, {
fileName: _jsxFileName, fileName: _jsxFileName,
lineNumber: 1, lineNumber: 1,
columnNumber: 11 columnNumber: 11

View File

@ -2,7 +2,7 @@ var _reactJsxDevRuntime = require("react/jsx-dev-runtime");
var _jsxFileName = "C:\\Users\\travis\\build\\babel\\babel\\packages\\babel-plugin-transform-react-jsx-development\\test\\fixtures\\windows\\handle-fragments-with-key-windows\\input.js"; var _jsxFileName = "C:\\Users\\travis\\build\\babel\\babel\\packages\\babel-plugin-transform-react-jsx-development\\test\\fixtures\\windows\\handle-fragments-with-key-windows\\input.js";
var x = _reactJsxDevRuntime.jsxDEV(React.Fragment, {}, "foo", false, { var x = /*#__PURE__*/_reactJsxDevRuntime.jsxDEV(React.Fragment, {}, "foo", false, {
fileName: _jsxFileName, fileName: _jsxFileName,
lineNumber: 1, lineNumber: 1,
columnNumber: 9 columnNumber: 9

View File

@ -2,12 +2,12 @@ var _reactJsxDevRuntime = require("react/jsx-dev-runtime");
var _jsxFileName = "C:\\Users\\travis\\build\\babel\\babel\\packages\\babel-plugin-transform-react-jsx-development\\test\\fixtures\\windows\\handle-nonstatic-children-windows\\input.js"; var _jsxFileName = "C:\\Users\\travis\\build\\babel\\babel\\packages\\babel-plugin-transform-react-jsx-development\\test\\fixtures\\windows\\handle-nonstatic-children-windows\\input.js";
var x = _reactJsxDevRuntime.jsxDEV("div", { var x = /*#__PURE__*/_reactJsxDevRuntime.jsxDEV("div", {
children: [_reactJsxDevRuntime.jsxDEV("span", {}, '0', false, { children: [/*#__PURE__*/_reactJsxDevRuntime.jsxDEV("span", {}, '0', false, {
fileName: _jsxFileName, fileName: _jsxFileName,
lineNumber: 3, lineNumber: 3,
columnNumber: 11 columnNumber: 11
}, this), _reactJsxDevRuntime.jsxDEV("span", {}, '1', false, { }, this), /*#__PURE__*/_reactJsxDevRuntime.jsxDEV("span", {}, '1', false, {
fileName: _jsxFileName, fileName: _jsxFileName,
lineNumber: 3, lineNumber: 3,
columnNumber: 31 columnNumber: 31

View File

@ -2,16 +2,16 @@ var _reactJsxDevRuntime = require("react/jsx-dev-runtime");
var _jsxFileName = "C:\\Users\\travis\\build\\babel\\babel\\packages\\babel-plugin-transform-react-jsx-development\\test\\fixtures\\windows\\handle-static-children-windows\\input.js"; var _jsxFileName = "C:\\Users\\travis\\build\\babel\\babel\\packages\\babel-plugin-transform-react-jsx-development\\test\\fixtures\\windows\\handle-static-children-windows\\input.js";
var x = _reactJsxDevRuntime.jsxDEV("div", { var x = /*#__PURE__*/_reactJsxDevRuntime.jsxDEV("div", {
children: [_reactJsxDevRuntime.jsxDEV("span", {}, void 0, false, { children: [/*#__PURE__*/_reactJsxDevRuntime.jsxDEV("span", {}, void 0, false, {
fileName: _jsxFileName, fileName: _jsxFileName,
lineNumber: 3, lineNumber: 3,
columnNumber: 9 columnNumber: 9
}, this), [_reactJsxDevRuntime.jsxDEV("span", {}, '0', false, { }, this), [/*#__PURE__*/_reactJsxDevRuntime.jsxDEV("span", {}, '0', false, {
fileName: _jsxFileName, fileName: _jsxFileName,
lineNumber: 4, lineNumber: 4,
columnNumber: 11 columnNumber: 11
}, this), _reactJsxDevRuntime.jsxDEV("span", {}, '1', false, { }, this), /*#__PURE__*/_reactJsxDevRuntime.jsxDEV("span", {}, '1', false, {
fileName: _jsxFileName, fileName: _jsxFileName,
lineNumber: 4, lineNumber: 4,
columnNumber: 31 columnNumber: 31

View File

@ -4,6 +4,8 @@ import { declare } from "@babel/helper-plugin-utils";
import { types as t } from "@babel/core"; import { types as t } from "@babel/core";
export default declare((api, options) => { export default declare((api, options) => {
const PURE_ANNOTATION = options.pure;
const visitor = helper(api, { const visitor = helper(api, {
pre(state) { pre(state) {
const tagName = state.tagName; const tagName = state.tagName;
@ -20,6 +22,9 @@ export default declare((api, options) => {
state.createElementCallee = pass.get( state.createElementCallee = pass.get(
"@babel/plugin-react-jsx/createElementIdentifier", "@babel/plugin-react-jsx/createElementIdentifier",
)(); )();
state.pure =
PURE_ANNOTATION ?? !pass.get("@babel/plugin-react-jsx/pragmaSet");
} else { } else {
state.jsxCallee = pass.get("@babel/plugin-react-jsx/jsxIdentifier")(); state.jsxCallee = pass.get("@babel/plugin-react-jsx/jsxIdentifier")();
state.jsxStaticCallee = pass.get( state.jsxStaticCallee = pass.get(
@ -28,6 +33,10 @@ export default declare((api, options) => {
state.createElementCallee = pass.get( state.createElementCallee = pass.get(
"@babel/plugin-react-jsx/createElementIdentifier", "@babel/plugin-react-jsx/createElementIdentifier",
)(); )();
state.pure =
PURE_ANNOTATION ??
!pass.get("@babel/plugin-react-jsx/importSourceSet");
} }
}, },

View File

@ -3,12 +3,18 @@ import jsx from "@babel/plugin-syntax-jsx";
import helper from "@babel/helper-builder-react-jsx"; import helper from "@babel/helper-builder-react-jsx";
import { types as t } from "@babel/core"; import { types as t } from "@babel/core";
const DEFAULT = {
pragma: "React.createElement",
pragmaFrag: "React.Fragment",
};
export default declare((api, options) => { export default declare((api, options) => {
const THROW_IF_NAMESPACE = const THROW_IF_NAMESPACE =
options.throwIfNamespace === undefined ? true : !!options.throwIfNamespace; options.throwIfNamespace === undefined ? true : !!options.throwIfNamespace;
const PRAGMA_DEFAULT = options.pragma || "React.createElement"; const PRAGMA_DEFAULT = options.pragma || DEFAULT.pragma;
const PRAGMA_FRAG_DEFAULT = options.pragmaFrag || "React.Fragment"; const PRAGMA_FRAG_DEFAULT = options.pragmaFrag || DEFAULT.pragmaFrag;
const PURE_ANNOTATION = options.pure;
const JSX_ANNOTATION_REGEX = /\*?\s*@jsx\s+([^\s]+)/; const JSX_ANNOTATION_REGEX = /\*?\s*@jsx\s+([^\s]+)/;
const JSX_FRAG_ANNOTATION_REGEX = /\*?\s*@jsxFrag\s+([^\s]+)/; const JSX_FRAG_ANNOTATION_REGEX = /\*?\s*@jsxFrag\s+([^\s]+)/;
@ -35,6 +41,7 @@ export default declare((api, options) => {
post(state, pass) { post(state, pass) {
state.callee = pass.get("jsxIdentifier")(); state.callee = pass.get("jsxIdentifier")();
state.pure = PURE_ANNOTATION ?? !pass.get("pragmaSet");
}, },
throwIfNamespace: THROW_IF_NAMESPACE, throwIfNamespace: THROW_IF_NAMESPACE,
@ -46,20 +53,16 @@ export default declare((api, options) => {
let pragma = PRAGMA_DEFAULT; let pragma = PRAGMA_DEFAULT;
let pragmaFrag = PRAGMA_FRAG_DEFAULT; let pragmaFrag = PRAGMA_FRAG_DEFAULT;
let pragmaSet = !!options.pragma;
let pragmaFragSet = !!options.pragmaFrag;
if (file.ast.comments) { if (file.ast.comments) {
for (const comment of (file.ast.comments: Array<Object>)) { for (const comment of (file.ast.comments: Array<Object>)) {
const jsxMatches = JSX_ANNOTATION_REGEX.exec(comment.value); const jsxMatches = JSX_ANNOTATION_REGEX.exec(comment.value);
if (jsxMatches) { if (jsxMatches) {
pragma = jsxMatches[1]; pragma = jsxMatches[1];
pragmaSet = true;
} }
const jsxFragMatches = JSX_FRAG_ANNOTATION_REGEX.exec(comment.value); const jsxFragMatches = JSX_FRAG_ANNOTATION_REGEX.exec(comment.value);
if (jsxFragMatches) { if (jsxFragMatches) {
pragmaFrag = jsxFragMatches[1]; pragmaFrag = jsxFragMatches[1];
pragmaFragSet = true;
} }
} }
} }
@ -67,8 +70,8 @@ export default declare((api, options) => {
state.set("jsxIdentifier", createIdentifierParser(pragma)); state.set("jsxIdentifier", createIdentifierParser(pragma));
state.set("jsxFragIdentifier", createIdentifierParser(pragmaFrag)); state.set("jsxFragIdentifier", createIdentifierParser(pragmaFrag));
state.set("usedFragment", false); state.set("usedFragment", false);
state.set("pragmaSet", pragmaSet); state.set("pragmaSet", pragma !== DEFAULT.pragma);
state.set("pragmaFragSet", pragmaFragSet); state.set("pragmaFragSet", pragmaFrag !== DEFAULT.pragmaFrag);
}, },
exit(path, state) { exit(path, state) {
if ( if (

View File

@ -3,11 +3,11 @@ import { jsxs as _jsxs } from "react/jsx-runtime";
import { jsx as _jsx } from "react/jsx-runtime"; import { jsx as _jsx } from "react/jsx-runtime";
import { Fragment as _Fragment } from "react/jsx-runtime"; import { Fragment as _Fragment } from "react/jsx-runtime";
var x = _jsx(_Fragment, { var x = /*#__PURE__*/_jsx(_Fragment, {
children: _jsxs("div", { children: /*#__PURE__*/_jsxs("div", {
children: [_jsx("div", {}, "1"), _jsx("div", { children: [/*#__PURE__*/_jsx("div", {}, "1"), /*#__PURE__*/_jsx("div", {
meow: "wolf" meow: "wolf"
}, "2"), _jsx("div", {}, "3"), _createElement("div", { ...props, }, "2"), /*#__PURE__*/_jsx("div", {}, "3"), /*#__PURE__*/_createElement("div", { ...props,
key: "4" key: "4"
})] })]
}) })

View File

@ -2,11 +2,11 @@ var _react = require("react");
var _reactJsxRuntime = require("react/jsx-runtime"); var _reactJsxRuntime = require("react/jsx-runtime");
var x = _reactJsxRuntime.jsx(_reactJsxRuntime.Fragment, { var x = /*#__PURE__*/_reactJsxRuntime.jsx(_reactJsxRuntime.Fragment, {
children: _reactJsxRuntime.jsxs("div", { children: /*#__PURE__*/_reactJsxRuntime.jsxs("div", {
children: [_reactJsxRuntime.jsx("div", {}, "1"), _reactJsxRuntime.jsx("div", { children: [/*#__PURE__*/_reactJsxRuntime.jsx("div", {}, "1"), /*#__PURE__*/_reactJsxRuntime.jsx("div", {
meow: "wolf" meow: "wolf"
}, "2"), _reactJsxRuntime.jsx("div", {}, "3"), _react.createElement("div", { ...props, }, "2"), /*#__PURE__*/_reactJsxRuntime.jsx("div", {}, "3"), /*#__PURE__*/_react.createElement("div", { ...props,
key: "4" key: "4"
})] })]
}) })

View File

@ -15,11 +15,11 @@ const Bar = () => {
var jsx = 1; var jsx = 1;
var _jsx = 2; var _jsx = 2;
return _jsx2("div", {}); return /*#__PURE__*/_jsx2("div", {});
} }
; ;
return _jsx2("span", {}); return /*#__PURE__*/_jsx2("span", {});
}; };
}; };
}; };

View File

@ -15,11 +15,11 @@ const Bar = () => {
var jsx = 1; var jsx = 1;
var _jsx = 2; var _jsx = 2;
return _reactJsxRuntime.jsx("div", {}); return /*#__PURE__*/_reactJsxRuntime.jsx("div", {});
} }
; ;
return _reactJsxRuntime.jsx("span", {}); return /*#__PURE__*/_reactJsxRuntime.jsx("span", {});
}; };
}; };
}; };

View File

@ -6,10 +6,10 @@ var y = react.createElement("div", {
foo: 1 foo: 1
}); });
var x = _jsxs("div", { var x = /*#__PURE__*/_jsxs("div", {
children: [_jsx("div", {}, "1"), _jsx("div", { children: [/*#__PURE__*/_jsx("div", {}, "1"), /*#__PURE__*/_jsx("div", {
meow: "wolf" meow: "wolf"
}, "2"), _jsx("div", {}, "3"), _createElement("div", { ...props, }, "2"), /*#__PURE__*/_jsx("div", {}, "3"), /*#__PURE__*/_createElement("div", { ...props,
key: "4" key: "4"
})] })]
}); });

View File

@ -1,5 +1,6 @@
import { jsx as _jsx } from "react/jsx-runtime"; import { jsx as _jsx } from "react/jsx-runtime";
/*#__PURE__*/
_jsx(Component, { ...props, _jsx(Component, { ...props,
sound: "moo" sound: "moo"
}); });

View File

@ -4,7 +4,7 @@ var foo = function () {
var _this = this; var _this = this;
return function () { return function () {
return _jsx(_this, {}); return /*#__PURE__*/_jsx(_this, {});
}; };
}; };
@ -12,6 +12,6 @@ var bar = function () {
var _this2 = this; var _this2 = this;
return function () { return function () {
return _jsx(_this2.foo, {}); return /*#__PURE__*/_jsx(_this2.foo, {});
}; };
}; };

View File

@ -1,5 +1,5 @@
import { jsx as _jsx } from "react/jsx-runtime"; import { jsx as _jsx } from "react/jsx-runtime";
var div = _jsx(Component, { ...props, var div = /*#__PURE__*/_jsx(Component, { ...props,
foo: "bar" foo: "bar"
}); });

View File

@ -1,8 +1,8 @@
import { jsx as _jsx } from "react/jsx-runtime"; import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime"; import { jsxs as _jsxs } from "react/jsx-runtime";
var x = _jsxs("div", { var x = /*#__PURE__*/_jsxs("div", {
children: ["foo", "bar", "baz", _jsx("div", { children: ["foo", "bar", "baz", /*#__PURE__*/_jsx("div", {
children: "buz bang" children: "buz bang"
}), "qux", null, "quack"] }), "qux", null, "quack"]
}); });

View File

@ -1,5 +1,6 @@
import { jsxs as _jsxs } from "react/jsx-runtime"; import { jsxs as _jsxs } from "react/jsx-runtime";
/*#__PURE__*/
_jsxs(Text, { _jsxs(Text, {
children: ["To get started, edit index.ios.js!!!", "\n", "Press Cmd+R to reload"] children: ["To get started, edit index.ios.js!!!", "\n", "Press Cmd+R to reload"]
}); });

View File

@ -1,4 +1,4 @@
import { jsx as _jsx } from "react/jsx-runtime"; import { jsx as _jsx } from "react/jsx-runtime";
import * as React from "react"; import * as React from "react";
var x = _jsx(React.Fragment, {}, "foo"); var x = /*#__PURE__*/_jsx(React.Fragment, {}, "foo");

View File

@ -1,4 +1,4 @@
import { jsx as _jsx } from "react/jsx-runtime"; import { jsx as _jsx } from "react/jsx-runtime";
import { Fragment as _Fragment } from "react/jsx-runtime"; import { Fragment as _Fragment } from "react/jsx-runtime";
var x = _jsx(_Fragment, {}); var x = /*#__PURE__*/_jsx(_Fragment, {});

View File

@ -1,6 +1,6 @@
import { jsx as _jsx } from "react/jsx-runtime"; import { jsx as _jsx } from "react/jsx-runtime";
import { Fragment as _Fragment } from "react/jsx-runtime"; import { Fragment as _Fragment } from "react/jsx-runtime";
var x = _jsx(_Fragment, { var x = /*#__PURE__*/_jsx(_Fragment, {
children: _jsx("div", {}) children: /*#__PURE__*/_jsx("div", {})
}); });

View File

@ -1,5 +1,5 @@
import { jsx as _jsx } from "react/jsx-runtime"; import { jsx as _jsx } from "react/jsx-runtime";
var x = _jsx("div", { var x = /*#__PURE__*/_jsx("div", {
children: [_jsx("span", {}, '0'), _jsx("span", {}, '1')] children: [/*#__PURE__*/_jsx("span", {}, '0'), /*#__PURE__*/_jsx("span", {}, '1')]
}); });

View File

@ -1,6 +1,6 @@
import { jsx as _jsx } from "react/jsx-runtime"; import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime"; import { jsxs as _jsxs } from "react/jsx-runtime";
var x = _jsxs("div", { var x = /*#__PURE__*/_jsxs("div", {
children: [_jsx("span", {}), [_jsx("span", {}, '0'), _jsx("span", {}, '1')]] children: [/*#__PURE__*/_jsx("span", {}), [/*#__PURE__*/_jsx("span", {}, '0'), /*#__PURE__*/_jsx("span", {}, '1')]]
}); });

View File

@ -1,13 +1,14 @@
import { jsxs as _jsxs } from "react/jsx-runtime"; import { jsxs as _jsxs } from "react/jsx-runtime";
import { jsx as _jsx } from "react/jsx-runtime"; import { jsx as _jsx } from "react/jsx-runtime";
/*#__PURE__*/
_jsx(Foo, {}); _jsx(Foo, {});
var profile = _jsxs("div", { var profile = /*#__PURE__*/_jsxs("div", {
children: [_jsx("img", { children: [/*#__PURE__*/_jsx("img", {
src: "avatar.png", src: "avatar.png",
className: "profile" className: "profile"
}), _jsx("h3", { }), /*#__PURE__*/_jsx("h3", {
children: [user.firstName, user.lastName].join(" ") children: [user.firstName, user.lastName].join(" ")
})] })]
}); });

Some files were not shown because too many files have changed in this diff Show More