public Result visitClassCall()

in meta/src/main/java/org/arend/lib/meta/cong/CongVisitor.java [240:284]


  public Result visitClassCall(@NotNull CoreClassCallExpression expr, ParamType param) {
    CoreExpression otherExpr = param.other.getUnderlyingExpression();
    if (!(otherExpr instanceof CoreClassCallExpression)) {
      return visit(expr, param);
    }

    CoreClassCallExpression other = (CoreClassCallExpression) otherExpr;
    if (expr.getDefinition() != other.getDefinition() || expr.getImplementations().size() != other.getImplementations().size()) {
      return visit(expr, param);
    }

    List<ConcreteClassElement> args = new ArrayList<>();
    boolean abstracted = false;
    Set<CoreClassField> fieldsToCheck = new HashSet<>();
    for (Map.Entry<? extends CoreClassField, ? extends CoreExpression> entry : expr.getImplementations()) {
      if (entry.getKey().isProperty()) continue;
      CoreExpression otherImpl = other.getAbsImplementationHere(entry.getKey());
      if (otherImpl == null) {
        return visit(expr, param);
      }
      Result arg = entry.getValue().accept(this, new ParamType(() -> new Result(null), otherImpl));
      if (arg != null) {
        if (arg.expression != null) {
          abstracted = true;
          fieldsToCheck.add(entry.getKey());
        }
        args.add(factory.implementation(entry.getKey().getRef(), arg.getExpression(entry.getValue(), factory)));
      }
    }

    if (!fieldsToCheck.isEmpty()) {
      boolean check = false;
      for (Map.Entry<? extends CoreClassField, ? extends CoreExpression> entry : expr.getImplementations()) {
        if (!check) {
          check = true;
          continue;
        }
        if (entry.getKey().getResultType().processSubexpression(subexpr -> subexpr instanceof CoreFieldCallExpression && fieldsToCheck.contains(((CoreFieldCallExpression) subexpr).getDefinition()) ? CoreExpression.FindAction.STOP : CoreExpression.FindAction.CONTINUE)) {
          return null;
        }
      }
    }

    return new Result(abstracted ? factory.classExt(factory.ref(expr.getDefinition().getRef()), args) : null);
  }