summaryrefslogtreecommitdiffstats
path: root/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java')
-rw-r--r--src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java561
1 files changed, 278 insertions, 283 deletions
diff --git a/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java b/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java
index cdad6ca..411789c 100644
--- a/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java
+++ b/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java
@@ -1,39 +1,26 @@
/*
- * Fernflower - The Analytical Java Decompiler
- * http://www.reversed-java.com
+ * Copyright 2000-2014 JetBrains s.r.o.
*
- * (C) 2008 - 2010, Stiver
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * This software is NEITHER public domain NOR free software
- * as per GNU License. See license.txt for more details.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * This software is distributed WITHOUT ANY WARRANTY; without
- * even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
-
package org.jetbrains.java.decompiler.main;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map.Entry;
-
import org.jetbrains.java.decompiler.code.CodeConstants;
import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode;
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences;
import org.jetbrains.java.decompiler.main.rels.ClassWrapper;
import org.jetbrains.java.decompiler.main.rels.MethodWrapper;
-import org.jetbrains.java.decompiler.modules.decompiler.exps.AssignmentExprent;
-import org.jetbrains.java.decompiler.modules.decompiler.exps.ConstExprent;
-import org.jetbrains.java.decompiler.modules.decompiler.exps.ExitExprent;
-import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent;
-import org.jetbrains.java.decompiler.modules.decompiler.exps.FieldExprent;
-import org.jetbrains.java.decompiler.modules.decompiler.exps.FunctionExprent;
-import org.jetbrains.java.decompiler.modules.decompiler.exps.InvocationExprent;
-import org.jetbrains.java.decompiler.modules.decompiler.exps.NewExprent;
-import org.jetbrains.java.decompiler.modules.decompiler.exps.VarExprent;
+import org.jetbrains.java.decompiler.modules.decompiler.exps.*;
import org.jetbrains.java.decompiler.modules.decompiler.sforms.DirectGraph;
import org.jetbrains.java.decompiler.modules.decompiler.stats.BasicBlockStatement;
import org.jetbrains.java.decompiler.modules.decompiler.stats.CatchStatement;
@@ -46,264 +33,272 @@ import org.jetbrains.java.decompiler.struct.gen.VarType;
import org.jetbrains.java.decompiler.util.InterpreterUtil;
import org.jetbrains.java.decompiler.util.VBStyleCollection;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map.Entry;
+
public class ClassReference14Processor {
-
- public ExitExprent bodyexprent;
-
- public ExitExprent handlerexprent;
-
-
- public ClassReference14Processor() {
-
- InvocationExprent invfor = new InvocationExprent();
- invfor.setName("forName");
- invfor.setClassname("java/lang/Class");
- invfor.setStringDescriptor("(Ljava/lang/String;)Ljava/lang/Class;");
- invfor.setDescriptor(MethodDescriptor.parseDescriptor("(Ljava/lang/String;)Ljava/lang/Class;"));
- invfor.setStatic(true);
- invfor.setLstParameters(Arrays.asList(new Exprent[] {new VarExprent(0, VarType.VARTYPE_STRING, null)}));
-
- bodyexprent = new ExitExprent(ExitExprent.EXIT_RETURN,
- invfor,
- VarType.VARTYPE_CLASS);
-
- InvocationExprent constr = new InvocationExprent();
- constr.setName("<init>");
- constr.setClassname("java/lang/NoClassDefFoundError");
- constr.setStringDescriptor("()V");
- constr.setFunctype(InvocationExprent.TYP_INIT);
- constr.setDescriptor(MethodDescriptor.parseDescriptor("()V"));
-
- NewExprent newexpr = new NewExprent(new VarType(CodeConstants.TYPE_OBJECT,0,"java/lang/NoClassDefFoundError"), new ArrayList<Exprent>());
- newexpr.setConstructor(constr);
-
- InvocationExprent invcause = new InvocationExprent();
- invcause.setName("initCause");
- invcause.setClassname("java/lang/NoClassDefFoundError");
- invcause.setStringDescriptor("(Ljava/lang/Throwable;)Ljava/lang/Throwable;");
- invcause.setDescriptor(MethodDescriptor.parseDescriptor("(Ljava/lang/Throwable;)Ljava/lang/Throwable;"));
- invcause.setInstance(newexpr);
- invcause.setLstParameters(Arrays.asList(new Exprent[] {new VarExprent(2, new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/ClassNotFoundException"), null)}));
-
- handlerexprent = new ExitExprent(ExitExprent.EXIT_THROW,
- invcause,
- null);
- }
-
-
- public void processClassReferences(ClassNode node) {
-
- ClassWrapper wrapper = node.wrapper;
-
-// int major_version = wrapper.getClassStruct().major_version;
-// int minor_version = wrapper.getClassStruct().minor_version;
-//
-// if(major_version > 48 || (major_version == 48 && minor_version > 0)) {
-// // version 1.5 or above
-// return;
-// }
-
- if(wrapper.getClassStruct().isVersionGE_1_5()) {
- // version 1.5 or above
- return;
- }
-
- // find the synthetic method Class class$(String) if present
- HashMap<ClassWrapper, MethodWrapper> mapClassMeths = new HashMap<ClassWrapper, MethodWrapper>();
- findClassMethod(node, mapClassMeths);
-
- if(mapClassMeths.isEmpty()) {
- return;
- }
-
- HashSet<ClassWrapper> setFound = new HashSet<ClassWrapper>();
- processClassRec(node, mapClassMeths, setFound);
-
- if(!setFound.isEmpty()) {
- for(ClassWrapper wrp : setFound) {
- StructMethod mt = mapClassMeths.get(wrp).methodStruct;
- wrp.getHideMembers().add(InterpreterUtil.makeUniqueKey(mt.getName(), mt.getDescriptor()));
- }
- }
-
- }
-
- private void processClassRec(ClassNode node, final HashMap<ClassWrapper, MethodWrapper> mapClassMeths, final HashSet<ClassWrapper> setFound) {
-
- final ClassWrapper wrapper = node.wrapper;
-
- // search code
- for(MethodWrapper meth : wrapper.getMethods()) {
-
- RootStatement root = meth.root;
- if(root != null) {
-
- DirectGraph graph = meth.getOrBuildGraph();
-
- graph.iterateExprents(new DirectGraph.ExprentIterator() {
- public int processExprent(Exprent exprent) {
- for(Entry<ClassWrapper, MethodWrapper> ent : mapClassMeths.entrySet()) {
- if(replaceInvocations(exprent, ent.getKey(), ent.getValue())) {
- setFound.add(ent.getKey());
- }
- }
- return 0;
- }
- });
-
- }
- }
-
- // search initializers
- for(int j=0;j<2;j++) {
- VBStyleCollection<Exprent, String> initializers = j==0?wrapper.getStaticFieldInitializers():wrapper.getDynamicFieldInitializers();
-
- for(int i=0; i<initializers.size();i++) {
- for(Entry<ClassWrapper, MethodWrapper> ent : mapClassMeths.entrySet()) {
- Exprent exprent = initializers.get(i);
- if(replaceInvocations(exprent, ent.getKey(), ent.getValue())) {
- setFound.add(ent.getKey());
- }
-
- String cl = isClass14Invocation(exprent, ent.getKey(), ent.getValue());
- if(cl != null) {
- initializers.set(i, new ConstExprent(VarType.VARTYPE_CLASS, cl.replace('.', '/')));
- setFound.add(ent.getKey());
- }
- }
- }
- }
-
- // iterate nested classes
- for(ClassNode nd : node.nested) {
- processClassRec(nd, mapClassMeths, setFound);
- }
-
- }
-
- private void findClassMethod(ClassNode node, HashMap<ClassWrapper, MethodWrapper> mapClassMeths) {
-
- boolean nosynthflag = DecompilerContext.getOption(IFernflowerPreferences.SYNTHETIC_NOT_SET);
-
- ClassWrapper wrapper = node.wrapper;
-
- for(MethodWrapper meth : wrapper.getMethods()) {
- StructMethod mt = meth.methodStruct;
-
- if(((mt.getAccessFlags() & CodeConstants.ACC_SYNTHETIC) != 0 || mt.getAttributes().containsKey("Synthetic")
- || nosynthflag) &&
- mt.getDescriptor().equals("(Ljava/lang/String;)Ljava/lang/Class;") &&
- (mt.getAccessFlags() & CodeConstants.ACC_STATIC) != 0) {
-
- RootStatement root = meth.root;
- if(root != null) {
- if(root.getFirst().type == Statement.TYPE_TRYCATCH) {
- CatchStatement cst = (CatchStatement)root.getFirst();
- if(cst.getStats().size() == 2 && cst.getFirst().type == Statement.TYPE_BASICBLOCK &&
- cst.getStats().get(1).type == Statement.TYPE_BASICBLOCK &&
- cst.getVars().get(0).getVartype().equals(new VarType(CodeConstants.TYPE_OBJECT,0,"java/lang/ClassNotFoundException"))) {
-
- BasicBlockStatement body = (BasicBlockStatement)cst.getFirst();
- BasicBlockStatement handler = (BasicBlockStatement)cst.getStats().get(1);
-
- if(body.getExprents().size() == 1 && handler.getExprents().size() == 1) {
- if(bodyexprent.equals(body.getExprents().get(0)) &&
- handlerexprent.equals(handler.getExprents().get(0))) {
- mapClassMeths.put(wrapper, meth);
- break;
- }
- }
- }
- }
- }
- }
- }
-
- // iterate nested classes
- for(ClassNode nd : node.nested) {
- findClassMethod(nd, mapClassMeths);
- }
-
- }
-
-
- private boolean replaceInvocations(Exprent exprent, ClassWrapper wrapper, MethodWrapper meth) {
-
- boolean res = false;
-
- for(;;) {
-
- boolean found = false;
-
- for(Exprent expr : exprent.getAllExprents()) {
- String cl = isClass14Invocation(expr, wrapper, meth);
- if(cl != null) {
- exprent.replaceExprent(expr, new ConstExprent(VarType.VARTYPE_CLASS, cl.replace('.', '/')));
- found = true;
- res = true;
- break;
- }
-
- res |= replaceInvocations(expr, wrapper, meth);
- }
-
- if(!found) {
- break;
- }
- }
-
- return res;
- }
-
-
-
- private String isClass14Invocation(Exprent exprent, ClassWrapper wrapper, MethodWrapper meth) {
-
- if(exprent.type == Exprent.EXPRENT_FUNCTION) {
- FunctionExprent fexpr = (FunctionExprent)exprent;
- if(fexpr.getFunctype() == FunctionExprent.FUNCTION_IIF) {
- if(fexpr.getLstOperands().get(0).type == Exprent.EXPRENT_FUNCTION) {
- FunctionExprent headexpr = (FunctionExprent)fexpr.getLstOperands().get(0);
- if(headexpr.getFunctype() == FunctionExprent.FUNCTION_EQ) {
- if(headexpr.getLstOperands().get(0).type == Exprent.EXPRENT_FIELD &&
- headexpr.getLstOperands().get(1).type == Exprent.EXPRENT_CONST &&
- ((ConstExprent)headexpr.getLstOperands().get(1)).getConsttype().equals(VarType.VARTYPE_NULL)) {
-
- FieldExprent field = (FieldExprent)headexpr.getLstOperands().get(0);
- ClassNode fieldnode = DecompilerContext.getClassprocessor().getMapRootClasses().get(field.getClassname());
-
- if(fieldnode != null && fieldnode.classStruct.qualifiedName.equals(wrapper.getClassStruct().qualifiedName)) { // source class
- StructField fd = wrapper.getClassStruct().getField(field.getName(), field.getDescriptor().descriptorString); // FIXME: can be null! why??
-
- if(fd != null && (fd.access_flags & CodeConstants.ACC_STATIC) != 0 &&
- ((fd.access_flags & CodeConstants.ACC_SYNTHETIC) != 0 || fd.getAttributes().containsKey("Synthetic")
- || DecompilerContext.getOption(IFernflowerPreferences.SYNTHETIC_NOT_SET))) {
-
- if(fexpr.getLstOperands().get(1).type == Exprent.EXPRENT_ASSIGNMENT && fexpr.getLstOperands().get(2).equals(field)) {
- AssignmentExprent asexpr = (AssignmentExprent)fexpr.getLstOperands().get(1);
-
- if(asexpr.getLeft().equals(field) && asexpr.getRight().type == Exprent.EXPRENT_INVOCATION) {
- InvocationExprent invexpr = (InvocationExprent)asexpr.getRight();
-
- if(invexpr.getClassname().equals(wrapper.getClassStruct().qualifiedName) &&
- invexpr.getName().equals(meth.methodStruct.getName()) &&
- invexpr.getStringDescriptor().equals(meth.methodStruct.getDescriptor())) {
-
- if(invexpr.getLstParameters().get(0).type == Exprent.EXPRENT_CONST) {
- wrapper.getHideMembers().add(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor())); // hide synthetic field
- return ((ConstExprent)invexpr.getLstParameters().get(0)).getValue().toString();
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
-
- return null;
- }
+
+ public ExitExprent bodyexprent;
+
+ public ExitExprent handlerexprent;
+
+
+ public ClassReference14Processor() {
+
+ InvocationExprent invfor = new InvocationExprent();
+ invfor.setName("forName");
+ invfor.setClassname("java/lang/Class");
+ invfor.setStringDescriptor("(Ljava/lang/String;)Ljava/lang/Class;");
+ invfor.setDescriptor(MethodDescriptor.parseDescriptor("(Ljava/lang/String;)Ljava/lang/Class;"));
+ invfor.setStatic(true);
+ invfor.setLstParameters(Arrays.asList(new Exprent[]{new VarExprent(0, VarType.VARTYPE_STRING, null)}));
+
+ bodyexprent = new ExitExprent(ExitExprent.EXIT_RETURN,
+ invfor,
+ VarType.VARTYPE_CLASS);
+
+ InvocationExprent constr = new InvocationExprent();
+ constr.setName("<init>");
+ constr.setClassname("java/lang/NoClassDefFoundError");
+ constr.setStringDescriptor("()V");
+ constr.setFunctype(InvocationExprent.TYP_INIT);
+ constr.setDescriptor(MethodDescriptor.parseDescriptor("()V"));
+
+ NewExprent newexpr =
+ new NewExprent(new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/NoClassDefFoundError"), new ArrayList<Exprent>());
+ newexpr.setConstructor(constr);
+
+ InvocationExprent invcause = new InvocationExprent();
+ invcause.setName("initCause");
+ invcause.setClassname("java/lang/NoClassDefFoundError");
+ invcause.setStringDescriptor("(Ljava/lang/Throwable;)Ljava/lang/Throwable;");
+ invcause.setDescriptor(MethodDescriptor.parseDescriptor("(Ljava/lang/Throwable;)Ljava/lang/Throwable;"));
+ invcause.setInstance(newexpr);
+ invcause.setLstParameters(
+ Arrays.asList(new Exprent[]{new VarExprent(2, new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/ClassNotFoundException"), null)}));
+
+ handlerexprent = new ExitExprent(ExitExprent.EXIT_THROW,
+ invcause,
+ null);
+ }
+
+
+ public void processClassReferences(ClassNode node) {
+
+ ClassWrapper wrapper = node.wrapper;
+
+ // int major_version = wrapper.getClassStruct().major_version;
+ // int minor_version = wrapper.getClassStruct().minor_version;
+ //
+ // if(major_version > 48 || (major_version == 48 && minor_version > 0)) {
+ // // version 1.5 or above
+ // return;
+ // }
+
+ if (wrapper.getClassStruct().isVersionGE_1_5()) {
+ // version 1.5 or above
+ return;
+ }
+
+ // find the synthetic method Class class$(String) if present
+ HashMap<ClassWrapper, MethodWrapper> mapClassMeths = new HashMap<ClassWrapper, MethodWrapper>();
+ findClassMethod(node, mapClassMeths);
+
+ if (mapClassMeths.isEmpty()) {
+ return;
+ }
+
+ HashSet<ClassWrapper> setFound = new HashSet<ClassWrapper>();
+ processClassRec(node, mapClassMeths, setFound);
+
+ if (!setFound.isEmpty()) {
+ for (ClassWrapper wrp : setFound) {
+ StructMethod mt = mapClassMeths.get(wrp).methodStruct;
+ wrp.getHideMembers().add(InterpreterUtil.makeUniqueKey(mt.getName(), mt.getDescriptor()));
+ }
+ }
+ }
+
+ private void processClassRec(ClassNode node,
+ final HashMap<ClassWrapper, MethodWrapper> mapClassMeths,
+ final HashSet<ClassWrapper> setFound) {
+
+ final ClassWrapper wrapper = node.wrapper;
+
+ // search code
+ for (MethodWrapper meth : wrapper.getMethods()) {
+
+ RootStatement root = meth.root;
+ if (root != null) {
+
+ DirectGraph graph = meth.getOrBuildGraph();
+
+ graph.iterateExprents(new DirectGraph.ExprentIterator() {
+ public int processExprent(Exprent exprent) {
+ for (Entry<ClassWrapper, MethodWrapper> ent : mapClassMeths.entrySet()) {
+ if (replaceInvocations(exprent, ent.getKey(), ent.getValue())) {
+ setFound.add(ent.getKey());
+ }
+ }
+ return 0;
+ }
+ });
+ }
+ }
+
+ // search initializers
+ for (int j = 0; j < 2; j++) {
+ VBStyleCollection<Exprent, String> initializers =
+ j == 0 ? wrapper.getStaticFieldInitializers() : wrapper.getDynamicFieldInitializers();
+
+ for (int i = 0; i < initializers.size(); i++) {
+ for (Entry<ClassWrapper, MethodWrapper> ent : mapClassMeths.entrySet()) {
+ Exprent exprent = initializers.get(i);
+ if (replaceInvocations(exprent, ent.getKey(), ent.getValue())) {
+ setFound.add(ent.getKey());
+ }
+
+ String cl = isClass14Invocation(exprent, ent.getKey(), ent.getValue());
+ if (cl != null) {
+ initializers.set(i, new ConstExprent(VarType.VARTYPE_CLASS, cl.replace('.', '/')));
+ setFound.add(ent.getKey());
+ }
+ }
+ }
+ }
+
+ // iterate nested classes
+ for (ClassNode nd : node.nested) {
+ processClassRec(nd, mapClassMeths, setFound);
+ }
+ }
+
+ private void findClassMethod(ClassNode node, HashMap<ClassWrapper, MethodWrapper> mapClassMeths) {
+
+ boolean nosynthflag = DecompilerContext.getOption(IFernflowerPreferences.SYNTHETIC_NOT_SET);
+
+ ClassWrapper wrapper = node.wrapper;
+
+ for (MethodWrapper meth : wrapper.getMethods()) {
+ StructMethod mt = meth.methodStruct;
+
+ if (((mt.getAccessFlags() & CodeConstants.ACC_SYNTHETIC) != 0 || mt.getAttributes().containsKey("Synthetic")
+ || nosynthflag) &&
+ mt.getDescriptor().equals("(Ljava/lang/String;)Ljava/lang/Class;") &&
+ (mt.getAccessFlags() & CodeConstants.ACC_STATIC) != 0) {
+
+ RootStatement root = meth.root;
+ if (root != null) {
+ if (root.getFirst().type == Statement.TYPE_TRYCATCH) {
+ CatchStatement cst = (CatchStatement)root.getFirst();
+ if (cst.getStats().size() == 2 && cst.getFirst().type == Statement.TYPE_BASICBLOCK &&
+ cst.getStats().get(1).type == Statement.TYPE_BASICBLOCK &&
+ cst.getVars().get(0).getVartype().equals(new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/ClassNotFoundException"))) {
+
+ BasicBlockStatement body = (BasicBlockStatement)cst.getFirst();
+ BasicBlockStatement handler = (BasicBlockStatement)cst.getStats().get(1);
+
+ if (body.getExprents().size() == 1 && handler.getExprents().size() == 1) {
+ if (bodyexprent.equals(body.getExprents().get(0)) &&
+ handlerexprent.equals(handler.getExprents().get(0))) {
+ mapClassMeths.put(wrapper, meth);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // iterate nested classes
+ for (ClassNode nd : node.nested) {
+ findClassMethod(nd, mapClassMeths);
+ }
+ }
+
+
+ private boolean replaceInvocations(Exprent exprent, ClassWrapper wrapper, MethodWrapper meth) {
+
+ boolean res = false;
+
+ for (; ; ) {
+
+ boolean found = false;
+
+ for (Exprent expr : exprent.getAllExprents()) {
+ String cl = isClass14Invocation(expr, wrapper, meth);
+ if (cl != null) {
+ exprent.replaceExprent(expr, new ConstExprent(VarType.VARTYPE_CLASS, cl.replace('.', '/')));
+ found = true;
+ res = true;
+ break;
+ }
+
+ res |= replaceInvocations(expr, wrapper, meth);
+ }
+
+ if (!found) {
+ break;
+ }
+ }
+
+ return res;
+ }
+
+
+ private String isClass14Invocation(Exprent exprent, ClassWrapper wrapper, MethodWrapper meth) {
+
+ if (exprent.type == Exprent.EXPRENT_FUNCTION) {
+ FunctionExprent fexpr = (FunctionExprent)exprent;
+ if (fexpr.getFunctype() == FunctionExprent.FUNCTION_IIF) {
+ if (fexpr.getLstOperands().get(0).type == Exprent.EXPRENT_FUNCTION) {
+ FunctionExprent headexpr = (FunctionExprent)fexpr.getLstOperands().get(0);
+ if (headexpr.getFunctype() == FunctionExprent.FUNCTION_EQ) {
+ if (headexpr.getLstOperands().get(0).type == Exprent.EXPRENT_FIELD &&
+ headexpr.getLstOperands().get(1).type == Exprent.EXPRENT_CONST &&
+ ((ConstExprent)headexpr.getLstOperands().get(1)).getConsttype().equals(VarType.VARTYPE_NULL)) {
+
+ FieldExprent field = (FieldExprent)headexpr.getLstOperands().get(0);
+ ClassNode fieldnode = DecompilerContext.getClassprocessor().getMapRootClasses().get(field.getClassname());
+
+ if (fieldnode != null && fieldnode.classStruct.qualifiedName.equals(wrapper.getClassStruct().qualifiedName)) { // source class
+ StructField fd =
+ wrapper.getClassStruct().getField(field.getName(), field.getDescriptor().descriptorString); // FIXME: can be null! why??
+
+ if (fd != null && (fd.access_flags & CodeConstants.ACC_STATIC) != 0 &&
+ ((fd.access_flags & CodeConstants.ACC_SYNTHETIC) != 0 || fd.getAttributes().containsKey("Synthetic")
+ || DecompilerContext.getOption(IFernflowerPreferences.SYNTHETIC_NOT_SET))) {
+
+ if (fexpr.getLstOperands().get(1).type == Exprent.EXPRENT_ASSIGNMENT && fexpr.getLstOperands().get(2).equals(field)) {
+ AssignmentExprent asexpr = (AssignmentExprent)fexpr.getLstOperands().get(1);
+
+ if (asexpr.getLeft().equals(field) && asexpr.getRight().type == Exprent.EXPRENT_INVOCATION) {
+ InvocationExprent invexpr = (InvocationExprent)asexpr.getRight();
+
+ if (invexpr.getClassname().equals(wrapper.getClassStruct().qualifiedName) &&
+ invexpr.getName().equals(meth.methodStruct.getName()) &&
+ invexpr.getStringDescriptor().equals(meth.methodStruct.getDescriptor())) {
+
+ if (invexpr.getLstParameters().get(0).type == Exprent.EXPRENT_CONST) {
+ wrapper.getHideMembers()
+ .add(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor())); // hide synthetic field
+ return ((ConstExprent)invexpr.getLstParameters().get(0)).getValue().toString();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return null;
+ }
}