private void generateBinOp(@NotNull DfaAnchor anchor, @NotNull IElementType op, PsiExpression rExpr, PsiType resType) {
    if ((op == JavaTokenType.DIV || op == JavaTokenType.PERC) && resType != null && PsiTypes.longType().isAssignableFrom(resType)) {
      Object divisorValue = ExpressionUtils.computeConstantExpression(rExpr);
      if (!(divisorValue instanceof Number number) || (number.longValue() == 0)) {
        checkZeroDivisor(resType);
      }
    }
    Instruction inst;
    if (op.equals(JavaTokenType.PLUS) && TypeUtils.isJavaLangString(resType)) {
      inst = new StringConcatInstruction(anchor, TypeConstraints.exact(resType));
    }
    else if (PsiTypes.booleanType().equals(resType)) {
      if (op.equals(JavaTokenType.AND)) {
        inst = new BooleanAndOrInstruction(false, anchor);
      }
      else if (op.equals(JavaTokenType.OR)) {
        inst = new BooleanAndOrInstruction(true, anchor);
      }
      else {
        RelationType relation = op == JavaTokenType.XOR ? RelationType.NE : DfaPsiUtil.getRelationByToken(op);
        inst = relation != null ? new BooleanBinaryInstruction(relation, false, anchor) :
               new EvalUnknownInstruction(anchor, 2);
      }
    }
    else {
      inst = new NumericBinaryInstruction(JvmPsiRangeSetUtil.binOpFromToken(op), anchor);
    }
    addInstruction(inst);
  }
private void generateBinOp(@NotNull DfaAnchor anchor, @NotNull IElementType op, PsiExpression rExpr, PsiType resType)