private static void invokeIntroduce()

in src/org/intellij/grammar/refactor/BnfIntroduceRuleHandler.java [121:187]


  private static void invokeIntroduce(Project project,
                                      Editor editor,
                                      PsiFile file,
                                      BnfRule currentRule,
                                      List<BnfExpression> selectedExpression) {
    BnfExpression firstExpression = Objects.requireNonNull(ContainerUtil.getFirstItem(selectedExpression));
    BnfExpression lastExpression = Objects.requireNonNull(ContainerUtil.getLastItem(selectedExpression));
    TextRange fixedRange = new TextRange(firstExpression.getTextRange().getStartOffset(), lastExpression.getTextRange().getEndOffset());
    BnfRule ruleFromText = BnfElementFactory.createRuleFromText(project, "a ::= " + fixedRange.substring(file.getText()));
    BnfExpressionOptimizer.optimize(project, ruleFromText.getExpression());

    Map<OccurrencesChooser.ReplaceChoice, List<BnfExpression[]>> occurrencesMap = new LinkedHashMap<>();
    occurrencesMap.put(OccurrencesChooser.ReplaceChoice.NO, Collections.singletonList(selectedExpression.toArray(GrammarUtil.EMPTY_EXPRESSIONS_ARRAY)));
    occurrencesMap.put(OccurrencesChooser.ReplaceChoice.ALL, new ArrayList<>());
    file.acceptChildren(new PsiRecursiveElementWalkingVisitor() {
      @Override
      public void visitElement(@NotNull PsiElement element) {
        if (element instanceof BnfExpression) {
          findOccurrences((BnfExpression)element, selectedExpression, occurrencesMap);
        }
        else if (element instanceof BnfAttrs) {
          return;
        }
        super.visitElement(element);
      }
    });
    if (occurrencesMap.get(OccurrencesChooser.ReplaceChoice.ALL).size() <= 1 && !ApplicationManager.getApplication().isUnitTestMode()) {
      occurrencesMap.remove(OccurrencesChooser.ReplaceChoice.ALL);
    }

    Consumer<OccurrencesChooser.ReplaceChoice> callback = new Pass<>() {
      @Override
      public void pass(OccurrencesChooser.ReplaceChoice choice) {
        WriteCommandAction.runWriteCommandAction(project, REFACTORING_NAME, null, () -> {
          PsiFile containingFile = currentRule.getContainingFile();
          String newRuleName = choseRuleName(containingFile);
          String newRuleText = "private " + newRuleName + " ::= " + ruleFromText.getExpression().getText();
          BnfRule addedRule = addNextRule(project, currentRule, newRuleText);
          if (choice == OccurrencesChooser.ReplaceChoice.ALL) {
            List<BnfExpression[]> exprToReplace = occurrencesMap.get(OccurrencesChooser.ReplaceChoice.ALL);
            replaceUsages(project, exprToReplace, addedRule.getId());
          }
          else {
            List<BnfExpression[]> exprToReplace = occurrencesMap.get(OccurrencesChooser.ReplaceChoice.NO);
            replaceUsages(project, exprToReplace, addedRule.getId());
          }
          BnfIntroduceRulePopup popup = new BnfIntroduceRulePopup(project, editor, addedRule, addedRule.getExpression());

          editor.getCaretModel().moveToOffset(addedRule.getTextOffset());
          PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument());
          popup.performInplaceRefactoring(null);
        }, file);
      }
    };
    if (ApplicationManager.getApplication().isUnitTestMode()) {
      callback.accept(OccurrencesChooser.ReplaceChoice.ALL);
    }
    else {
      new OccurrencesChooser<BnfExpression[]>(editor) {
        @Override
        protected TextRange getOccurrenceRange(BnfExpression[] occurrence) {
          return new TextRange(occurrence[0].getTextRange().getStartOffset(),
                               occurrence[occurrence.length - 1].getTextRange().getEndOffset());
        }
      }.showChooser(occurrencesMap, callback);
    }
  }