whole_func_string: function combineRepeatingPatternLeft(alternative, child, index) {
    const {node} = alternative;
  
    const nbPossibleLengths = Math.ceil(index / 2);
    let i = 0;
  
    while (i < nbPossibleLengths) {
      const startIndex = index - 2 * i - 1;
      let right, left;
  
      if (i === 0) {
        right = child;
        left = alternative.getChild(startIndex);
      } else {
        right = NodePath.getForNode({
          type: 'Alternative',
          expressions: [...node.expressions.slice(index - i, index), child.node]
        });
  
        left = NodePath.getForNode({
          type: 'Alternative',
          expressions: [...node.expressions.slice(startIndex, index - i)]
        });
      }
  
      if (right.hasEqualSource(left)) {
        for (let j = 0; j < 2 * i + 1; j++) {
          alternative.getChild(startIndex).remove();
        }
  
        child.replace({
          type: 'Repetition',
          expression: i === 0 ? right.node : {
            type: 'Group',
            capturing: false,
            expression: right.node
          },
          quantifier: {
            type: 'Quantifier',
            kind: 'Range',
            from: 2,
            to: 2,
            greedy: true
          }
        });
        return startIndex;
      }
  
      i++;
    }
  
    return index;
  }
func_code_string: function combineRepeatingPatternLeft(alternative, child, index) {
    const {node} = alternative;
  
    const nbPossibleLengths = Math.ceil(index / 2);
    let i = 0;
  
    while (i < nbPossibleLengths) {
      const startIndex = index - 2 * i - 1;
      let right, left;
  
      if (i === 0) {
        right = child;
        left = alternative.getChild(startIndex);
      } else {
        right = NodePath.getForNode({
          type: 'Alternative',
          expressions: [...node.expressions.slice(index - i, index), child.node]
        });
  
        left = NodePath.getForNode({
          type: 'Alternative',
          expressions: [...node.expressions.slice(startIndex, index - i)]
        });
      }
  
      if (right.hasEqualSource(left)) {
        for (let j = 0; j < 2 * i + 1; j++) {
          alternative.getChild(startIndex).remove();
        }
  
        child.replace({
          type: 'Repetition',
          expression: i === 0 ? right.node : {
            type: 'Group',
            capturing: false,
            expression: right.node
          },
          quantifier: {
            type: 'Quantifier',
            kind: 'Range',
            from: 2,
            to: 2,
            greedy: true
          }
        });
        return startIndex;
      }
  
      i++;
    }
  
    return index;
  }
func_documentation_string: abcabc -> (?:abc){2}