private void computeMethodType()

in src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java [55:203]


  private void computeMethodType(ClassNode node, MethodWrapper method) {
    MethodAccess type = MethodAccess.NORMAL;

    if (method.root != null) {
      DirectGraph graph = method.getOrBuildGraph();

      StructMethod mt = method.methodStruct;
      if ((noSynthFlag || mt.isSynthetic()) && mt.hasModifier(CodeConstants.ACC_STATIC)) {
        if (graph.nodes.size() == 2) {  // incl. dummy exit node
          if (graph.first.exprents.size() == 1) {
            Exprent exprent = graph.first.exprents.get(0);

            MethodDescriptor mtdesc = MethodDescriptor.parseDescriptor(mt.getDescriptor());
            int parcount = mtdesc.params.length;

            Exprent exprCore = exprent;

            if (exprent.type == Exprent.EXPRENT_EXIT) {
              ExitExprent exexpr = (ExitExprent)exprent;
              if (exexpr.getExitType() == ExitExprent.EXIT_RETURN && exexpr.getValue() != null) {
                exprCore = exexpr.getValue();
              }
            }

            switch (exprCore.type) {
              case Exprent.EXPRENT_FIELD -> {
                FieldExprent fexpr = (FieldExprent)exprCore;
                if ((parcount == 1 && !fexpr.isStatic()) ||
                    (parcount == 0 && fexpr.isStatic())) {
                  if (fexpr.getClassname().equals(node.classStruct.qualifiedName)) {  // FIXME: check for private flag of the field
                    if (fexpr.isStatic() ||
                        (fexpr.getInstance().type == Exprent.EXPRENT_VAR && ((VarExprent)fexpr.getInstance()).getIndex() == 0)) {
                      type = MethodAccess.FIELD_GET;
                    }
                  }
                }
              }
              case Exprent.EXPRENT_VAR -> {  // qualified this
                if (parcount == 1) {
                  // this or final variable
                  if (((VarExprent)exprCore).getIndex() != 0) {
                    type = MethodAccess.FIELD_GET;
                  }
                }
              }
              case Exprent.EXPRENT_FUNCTION -> {
                // for now detect only increment/decrement
                FunctionExprent functionExprent = (FunctionExprent)exprCore;
                if (functionExprent.getFuncType() >= FunctionExprent.FUNCTION_IMM &&
                    functionExprent.getFuncType() <= FunctionExprent.FUNCTION_PPI) {
                  if (functionExprent.getLstOperands().get(0).type == Exprent.EXPRENT_FIELD) {
                    type = MethodAccess.FUNCTION;
                  }
                }
              }
              case Exprent.EXPRENT_INVOCATION -> type = MethodAccess.METHOD;
              case Exprent.EXPRENT_ASSIGNMENT -> {
                AssignmentExprent asexpr = (AssignmentExprent)exprCore;
                if (asexpr.getLeft().type == Exprent.EXPRENT_FIELD && asexpr.getRight().type == Exprent.EXPRENT_VAR) {
                  FieldExprent fexpras = (FieldExprent)asexpr.getLeft();
                  if ((parcount == 2 && !fexpras.isStatic()) ||
                      (parcount == 1 && fexpras.isStatic())) {
                    if (fexpras.getClassname().equals(node.classStruct.qualifiedName)) { // FIXME: check for private flag of the field
                      if (fexpras.isStatic() ||
                          (fexpras.getInstance().type == Exprent.EXPRENT_VAR && ((VarExprent)fexpras.getInstance()).getIndex() == 0)) {
                        if (((VarExprent)asexpr.getRight()).getIndex() == parcount - 1) {
                          type = MethodAccess.FIELD_SET;
                        }
                      }
                    }
                  }
                }
              }
            }

            if (type == MethodAccess.METHOD) { // FIXME: check for private flag of the method

              type = MethodAccess.NORMAL;

              InvocationExprent invexpr = (InvocationExprent)exprCore;

              boolean isStatic = invexpr.isStatic();
              if ((isStatic && invexpr.getParameters().size() == parcount) ||
                  (!isStatic && invexpr.getInstance().type == Exprent.EXPRENT_VAR
                   && ((VarExprent)invexpr.getInstance()).getIndex() == 0 && invexpr.getParameters().size() == parcount - 1)) {

                boolean equalpars = true;

                int index = isStatic ? 0 : 1;
                for (int i = 0; i < invexpr.getParameters().size(); i++) {
                  Exprent parexpr = invexpr.getParameters().get(i);
                  if (parexpr.type != Exprent.EXPRENT_VAR || ((VarExprent)parexpr).getIndex() != index) {
                    equalpars = false;
                    break;
                  }
                  index += mtdesc.params[i + (isStatic ? 0 : 1)].getStackSize();
                }

                if (equalpars) {
                  type = MethodAccess.METHOD;
                }
              }
            }
          }
          else if (graph.first.exprents.size() == 2) {
            Exprent exprentFirst = graph.first.exprents.get(0);
            Exprent exprentSecond = graph.first.exprents.get(1);

            if (exprentFirst.type == Exprent.EXPRENT_ASSIGNMENT &&
                exprentSecond.type == Exprent.EXPRENT_EXIT) {

              MethodDescriptor mtdesc = MethodDescriptor.parseDescriptor(mt.getDescriptor());
              int parcount = mtdesc.params.length;

              AssignmentExprent asexpr = (AssignmentExprent)exprentFirst;
              if (asexpr.getLeft().type == Exprent.EXPRENT_FIELD && asexpr.getRight().type == Exprent.EXPRENT_VAR) {
                FieldExprent fexpras = (FieldExprent)asexpr.getLeft();
                if ((parcount == 2 && !fexpras.isStatic()) ||
                    (parcount == 1 && fexpras.isStatic())) {
                  if (fexpras.getClassname().equals(node.classStruct.qualifiedName)) { // FIXME: check for private flag of the field
                    if (fexpras.isStatic() ||
                        (fexpras.getInstance().type == Exprent.EXPRENT_VAR && ((VarExprent)fexpras.getInstance()).getIndex() == 0)) {
                      if (((VarExprent)asexpr.getRight()).getIndex() == parcount - 1) {

                        ExitExprent exexpr = (ExitExprent)exprentSecond;
                        if (exexpr.getExitType() == ExitExprent.EXIT_RETURN && exexpr.getValue() != null) {
                          if (exexpr.getValue().type == Exprent.EXPRENT_VAR &&
                              ((VarExprent)asexpr.getRight()).getIndex() == parcount - 1) {
                            type = MethodAccess.FIELD_SET;
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }

    if (type != MethodAccess.NORMAL) {
      mapMethodType.put(method, type);
    }
    else {
      mapMethodType.remove(method);
    }
  }