in src/org/intellij/grammar/refactor/BnfIntroduceTokenHandler.java [57:140]
public void invoke(@NotNull Project project,
Editor editor,
PsiFile file,
@Nullable DataContext dataContext) {
if (!(file instanceof BnfFile)) return;
BnfFile bnfFile = (BnfFile) file;
Map<String, String> tokenNameMap = RuleGraphHelper.getTokenNameToTextMap(bnfFile);
Map<String, String> tokenTextMap = RuleGraphHelper.getTokenTextToNameMap(bnfFile);
String tokenText;
String tokenName;
BnfExpression target = PsiTreeUtil.getParentOfType(file.findElementAt(editor.getCaretModel().getOffset()), BnfReferenceOrToken.class, BnfStringLiteralExpression.class);
if (target instanceof BnfReferenceOrToken) {
if (bnfFile.getRule(target.getText()) != null) return;
if (GrammarUtil.isExternalReference(target)) return;
tokenName = target.getText();
tokenText = "\"" + StringUtil.notNullize(tokenNameMap.get(tokenName), tokenName) + "\"";
}
else if (target instanceof BnfStringLiteralExpression) {
if (PsiTreeUtil.getParentOfType(target, BnfAttrs.class) != null) return;
tokenText = target.getText();
tokenName = tokenTextMap.get(GrammarUtil.unquote(tokenText));
}
else return;
List<BnfExpression> allOccurrences = new ArrayList<>();
Map<OccurrencesChooser.ReplaceChoice, List<BnfExpression>> occurrencesMap = new LinkedHashMap<>();
occurrencesMap.put(OccurrencesChooser.ReplaceChoice.NO, Collections.singletonList(target));
occurrencesMap.put(OccurrencesChooser.ReplaceChoice.ALL, allOccurrences);
BnfVisitor<Void> visitor = new BnfVisitor<>() {
@Override
public Void visitStringLiteralExpression(@NotNull BnfStringLiteralExpression o) {
if (Objects.equals(tokenText, o.getText())) {
allOccurrences.add(o);
}
return null;
}
@Override
public Void visitReferenceOrToken(@NotNull BnfReferenceOrToken o) {
if (GrammarUtil.isExternalReference(o)) return null;
if (tokenName != null && tokenName.equals(o.getText())) {
allOccurrences.add(o);
}
return null;
}
};
for (PsiElement o : GrammarUtil.bnfTraverserNoAttrs(file)) {
o.accept(visitor);
}
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.writeCommandAction(project, file)
.withName(REFACTORING_NAME)
.run(() -> {
try {
buildTemplateAndRun(project, editor, bnfFile, occurrencesMap.get(choice), tokenName, tokenText, tokenNameMap.keySet());
}
catch (StartMarkAction.AlreadyStartedException e) {
ExceptionUtil.rethrowAllAsUnchecked(e);
}
});
}
};
if (ApplicationManager.getApplication().isUnitTestMode()) {
callback.accept(OccurrencesChooser.ReplaceChoice.ALL);
}
else {
new OccurrencesChooser<BnfExpression>(editor) {
@Override
protected TextRange getOccurrenceRange(BnfExpression occurrence) {
return occurrence.getTextRange();
}
}.showChooser(occurrencesMap, callback);
}
}