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);
}
}