Repository: babel/babel
File: packages/babel-plugin-transform-react-jsx/src/create-plugin.ts (TypeScript)

Code before:
        }
      }
    }

    const injectMetaPropertiesVisitor: Visitor<PluginPass> = {
      JSXOpeningElement(path, state) {
        const attributes = [];
        if (isThisAllowed(path.scope)) {
          attributes.push(
            t.jsxAttribute(
              t.jsxIdentifier("__self"),
              t.jsxExpressionContainer(t.thisExpression()),
            ),
          );
        }
        attributes.push(
          t.jsxAttribute(
            t.jsxIdentifier("__source"),
            t.jsxExpressionContainer(makeSource(path, state)),
          ),
        );
        path.pushContainer("attributes", attributes);
      },
    };

    let leadingComments: t.Comment[] | undefined;

    return {
      name,
      inherits: jsx,
      visitor: {
        JSXNamespacedName(path) {
          if (throwIfNamespace) {
            throw path.buildCodeFrameError(
              `Namespace tags are not supported by default. React's JSX doesn't support namespace tags. \
You can set \`throwIfNamespace: false\` to bypass this warning.`,
            );
          }
        },

        JSXSpreadChild(path) {
          throw path.buildCodeFrameError(
            "Spread children are not supported in React.",
          );
        },

        Program: {
          enter(path, state) {
            const { file } = state;
            let runtime: string = RUNTIME_DEFAULT;


Review comment (suggestion):
Personally, I think it’s a bit hacky to intertwine the `leadingComments` logic with the attribute accumulator. This approach doesn’t address how we should handle the `trailingComments` of a `JSXSpreadAttribute`, such as in `<div {...{ id: 'hello' }/*i18n*/} />`.

Could we record the source node where the comments originate and the target node to which they will be attached? Then we could call the `t.inheritsComments` API, which was designed for comment adjustment.

Code after:
        }
      }
    }

    let commentsNode: t.Node | null = null;

    return {
      name,
      inherits: jsx,
      visitor: {
        JSXNamespacedName(path) {
          if (throwIfNamespace) {
            throw path.buildCodeFrameError(
              `Namespace tags are not supported by default. React's JSX doesn't support namespace tags. \
You can set \`throwIfNamespace: false\` to bypass this warning.`,
            );
          }
        },

        JSXSpreadChild(path) {
          throw path.buildCodeFrameError(
            "Spread children are not supported in React.",
          );
        },

        Program: {
          enter(path, state) {
            const { file } = state;
            let runtime: string = RUNTIME_DEFAULT;

            let source: string = IMPORT_SOURCE_DEFAULT;
            let pragma: string = PRAGMA_DEFAULT;
            let pragmaFrag: string = PRAGMA_FRAG_DEFAULT;

            let sourceSet = !!options.importSource;
            let pragmaSet = !!options.pragma;
            let pragmaFragSet = !!options.pragmaFrag;

            if (file.ast.comments) {
              for (const comment of file.ast.comments) {
                const sourceMatches = JSX_SOURCE_ANNOTATION_REGEX.exec(
                  comment.value,
                );
                if (sourceMatches) {
                  source = sourceMatches[1];
                  sourceSet = true;
                }

                const runtimeMatches = JSX_RUNTIME_ANNOTATION_REGEX.exec(
                  comment.value,
                );