private static boolean findAndRemoveParameterCheck()

in src/org/jetbrains/java/decompiler/modules/decompiler/IdeaNotNullHelper.java [44:139]


  private static boolean findAndRemoveParameterCheck(Statement stat, StructMethod mt) {

    Statement st = stat.getFirst();
    while (st.type == StatementType.SEQUENCE) {
      if (st.getFirst() instanceof BasicBlockStatement blockStatement &&
          st.getStats().size() > 1 &&
          (blockStatement.getExprents() == null ||
           blockStatement.getExprents().isEmpty())) {
        st = st.getStats().get(1);
      }
      else {
        st = st.getFirst();
      }
    }

    if (st.type == StatementType.IF) {

      IfStatement ifstat = (IfStatement)st;
      Statement ifbranch = ifstat.getIfstat();

      Exprent if_condition = ifstat.getHeadexprent().getCondition();

      boolean is_notnull_check = false;

      // TODO: FUNCTION_NE also possible if reversed order (in theory)
      if (ifbranch != null &&
          if_condition.type == Exprent.EXPRENT_FUNCTION &&
          ((FunctionExprent)if_condition).getFuncType() == FunctionExprent.FUNCTION_EQ &&
          ifbranch.type == StatementType.BASIC_BLOCK &&
          ifbranch.getExprents() != null && ifbranch.getExprents().size() == 1 &&
          (ifbranch.getExprents().get(0).type == Exprent.EXPRENT_EXIT ||
           (ifbranch.getExprents().get(0) instanceof InvocationExprent invocationExprent &&
            invocationExprent.getName() != null &&
            invocationExprent.getName().startsWith(REPORT_NOT_NULL)))) {

        FunctionExprent func = (FunctionExprent)if_condition;
        Exprent first_param = func.getLstOperands().get(0);
        Exprent second_param = func.getLstOperands().get(1);

        if (second_param.type == Exprent.EXPRENT_CONST &&
            second_param.getExprType().getType() == CodeConstants.TYPE_NULL) { // TODO: reversed parameter order
          if (first_param.type == Exprent.EXPRENT_VAR) {
            VarExprent var = (VarExprent)first_param;

            boolean thisvar = !mt.hasModifier(CodeConstants.ACC_STATIC);

            MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor());

            // parameter annotations
            StructAnnotationParameterAttribute param_annotations =
              mt.getAttribute(StructGeneralAttribute.ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS);
            if (param_annotations != null) {

              List<List<AnnotationExprent>> param_annotations_lists = param_annotations.getParamAnnotations();
              int method_param_number = md.params.length;

              int index = thisvar ? 1 : 0;
              for (int i = 0; i < method_param_number; i++) {

                if (index == var.getIndex()) {
                  if (param_annotations_lists.size() >= method_param_number - i) {
                    int shift = method_param_number -
                                param_annotations_lists
                                  .size(); // NOTE: workaround for compiler bug, count annotations starting with the last parameter

                    List<AnnotationExprent> annotations = param_annotations_lists.get(i - shift);

                    for (AnnotationExprent ann : annotations) {
                      if (ann.getClassName().equals("org/jetbrains/annotations/NotNull")) {
                        is_notnull_check = true;
                        break;
                      }
                    }
                  }

                  break;
                }

                index += md.params[i].getStackSize();
              }
            }
          }
        }
      }

      if (!is_notnull_check) {
        return false;
      }

      removeParameterCheck(stat);

      return true;
    }

    return false;
  }