Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

`@babel/plugin-transform-named-capturing-groups-regex` fails to wrap all groups #10045

Open
0xdevalias opened this issue May 30, 2019 · 2 comments

Comments

Projects
None yet
2 participants
@0xdevalias
Copy link

commented May 30, 2019

Bug Report

Current Behavior

When composing regular expressions that contain named capture groups, they aren't properly wrapped in all cases. It seems only the /foo/ regex literals get wrapped?

Input Code

export const EMBED_CODE_REGEX = (() => {
  const alt = /(?<alt>.*?)?/
  const link = /(?<link>.*?)?/
  const title = /(?:"(?<title>.*?)")?/

  const markdownImage = /(?<match>!\[ALT\]\(LINK\s*TITLE\))/.source
    .replace('ALT', alt.source)
    .replace('LINK', link.source)
    .replace('TITLE', title.source)

  return new RegExp(markdownImage, 'g')
})()

This turns into (with some boilerplate removed):

var EMBED_CODE_REGEX = function () {
  var alt = _wrapRegExp(/(.*?)?/, {
    alt: 1
  });

  var link = _wrapRegExp(/(.*?)?/, {
    link: 1
  });

  var title = _wrapRegExp(/(?:"(.*?)")?/, {
    title: 1
  });

  var markdownImage = _wrapRegExp(/(!\[ALT\]\(LINK\s*TITLE\))/, {
    match: 1
  }).source.replace('ALT', alt.source).replace('LINK', link.source).replace('TITLE', title.source);

  return new RegExp(markdownImage, 'g');
}();

The intermediate regex literals are correctly wrapped, but on the second last line, the explicit new RegExp isn't wrapped.

Somewhere in this composure, the groups are lost, such that downstream code ends up breaking due to them not being present.

Running the above code in chrome console produces:

export const EMBED_CODE_REGEX = /(?<match>!\[(?<alt>.*?)?\]\((?<link>.*?)?\s*(?:"(?<title>.*?)")?\))/g

Which when transpiled comes out as you would expect:

var EMBED_CODE_REGEX = _wrapRegExp(/(!\[(.*?)?\]\((.*?)?\s*(?:"(.*?)")?\))/g, {
  match: 1,
  alt: 2,
  link: 3,
  title: 4
});

Expected behavior/code

I would expect that all code output from this would get transformed, including the explicit new RegExp/etc.

Environment

  • Babel version(s): [e.g. v6.0.0, v7.0.0-beta.34]
  • Node/npm version: [e.g. Node 8/npm 5]
  • OS: [e.g. OSX 10.13.4, Windows 10]
  • Monorepo: no
  • How you are using Babel: [e.g. cli, register, loader]

Additional context/Screenshots
Add any other context about the problem here. If applicable, add screenshots to help explain.

@babel-bot

This comment has been minimized.

Copy link
Collaborator

commented May 30, 2019

Hey @0xdevalias! We really appreciate you taking the time to report an issue. The collaborators
on this project attempt to help as many people as possible, but we're a limited number of volunteers,
so it's possible this won't be addressed swiftly.

If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack
community
that typically always has someone willing to help. You can sign-up here
for an invite.

@0xdevalias

This comment has been minimized.

Copy link
Author

commented May 30, 2019

This is how it looks when I manually compose it (eg. looks like it should work fine)

/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EMBED_CODE_REGEX", function() { return EMBED_CODE_REGEX; });

// ..snip..

var EMBED_CODE_REGEX = _wrapRegExp(/(!\[(.*?)?\]\((.*?)?\s*(?:"(.*?)")?\))/g, {
  match: 1,
  alt: 2,
  link: 2,
  title: 2
}); // export const EMBED_CODE_REGEX = (() => {
//   const alt = /(?<alt>.*?)?/
//   const link = /(?<link>.*?)?/
//   const title = /(?:"(?<title>.*?)")?/
//
//   const markdownImage = /(?<match>!\[ALT\]\(LINK\s*TITLE\))/.source
//     .replace('ALT', alt.source)
//     .replace('LINK', link.source)
//     .replace('TITLE', title.source)
//
//   return new RegExp(markdownImage, 'g')
// })()

But then in my calling code:

return function (markdown) {
    return Array.from(markdown.matchAll(markdown_field_constants__WEBPACK_IMPORTED_MODULE_0__["EMBED_CODE_REGEX"])).map(function (match) {
      return match.groups;
    }).filter(filter).reduce(reducer, markdown);
  };

It seems it fails to see any of the wrapping/groups stuff:

markdown_field_constants__WEBPACK_IMPORTED_MODULE_0__["EMBED_CODE_REGEX"]
/(!\[(.*?)?\]\((.*?)?\s*(?:"(.*?)")?\))/g

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.