index.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.helper = helper;
  6. var t = _interopRequireWildcard(require("@babel/types"));
  7. var _helperModuleImports = require("@babel/helper-module-imports");
  8. var _helperAnnotateAsPure = _interopRequireDefault(require("@babel/helper-annotate-as-pure"));
  9. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  10. function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
  11. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
  12. const DEFAULT = {
  13. importSource: "react",
  14. runtime: "automatic",
  15. pragma: "React.createElement",
  16. pragmaFrag: "React.Fragment"
  17. };
  18. function helper(babel, options) {
  19. const FILE_NAME_VAR = "_jsxFileName";
  20. const JSX_SOURCE_ANNOTATION_REGEX = /\*?\s*@jsxImportSource\s+([^\s]+)/;
  21. const JSX_RUNTIME_ANNOTATION_REGEX = /\*?\s*@jsxRuntime\s+([^\s]+)/;
  22. const JSX_ANNOTATION_REGEX = /\*?\s*@jsx\s+([^\s]+)/;
  23. const JSX_FRAG_ANNOTATION_REGEX = /\*?\s*@jsxFrag\s+([^\s]+)/;
  24. const IMPORT_NAME_SIZE = options.development ? 3 : 4;
  25. const {
  26. importSource: IMPORT_SOURCE_DEFAULT = DEFAULT.importSource,
  27. runtime: RUNTIME_DEFAULT = DEFAULT.runtime,
  28. pragma: PRAGMA_DEFAULT = DEFAULT.pragma,
  29. pragmaFrag: PRAGMA_FRAG_DEFAULT = DEFAULT.pragmaFrag
  30. } = options;
  31. const injectMetaPropertiesVisitor = {
  32. JSXOpeningElement(path, state) {
  33. for (const attr of path.get("attributes")) {
  34. if (!attr.isJSXElement()) continue;
  35. const {
  36. name
  37. } = attr.node.name;
  38. if (name === "__source" || name === "__self") {
  39. throw path.buildCodeFrameError(`__source and __self should not be defined in props and are reserved for internal usage.`);
  40. }
  41. }
  42. const source = t.jsxAttribute(t.jsxIdentifier("__source"), t.jsxExpressionContainer(makeSource(path, state)));
  43. const self = t.jsxAttribute(t.jsxIdentifier("__self"), t.jsxExpressionContainer(t.thisExpression()));
  44. path.pushContainer("attributes", [source, self]);
  45. }
  46. };
  47. return {
  48. JSXNamespacedName(path, state) {
  49. const throwIfNamespace = state.opts.throwIfNamespace === undefined ? true : !!state.opts.throwIfNamespace;
  50. if (throwIfNamespace) {
  51. throw path.buildCodeFrameError(`Namespace tags are not supported by default. React's JSX doesn't support namespace tags. \
  52. You can set \`throwIfNamespace: false\` to bypass this warning.`);
  53. }
  54. },
  55. JSXSpreadChild(path) {
  56. throw path.buildCodeFrameError("Spread children are not supported in React.");
  57. },
  58. JSXElement: {
  59. exit(path, file) {
  60. let callExpr;
  61. if (file.get("@babel/plugin-react-jsx/runtime") === "classic" || shouldUseCreateElement(path)) {
  62. callExpr = buildCreateElementCall(path, file);
  63. } else {
  64. callExpr = buildJSXElementCall(path, file);
  65. }
  66. path.replaceWith(t.inherits(callExpr, path.node));
  67. }
  68. },
  69. JSXFragment: {
  70. exit(path, file) {
  71. let callExpr;
  72. if (file.get("@babel/plugin-react-jsx/runtime") === "classic") {
  73. callExpr = buildCreateElementFragmentCall(path, file);
  74. } else {
  75. callExpr = buildJSXFragmentCall(path, file);
  76. }
  77. path.replaceWith(t.inherits(callExpr, path.node));
  78. }
  79. },
  80. JSXAttribute(path) {
  81. if (t.isJSXElement(path.node.value)) {
  82. path.node.value = t.jsxExpressionContainer(path.node.value);
  83. }
  84. },
  85. Program: {
  86. enter(path, state) {
  87. if (hasJSX(path)) {
  88. const {
  89. file
  90. } = state;
  91. let runtime = RUNTIME_DEFAULT;
  92. let source = IMPORT_SOURCE_DEFAULT;
  93. let sourceSet = !!options.importSource;
  94. let pragma = PRAGMA_DEFAULT;
  95. let pragmaFrag = PRAGMA_FRAG_DEFAULT;
  96. let pragmaSet = !!options.pragma;
  97. let pragmaFragSet = !!options.pragmaFrag;
  98. if (file.ast.comments) {
  99. for (const comment of file.ast.comments) {
  100. const sourceMatches = JSX_SOURCE_ANNOTATION_REGEX.exec(comment.value);
  101. if (sourceMatches) {
  102. source = sourceMatches[1];
  103. sourceSet = true;
  104. }
  105. const runtimeMatches = JSX_RUNTIME_ANNOTATION_REGEX.exec(comment.value);
  106. if (runtimeMatches) {
  107. runtime = runtimeMatches[1];
  108. }
  109. const jsxMatches = JSX_ANNOTATION_REGEX.exec(comment.value);
  110. if (jsxMatches) {
  111. pragma = jsxMatches[1];
  112. pragmaSet = true;
  113. }
  114. const jsxFragMatches = JSX_FRAG_ANNOTATION_REGEX.exec(comment.value);
  115. if (jsxFragMatches) {
  116. pragmaFrag = jsxFragMatches[1];
  117. pragmaFragSet = true;
  118. }
  119. }
  120. }
  121. state.set("@babel/plugin-react-jsx/runtime", runtime);
  122. if (runtime === "classic") {
  123. if (sourceSet) {
  124. throw path.buildCodeFrameError(`importSource cannot be set when runtime is classic.`);
  125. }
  126. state.set("@babel/plugin-react-jsx/createElementIdentifier", createIdentifierParser(pragma));
  127. state.set("@babel/plugin-react-jsx/jsxFragIdentifier", createIdentifierParser(pragmaFrag));
  128. state.set("@babel/plugin-react-jsx/usedFragment", false);
  129. state.set("@babel/plugin-react-jsx/pragmaSet", pragma !== DEFAULT.pragma);
  130. state.set("@babel/plugin-react-jsx/pragmaFragSet", pragmaFrag !== DEFAULT.pragmaFrag);
  131. } else if (runtime === "automatic") {
  132. if (pragmaSet || pragmaFragSet) {
  133. throw path.buildCodeFrameError(`pragma and pragmaFrag cannot be set when runtime is automatic.`);
  134. }
  135. const importName = addAutoImports(path, Object.assign({}, state.opts, {
  136. source
  137. }));
  138. state.set("@babel/plugin-react-jsx/jsxIdentifier", createIdentifierParser(createIdentifierName(path, options.development ? "jsxDEV" : "jsx", importName)));
  139. state.set("@babel/plugin-react-jsx/jsxStaticIdentifier", createIdentifierParser(createIdentifierName(path, options.development ? "jsxDEV" : "jsxs", importName)));
  140. state.set("@babel/plugin-react-jsx/createElementIdentifier", createIdentifierParser(createIdentifierName(path, "createElement", importName)));
  141. state.set("@babel/plugin-react-jsx/jsxFragIdentifier", createIdentifierParser(createIdentifierName(path, "Fragment", importName)));
  142. state.set("@babel/plugin-react-jsx/importSourceSet", source !== DEFAULT.importSource);
  143. } else {
  144. throw path.buildCodeFrameError(`Runtime must be either "classic" or "automatic".`);
  145. }
  146. if (options.development) {
  147. path.traverse(injectMetaPropertiesVisitor, state);
  148. }
  149. }
  150. },
  151. exit(path, state) {
  152. if (state.get("@babel/plugin-react-jsx/runtime") === "classic" && state.get("@babel/plugin-react-jsx/pragmaSet") && state.get("@babel/plugin-react-jsx/usedFragment") && !state.get("@babel/plugin-react-jsx/pragmaFragSet")) {
  153. throw new Error("transform-react-jsx: pragma has been set but " + "pragmaFrag has not been set");
  154. }
  155. }
  156. }
  157. };
  158. function shouldUseCreateElement(path) {
  159. const openingPath = path.get("openingElement");
  160. const attributes = openingPath.node.attributes;
  161. let seenPropsSpread = false;
  162. for (let i = 0; i < attributes.length; i++) {
  163. const attr = attributes[i];
  164. if (seenPropsSpread && t.isJSXAttribute(attr) && attr.name.name === "key") {
  165. return true;
  166. } else if (t.isJSXSpreadAttribute(attr)) {
  167. seenPropsSpread = true;
  168. }
  169. }
  170. return false;
  171. }
  172. function createIdentifierName(path, name, importName) {
  173. if ((0, _helperModuleImports.isModule)(path)) {
  174. const identifierName = `${importName[name]}`;
  175. return identifierName;
  176. } else {
  177. return `${importName[name]}.${name}`;
  178. }
  179. }
  180. function getImportNames(parentPath) {
  181. const imports = new Set();
  182. parentPath.traverse({
  183. "JSXElement|JSXFragment"(path) {
  184. if (path.type === "JSXFragment") imports.add("Fragment");
  185. const openingPath = path.get("openingElement");
  186. const validChildren = openingPath.parent.children.filter(child => !t.isJSXEmptyExpression(child) && !(t.isJSXText(child) && child.value.trim() === ""));
  187. let importName;
  188. if (path.type === "JSXElement" && shouldUseCreateElement(path)) {
  189. importName = "createElement";
  190. } else if (options.development) {
  191. importName = "jsxDEV";
  192. } else if (validChildren.length > 1) {
  193. importName = "jsxs";
  194. } else {
  195. importName = "jsx";
  196. }
  197. imports.add(importName);
  198. if (imports.size === IMPORT_NAME_SIZE) {
  199. path.stop();
  200. }
  201. }
  202. });
  203. return imports;
  204. }
  205. function hasJSX(parentPath) {
  206. let fileHasJSX = false;
  207. parentPath.traverse({
  208. "JSXElement|JSXFragment"(path) {
  209. fileHasJSX = true;
  210. path.stop();
  211. }
  212. });
  213. return fileHasJSX;
  214. }
  215. function getSource(source, importName) {
  216. switch (importName) {
  217. case "Fragment":
  218. return `${source}/${options.development ? "jsx-dev-runtime" : "jsx-runtime"}`;
  219. case "jsxDEV":
  220. return `${source}/jsx-dev-runtime`;
  221. case "jsx":
  222. case "jsxs":
  223. return `${source}/jsx-runtime`;
  224. case "createElement":
  225. return source;
  226. }
  227. }
  228. function addAutoImports(path, state) {
  229. const imports = getImportNames(path, state);
  230. if ((0, _helperModuleImports.isModule)(path)) {
  231. const importMap = {};
  232. imports.forEach(importName => {
  233. if (!importMap[importName]) {
  234. importMap[importName] = (0, _helperModuleImports.addNamed)(path, importName, getSource(state.source, importName), {
  235. importedInterop: "uncompiled",
  236. ensureLiveReference: true
  237. }).name;
  238. }
  239. });
  240. return importMap;
  241. } else {
  242. const importMap = {};
  243. const sourceMap = {};
  244. imports.forEach(importName => {
  245. const source = getSource(state.source, importName);
  246. if (!importMap[importName]) {
  247. if (!sourceMap[source]) {
  248. sourceMap[source] = (0, _helperModuleImports.addNamespace)(path, source, {
  249. importedInterop: "uncompiled",
  250. ensureLiveReference: true
  251. }).name;
  252. }
  253. importMap[importName] = sourceMap[source];
  254. }
  255. });
  256. return importMap;
  257. }
  258. }
  259. function createIdentifierParser(id) {
  260. return () => {
  261. return id.split(".").map(name => t.identifier(name)).reduce((object, property) => t.memberExpression(object, property));
  262. };
  263. }
  264. function makeTrace(fileNameIdentifier, lineNumber, column0Based) {
  265. const fileLineLiteral = lineNumber != null ? t.numericLiteral(lineNumber) : t.nullLiteral();
  266. const fileColumnLiteral = column0Based != null ? t.numericLiteral(column0Based + 1) : t.nullLiteral();
  267. const fileNameProperty = t.objectProperty(t.identifier("fileName"), fileNameIdentifier);
  268. const lineNumberProperty = t.objectProperty(t.identifier("lineNumber"), fileLineLiteral);
  269. const columnNumberProperty = t.objectProperty(t.identifier("columnNumber"), fileColumnLiteral);
  270. return t.objectExpression([fileNameProperty, lineNumberProperty, columnNumberProperty]);
  271. }
  272. function makeSource(path, state) {
  273. const location = path.node.loc;
  274. if (!location) {
  275. return;
  276. }
  277. if (!state.fileNameIdentifier) {
  278. const {
  279. filename = ""
  280. } = state;
  281. const fileNameIdentifier = path.scope.generateUidIdentifier(FILE_NAME_VAR);
  282. const scope = path.hub.getScope();
  283. if (scope) {
  284. scope.push({
  285. id: fileNameIdentifier,
  286. init: t.stringLiteral(filename)
  287. });
  288. }
  289. state.fileNameIdentifier = fileNameIdentifier;
  290. }
  291. return makeTrace(state.fileNameIdentifier, location.start.line, location.start.column);
  292. }
  293. function convertJSXIdentifier(node, parent) {
  294. if (t.isJSXIdentifier(node)) {
  295. if (node.name === "this" && t.isReferenced(node, parent)) {
  296. return t.thisExpression();
  297. } else if (t.isValidIdentifier(node.name, false)) {
  298. node.type = "Identifier";
  299. } else {
  300. return t.stringLiteral(node.name);
  301. }
  302. } else if (t.isJSXMemberExpression(node)) {
  303. return t.memberExpression(convertJSXIdentifier(node.object, node), convertJSXIdentifier(node.property, node));
  304. } else if (t.isJSXNamespacedName(node)) {
  305. return t.stringLiteral(`${node.namespace.name}:${node.name.name}`);
  306. }
  307. return node;
  308. }
  309. function convertAttributeValue(node) {
  310. if (t.isJSXExpressionContainer(node)) {
  311. return node.expression;
  312. } else {
  313. return node;
  314. }
  315. }
  316. function convertAttribute(node) {
  317. const value = convertAttributeValue(node.value || t.booleanLiteral(true));
  318. if (t.isJSXSpreadAttribute(node)) {
  319. return t.spreadElement(node.argument);
  320. }
  321. if (t.isStringLiteral(value) && !t.isJSXExpressionContainer(node.value)) {
  322. value.value = value.value.replace(/\n\s+/g, " ");
  323. if (value.extra && value.extra.raw) {
  324. delete value.extra.raw;
  325. }
  326. }
  327. if (t.isJSXNamespacedName(node.name)) {
  328. node.name = t.stringLiteral(node.name.namespace.name + ":" + node.name.name.name);
  329. } else if (t.isValidIdentifier(node.name.name, false)) {
  330. node.name.type = "Identifier";
  331. } else {
  332. node.name = t.stringLiteral(node.name.name);
  333. }
  334. return t.inherits(t.objectProperty(node.name, value), node);
  335. }
  336. function buildJSXElementCall(path, file) {
  337. const openingPath = path.get("openingElement");
  338. openingPath.parent.children = t.react.buildChildren(openingPath.parent);
  339. const tagExpr = convertJSXIdentifier(openingPath.node.name, openingPath.node);
  340. const args = [];
  341. let tagName;
  342. if (t.isIdentifier(tagExpr)) {
  343. tagName = tagExpr.name;
  344. } else if (t.isLiteral(tagExpr)) {
  345. tagName = tagExpr.value;
  346. }
  347. const state = {
  348. tagExpr: tagExpr,
  349. tagName: tagName,
  350. args: args,
  351. pure: false
  352. };
  353. if (options.pre) {
  354. options.pre(state, file);
  355. }
  356. let attribs = [];
  357. const extracted = Object.create(null);
  358. for (const attr of openingPath.get("attributes")) {
  359. if (attr.isJSXAttribute() && t.isJSXIdentifier(attr.node.name)) {
  360. const {
  361. name
  362. } = attr.node.name;
  363. switch (name) {
  364. case "__source":
  365. case "__self":
  366. if (extracted[name]) throw sourceSelfError(path, name);
  367. case "key":
  368. extracted[name] = convertAttributeValue(attr.node.value);
  369. break;
  370. default:
  371. attribs.push(attr.node);
  372. }
  373. } else {
  374. attribs.push(attr.node);
  375. }
  376. }
  377. if (attribs.length || path.node.children.length) {
  378. attribs = buildJSXOpeningElementAttributes(attribs, file, path.node.children);
  379. } else {
  380. attribs = t.objectExpression([]);
  381. }
  382. args.push(attribs);
  383. if (!options.development) {
  384. if (extracted.key !== undefined) {
  385. args.push(extracted.key);
  386. }
  387. } else {
  388. var _extracted$key, _extracted$__source, _extracted$__self;
  389. args.push((_extracted$key = extracted.key) != null ? _extracted$key : path.scope.buildUndefinedNode(), t.booleanLiteral(path.node.children.length > 1), (_extracted$__source = extracted.__source) != null ? _extracted$__source : path.scope.buildUndefinedNode(), (_extracted$__self = extracted.__self) != null ? _extracted$__self : t.thisExpression());
  390. }
  391. if (options.post) {
  392. options.post(state, file);
  393. }
  394. const call = state.call || t.callExpression(path.node.children.length > 1 ? state.jsxStaticCallee : state.jsxCallee, args);
  395. if (state.pure) (0, _helperAnnotateAsPure.default)(call);
  396. return call;
  397. }
  398. function buildJSXOpeningElementAttributes(attribs, file, children) {
  399. const props = attribs.map(convertAttribute);
  400. if (children && children.length > 0) {
  401. if (children.length === 1) {
  402. props.push(t.objectProperty(t.identifier("children"), children[0]));
  403. } else {
  404. props.push(t.objectProperty(t.identifier("children"), t.arrayExpression(children)));
  405. }
  406. }
  407. return t.objectExpression(props);
  408. }
  409. function buildJSXFragmentCall(path, file) {
  410. const openingPath = path.get("openingElement");
  411. openingPath.parent.children = t.react.buildChildren(openingPath.parent);
  412. const args = [];
  413. const tagName = null;
  414. const tagExpr = file.get("@babel/plugin-react-jsx/jsxFragIdentifier")();
  415. const state = {
  416. tagExpr: tagExpr,
  417. tagName: tagName,
  418. args: args,
  419. pure: false
  420. };
  421. if (options.pre) {
  422. options.pre(state, file);
  423. }
  424. let childrenNode;
  425. if (path.node.children.length > 0) {
  426. if (path.node.children.length === 1) {
  427. childrenNode = path.node.children[0];
  428. } else {
  429. childrenNode = t.arrayExpression(path.node.children);
  430. }
  431. }
  432. args.push(t.objectExpression(childrenNode !== undefined ? [t.objectProperty(t.identifier("children"), childrenNode)] : []));
  433. if (options.development) {
  434. args.push(path.scope.buildUndefinedNode(), t.booleanLiteral(path.node.children.length > 1));
  435. }
  436. if (options.post) {
  437. options.post(state, file);
  438. }
  439. const call = state.call || t.callExpression(path.node.children.length > 1 ? state.jsxStaticCallee : state.jsxCallee, args);
  440. if (state.pure) (0, _helperAnnotateAsPure.default)(call);
  441. return call;
  442. }
  443. function buildCreateElementFragmentCall(path, file) {
  444. if (options.filter && !options.filter(path.node, file)) {
  445. return;
  446. }
  447. const openingPath = path.get("openingElement");
  448. openingPath.parent.children = t.react.buildChildren(openingPath.parent);
  449. const args = [];
  450. const tagName = null;
  451. const tagExpr = file.get("@babel/plugin-react-jsx/jsxFragIdentifier")();
  452. const state = {
  453. tagExpr: tagExpr,
  454. tagName: tagName,
  455. args: args,
  456. pure: false
  457. };
  458. if (options.pre) {
  459. options.pre(state, file);
  460. }
  461. args.push(t.nullLiteral(), ...path.node.children);
  462. if (options.post) {
  463. options.post(state, file);
  464. }
  465. file.set("@babel/plugin-react-jsx/usedFragment", true);
  466. const call = state.call || t.callExpression(state.createElementCallee, args);
  467. if (state.pure) (0, _helperAnnotateAsPure.default)(call);
  468. return call;
  469. }
  470. function buildCreateElementCall(path, file) {
  471. const openingPath = path.get("openingElement");
  472. openingPath.parent.children = t.react.buildChildren(openingPath.parent);
  473. const tagExpr = convertJSXIdentifier(openingPath.node.name, openingPath.node);
  474. const args = [];
  475. let tagName;
  476. if (t.isIdentifier(tagExpr)) {
  477. tagName = tagExpr.name;
  478. } else if (t.isLiteral(tagExpr)) {
  479. tagName = tagExpr.value;
  480. }
  481. const state = {
  482. tagExpr: tagExpr,
  483. tagName: tagName,
  484. args: args,
  485. pure: false
  486. };
  487. if (options.pre) {
  488. options.pre(state, file);
  489. }
  490. const attribs = buildCreateElementOpeningElementAttributes(path, openingPath.node.attributes);
  491. args.push(attribs, ...path.node.children);
  492. if (options.post) {
  493. options.post(state, file);
  494. }
  495. const call = state.call || t.callExpression(state.createElementCallee, args);
  496. if (state.pure) (0, _helperAnnotateAsPure.default)(call);
  497. return call;
  498. }
  499. function buildCreateElementOpeningElementAttributes(path, attribs) {
  500. const props = [];
  501. const found = Object.create(null);
  502. for (const attr of attribs) {
  503. const name = t.isJSXAttribute(attr) && t.isJSXIdentifier(attr.name) && attr.name.name;
  504. if (name === "__source" || name === "__self") {
  505. if (found[name]) throw sourceSelfError(path, name);
  506. found[name] = true;
  507. if (!options.development) continue;
  508. }
  509. props.push(convertAttribute(attr));
  510. }
  511. return props.length > 0 ? t.objectExpression(props) : t.nullLiteral();
  512. }
  513. function sourceSelfError(path, name) {
  514. const pluginName = `transform-react-jsx-${name.slice(2)}`;
  515. return path.buildCodeFrameError(`Duplicate ${name} prop found. You are most likely using the deprecated ${pluginName} Babel plugin. Both __source and __self are automatically set when using the automatic runtime. Please remove transform-react-jsx-source and transform-react-jsx-self from your Babel config.`);
  516. }
  517. }