private static void inlineMetaRuleUsage()

in src/org/intellij/grammar/refactor/BnfInlineRuleProcessor.java [121:172]


  private static void inlineMetaRuleUsage(Project project, BnfExpression place, BnfExpression expression) {
    BnfRule rule = PsiTreeUtil.getParentOfType(place, BnfRule.class);
    PsiElement parent = place.getParent();
    List<BnfExpression> expressionList;
    if (parent instanceof BnfExternalExpression) {
      expressionList = ((BnfExternalExpression)parent).getExpressionList();
    }
    else if (parent instanceof BnfSequence) {
      expressionList = ((BnfSequence)parent).getExpressionList();
    }
    else if (parent instanceof BnfRule) {
      expressionList = Collections.emptyList();
    }
    else {
      LOG.error("Unexpected element: " + (parent == null ? "null" : parent.getClass().getName()));
      return;
    }
    Object2IntMap<String> visited = new Object2IntOpenHashMap<>();
    LinkedList<Pair<PsiElement, PsiElement>> work = new LinkedList<>();
    (expression = (BnfExpression)expression.copy()).acceptChildren(new PsiRecursiveElementWalkingVisitor() {
      @Override
      public void visitElement(@NotNull PsiElement element) {
        if (element instanceof BnfExternalExpression) {
          List<BnfExpression> list = ((BnfExternalExpression)element).getExpressionList();
          if (list.size() == 1) {
            String text = list.get(0).getText();
            int idx = visited.getInt(text);
            if (idx == 0) visited.put(text, idx = visited.size() + 1);
            if (idx < expressionList.size()) {
              work.addFirst(Pair.create(element, expressionList.get(idx)));
            }
          }
        }
        else {
          super.visitElement(element);
        }
      }
    });
    for (Pair<PsiElement, PsiElement> pair : work) {
      BnfExpressionOptimizer.optimize(project, pair.first.replace(pair.second));
    }
    inlineExpressionUsage(project, (BnfExpression)parent, expression);
    if (!(parent instanceof BnfExternalExpression)) {
      for (BnfModifier modifier : rule.getModifierList()) {
        if (modifier.getText().equals("external")) {
          modifier.getNextSibling().delete(); // whitespace
          modifier.delete();
          break;
        }
      }
    }
  }