1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- import { classProperty, inheritsComments } from '@babel/types';
- import getMemberExpressionRoot from '../utils/getMemberExpressionRoot.js';
- import getMembers from '../utils/getMembers.js';
- import { visitors } from '@babel/traverse';
- import { ignore } from './traverse.js';
- const explodedVisitors = visitors.explode({
- Function: { enter: ignore },
- Class: { enter: ignore },
- Loop: { enter: ignore },
- AssignmentExpression(path, state) {
- const left = path.get('left');
- if (left.isMemberExpression()) {
- const first = getMemberExpressionRoot(left);
- if (first.isIdentifier({ name: state.variableName })) {
- const [member] = getMembers(left);
- if (member &&
- !member.path.has('computed') &&
- !member.path.isPrivateName()) {
- const property = classProperty(member.path.node, path.node.right, null, null, false, true);
- inheritsComments(property, path.node);
- if (path.parentPath.isExpressionStatement()) {
- inheritsComments(property, path.parentPath.node);
- }
- state.classDefinition.get('body').unshiftContainer('body', property);
- path.skip();
- path.remove();
- }
- }
- }
- else {
- path.skip();
- }
- },
- });
- /**
- * Given a class definition (i.e. `class` declaration or expression), this
- * function "normalizes" the definition, by looking for assignments of static
- * properties and converting them to ClassProperties.
- *
- * Example:
- *
- * class MyComponent extends React.Component {
- * // ...
- * }
- * MyComponent.propTypes = { ... };
- *
- * is converted to
- *
- * class MyComponent extends React.Component {
- * // ...
- * static propTypes = { ... };
- * }
- */
- export default function normalizeClassDefinition(classDefinition) {
- let variableName;
- if (classDefinition.isClassDeclaration()) {
- // Class declarations may not have an id, e.g.: `export default class extends React.Component {}`
- if (classDefinition.node.id) {
- variableName = classDefinition.node.id.name;
- }
- }
- else if (classDefinition.isClassExpression()) {
- let parentPath = classDefinition.parentPath;
- while (parentPath &&
- parentPath.node !== classDefinition.scope.block &&
- !parentPath.isBlockStatement()) {
- if (parentPath.isVariableDeclarator()) {
- const idPath = parentPath.get('id');
- if (idPath.isIdentifier()) {
- variableName = idPath.node.name;
- break;
- }
- }
- else if (parentPath.isAssignmentExpression()) {
- const leftPath = parentPath.get('left');
- if (leftPath.isIdentifier()) {
- variableName = leftPath.node.name;
- break;
- }
- }
- parentPath = parentPath.parentPath;
- }
- }
- if (!variableName) {
- return;
- }
- const state = {
- variableName,
- classDefinition,
- };
- classDefinition.parentPath.scope.path.traverse(explodedVisitors, state);
- }
|