| /* |
| * Copyright 2000-2014 JetBrains s.r.o. |
| * |
| * 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 |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * 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 org.jetbrains.java.decompiler.main.rels.ClassWrapper; |
| import org.jetbrains.java.decompiler.main.rels.MethodWrapper; |
| import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent; |
| import org.jetbrains.java.decompiler.modules.decompiler.exps.InvocationExprent; |
| import org.jetbrains.java.decompiler.modules.decompiler.exps.VarExprent; |
| import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; |
| import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPaar; |
| import org.jetbrains.java.decompiler.struct.StructClass; |
| import org.jetbrains.java.decompiler.struct.StructField; |
| import org.jetbrains.java.decompiler.struct.StructMethod; |
| import org.jetbrains.java.decompiler.util.InterpreterUtil; |
| |
| public class EnumProcessor { |
| |
| public static void clearEnum(ClassWrapper wrapper) { |
| StructClass cl = wrapper.getClassStruct(); |
| |
| // hide values/valueOf methods and super() invocations |
| for (MethodWrapper method : wrapper.getMethods()) { |
| StructMethod mt = method.methodStruct; |
| String name = mt.getName(); |
| String descriptor = mt.getDescriptor(); |
| |
| if ("values".equals(name)) { |
| if (descriptor.equals("()[L" + cl.qualifiedName + ";")) { |
| wrapper.getHiddenMembers().add(InterpreterUtil.makeUniqueKey(name, descriptor)); |
| } |
| } |
| else if ("valueOf".equals(name)) { |
| if (descriptor.equals("(Ljava/lang/String;)L" + cl.qualifiedName + ";")) { |
| wrapper.getHiddenMembers().add(InterpreterUtil.makeUniqueKey(name, descriptor)); |
| } |
| } |
| else if ("<init>".equals(name)) { |
| Statement firstData = findFirstData(method.root); |
| if (firstData != null && !firstData.getExprents().isEmpty()) { |
| Exprent exprent = firstData.getExprents().get(0); |
| if (exprent.type == Exprent.EXPRENT_INVOCATION) { |
| InvocationExprent invexpr = (InvocationExprent)exprent; |
| if (isInvocationSuperConstructor(invexpr, method, wrapper)) { |
| firstData.getExprents().remove(0); |
| } |
| } |
| } |
| } |
| } |
| |
| // hide synthetic fields of enum and it's constants |
| for (StructField fd : cl.getFields()) { |
| String descriptor = fd.getDescriptor(); |
| if (fd.isSynthetic() && descriptor.equals("[L" + cl.qualifiedName + ";")) { |
| wrapper.getHiddenMembers().add(InterpreterUtil.makeUniqueKey(fd.getName(), descriptor)); |
| } |
| } |
| } |
| |
| // FIXME: move to a util class (see also InitializerProcessor) |
| private static Statement findFirstData(Statement stat) { |
| |
| if (stat.getExprents() != null) { |
| return stat; |
| } |
| else { |
| if (stat.isLabeled()) { |
| return null; |
| } |
| |
| switch (stat.type) { |
| case Statement.TYPE_SEQUENCE: |
| case Statement.TYPE_IF: |
| case Statement.TYPE_ROOT: |
| case Statement.TYPE_SWITCH: |
| case Statement.TYPE_SYNCRONIZED: |
| return findFirstData(stat.getFirst()); |
| default: |
| return null; |
| } |
| } |
| } |
| |
| // FIXME: move to util class (see also InitializerProcessor) |
| private static boolean isInvocationSuperConstructor(InvocationExprent inv, MethodWrapper meth, ClassWrapper wrapper) { |
| |
| if (inv.getFunctype() == InvocationExprent.TYP_INIT) { |
| if (inv.getInstance().type == Exprent.EXPRENT_VAR) { |
| VarExprent instvar = (VarExprent)inv.getInstance(); |
| VarVersionPaar varpaar = new VarVersionPaar(instvar); |
| |
| String classname = meth.varproc.getThisvars().get(varpaar); |
| |
| if (classname != null) { // any this instance. TODO: Restrict to current class? |
| if (!wrapper.getClassStruct().qualifiedName.equals(inv.getClassname())) { |
| return true; |
| } |
| } |
| } |
| } |
| |
| return false; |
| } |
| } |