summaryrefslogtreecommitdiffstats
path: root/src/org/jetbrains/java/decompiler/struct/gen
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/jetbrains/java/decompiler/struct/gen')
-rw-r--r--src/org/jetbrains/java/decompiler/struct/gen/DataPoint.java170
-rw-r--r--src/org/jetbrains/java/decompiler/struct/gen/FieldDescriptor.java89
-rw-r--r--src/org/jetbrains/java/decompiler/struct/gen/MethodDescriptor.java160
-rw-r--r--src/org/jetbrains/java/decompiler/struct/gen/VarType.java808
-rw-r--r--src/org/jetbrains/java/decompiler/struct/gen/generics/GenericClassDescriptor.java32
-rw-r--r--src/org/jetbrains/java/decompiler/struct/gen/generics/GenericFieldDescriptor.java22
-rw-r--r--src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java436
-rw-r--r--src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMethodDescriptor.java34
-rw-r--r--src/org/jetbrains/java/decompiler/struct/gen/generics/GenericType.java514
9 files changed, 1141 insertions, 1124 deletions
diff --git a/src/org/jetbrains/java/decompiler/struct/gen/DataPoint.java b/src/org/jetbrains/java/decompiler/struct/gen/DataPoint.java
index db6ecd1..53269da 100644
--- a/src/org/jetbrains/java/decompiler/struct/gen/DataPoint.java
+++ b/src/org/jetbrains/java/decompiler/struct/gen/DataPoint.java
@@ -1,98 +1,100 @@
/*
- * 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.struct.gen;
-import java.util.ArrayList;
-import java.util.List;
-
import org.jetbrains.java.decompiler.code.CodeConstants;
import org.jetbrains.java.decompiler.struct.StructMethod;
import org.jetbrains.java.decompiler.util.ListStack;
+import java.util.ArrayList;
+import java.util.List;
+
public class DataPoint {
- private List<VarType> localVariables = new ArrayList<VarType>();
-
- private ListStack<VarType> stack = new ListStack<VarType>();
-
-
- public void setVariable(int index, VarType value) {
- if(index>=localVariables.size()) {
- for(int i=localVariables.size();i<=index;i++) {
- localVariables.add(new VarType(CodeConstants.TYPE_NOTINITIALIZED));
- }
- }
-
- localVariables.set(index, value);
- }
-
- public VarType getVariable(int index) {
- if(index<localVariables.size()) {
- return localVariables.get(index);
- } else if(index<0) {
- throw new IndexOutOfBoundsException();
- } else {
- return new VarType(CodeConstants.TYPE_NOTINITIALIZED);
- }
- }
-
- public DataPoint copy() {
- DataPoint point = new DataPoint();
- point.setLocalVariables(new ArrayList<VarType>(localVariables));
- point.setStack(stack.clone());
- return point;
- }
-
- public static DataPoint getInitialDataPoint(StructMethod mt) {
-
- DataPoint point = new DataPoint();
-
- MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor());
-
- int k = 0;
- if((mt.getAccessFlags() & CodeConstants.ACC_STATIC) == 0) {
- point.setVariable(k++, new VarType(CodeConstants.TYPE_OBJECT, 0, null));
- }
-
- for(int i=0;i<md.params.length;i++) {
- VarType var = md.params[i];
-
- point.setVariable(k++, var);
- if(var.stack_size == 2) {
- point.setVariable(k++, new VarType(CodeConstants.TYPE_GROUP2EMPTY));
- }
- }
-
- return point;
- }
-
-
- public List<VarType> getLocalVariables() {
- return localVariables;
- }
-
- public void setLocalVariables(List<VarType> localVariables) {
- this.localVariables = localVariables;
- }
-
- public ListStack<VarType> getStack() {
- return stack;
- }
-
- public void setStack(ListStack<VarType> stack) {
- this.stack = stack;
- }
-
+ private List<VarType> localVariables = new ArrayList<VarType>();
+
+ private ListStack<VarType> stack = new ListStack<VarType>();
+
+
+ public void setVariable(int index, VarType value) {
+ if (index >= localVariables.size()) {
+ for (int i = localVariables.size(); i <= index; i++) {
+ localVariables.add(new VarType(CodeConstants.TYPE_NOTINITIALIZED));
+ }
+ }
+
+ localVariables.set(index, value);
+ }
+
+ public VarType getVariable(int index) {
+ if (index < localVariables.size()) {
+ return localVariables.get(index);
+ }
+ else if (index < 0) {
+ throw new IndexOutOfBoundsException();
+ }
+ else {
+ return new VarType(CodeConstants.TYPE_NOTINITIALIZED);
+ }
+ }
+
+ public DataPoint copy() {
+ DataPoint point = new DataPoint();
+ point.setLocalVariables(new ArrayList<VarType>(localVariables));
+ point.setStack(stack.clone());
+ return point;
+ }
+
+ public static DataPoint getInitialDataPoint(StructMethod mt) {
+
+ DataPoint point = new DataPoint();
+
+ MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor());
+
+ int k = 0;
+ if ((mt.getAccessFlags() & CodeConstants.ACC_STATIC) == 0) {
+ point.setVariable(k++, new VarType(CodeConstants.TYPE_OBJECT, 0, null));
+ }
+
+ for (int i = 0; i < md.params.length; i++) {
+ VarType var = md.params[i];
+
+ point.setVariable(k++, var);
+ if (var.stack_size == 2) {
+ point.setVariable(k++, new VarType(CodeConstants.TYPE_GROUP2EMPTY));
+ }
+ }
+
+ return point;
+ }
+
+
+ public List<VarType> getLocalVariables() {
+ return localVariables;
+ }
+
+ public void setLocalVariables(List<VarType> localVariables) {
+ this.localVariables = localVariables;
+ }
+
+ public ListStack<VarType> getStack() {
+ return stack;
+ }
+
+ public void setStack(ListStack<VarType> stack) {
+ this.stack = stack;
+ }
}
diff --git a/src/org/jetbrains/java/decompiler/struct/gen/FieldDescriptor.java b/src/org/jetbrains/java/decompiler/struct/gen/FieldDescriptor.java
index a475937..ff731ae 100644
--- a/src/org/jetbrains/java/decompiler/struct/gen/FieldDescriptor.java
+++ b/src/org/jetbrains/java/decompiler/struct/gen/FieldDescriptor.java
@@ -1,58 +1,59 @@
/*
- * 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.struct.gen;
public class FieldDescriptor {
-
- public static final FieldDescriptor INTEGER_DESCRIPTOR = FieldDescriptor.parseDescriptor("Ljava/lang/Integer;");
- public static final FieldDescriptor LONG_DESCRIPTOR = FieldDescriptor.parseDescriptor("Ljava/lang/Long;");
- public static final FieldDescriptor FLOAT_DESCRIPTOR = FieldDescriptor.parseDescriptor("Ljava/lang/Float;");
- public static final FieldDescriptor DOUBLE_DESCRIPTOR = FieldDescriptor.parseDescriptor("Ljava/lang/Double;");
-
- public VarType type;
-
- public String descriptorString;
-
- private FieldDescriptor() {}
-
- public static FieldDescriptor parseDescriptor(String descr) {
-
- FieldDescriptor fd = new FieldDescriptor();
-
- fd.type = new VarType(descr);
- fd.descriptorString = descr;
-
- return fd;
- }
-
- public String getDescriptor() {
- return type.toString();
- }
-
- @Override
- public boolean equals(Object o) {
- if(o == this) return true;
- if(o == null || !(o instanceof FieldDescriptor)) return false;
+
+ public static final FieldDescriptor INTEGER_DESCRIPTOR = FieldDescriptor.parseDescriptor("Ljava/lang/Integer;");
+ public static final FieldDescriptor LONG_DESCRIPTOR = FieldDescriptor.parseDescriptor("Ljava/lang/Long;");
+ public static final FieldDescriptor FLOAT_DESCRIPTOR = FieldDescriptor.parseDescriptor("Ljava/lang/Float;");
+ public static final FieldDescriptor DOUBLE_DESCRIPTOR = FieldDescriptor.parseDescriptor("Ljava/lang/Double;");
+
+ public VarType type;
+
+ public String descriptorString;
+
+ private FieldDescriptor() {
+ }
+
+ public static FieldDescriptor parseDescriptor(String descr) {
+
+ FieldDescriptor fd = new FieldDescriptor();
+
+ fd.type = new VarType(descr);
+ fd.descriptorString = descr;
+
+ return fd;
+ }
+
+ public String getDescriptor() {
+ return type.toString();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) return true;
+ if (o == null || !(o instanceof FieldDescriptor)) return false;
FieldDescriptor fd = (FieldDescriptor)o;
return type.equals(fd.type);
}
- @Override
- public int hashCode() {
- return type.hashCode();
- }
-
+ @Override
+ public int hashCode() {
+ return type.hashCode();
+ }
}
diff --git a/src/org/jetbrains/java/decompiler/struct/gen/MethodDescriptor.java b/src/org/jetbrains/java/decompiler/struct/gen/MethodDescriptor.java
index 77a8394..7dbc16c 100644
--- a/src/org/jetbrains/java/decompiler/struct/gen/MethodDescriptor.java
+++ b/src/org/jetbrains/java/decompiler/struct/gen/MethodDescriptor.java
@@ -1,17 +1,18 @@
/*
- * 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.struct.gen;
import java.util.ArrayList;
@@ -20,83 +21,82 @@ import java.util.List;
public class MethodDescriptor {
- public VarType[] params;
-
- public VarType ret;
-
-
- public static MethodDescriptor parseDescriptor(String mdescr) {
-
- MethodDescriptor md = new MethodDescriptor();
-
- List<String> lst = new ArrayList<String>();
- String[] pars = mdescr.split("[()]");
-
- String par = pars[1];
-
- int indexFrom = -1, ind,index = 0;
- int len = par.length();
-
- for(;index<len;index++) {
-
- switch(par.charAt(index)){
- case '[':
- if(indexFrom<0){
- indexFrom = index;
- }
- break;
- case 'L':
- ind = par.indexOf(";", index);
- lst.add(par.substring(indexFrom<0?index:indexFrom, ind+1));
- index = ind;
- indexFrom = -1;
- break;
- default:
- lst.add(par.substring(indexFrom<0?index:indexFrom, index+1));
- indexFrom = -1;
- }
- }
-
- lst.add(pars[2]);
-
-
- md.params = new VarType[lst.size()-1];
-
- int i = 0;
- for(;i<lst.size()-1;i++) {
- md.params[i] = new VarType(lst.get(i));
- }
- md.ret = new VarType(lst.get(i));
-
- return md;
- }
-
- public String getDescriptor() {
- String res = "(";
-
- for(int j = 0;j<params.length;j++) {
- res+=params[j].toString();
- }
-
- res+=")"+ret.toString();
-
- return res;
- }
-
- @Override
- public boolean equals(Object o) {
- if(o == this) return true;
- if(o == null || !(o instanceof MethodDescriptor)) return false;
+ public VarType[] params;
+
+ public VarType ret;
+
+
+ public static MethodDescriptor parseDescriptor(String mdescr) {
+
+ MethodDescriptor md = new MethodDescriptor();
+
+ List<String> lst = new ArrayList<String>();
+ String[] pars = mdescr.split("[()]");
+
+ String par = pars[1];
+
+ int indexFrom = -1, ind, index = 0;
+ int len = par.length();
+
+ for (; index < len; index++) {
+
+ switch (par.charAt(index)) {
+ case '[':
+ if (indexFrom < 0) {
+ indexFrom = index;
+ }
+ break;
+ case 'L':
+ ind = par.indexOf(";", index);
+ lst.add(par.substring(indexFrom < 0 ? index : indexFrom, ind + 1));
+ index = ind;
+ indexFrom = -1;
+ break;
+ default:
+ lst.add(par.substring(indexFrom < 0 ? index : indexFrom, index + 1));
+ indexFrom = -1;
+ }
+ }
+
+ lst.add(pars[2]);
+
+
+ md.params = new VarType[lst.size() - 1];
+
+ int i = 0;
+ for (; i < lst.size() - 1; i++) {
+ md.params[i] = new VarType(lst.get(i));
+ }
+ md.ret = new VarType(lst.get(i));
+
+ return md;
+ }
+
+ public String getDescriptor() {
+ String res = "(";
+
+ for (int j = 0; j < params.length; j++) {
+ res += params[j].toString();
+ }
+
+ res += ")" + ret.toString();
+
+ return res;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) return true;
+ if (o == null || !(o instanceof MethodDescriptor)) return false;
MethodDescriptor md = (MethodDescriptor)o;
return ret.equals(md.ret) && Arrays.equals(params, md.params);
}
- @Override
- public int hashCode() {
+ @Override
+ public int hashCode() {
int result = ret.hashCode();
result = 31 * result + params.length;
return result;
- }
-
+ }
}
diff --git a/src/org/jetbrains/java/decompiler/struct/gen/VarType.java b/src/org/jetbrains/java/decompiler/struct/gen/VarType.java
index 5ee0c4b..79e2cbf 100644
--- a/src/org/jetbrains/java/decompiler/struct/gen/VarType.java
+++ b/src/org/jetbrains/java/decompiler/struct/gen/VarType.java
@@ -1,410 +1,422 @@
/*
- * 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.struct.gen;
import org.jetbrains.java.decompiler.code.CodeConstants;
import org.jetbrains.java.decompiler.util.InterpreterUtil;
public class VarType { // TODO: optimize switch
-
- public static final int FALSEBOOLEAN = 1;
-
- public static final VarType VARTYPE_UNKNOWN = new VarType(CodeConstants.TYPE_UNKNOWN);
- public static final VarType VARTYPE_INT = new VarType(CodeConstants.TYPE_INT);
- public static final VarType VARTYPE_FLOAT = new VarType(CodeConstants.TYPE_FLOAT);
- public static final VarType VARTYPE_LONG = new VarType(CodeConstants.TYPE_LONG);
- public static final VarType VARTYPE_DOUBLE = new VarType(CodeConstants.TYPE_DOUBLE);
- public static final VarType VARTYPE_BYTE = new VarType(CodeConstants.TYPE_BYTE);
- public static final VarType VARTYPE_CHAR = new VarType(CodeConstants.TYPE_CHAR);
- public static final VarType VARTYPE_SHORT = new VarType(CodeConstants.TYPE_SHORT);
- public static final VarType VARTYPE_BOOLEAN = new VarType(CodeConstants.TYPE_BOOLEAN);
- public static final VarType VARTYPE_BYTECHAR = new VarType(CodeConstants.TYPE_BYTECHAR);
- public static final VarType VARTYPE_SHORTCHAR = new VarType(CodeConstants.TYPE_SHORTCHAR);
-
- public static final VarType VARTYPE_NULL = new VarType(CodeConstants.TYPE_NULL,0,null);
- public static final VarType VARTYPE_GROUP2EMPTY = new VarType(CodeConstants.TYPE_GROUP2EMPTY);
- public static final VarType VARTYPE_STRING = new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/String");
- public static final VarType VARTYPE_CLASS = new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/Class");
- public static final VarType VARTYPE_OBJECT = new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/Object");
- public static final VarType VARTYPE_VOID = new VarType(CodeConstants.TYPE_VOID);
-
- public int type;
-
- public int type_family;
-
- public int arraydim;
-
- public String value;
-
- public int stack_size;
-
- public int convinfo;
-
- public VarType(int type) {
- this.type = type;
- this.arraydim = 0;
-
- value = getChar(type);
- setStackSize(type);
- setFamily();
- }
-
- public VarType(int type, int arraydim) {
- this(type);
- this.arraydim = arraydim;
- setFamily();
- }
-
- public VarType(int type, int arraydim, String value) {
- this(type);
- this.arraydim = arraydim;
- this.value = value;
- setFamily();
- }
-
- public VarType(String strtype) {
- this(strtype, false);
- }
-
- public VarType(String strtype, boolean cltype) {
- parseTypeString(strtype, cltype);
- setStackSize(type);
- setFamily();
- }
-
- public void decArrayDim() {
- if(arraydim > 0) {
- arraydim--;
- setFamily();
- } else {
- // throw new RuntimeException("array dimension equals 0!"); FIXME: investigate this case
- }
- }
-
- public String toString() {
- String res = "";
-
- for(int i=0;i<arraydim;i++) {
- res+="[";
- }
-
- if(type == CodeConstants.TYPE_OBJECT) {
- res+="L"+value+";";
- } else {
- res+=value;
- }
-
- return res;
- }
-
- public VarType copy() {
- VarType v = new VarType(type, arraydim, value);
- v.convinfo = convinfo;
- return v;
- }
-
- public boolean isFalseBoolean() {
- return (convinfo & VarType.FALSEBOOLEAN) != 0;
- }
-
- public boolean isSuperset(VarType val) {
-
- return this.equals(val) || this.isStrictSuperset(val);
- }
-
- public boolean isStrictSuperset(VarType val) {
-
- int valtype = val.type;
-
- if(valtype == CodeConstants.TYPE_UNKNOWN && type != CodeConstants.TYPE_UNKNOWN) {
- return true;
- }
-
- if(val.arraydim > 0) {
- return this.equals(VARTYPE_OBJECT);
- } else if(arraydim > 0) {
- return (valtype == CodeConstants.TYPE_NULL);
- }
-
- boolean res = false;
-
- switch(type) {
- case CodeConstants.TYPE_INT:
- res |= (valtype == CodeConstants.TYPE_SHORT ||
- valtype == CodeConstants.TYPE_CHAR);
- case CodeConstants.TYPE_SHORT:
- res |= (valtype == CodeConstants.TYPE_BYTE);
- case CodeConstants.TYPE_CHAR:
- res |= (valtype == CodeConstants.TYPE_SHORTCHAR);
- case CodeConstants.TYPE_BYTE:
- case CodeConstants.TYPE_SHORTCHAR:
- res |= (valtype == CodeConstants.TYPE_BYTECHAR);
- case CodeConstants.TYPE_BYTECHAR:
- res |= (valtype == CodeConstants.TYPE_BOOLEAN);
- break;
- case CodeConstants.TYPE_OBJECT:
- if(valtype == CodeConstants.TYPE_NULL) {
- return true;
- } else if(this.equals(VARTYPE_OBJECT)) {
- return valtype == CodeConstants.TYPE_OBJECT &&
- !val.equals(VARTYPE_OBJECT);
- }
- }
-
- return res;
- }
-
- // type1 and type2 must not be null
- public static VarType getCommonMinType(VarType type1, VarType type2) {
-
- if(type1.type == CodeConstants.TYPE_BOOLEAN && type2.type == CodeConstants.TYPE_BOOLEAN) { // special case booleans
- return type1.isFalseBoolean() ? type2 : type1;
- }
-
- if(type1.isSuperset(type2)) {
- return type2;
- } else if(type2.isSuperset(type1)) {
- return type1;
- } else if(type1.type_family == type2.type_family) {
- switch(type1.type_family) {
- case CodeConstants.TYPE_FAMILY_INTEGER:
- if((type1.type == CodeConstants.TYPE_CHAR && type2.type == CodeConstants.TYPE_SHORT)
- || (type1.type == CodeConstants.TYPE_SHORT && type2.type == CodeConstants.TYPE_CHAR)) {
- return VarType.VARTYPE_SHORTCHAR;
- } else {
- return VarType.VARTYPE_BYTECHAR;
- }
- case CodeConstants.TYPE_FAMILY_OBJECT:
- return VarType.VARTYPE_NULL;
- }
- }
-
- return null;
- }
-
- // type1 and type2 must not be null
- public static VarType getCommonSupertype(VarType type1, VarType type2) {
-
- if(type1.type == CodeConstants.TYPE_BOOLEAN && type2.type == CodeConstants.TYPE_BOOLEAN) { // special case booleans
- return type1.isFalseBoolean() ? type1 : type2;
- }
-
- if(type1.isSuperset(type2)) {
- return type1;
- } else if(type2.isSuperset(type1)) {
- return type2;
- } else if(type1.type_family == type2.type_family) {
- switch(type1.type_family) {
- case CodeConstants.TYPE_FAMILY_INTEGER:
- if((type1.type == CodeConstants.TYPE_SHORTCHAR && type2.type == CodeConstants.TYPE_BYTE)
- || (type1.type == CodeConstants.TYPE_BYTE && type2.type == CodeConstants.TYPE_SHORTCHAR)) {
- return VarType.VARTYPE_SHORT;
- } else {
- return VarType.VARTYPE_INT;
- }
- case CodeConstants.TYPE_FAMILY_OBJECT:
- return VarType.VARTYPE_OBJECT;
- }
- }
-
- return null;
- }
-
- public static VarType getMinTypeInFamily(int family) {
- switch(family) {
- case CodeConstants.TYPE_FAMILY_BOOLEAN:
- return VarType.VARTYPE_BOOLEAN;
- case CodeConstants.TYPE_FAMILY_INTEGER:
- return VarType.VARTYPE_BYTECHAR;
- case CodeConstants.TYPE_FAMILY_OBJECT:
- return VarType.VARTYPE_NULL;
- case CodeConstants.TYPE_FAMILY_FLOAT:
- return VarType.VARTYPE_FLOAT;
- case CodeConstants.TYPE_FAMILY_LONG:
- return VarType.VARTYPE_LONG;
- case CodeConstants.TYPE_FAMILY_DOUBLE:
- return VarType.VARTYPE_DOUBLE;
- case CodeConstants.TYPE_FAMILY_UNKNOWN:
- return VarType.VARTYPE_UNKNOWN;
- default:
- throw new RuntimeException("invalid type family!");
- }
- }
-
- public boolean equals(Object o) {
-
- if(o == this) {
- return true;
- }
-
- if(o == null || !(o instanceof VarType)) {
- return false;
- }
-
- VarType vt = (VarType) o;
- return type == vt.type && arraydim == vt.arraydim && InterpreterUtil.equalObjects(value, vt.value);
- }
-
- private void parseTypeString(String strtype, boolean cltype) {
-
- for(int i=0;i<strtype.length();i++) {
- switch(strtype.charAt(i)){
- case '[':
- arraydim++;
- break;
- case 'L':
- if(strtype.charAt(strtype.length()-1) == ';') {
- type = CodeConstants.TYPE_OBJECT;
- value = strtype.substring(i+1, strtype.length()-1);
- return;
- }
- default:
- value = strtype.substring(i, strtype.length());
- if((cltype && i == 0) || value.length()>1) {
- type = CodeConstants.TYPE_OBJECT;
- } else {
- type = getType(value.charAt(0));
- }
- return;
- }
- }
- }
-
- private void setStackSize(int type) {
- if(arraydim > 0) {
- stack_size = 1;
- } else {
- stack_size = (type == CodeConstants.TYPE_DOUBLE ||
- type == CodeConstants.TYPE_LONG)?2:
- ((type == CodeConstants.TYPE_VOID ||
- type == CodeConstants.TYPE_GROUP2EMPTY)?0:1);
- }
- }
-
- private int getType(char c) {
- switch(c) {
- case 'B':
- return CodeConstants.TYPE_BYTE;
- case 'C':
- return CodeConstants.TYPE_CHAR;
- case 'D':
- return CodeConstants.TYPE_DOUBLE;
- case 'F':
- return CodeConstants.TYPE_FLOAT;
- case 'I':
- return CodeConstants.TYPE_INT;
- case 'J':
- return CodeConstants.TYPE_LONG;
- case 'S':
- return CodeConstants.TYPE_SHORT;
- case 'Z':
- return CodeConstants.TYPE_BOOLEAN;
- case 'V':
- return CodeConstants.TYPE_VOID;
- case 'G':
- return CodeConstants.TYPE_GROUP2EMPTY;
- case 'N':
- return CodeConstants.TYPE_NOTINITIALIZED;
- case 'A':
- return CodeConstants.TYPE_ADDRESS;
- case 'X':
- return CodeConstants.TYPE_BYTECHAR;
- case 'Y':
- return CodeConstants.TYPE_SHORTCHAR;
- case 'U':
- return CodeConstants.TYPE_UNKNOWN;
- default:
- throw new RuntimeException("Invalid type");
- }
- }
-
- private String getChar(int type) {
- switch(type) {
- case CodeConstants.TYPE_BYTE:
- return "B";
- case CodeConstants.TYPE_CHAR:
- return "C";
- case CodeConstants.TYPE_DOUBLE:
- return "D";
- case CodeConstants.TYPE_FLOAT:
- return "F";
- case CodeConstants.TYPE_INT:
- return "I";
- case CodeConstants.TYPE_LONG:
- return "J";
- case CodeConstants.TYPE_SHORT:
- return "S";
- case CodeConstants.TYPE_BOOLEAN:
- return "Z";
- case CodeConstants.TYPE_VOID:
- return "V";
- case CodeConstants.TYPE_GROUP2EMPTY:
- return "G";
- case CodeConstants.TYPE_NOTINITIALIZED:
- return "N";
- case CodeConstants.TYPE_ADDRESS:
- return "A";
- case CodeConstants.TYPE_BYTECHAR:
- return "X";
- case CodeConstants.TYPE_SHORTCHAR:
- return "Y";
- case CodeConstants.TYPE_UNKNOWN:
- return "U";
- case CodeConstants.TYPE_NULL:
- case CodeConstants.TYPE_OBJECT:
- return null;
- default:
- throw new RuntimeException("Invalid type");
- }
- }
-
- public void setFamily() {
-
- if(arraydim > 0) {
- this.type_family = CodeConstants.TYPE_FAMILY_OBJECT;
- return;
- }
-
- switch(type) {
- case CodeConstants.TYPE_BYTE:
- case CodeConstants.TYPE_BYTECHAR:
- case CodeConstants.TYPE_SHORTCHAR:
- case CodeConstants.TYPE_CHAR:
- case CodeConstants.TYPE_SHORT:
- case CodeConstants.TYPE_INT:
- this.type_family = CodeConstants.TYPE_FAMILY_INTEGER;
- break;
- case CodeConstants.TYPE_DOUBLE:
- this.type_family = CodeConstants.TYPE_FAMILY_DOUBLE;
- break;
- case CodeConstants.TYPE_FLOAT:
- this.type_family = CodeConstants.TYPE_FAMILY_FLOAT;
- break;
- case CodeConstants.TYPE_LONG:
- this.type_family = CodeConstants.TYPE_FAMILY_LONG;
- break;
- case CodeConstants.TYPE_BOOLEAN:
- this.type_family = CodeConstants.TYPE_FAMILY_BOOLEAN;
- break;
- case CodeConstants.TYPE_NULL:
- case CodeConstants.TYPE_OBJECT:
- this.type_family = CodeConstants.TYPE_FAMILY_OBJECT;
- break;
- default:
- this.type_family = CodeConstants.TYPE_FAMILY_UNKNOWN;
- }
- }
-
+
+ public static final int FALSEBOOLEAN = 1;
+
+ public static final VarType VARTYPE_UNKNOWN = new VarType(CodeConstants.TYPE_UNKNOWN);
+ public static final VarType VARTYPE_INT = new VarType(CodeConstants.TYPE_INT);
+ public static final VarType VARTYPE_FLOAT = new VarType(CodeConstants.TYPE_FLOAT);
+ public static final VarType VARTYPE_LONG = new VarType(CodeConstants.TYPE_LONG);
+ public static final VarType VARTYPE_DOUBLE = new VarType(CodeConstants.TYPE_DOUBLE);
+ public static final VarType VARTYPE_BYTE = new VarType(CodeConstants.TYPE_BYTE);
+ public static final VarType VARTYPE_CHAR = new VarType(CodeConstants.TYPE_CHAR);
+ public static final VarType VARTYPE_SHORT = new VarType(CodeConstants.TYPE_SHORT);
+ public static final VarType VARTYPE_BOOLEAN = new VarType(CodeConstants.TYPE_BOOLEAN);
+ public static final VarType VARTYPE_BYTECHAR = new VarType(CodeConstants.TYPE_BYTECHAR);
+ public static final VarType VARTYPE_SHORTCHAR = new VarType(CodeConstants.TYPE_SHORTCHAR);
+
+ public static final VarType VARTYPE_NULL = new VarType(CodeConstants.TYPE_NULL, 0, null);
+ public static final VarType VARTYPE_GROUP2EMPTY = new VarType(CodeConstants.TYPE_GROUP2EMPTY);
+ public static final VarType VARTYPE_STRING = new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/String");
+ public static final VarType VARTYPE_CLASS = new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/Class");
+ public static final VarType VARTYPE_OBJECT = new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/Object");
+ public static final VarType VARTYPE_VOID = new VarType(CodeConstants.TYPE_VOID);
+
+ public int type;
+
+ public int type_family;
+
+ public int arraydim;
+
+ public String value;
+
+ public int stack_size;
+
+ public int convinfo;
+
+ public VarType(int type) {
+ this.type = type;
+ this.arraydim = 0;
+
+ value = getChar(type);
+ setStackSize(type);
+ setFamily();
+ }
+
+ public VarType(int type, int arraydim) {
+ this(type);
+ this.arraydim = arraydim;
+ setFamily();
+ }
+
+ public VarType(int type, int arraydim, String value) {
+ this(type);
+ this.arraydim = arraydim;
+ this.value = value;
+ setFamily();
+ }
+
+ public VarType(String strtype) {
+ this(strtype, false);
+ }
+
+ public VarType(String strtype, boolean cltype) {
+ parseTypeString(strtype, cltype);
+ setStackSize(type);
+ setFamily();
+ }
+
+ public void decArrayDim() {
+ if (arraydim > 0) {
+ arraydim--;
+ setFamily();
+ }
+ else {
+ // throw new RuntimeException("array dimension equals 0!"); FIXME: investigate this case
+ }
+ }
+
+ public String toString() {
+ String res = "";
+
+ for (int i = 0; i < arraydim; i++) {
+ res += "[";
+ }
+
+ if (type == CodeConstants.TYPE_OBJECT) {
+ res += "L" + value + ";";
+ }
+ else {
+ res += value;
+ }
+
+ return res;
+ }
+
+ public VarType copy() {
+ VarType v = new VarType(type, arraydim, value);
+ v.convinfo = convinfo;
+ return v;
+ }
+
+ public boolean isFalseBoolean() {
+ return (convinfo & VarType.FALSEBOOLEAN) != 0;
+ }
+
+ public boolean isSuperset(VarType val) {
+
+ return this.equals(val) || this.isStrictSuperset(val);
+ }
+
+ public boolean isStrictSuperset(VarType val) {
+
+ int valtype = val.type;
+
+ if (valtype == CodeConstants.TYPE_UNKNOWN && type != CodeConstants.TYPE_UNKNOWN) {
+ return true;
+ }
+
+ if (val.arraydim > 0) {
+ return this.equals(VARTYPE_OBJECT);
+ }
+ else if (arraydim > 0) {
+ return (valtype == CodeConstants.TYPE_NULL);
+ }
+
+ boolean res = false;
+
+ switch (type) {
+ case CodeConstants.TYPE_INT:
+ res |= (valtype == CodeConstants.TYPE_SHORT ||
+ valtype == CodeConstants.TYPE_CHAR);
+ case CodeConstants.TYPE_SHORT:
+ res |= (valtype == CodeConstants.TYPE_BYTE);
+ case CodeConstants.TYPE_CHAR:
+ res |= (valtype == CodeConstants.TYPE_SHORTCHAR);
+ case CodeConstants.TYPE_BYTE:
+ case CodeConstants.TYPE_SHORTCHAR:
+ res |= (valtype == CodeConstants.TYPE_BYTECHAR);
+ case CodeConstants.TYPE_BYTECHAR:
+ res |= (valtype == CodeConstants.TYPE_BOOLEAN);
+ break;
+ case CodeConstants.TYPE_OBJECT:
+ if (valtype == CodeConstants.TYPE_NULL) {
+ return true;
+ }
+ else if (this.equals(VARTYPE_OBJECT)) {
+ return valtype == CodeConstants.TYPE_OBJECT &&
+ !val.equals(VARTYPE_OBJECT);
+ }
+ }
+
+ return res;
+ }
+
+ // type1 and type2 must not be null
+ public static VarType getCommonMinType(VarType type1, VarType type2) {
+
+ if (type1.type == CodeConstants.TYPE_BOOLEAN && type2.type == CodeConstants.TYPE_BOOLEAN) { // special case booleans
+ return type1.isFalseBoolean() ? type2 : type1;
+ }
+
+ if (type1.isSuperset(type2)) {
+ return type2;
+ }
+ else if (type2.isSuperset(type1)) {
+ return type1;
+ }
+ else if (type1.type_family == type2.type_family) {
+ switch (type1.type_family) {
+ case CodeConstants.TYPE_FAMILY_INTEGER:
+ if ((type1.type == CodeConstants.TYPE_CHAR && type2.type == CodeConstants.TYPE_SHORT)
+ || (type1.type == CodeConstants.TYPE_SHORT && type2.type == CodeConstants.TYPE_CHAR)) {
+ return VarType.VARTYPE_SHORTCHAR;
+ }
+ else {
+ return VarType.VARTYPE_BYTECHAR;
+ }
+ case CodeConstants.TYPE_FAMILY_OBJECT:
+ return VarType.VARTYPE_NULL;
+ }
+ }
+
+ return null;
+ }
+
+ // type1 and type2 must not be null
+ public static VarType getCommonSupertype(VarType type1, VarType type2) {
+
+ if (type1.type == CodeConstants.TYPE_BOOLEAN && type2.type == CodeConstants.TYPE_BOOLEAN) { // special case booleans
+ return type1.isFalseBoolean() ? type1 : type2;
+ }
+
+ if (type1.isSuperset(type2)) {
+ return type1;
+ }
+ else if (type2.isSuperset(type1)) {
+ return type2;
+ }
+ else if (type1.type_family == type2.type_family) {
+ switch (type1.type_family) {
+ case CodeConstants.TYPE_FAMILY_INTEGER:
+ if ((type1.type == CodeConstants.TYPE_SHORTCHAR && type2.type == CodeConstants.TYPE_BYTE)
+ || (type1.type == CodeConstants.TYPE_BYTE && type2.type == CodeConstants.TYPE_SHORTCHAR)) {
+ return VarType.VARTYPE_SHORT;
+ }
+ else {
+ return VarType.VARTYPE_INT;
+ }
+ case CodeConstants.TYPE_FAMILY_OBJECT:
+ return VarType.VARTYPE_OBJECT;
+ }
+ }
+
+ return null;
+ }
+
+ public static VarType getMinTypeInFamily(int family) {
+ switch (family) {
+ case CodeConstants.TYPE_FAMILY_BOOLEAN:
+ return VarType.VARTYPE_BOOLEAN;
+ case CodeConstants.TYPE_FAMILY_INTEGER:
+ return VarType.VARTYPE_BYTECHAR;
+ case CodeConstants.TYPE_FAMILY_OBJECT:
+ return VarType.VARTYPE_NULL;
+ case CodeConstants.TYPE_FAMILY_FLOAT:
+ return VarType.VARTYPE_FLOAT;
+ case CodeConstants.TYPE_FAMILY_LONG:
+ return VarType.VARTYPE_LONG;
+ case CodeConstants.TYPE_FAMILY_DOUBLE:
+ return VarType.VARTYPE_DOUBLE;
+ case CodeConstants.TYPE_FAMILY_UNKNOWN:
+ return VarType.VARTYPE_UNKNOWN;
+ default:
+ throw new RuntimeException("invalid type family!");
+ }
+ }
+
+ public boolean equals(Object o) {
+
+ if (o == this) {
+ return true;
+ }
+
+ if (o == null || !(o instanceof VarType)) {
+ return false;
+ }
+
+ VarType vt = (VarType)o;
+ return type == vt.type && arraydim == vt.arraydim && InterpreterUtil.equalObjects(value, vt.value);
+ }
+
+ private void parseTypeString(String strtype, boolean cltype) {
+
+ for (int i = 0; i < strtype.length(); i++) {
+ switch (strtype.charAt(i)) {
+ case '[':
+ arraydim++;
+ break;
+ case 'L':
+ if (strtype.charAt(strtype.length() - 1) == ';') {
+ type = CodeConstants.TYPE_OBJECT;
+ value = strtype.substring(i + 1, strtype.length() - 1);
+ return;
+ }
+ default:
+ value = strtype.substring(i, strtype.length());
+ if ((cltype && i == 0) || value.length() > 1) {
+ type = CodeConstants.TYPE_OBJECT;
+ }
+ else {
+ type = getType(value.charAt(0));
+ }
+ return;
+ }
+ }
+ }
+
+ private void setStackSize(int type) {
+ if (arraydim > 0) {
+ stack_size = 1;
+ }
+ else {
+ stack_size = (type == CodeConstants.TYPE_DOUBLE ||
+ type == CodeConstants.TYPE_LONG) ? 2 :
+ ((type == CodeConstants.TYPE_VOID ||
+ type == CodeConstants.TYPE_GROUP2EMPTY) ? 0 : 1);
+ }
+ }
+
+ private int getType(char c) {
+ switch (c) {
+ case 'B':
+ return CodeConstants.TYPE_BYTE;
+ case 'C':
+ return CodeConstants.TYPE_CHAR;
+ case 'D':
+ return CodeConstants.TYPE_DOUBLE;
+ case 'F':
+ return CodeConstants.TYPE_FLOAT;
+ case 'I':
+ return CodeConstants.TYPE_INT;
+ case 'J':
+ return CodeConstants.TYPE_LONG;
+ case 'S':
+ return CodeConstants.TYPE_SHORT;
+ case 'Z':
+ return CodeConstants.TYPE_BOOLEAN;
+ case 'V':
+ return CodeConstants.TYPE_VOID;
+ case 'G':
+ return CodeConstants.TYPE_GROUP2EMPTY;
+ case 'N':
+ return CodeConstants.TYPE_NOTINITIALIZED;
+ case 'A':
+ return CodeConstants.TYPE_ADDRESS;
+ case 'X':
+ return CodeConstants.TYPE_BYTECHAR;
+ case 'Y':
+ return CodeConstants.TYPE_SHORTCHAR;
+ case 'U':
+ return CodeConstants.TYPE_UNKNOWN;
+ default:
+ throw new RuntimeException("Invalid type");
+ }
+ }
+
+ private String getChar(int type) {
+ switch (type) {
+ case CodeConstants.TYPE_BYTE:
+ return "B";
+ case CodeConstants.TYPE_CHAR:
+ return "C";
+ case CodeConstants.TYPE_DOUBLE:
+ return "D";
+ case CodeConstants.TYPE_FLOAT:
+ return "F";
+ case CodeConstants.TYPE_INT:
+ return "I";
+ case CodeConstants.TYPE_LONG:
+ return "J";
+ case CodeConstants.TYPE_SHORT:
+ return "S";
+ case CodeConstants.TYPE_BOOLEAN:
+ return "Z";
+ case CodeConstants.TYPE_VOID:
+ return "V";
+ case CodeConstants.TYPE_GROUP2EMPTY:
+ return "G";
+ case CodeConstants.TYPE_NOTINITIALIZED:
+ return "N";
+ case CodeConstants.TYPE_ADDRESS:
+ return "A";
+ case CodeConstants.TYPE_BYTECHAR:
+ return "X";
+ case CodeConstants.TYPE_SHORTCHAR:
+ return "Y";
+ case CodeConstants.TYPE_UNKNOWN:
+ return "U";
+ case CodeConstants.TYPE_NULL:
+ case CodeConstants.TYPE_OBJECT:
+ return null;
+ default:
+ throw new RuntimeException("Invalid type");
+ }
+ }
+
+ public void setFamily() {
+
+ if (arraydim > 0) {
+ this.type_family = CodeConstants.TYPE_FAMILY_OBJECT;
+ return;
+ }
+
+ switch (type) {
+ case CodeConstants.TYPE_BYTE:
+ case CodeConstants.TYPE_BYTECHAR:
+ case CodeConstants.TYPE_SHORTCHAR:
+ case CodeConstants.TYPE_CHAR:
+ case CodeConstants.TYPE_SHORT:
+ case CodeConstants.TYPE_INT:
+ this.type_family = CodeConstants.TYPE_FAMILY_INTEGER;
+ break;
+ case CodeConstants.TYPE_DOUBLE:
+ this.type_family = CodeConstants.TYPE_FAMILY_DOUBLE;
+ break;
+ case CodeConstants.TYPE_FLOAT:
+ this.type_family = CodeConstants.TYPE_FAMILY_FLOAT;
+ break;
+ case CodeConstants.TYPE_LONG:
+ this.type_family = CodeConstants.TYPE_FAMILY_LONG;
+ break;
+ case CodeConstants.TYPE_BOOLEAN:
+ this.type_family = CodeConstants.TYPE_FAMILY_BOOLEAN;
+ break;
+ case CodeConstants.TYPE_NULL:
+ case CodeConstants.TYPE_OBJECT:
+ this.type_family = CodeConstants.TYPE_FAMILY_OBJECT;
+ break;
+ default:
+ this.type_family = CodeConstants.TYPE_FAMILY_UNKNOWN;
+ }
+ }
}
diff --git a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericClassDescriptor.java b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericClassDescriptor.java
index d4551ac..66fab96 100644
--- a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericClassDescriptor.java
+++ b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericClassDescriptor.java
@@ -1,17 +1,18 @@
/*
- * 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.struct.gen.generics;
import java.util.ArrayList;
@@ -19,12 +20,11 @@ import java.util.List;
public class GenericClassDescriptor {
- public GenericType superclass;
-
- public List<GenericType> superinterfaces = new ArrayList<GenericType>();
-
- public List<String> fparameters = new ArrayList<String>();
+ public GenericType superclass;
+
+ public List<GenericType> superinterfaces = new ArrayList<GenericType>();
+
+ public List<String> fparameters = new ArrayList<String>();
- public List<List<GenericType>> fbounds = new ArrayList<List<GenericType>>();
-
+ public List<List<GenericType>> fbounds = new ArrayList<List<GenericType>>();
}
diff --git a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericFieldDescriptor.java b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericFieldDescriptor.java
index 4b4114d..598d17b 100644
--- a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericFieldDescriptor.java
+++ b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericFieldDescriptor.java
@@ -1,21 +1,21 @@
/*
- * 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.struct.gen.generics;
public class GenericFieldDescriptor {
- public GenericType type;
-
+ public GenericType type;
}
diff --git a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java
index 50433a9..db7d84b 100644
--- a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java
+++ b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java
@@ -1,229 +1,233 @@
/*
- * 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.struct.gen.generics;
-import java.util.ArrayList;
-import java.util.List;
-
import org.jetbrains.java.decompiler.code.CodeConstants;
import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.struct.StructClass;
+import java.util.ArrayList;
+import java.util.List;
+
public class GenericMain {
-
- private static final String[] typeNames = new String[] {
- "byte",
- "char",
- "double",
- "float",
- "int",
- "long",
- "short",
- "boolean",
- };
-
- public static GenericClassDescriptor parseClassSignature(String signature) {
-
- GenericClassDescriptor descriptor = new GenericClassDescriptor();
-
- signature = parseFormalParameters(signature, descriptor.fparameters, descriptor.fbounds);
-
- String supercl = GenericType.getNextType(signature);
- descriptor.superclass = new GenericType(supercl);
-
- signature = signature.substring(supercl.length());
- while(signature.length() > 0) {
- String superintr = GenericType.getNextType(signature);
- descriptor.superinterfaces.add(new GenericType(superintr));
- signature = signature.substring(superintr.length());
- }
-
- return descriptor;
- }
-
- public static GenericFieldDescriptor parseFieldSignature(String signature) {
- GenericFieldDescriptor descriptor = new GenericFieldDescriptor();
- descriptor.type = new GenericType(signature);
- return descriptor;
- }
-
- public static GenericMethodDescriptor parseMethodSignature(String signature) {
-
- GenericMethodDescriptor descriptor = new GenericMethodDescriptor();
-
- signature = parseFormalParameters(signature, descriptor.fparameters, descriptor.fbounds);
-
- int to = signature.indexOf(")");
- String pars = signature.substring(1, to);
- signature = signature.substring(to+1);
-
- while(pars.length() > 0) {
- String par = GenericType.getNextType(pars);
- descriptor.params.add(new GenericType(par));
- pars = pars.substring(par.length());
- }
-
- String par = GenericType.getNextType(signature);
- descriptor.ret = new GenericType(par);
- signature = signature.substring(par.length());
-
- if(signature.length() > 0) {
- String[] excs = signature.split("\\^");
-
- for(int i=1;i<excs.length;i++) {
- descriptor.exceptions.add(new GenericType(excs[i]));
- }
- }
-
- return descriptor;
- }
-
- private static String parseFormalParameters(String signature, List<String> fparameters, List<List<GenericType>> fbounds) {
-
- if(signature.charAt(0) != '<') {
- return signature;
- }
-
- int counter = 1;
- int index = 1;
-
- loop:
- while(index < signature.length()) {
- switch(signature.charAt(index)) {
- case '<':
- counter++;
- break;
- case '>':
- counter--;
- if(counter == 0) {
- break loop;
- }
- }
-
- index++;
- }
-
- String value = signature.substring(1, index);
- signature = signature.substring(index+1);
-
- while(value.length() > 0) {
- int parto = value.indexOf(":");
-
- String param = value.substring(0, parto);
- value = value.substring(parto+1);
-
- List<GenericType> lstBounds = new ArrayList<GenericType>();
-
- for(;;) {
- if(value.charAt(0) == ':') {
- // empty superclass, skip
- value = value.substring(1);
- }
-
- String bound = GenericType.getNextType(value);
- lstBounds.add(new GenericType(bound));
- value = value.substring(bound.length());
-
-
- if(value.length() == 0 || value.charAt(0) != ':') {
- break;
- } else {
- value = value.substring(1);
- }
- }
-
- fparameters.add(param);
- fbounds.add(lstBounds);
- }
-
- return signature;
- }
-
- public static String getGenericCastTypeName(GenericType type) {
- String s = getTypeName(type);
- int dim = type.arraydim;
- while(dim-->0) {
- s+="[]";
- }
- return s;
- }
-
- public static String getTypeName(GenericType type) {
-
- int tp = type.type;
- if(tp <= CodeConstants.TYPE_BOOLEAN) {
- return typeNames[tp];
- } else if(tp == CodeConstants.TYPE_VOID) {
- return "void";
- } else if(tp == CodeConstants.TYPE_GENVAR) {
- return type.value;
- } else if(tp == CodeConstants.TYPE_OBJECT) {
- StringBuilder buffer = new StringBuilder();
- buffer.append(DecompilerContext.getImpcollector().getShortName(buildJavaClassName(type)));
-
- if(!type.getArguments().isEmpty()) {
- buffer.append("<");
- for(int i=0;i<type.getArguments().size();i++) {
- if(i>0) {
- buffer.append(", ");
- }
- int wildcard = type.getWildcards().get(i);
- if(wildcard != GenericType.WILDCARD_NO) {
- buffer.append("?");
-
- switch(wildcard){
- case GenericType.WILDCARD_EXTENDS:
- buffer.append(" extends ");
- break;
- case GenericType.WILDCARD_SUPER:
- buffer.append(" super ");
- }
- }
-
- GenericType genpar = type.getArguments().get(i);
- if(genpar != null) {
- buffer.append(GenericMain.getGenericCastTypeName(genpar));
- }
- }
- buffer.append(">");
- }
-
- return buffer.toString();
- }
-
- throw new RuntimeException("invalid type");
- }
-
- public static String buildJavaClassName(GenericType type) {
-
- String name = "";
- for(GenericType tp : type.getEnclosingClasses()) {
- name += tp.value+"$";
- }
- name+=type.value;
-
- String res = name.replace('/', '.');
-
- if(res.indexOf("$") >=0) {
- StructClass cl = DecompilerContext.getStructcontext().getClass(name);
- if(cl == null || !cl.isOwn()) {
- res = res.replace('$', '.');
- }
- }
-
- return res;
- }
-
+
+ private static final String[] typeNames = new String[]{
+ "byte",
+ "char",
+ "double",
+ "float",
+ "int",
+ "long",
+ "short",
+ "boolean",
+ };
+
+ public static GenericClassDescriptor parseClassSignature(String signature) {
+
+ GenericClassDescriptor descriptor = new GenericClassDescriptor();
+
+ signature = parseFormalParameters(signature, descriptor.fparameters, descriptor.fbounds);
+
+ String supercl = GenericType.getNextType(signature);
+ descriptor.superclass = new GenericType(supercl);
+
+ signature = signature.substring(supercl.length());
+ while (signature.length() > 0) {
+ String superintr = GenericType.getNextType(signature);
+ descriptor.superinterfaces.add(new GenericType(superintr));
+ signature = signature.substring(superintr.length());
+ }
+
+ return descriptor;
+ }
+
+ public static GenericFieldDescriptor parseFieldSignature(String signature) {
+ GenericFieldDescriptor descriptor = new GenericFieldDescriptor();
+ descriptor.type = new GenericType(signature);
+ return descriptor;
+ }
+
+ public static GenericMethodDescriptor parseMethodSignature(String signature) {
+
+ GenericMethodDescriptor descriptor = new GenericMethodDescriptor();
+
+ signature = parseFormalParameters(signature, descriptor.fparameters, descriptor.fbounds);
+
+ int to = signature.indexOf(")");
+ String pars = signature.substring(1, to);
+ signature = signature.substring(to + 1);
+
+ while (pars.length() > 0) {
+ String par = GenericType.getNextType(pars);
+ descriptor.params.add(new GenericType(par));
+ pars = pars.substring(par.length());
+ }
+
+ String par = GenericType.getNextType(signature);
+ descriptor.ret = new GenericType(par);
+ signature = signature.substring(par.length());
+
+ if (signature.length() > 0) {
+ String[] excs = signature.split("\\^");
+
+ for (int i = 1; i < excs.length; i++) {
+ descriptor.exceptions.add(new GenericType(excs[i]));
+ }
+ }
+
+ return descriptor;
+ }
+
+ private static String parseFormalParameters(String signature, List<String> fparameters, List<List<GenericType>> fbounds) {
+
+ if (signature.charAt(0) != '<') {
+ return signature;
+ }
+
+ int counter = 1;
+ int index = 1;
+
+ loop:
+ while (index < signature.length()) {
+ switch (signature.charAt(index)) {
+ case '<':
+ counter++;
+ break;
+ case '>':
+ counter--;
+ if (counter == 0) {
+ break loop;
+ }
+ }
+
+ index++;
+ }
+
+ String value = signature.substring(1, index);
+ signature = signature.substring(index + 1);
+
+ while (value.length() > 0) {
+ int parto = value.indexOf(":");
+
+ String param = value.substring(0, parto);
+ value = value.substring(parto + 1);
+
+ List<GenericType> lstBounds = new ArrayList<GenericType>();
+
+ for (; ; ) {
+ if (value.charAt(0) == ':') {
+ // empty superclass, skip
+ value = value.substring(1);
+ }
+
+ String bound = GenericType.getNextType(value);
+ lstBounds.add(new GenericType(bound));
+ value = value.substring(bound.length());
+
+
+ if (value.length() == 0 || value.charAt(0) != ':') {
+ break;
+ }
+ else {
+ value = value.substring(1);
+ }
+ }
+
+ fparameters.add(param);
+ fbounds.add(lstBounds);
+ }
+
+ return signature;
+ }
+
+ public static String getGenericCastTypeName(GenericType type) {
+ String s = getTypeName(type);
+ int dim = type.arraydim;
+ while (dim-- > 0) {
+ s += "[]";
+ }
+ return s;
+ }
+
+ public static String getTypeName(GenericType type) {
+
+ int tp = type.type;
+ if (tp <= CodeConstants.TYPE_BOOLEAN) {
+ return typeNames[tp];
+ }
+ else if (tp == CodeConstants.TYPE_VOID) {
+ return "void";
+ }
+ else if (tp == CodeConstants.TYPE_GENVAR) {
+ return type.value;
+ }
+ else if (tp == CodeConstants.TYPE_OBJECT) {
+ StringBuilder buffer = new StringBuilder();
+ buffer.append(DecompilerContext.getImpcollector().getShortName(buildJavaClassName(type)));
+
+ if (!type.getArguments().isEmpty()) {
+ buffer.append("<");
+ for (int i = 0; i < type.getArguments().size(); i++) {
+ if (i > 0) {
+ buffer.append(", ");
+ }
+ int wildcard = type.getWildcards().get(i);
+ if (wildcard != GenericType.WILDCARD_NO) {
+ buffer.append("?");
+
+ switch (wildcard) {
+ case GenericType.WILDCARD_EXTENDS:
+ buffer.append(" extends ");
+ break;
+ case GenericType.WILDCARD_SUPER:
+ buffer.append(" super ");
+ }
+ }
+
+ GenericType genpar = type.getArguments().get(i);
+ if (genpar != null) {
+ buffer.append(GenericMain.getGenericCastTypeName(genpar));
+ }
+ }
+ buffer.append(">");
+ }
+
+ return buffer.toString();
+ }
+
+ throw new RuntimeException("invalid type");
+ }
+
+ public static String buildJavaClassName(GenericType type) {
+
+ String name = "";
+ for (GenericType tp : type.getEnclosingClasses()) {
+ name += tp.value + "$";
+ }
+ name += type.value;
+
+ String res = name.replace('/', '.');
+
+ if (res.indexOf("$") >= 0) {
+ StructClass cl = DecompilerContext.getStructcontext().getClass(name);
+ if (cl == null || !cl.isOwn()) {
+ res = res.replace('$', '.');
+ }
+ }
+
+ return res;
+ }
}
diff --git a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMethodDescriptor.java b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMethodDescriptor.java
index 7a0a4d1..7b4c9dc 100644
--- a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMethodDescriptor.java
+++ b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMethodDescriptor.java
@@ -1,17 +1,18 @@
/*
- * 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.struct.gen.generics;
import java.util.ArrayList;
@@ -19,14 +20,13 @@ import java.util.List;
public class GenericMethodDescriptor {
- public List<String> fparameters = new ArrayList<String>();
+ public List<String> fparameters = new ArrayList<String>();
+
+ public List<List<GenericType>> fbounds = new ArrayList<List<GenericType>>();
+
+ public List<GenericType> params = new ArrayList<GenericType>();
- public List<List<GenericType>> fbounds = new ArrayList<List<GenericType>>();
+ public GenericType ret;
- public List<GenericType> params = new ArrayList<GenericType>();
-
- public GenericType ret;
-
- public List<GenericType> exceptions = new ArrayList<GenericType>();
-
+ public List<GenericType> exceptions = new ArrayList<GenericType>();
}
diff --git a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericType.java b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericType.java
index 1f720e6..e2faa4a 100644
--- a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericType.java
+++ b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericType.java
@@ -1,270 +1,268 @@
/*
- * 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.struct.gen.generics;
+import org.jetbrains.java.decompiler.code.CodeConstants;
+
import java.util.ArrayList;
import java.util.List;
-import org.jetbrains.java.decompiler.code.CodeConstants;
-
public class GenericType {
-
- public static final int WILDCARD_EXTENDS = 1;
- public static final int WILDCARD_SUPER = 2;
- public static final int WILDCARD_UNBOUND = 3;
- public static final int WILDCARD_NO = 4;
-
- public int type;
-
- public int arraydim;
-
- public String value;
-
-
- private List<GenericType> enclosingClasses = new ArrayList<GenericType>();
-
- private List<GenericType> arguments = new ArrayList<GenericType>();
-
- private List<Integer> wildcards = new ArrayList<Integer>();
-
-
- public GenericType(int type, int arraydim, String value) {
- this.type = type;
- this.arraydim = arraydim;
- this.value = value;
- }
-
-
- public GenericType(String strtype) {
-
- parseSignature(strtype);
-
- }
-
- private void parseSignature(String sig) {
-
- int index = 0;
- while(index < sig.length()) {
-
- switch(sig.charAt(index)){
- case '[':
- arraydim++;
- break;
- case 'T':
- type = CodeConstants.TYPE_GENVAR;
- value = sig.substring(index+1, sig.length()-1);
- return;
- case 'L':
- type = CodeConstants.TYPE_OBJECT;
- sig = sig.substring(index+1, sig.length()-1);
-
- for(;;) {
- String cl = getNextClassSignature(sig);
-
- String name = cl;
- String args = null;
-
- int argfrom = cl.indexOf("<");
- if(argfrom >= 0) {
- name = cl.substring(0, argfrom);
- args = cl.substring(argfrom+1, cl.length()-1);
- }
-
- if(cl.length() < sig.length()) {
- sig = sig.substring(cl.length()+1); // skip '.'
- GenericType type = new GenericType(CodeConstants.TYPE_OBJECT, 0, name);
- parseArgumentsList(args, type);
- enclosingClasses.add(type);
- } else {
- value = name;
- parseArgumentsList(args, this);
- break;
- }
- }
-
- return;
- default:
- value = sig.substring(index, index+1);
- type = getType(value.charAt(0));
- }
-
- index++;
- }
-
- }
-
- private String getNextClassSignature(String value) {
-
- int counter = 0;
- int index = 0;
-
- loop:
- while(index < value.length()) {
- switch(value.charAt(index)) {
- case '<':
- counter++;
- break;
- case '>':
- counter--;
- break;
- case '.':
- if(counter == 0) {
- break loop;
- }
- }
-
- index++;
- }
-
- return value.substring(0, index);
- }
-
- private void parseArgumentsList(String value, GenericType type) {
-
- if(value == null) {
- return;
- }
-
- while(value.length() > 0) {
-
- String tstr = getNextType(value);
- int len = tstr.length();
- int wildcard = WILDCARD_NO;
-
- switch(tstr.charAt(0)) {
- case '*':
- wildcard = WILDCARD_UNBOUND;
- break;
- case '+':
- wildcard = WILDCARD_EXTENDS;
- break;
- case '-':
- wildcard = WILDCARD_SUPER;
- break;
- }
-
- type.getWildcards().add(wildcard);
-
- if(wildcard != WILDCARD_NO) {
- tstr = tstr.substring(1);
- }
-
- type.getArguments().add(tstr.length() == 0?null:new GenericType(tstr));
-
- value = value.substring(len);
- }
-
- }
-
- public static String getNextType(String value) {
-
- int counter = 0;
- int index = 0;
-
- boolean contmode = false;
-
- loop:
- while(index < value.length()) {
- switch(value.charAt(index)) {
- case '*':
- if(!contmode) {
- break loop;
- }
- break;
- case 'L':
- case 'T':
- if(!contmode) {
- contmode = true;
- }
- case '[':
- case '+':
- case '-':
- break;
- default:
- if(!contmode) {
- break loop;
- }
- break;
- case '<':
- counter++;
- break;
- case '>':
- counter--;
- break;
- case ';':
- if(counter == 0) {
- break loop;
- }
- }
-
- index++;
- }
-
- return value.substring(0, index+1);
- }
-
- private int getType(char c) {
- switch(c) {
- case 'B':
- return CodeConstants.TYPE_BYTE;
- case 'C':
- return CodeConstants.TYPE_CHAR;
- case 'D':
- return CodeConstants.TYPE_DOUBLE;
- case 'F':
- return CodeConstants.TYPE_FLOAT;
- case 'I':
- return CodeConstants.TYPE_INT;
- case 'J':
- return CodeConstants.TYPE_LONG;
- case 'S':
- return CodeConstants.TYPE_SHORT;
- case 'Z':
- return CodeConstants.TYPE_BOOLEAN;
- case 'V':
- return CodeConstants.TYPE_VOID;
- case 'G':
- return CodeConstants.TYPE_GROUP2EMPTY;
- case 'N':
- return CodeConstants.TYPE_NOTINITIALIZED;
- case 'A':
- return CodeConstants.TYPE_ADDRESS;
- case 'X':
- return CodeConstants.TYPE_BYTECHAR;
- case 'Y':
- return CodeConstants.TYPE_SHORTCHAR;
- case 'U':
- return CodeConstants.TYPE_UNKNOWN;
- default:
- throw new RuntimeException("Invalid type");
- }
- }
-
-
- public List<GenericType> getArguments() {
- return arguments;
- }
-
-
- public List<GenericType> getEnclosingClasses() {
- return enclosingClasses;
- }
-
-
- public List<Integer> getWildcards() {
- return wildcards;
- }
-
+
+ public static final int WILDCARD_EXTENDS = 1;
+ public static final int WILDCARD_SUPER = 2;
+ public static final int WILDCARD_UNBOUND = 3;
+ public static final int WILDCARD_NO = 4;
+
+ public int type;
+
+ public int arraydim;
+
+ public String value;
+
+
+ private List<GenericType> enclosingClasses = new ArrayList<GenericType>();
+
+ private List<GenericType> arguments = new ArrayList<GenericType>();
+
+ private List<Integer> wildcards = new ArrayList<Integer>();
+
+
+ public GenericType(int type, int arraydim, String value) {
+ this.type = type;
+ this.arraydim = arraydim;
+ this.value = value;
+ }
+
+
+ public GenericType(String strtype) {
+
+ parseSignature(strtype);
+ }
+
+ private void parseSignature(String sig) {
+
+ int index = 0;
+ while (index < sig.length()) {
+
+ switch (sig.charAt(index)) {
+ case '[':
+ arraydim++;
+ break;
+ case 'T':
+ type = CodeConstants.TYPE_GENVAR;
+ value = sig.substring(index + 1, sig.length() - 1);
+ return;
+ case 'L':
+ type = CodeConstants.TYPE_OBJECT;
+ sig = sig.substring(index + 1, sig.length() - 1);
+
+ for (; ; ) {
+ String cl = getNextClassSignature(sig);
+
+ String name = cl;
+ String args = null;
+
+ int argfrom = cl.indexOf("<");
+ if (argfrom >= 0) {
+ name = cl.substring(0, argfrom);
+ args = cl.substring(argfrom + 1, cl.length() - 1);
+ }
+
+ if (cl.length() < sig.length()) {
+ sig = sig.substring(cl.length() + 1); // skip '.'
+ GenericType type = new GenericType(CodeConstants.TYPE_OBJECT, 0, name);
+ parseArgumentsList(args, type);
+ enclosingClasses.add(type);
+ }
+ else {
+ value = name;
+ parseArgumentsList(args, this);
+ break;
+ }
+ }
+
+ return;
+ default:
+ value = sig.substring(index, index + 1);
+ type = getType(value.charAt(0));
+ }
+
+ index++;
+ }
+ }
+
+ private String getNextClassSignature(String value) {
+
+ int counter = 0;
+ int index = 0;
+
+ loop:
+ while (index < value.length()) {
+ switch (value.charAt(index)) {
+ case '<':
+ counter++;
+ break;
+ case '>':
+ counter--;
+ break;
+ case '.':
+ if (counter == 0) {
+ break loop;
+ }
+ }
+
+ index++;
+ }
+
+ return value.substring(0, index);
+ }
+
+ private void parseArgumentsList(String value, GenericType type) {
+
+ if (value == null) {
+ return;
+ }
+
+ while (value.length() > 0) {
+
+ String tstr = getNextType(value);
+ int len = tstr.length();
+ int wildcard = WILDCARD_NO;
+
+ switch (tstr.charAt(0)) {
+ case '*':
+ wildcard = WILDCARD_UNBOUND;
+ break;
+ case '+':
+ wildcard = WILDCARD_EXTENDS;
+ break;
+ case '-':
+ wildcard = WILDCARD_SUPER;
+ break;
+ }
+
+ type.getWildcards().add(wildcard);
+
+ if (wildcard != WILDCARD_NO) {
+ tstr = tstr.substring(1);
+ }
+
+ type.getArguments().add(tstr.length() == 0 ? null : new GenericType(tstr));
+
+ value = value.substring(len);
+ }
+ }
+
+ public static String getNextType(String value) {
+
+ int counter = 0;
+ int index = 0;
+
+ boolean contmode = false;
+
+ loop:
+ while (index < value.length()) {
+ switch (value.charAt(index)) {
+ case '*':
+ if (!contmode) {
+ break loop;
+ }
+ break;
+ case 'L':
+ case 'T':
+ if (!contmode) {
+ contmode = true;
+ }
+ case '[':
+ case '+':
+ case '-':
+ break;
+ default:
+ if (!contmode) {
+ break loop;
+ }
+ break;
+ case '<':
+ counter++;
+ break;
+ case '>':
+ counter--;
+ break;
+ case ';':
+ if (counter == 0) {
+ break loop;
+ }
+ }
+
+ index++;
+ }
+
+ return value.substring(0, index + 1);
+ }
+
+ private int getType(char c) {
+ switch (c) {
+ case 'B':
+ return CodeConstants.TYPE_BYTE;
+ case 'C':
+ return CodeConstants.TYPE_CHAR;
+ case 'D':
+ return CodeConstants.TYPE_DOUBLE;
+ case 'F':
+ return CodeConstants.TYPE_FLOAT;
+ case 'I':
+ return CodeConstants.TYPE_INT;
+ case 'J':
+ return CodeConstants.TYPE_LONG;
+ case 'S':
+ return CodeConstants.TYPE_SHORT;
+ case 'Z':
+ return CodeConstants.TYPE_BOOLEAN;
+ case 'V':
+ return CodeConstants.TYPE_VOID;
+ case 'G':
+ return CodeConstants.TYPE_GROUP2EMPTY;
+ case 'N':
+ return CodeConstants.TYPE_NOTINITIALIZED;
+ case 'A':
+ return CodeConstants.TYPE_ADDRESS;
+ case 'X':
+ return CodeConstants.TYPE_BYTECHAR;
+ case 'Y':
+ return CodeConstants.TYPE_SHORTCHAR;
+ case 'U':
+ return CodeConstants.TYPE_UNKNOWN;
+ default:
+ throw new RuntimeException("Invalid type");
+ }
+ }
+
+
+ public List<GenericType> getArguments() {
+ return arguments;
+ }
+
+
+ public List<GenericType> getEnclosingClasses() {
+ return enclosingClasses;
+ }
+
+
+ public List<Integer> getWildcards() {
+ return wildcards;
+ }
}