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);
}
}