{
  "version": 3,
  "sources": ["../../../src/optimizer/transforms/unwrap-useless-groups.ts"],
  "sourcesContent": ["import type {AlternativeContainerNode, AlternativeElementNode, GroupNode, Node, QuantifiableNode} from '../../parser/parse.js';\nimport type {Visitor} from '../../traverser/traverse.js';\nimport {isAlternativeContainer, isQuantifiable} from '../../parser/node-utils.js';\n\n/**\nUnwrap nonbeneficial noncapturing and atomic groups.\n*/\nconst unwrapUselessGroups: Visitor = {\n  // Unwrap kid from the outside in, since the traverser doesn't support stepping multiple levels\n  // up the tree\n  '*'({node}) {\n    if (!isAlternativeContainer(node)) {\n      return;\n    }\n    if (hasMultiAltNoncapturingGroupOnlyChild(node)) {\n      // Isn't needed in some cases like if `node` is itself a basic noncapturing group (since\n      // there's already handling in `Group`), but it doesn't hurt to handle it here instead\n      node.body = (node.body[0].body[0] as GroupNode).body;\n    }\n  },\n\n  Group({node, parent, replaceWithMultiple}) {\n    const {atomic, body, flags} = node;\n    const firstAltEls = body[0].body;\n    if (body.length > 1 || parent.type === 'Quantifier') {\n      return;\n    }\n    let unwrap = false;\n    if (atomic) {\n      if (firstAltEls.every(({type}: AlternativeElementNode) => atomicTypes.has(type))) {\n        unwrap = true;\n      }\n    // For flag groups, rely on `removeUselessFlags`, after which the group can be unwrapped in a\n    // subsequent pass\n    } else if (!flags) {\n      unwrap = true;\n    }\n    if (unwrap) {\n      replaceWithMultiple(firstAltEls, {traverse: true});\n    }\n  },\n\n  // Unwrap quantified groups that contain a single quantifiable node\n  Quantifier({node}) {\n    if (node.body.type !== 'Group') {\n      return;\n    }\n    const quantifiedGroup = node.body;\n    if (quantifiedGroup.body.length > 1) {\n      return;\n    }\n    const groupKids = quantifiedGroup.body[0].body;\n    if (groupKids.length !== 1) {\n      return;\n    }\n    const candidate = groupKids[0];\n    if (\n      !isQuantifiable(candidate) ||\n      // Some atomic types have already been ruled out as not quantifiable\n      (quantifiedGroup.atomic && !atomicTypes.has(candidate.type)) ||\n      quantifiedGroup.flags\n    ) {\n      return;\n    }\n    // Make the only child of the group the new `body` of the quantifier\n    node.body = candidate;\n  },\n};\n\nconst atomicTypes = new Set<Node['type']>([\n  'Assertion',\n  'Backreference',\n  'Character',\n  'CharacterClass',\n  'CharacterSet',\n  'Directive',\n  'NamedCallout',\n]);\n\nfunction hasMultiAltNoncapturingGroupOnlyChild({body}: AlternativeContainerNode): boolean {\n  const firstAltEls = body[0].body;\n  return (\n    body.length === 1 &&\n    firstAltEls.length === 1 &&\n    firstAltEls[0].type === 'Group' &&\n    !firstAltEls[0].atomic &&\n    !firstAltEls[0].flags &&\n    firstAltEls[0].body.length > 1\n  );\n}\n\nexport {\n  unwrapUselessGroups,\n};\n"],
  "mappings": "aAEA,OAAQ,0BAAAA,EAAwB,kBAAAC,MAAqB,6BAKrD,MAAMC,EAA+B,CAGnC,IAAI,CAAC,KAAAC,CAAI,EAAG,CACLH,EAAuBG,CAAI,GAG5BC,EAAsCD,CAAI,IAG5CA,EAAK,KAAQA,EAAK,KAAK,CAAC,EAAE,KAAK,CAAC,EAAgB,KAEpD,EAEA,MAAM,CAAC,KAAAA,EAAM,OAAAE,EAAQ,oBAAAC,CAAmB,EAAG,CACzC,KAAM,CAAC,OAAAC,EAAQ,KAAAC,EAAM,MAAAC,CAAK,EAAIN,EACxBO,EAAcF,EAAK,CAAC,EAAE,KAC5B,GAAIA,EAAK,OAAS,GAAKH,EAAO,OAAS,aACrC,OAEF,IAAIM,EAAS,GACTJ,EACEG,EAAY,MAAM,CAAC,CAAC,KAAAE,CAAI,IAA8BC,EAAY,IAAID,CAAI,CAAC,IAC7ED,EAAS,IAIDF,IACVE,EAAS,IAEPA,GACFL,EAAoBI,EAAa,CAAC,SAAU,EAAI,CAAC,CAErD,EAGA,WAAW,CAAC,KAAAP,CAAI,EAAG,CACjB,GAAIA,EAAK,KAAK,OAAS,QACrB,OAEF,MAAMW,EAAkBX,EAAK,KAC7B,GAAIW,EAAgB,KAAK,OAAS,EAChC,OAEF,MAAMC,EAAYD,EAAgB,KAAK,CAAC,EAAE,KAC1C,GAAIC,EAAU,SAAW,EACvB,OAEF,MAAMC,EAAYD,EAAU,CAAC,EAE3B,CAACd,EAAee,CAAS,GAExBF,EAAgB,QAAU,CAACD,EAAY,IAAIG,EAAU,IAAI,GAC1DF,EAAgB,QAKlBX,EAAK,KAAOa,EACd,CACF,EAEMH,EAAc,IAAI,IAAkB,CACxC,YACA,gBACA,YACA,iBACA,eACA,YACA,cACF,CAAC,EAED,SAAST,EAAsC,CAAC,KAAAI,CAAI,EAAsC,CACxF,MAAME,EAAcF,EAAK,CAAC,EAAE,KAC5B,OACEA,EAAK,SAAW,GAChBE,EAAY,SAAW,GACvBA,EAAY,CAAC,EAAE,OAAS,SACxB,CAACA,EAAY,CAAC,EAAE,QAChB,CAACA,EAAY,CAAC,EAAE,OAChBA,EAAY,CAAC,EAAE,KAAK,OAAS,CAEjC,CAEA,OACER,KAAA",
  "names": ["isAlternativeContainer", "isQuantifiable", "unwrapUselessGroups", "node", "hasMultiAltNoncapturingGroupOnlyChild", "parent", "replaceWithMultiple", "atomic", "body", "flags", "firstAltEls", "unwrap", "type", "atomicTypes", "quantifiedGroup", "groupKids", "candidate"]
}
