summaryrefslogtreecommitdiff
path: root/@linaria/packages/babel/src/evaluators/visitors/JSXElement.ts
diff options
context:
space:
mode:
Diffstat (limited to '@linaria/packages/babel/src/evaluators/visitors/JSXElement.ts')
-rw-r--r--@linaria/packages/babel/src/evaluators/visitors/JSXElement.ts56
1 files changed, 56 insertions, 0 deletions
diff --git a/@linaria/packages/babel/src/evaluators/visitors/JSXElement.ts b/@linaria/packages/babel/src/evaluators/visitors/JSXElement.ts
new file mode 100644
index 0000000..89a0ccd
--- /dev/null
+++ b/@linaria/packages/babel/src/evaluators/visitors/JSXElement.ts
@@ -0,0 +1,56 @@
+import { types as t } from '@babel/core';
+import type { NodePath } from '@babel/traverse';
+import type { Function, JSXElement as JSXElementNode } from '@babel/types';
+
+function getFunctionName(path: NodePath<Function>): string | null {
+ if (path.isClassMethod() && t.isIdentifier(path.node.key)) {
+ return path.node.key.name;
+ }
+
+ return null;
+}
+
+export default function JSXElement(path: NodePath<JSXElementNode>) {
+ // JSX can be safely replaced on an empty fragment because it is unnecessary for styles
+ const emptyFragment = t.jsxFragment(
+ t.jsxOpeningFragment(),
+ t.jsxClosingFragment(),
+ []
+ );
+
+ // We can do even more
+ // If that JSX is a result of a function, we can replace the function body.
+ const scopePath = path.scope.path;
+ if (scopePath.isFunction()) {
+ const emptyBody = t.blockStatement([t.returnStatement(emptyFragment)]);
+
+ // Is it not just a function, but a method `render`?
+ if (getFunctionName(scopePath) === 'render') {
+ const decl = scopePath.findParent((p) => p.isClassDeclaration());
+
+ // Replace the whole component
+ if (decl?.isClassDeclaration()) {
+ decl.replaceWith(t.functionDeclaration(decl.node.id, [], emptyBody));
+
+ return;
+ }
+ }
+
+ const body = scopePath.get('body');
+ if (Array.isArray(body)) {
+ throw new Error(
+ `A body of a function is expected to be a single element but an array was returned. It's possible if JS syntax has been changed since that code was written.`
+ );
+ }
+
+ const node: typeof scopePath.node = {
+ ...scopePath.node,
+ body: emptyBody,
+ params: [],
+ };
+
+ scopePath.replaceWith(node);
+ } else {
+ path.replaceWith(emptyFragment);
+ }
+}