java-decompiler: cleanups and fixes
- duplicates eliminated - immutable fields - typos - formatting
This commit is contained in:
@@ -20,6 +20,7 @@ import org.jetbrains.java.decompiler.main.DecompilerContext;
|
||||
import org.jetbrains.java.decompiler.modules.renamer.PoolInterceptor;
|
||||
import org.jetbrains.java.decompiler.struct.gen.FieldDescriptor;
|
||||
import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor;
|
||||
import org.jetbrains.java.decompiler.struct.gen.NewClassNameBuilder;
|
||||
import org.jetbrains.java.decompiler.struct.gen.VarType;
|
||||
import org.jetbrains.java.decompiler.util.DataInputFullStream;
|
||||
|
||||
@@ -28,7 +29,7 @@ import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ConstantPool {
|
||||
public class ConstantPool implements NewClassNameBuilder {
|
||||
|
||||
public static final int FIELD = 1;
|
||||
public static final int METHOD = 2;
|
||||
@@ -154,8 +155,7 @@ public class ConstantPool {
|
||||
elementName = newElement.split(" ")[1];
|
||||
}
|
||||
|
||||
int type = elementType == FIELD ? CodeConstants.CONSTANT_Fieldref : CodeConstants.CONSTANT_Methodref;
|
||||
String newDescriptor = buildNewDescriptor(type, descriptor);
|
||||
String newDescriptor = buildNewDescriptor(elementType == FIELD, descriptor);
|
||||
if (newDescriptor != null) {
|
||||
descriptor = newDescriptor;
|
||||
}
|
||||
@@ -192,7 +192,7 @@ public class ConstantPool {
|
||||
ln.type == CodeConstants.CONSTANT_InterfaceMethodref)) {
|
||||
String newClassName = buildNewClassname(ln.classname);
|
||||
String newElement = interceptor.getName(ln.classname + " " + ln.elementname + " " + ln.descriptor);
|
||||
String newDescriptor = buildNewDescriptor(ln.type, ln.descriptor);
|
||||
String newDescriptor = buildNewDescriptor(ln.type == CodeConstants.CONSTANT_Fieldref, ln.descriptor);
|
||||
|
||||
if (newClassName != null || newElement != null || newDescriptor != null) {
|
||||
String className = newClassName == null ? ln.classname : newClassName;
|
||||
@@ -205,15 +205,16 @@ public class ConstantPool {
|
||||
return ln;
|
||||
}
|
||||
|
||||
private String buildNewClassname(String className) {
|
||||
@Override
|
||||
public String buildNewClassname(String className) {
|
||||
VarType vt = new VarType(className, true);
|
||||
|
||||
String newName = interceptor.getName(vt.value);
|
||||
if (newName != null) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
|
||||
if (vt.arraydim > 0) {
|
||||
for (int i = 0; i < vt.arraydim; i++) {
|
||||
if (vt.arrayDim > 0) {
|
||||
for (int i = 0; i < vt.arrayDim; i++) {
|
||||
buffer.append("[");
|
||||
}
|
||||
|
||||
@@ -229,53 +230,12 @@ public class ConstantPool {
|
||||
return null;
|
||||
}
|
||||
|
||||
private String buildNewDescriptor(int type, String descriptor) {
|
||||
boolean updated = false;
|
||||
|
||||
if (type == CodeConstants.CONSTANT_Fieldref) {
|
||||
FieldDescriptor fd = FieldDescriptor.parseDescriptor(descriptor);
|
||||
|
||||
VarType fType = fd.type;
|
||||
if (fType.type == CodeConstants.TYPE_OBJECT) {
|
||||
String newClassName = buildNewClassname(fType.value);
|
||||
if (newClassName != null) {
|
||||
fType.value = newClassName;
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (updated) {
|
||||
return fd.getDescriptor();
|
||||
}
|
||||
private String buildNewDescriptor(boolean isField, String descriptor) {
|
||||
if (isField) {
|
||||
return FieldDescriptor.parseDescriptor(descriptor).buildNewDescriptor(this);
|
||||
}
|
||||
else {
|
||||
MethodDescriptor md = MethodDescriptor.parseDescriptor(descriptor);
|
||||
|
||||
// parameters
|
||||
for (VarType paramType : md.params) {
|
||||
if (paramType.type == CodeConstants.TYPE_OBJECT) {
|
||||
String newClassName = buildNewClassname(paramType.value);
|
||||
if (newClassName != null) {
|
||||
paramType.value = newClassName;
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return value
|
||||
if (md.ret.type == CodeConstants.TYPE_OBJECT) {
|
||||
String newClassName = buildNewClassname(md.ret.value);
|
||||
if (newClassName != null) {
|
||||
md.ret.value = newClassName;
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (updated) {
|
||||
return md.getDescriptor();
|
||||
}
|
||||
return MethodDescriptor.parseDescriptor(descriptor).buildNewDescriptor(this);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ public class DataPoint {
|
||||
VarType var = md.params[i];
|
||||
|
||||
point.setVariable(k++, var);
|
||||
if (var.stack_size == 2) {
|
||||
if (var.stackSize == 2) {
|
||||
point.setVariable(k++, new VarType(CodeConstants.TYPE_GROUP2EMPTY));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.jetbrains.java.decompiler.struct.gen;
|
||||
|
||||
import org.jetbrains.java.decompiler.code.CodeConstants;
|
||||
|
||||
public class FieldDescriptor {
|
||||
|
||||
public static final FieldDescriptor INTEGER_DESCRIPTOR = parseDescriptor("Ljava/lang/Integer;");
|
||||
@@ -22,25 +24,27 @@ public class FieldDescriptor {
|
||||
public static final FieldDescriptor FLOAT_DESCRIPTOR = parseDescriptor("Ljava/lang/Float;");
|
||||
public static final FieldDescriptor DOUBLE_DESCRIPTOR = parseDescriptor("Ljava/lang/Double;");
|
||||
|
||||
public VarType type;
|
||||
public final VarType type;
|
||||
public final String descriptorString;
|
||||
|
||||
public String descriptorString;
|
||||
|
||||
private FieldDescriptor() {
|
||||
private FieldDescriptor(String descriptor) {
|
||||
type = new VarType(descriptor);
|
||||
descriptorString = descriptor;
|
||||
}
|
||||
|
||||
public static FieldDescriptor parseDescriptor(String descr) {
|
||||
|
||||
FieldDescriptor fd = new FieldDescriptor();
|
||||
|
||||
fd.type = new VarType(descr);
|
||||
fd.descriptorString = descr;
|
||||
|
||||
return fd;
|
||||
public static FieldDescriptor parseDescriptor(String descriptor) {
|
||||
return new FieldDescriptor(descriptor);
|
||||
}
|
||||
|
||||
public String getDescriptor() {
|
||||
return type.toString();
|
||||
public String buildNewDescriptor(NewClassNameBuilder builder) {
|
||||
if (type.type == CodeConstants.TYPE_OBJECT) {
|
||||
String newClassName = builder.buildNewClassname(type.value);
|
||||
if (newClassName != null) {
|
||||
return new VarType(type.type, type.arrayDim, newClassName).toString();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,73 +15,115 @@
|
||||
*/
|
||||
package org.jetbrains.java.decompiler.struct.gen;
|
||||
|
||||
import org.jetbrains.java.decompiler.code.CodeConstants;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class MethodDescriptor {
|
||||
|
||||
public VarType[] params;
|
||||
public final VarType[] params;
|
||||
public final VarType ret;
|
||||
|
||||
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;
|
||||
private MethodDescriptor(VarType[] params, VarType ret) {
|
||||
this.params = params;
|
||||
this.ret = ret;
|
||||
}
|
||||
|
||||
public String getDescriptor() {
|
||||
String res = "(";
|
||||
|
||||
for (int j = 0; j < params.length; j++) {
|
||||
res += params[j].toString();
|
||||
public static MethodDescriptor parseDescriptor(String descriptor) {
|
||||
int parenth = descriptor.lastIndexOf(')');
|
||||
if (descriptor.length() < 2 || parenth < 0 || descriptor.charAt(0) != '(') {
|
||||
throw new IllegalArgumentException("Invalid descriptor: " + descriptor);
|
||||
}
|
||||
|
||||
res += ")" + ret.toString();
|
||||
VarType[] params;
|
||||
|
||||
return res;
|
||||
if (parenth > 1) {
|
||||
String parameters = descriptor.substring(1, parenth);
|
||||
List<String> lst = new ArrayList<String>();
|
||||
|
||||
int indexFrom = -1, ind, len = parameters.length(), index = 0;
|
||||
while (index < len) {
|
||||
switch (parameters.charAt(index)) {
|
||||
case '[':
|
||||
if (indexFrom < 0) {
|
||||
indexFrom = index;
|
||||
}
|
||||
break;
|
||||
case 'L':
|
||||
ind = parameters.indexOf(";", index);
|
||||
lst.add(parameters.substring(indexFrom < 0 ? index : indexFrom, ind + 1));
|
||||
index = ind;
|
||||
indexFrom = -1;
|
||||
break;
|
||||
default:
|
||||
lst.add(parameters.substring(indexFrom < 0 ? index : indexFrom, index + 1));
|
||||
indexFrom = -1;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
params = new VarType[lst.size()];
|
||||
for (int i = 0; i < lst.size(); i++) {
|
||||
params[i] = new VarType(lst.get(i));
|
||||
}
|
||||
}
|
||||
else {
|
||||
params = VarType.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
VarType ret = new VarType(descriptor.substring(parenth + 1));
|
||||
|
||||
return new MethodDescriptor(params, ret);
|
||||
}
|
||||
|
||||
public String buildNewDescriptor(NewClassNameBuilder builder) {
|
||||
boolean updated = false;
|
||||
|
||||
VarType[] newParams;
|
||||
if (params.length > 0) {
|
||||
newParams = new VarType[params.length];
|
||||
System.arraycopy(params, 0, newParams, 0, params.length);
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
VarType substitute = buildNewType(params[i], builder);
|
||||
if (substitute != null) {
|
||||
newParams[i] = substitute;
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
newParams = VarType.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
VarType newRet = ret;
|
||||
VarType substitute = buildNewType(ret, builder);
|
||||
if (substitute != null) {
|
||||
newRet = substitute;
|
||||
updated = true;
|
||||
}
|
||||
|
||||
if (updated) {
|
||||
StringBuilder res = new StringBuilder("(");
|
||||
for (VarType param : newParams) {
|
||||
res.append(param);
|
||||
}
|
||||
res.append(")").append(newRet.toString());
|
||||
return res.toString();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static VarType buildNewType(VarType type, NewClassNameBuilder builder) {
|
||||
if (type.type == CodeConstants.TYPE_OBJECT) {
|
||||
String newClassName = builder.buildNewClassname(type.value);
|
||||
if (newClassName != null) {
|
||||
return new VarType(type.type, type.arrayDim, newClassName);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.struct.gen;
|
||||
|
||||
public interface NewClassNameBuilder {
|
||||
String buildNewClassname(String className);
|
||||
}
|
||||
@@ -20,7 +20,7 @@ import org.jetbrains.java.decompiler.util.InterpreterUtil;
|
||||
|
||||
public class VarType { // TODO: optimize switch
|
||||
|
||||
public static final int FALSEBOOLEAN = 1;
|
||||
public static final VarType[] EMPTY_ARRAY = {};
|
||||
|
||||
public static final VarType VARTYPE_UNKNOWN = new VarType(CodeConstants.TYPE_UNKNOWN);
|
||||
public static final VarType VARTYPE_INT = new VarType(CodeConstants.TYPE_INT);
|
||||
@@ -35,312 +35,80 @@ public class VarType { // TODO: optimize switch
|
||||
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 final int type;
|
||||
public final int arrayDim;
|
||||
public final String value;
|
||||
public final int typeFamily;
|
||||
public final int stackSize;
|
||||
public final boolean falseBoolean;
|
||||
|
||||
public VarType(int type) {
|
||||
this(type, 0);
|
||||
}
|
||||
|
||||
public VarType(int type, int arrayDim) {
|
||||
this(type, arrayDim, getChar(type));
|
||||
}
|
||||
|
||||
public VarType(int type, int arrayDim, String value) {
|
||||
this(type, arrayDim, value, getFamily(type, arrayDim), getStackSize(type, arrayDim), false);
|
||||
}
|
||||
|
||||
private VarType(int type, int arrayDim, String value, int typeFamily, int stackSize, boolean falseBoolean) {
|
||||
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.arrayDim = arrayDim;
|
||||
this.value = value;
|
||||
setFamily();
|
||||
this.typeFamily = typeFamily;
|
||||
this.stackSize = stackSize;
|
||||
this.falseBoolean = falseBoolean;
|
||||
}
|
||||
|
||||
public VarType(String strtype) {
|
||||
this(strtype, false);
|
||||
public VarType(String signature) {
|
||||
this(signature, false);
|
||||
}
|
||||
|
||||
public VarType(String strtype, boolean cltype) {
|
||||
parseTypeString(strtype, cltype);
|
||||
setStackSize(type);
|
||||
setFamily();
|
||||
}
|
||||
public VarType(String signature, boolean clType) {
|
||||
int type = 0;
|
||||
int arrayDim = 0;
|
||||
String value = null;
|
||||
|
||||
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 & 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_SHORTCHAR;
|
||||
}
|
||||
else {
|
||||
return VARTYPE_BYTECHAR;
|
||||
}
|
||||
case CodeConstants.TYPE_FAMILY_OBJECT:
|
||||
return 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_SHORT;
|
||||
}
|
||||
else {
|
||||
return VARTYPE_INT;
|
||||
}
|
||||
case CodeConstants.TYPE_FAMILY_OBJECT:
|
||||
return VARTYPE_OBJECT;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static VarType getMinTypeInFamily(int family) {
|
||||
switch (family) {
|
||||
case CodeConstants.TYPE_FAMILY_BOOLEAN:
|
||||
return VARTYPE_BOOLEAN;
|
||||
case CodeConstants.TYPE_FAMILY_INTEGER:
|
||||
return VARTYPE_BYTECHAR;
|
||||
case CodeConstants.TYPE_FAMILY_OBJECT:
|
||||
return VARTYPE_NULL;
|
||||
case CodeConstants.TYPE_FAMILY_FLOAT:
|
||||
return VARTYPE_FLOAT;
|
||||
case CodeConstants.TYPE_FAMILY_LONG:
|
||||
return VARTYPE_LONG;
|
||||
case CodeConstants.TYPE_FAMILY_DOUBLE:
|
||||
return VARTYPE_DOUBLE;
|
||||
case CodeConstants.TYPE_FAMILY_UNKNOWN:
|
||||
return 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)) {
|
||||
loop:
|
||||
for (int i = 0; i < signature.length(); i++) {
|
||||
switch (signature.charAt(i)) {
|
||||
case '[':
|
||||
arraydim++;
|
||||
arrayDim++;
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
if (strtype.charAt(strtype.length() - 1) == ';') {
|
||||
if (signature.charAt(signature.length() - 1) == ';') {
|
||||
type = CodeConstants.TYPE_OBJECT;
|
||||
value = strtype.substring(i + 1, strtype.length() - 1);
|
||||
return;
|
||||
value = signature.substring(i + 1, signature.length() - 1);
|
||||
break loop;
|
||||
}
|
||||
|
||||
default:
|
||||
value = strtype.substring(i, strtype.length());
|
||||
if ((cltype && i == 0) || value.length() > 1) {
|
||||
value = signature.substring(i, signature.length());
|
||||
if ((clType && i == 0) || value.length() > 1) {
|
||||
type = CodeConstants.TYPE_OBJECT;
|
||||
}
|
||||
else {
|
||||
type = getType(value.charAt(0));
|
||||
}
|
||||
return;
|
||||
break loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 static 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");
|
||||
}
|
||||
this.type = type;
|
||||
this.arrayDim = arrayDim;
|
||||
this.value = value;
|
||||
this.typeFamily = getFamily(type, arrayDim);
|
||||
this.stackSize = getStackSize(type, arrayDim);
|
||||
this.falseBoolean = false;
|
||||
}
|
||||
|
||||
private static String getChar(int type) {
|
||||
@@ -383,11 +151,26 @@ public class VarType { // TODO: optimize switch
|
||||
}
|
||||
}
|
||||
|
||||
public void setFamily() {
|
||||
private static int getStackSize(int type, int arrayDim) {
|
||||
if (arrayDim > 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (arraydim > 0) {
|
||||
this.type_family = CodeConstants.TYPE_FAMILY_OBJECT;
|
||||
return;
|
||||
switch (type) {
|
||||
case CodeConstants.TYPE_DOUBLE:
|
||||
case CodeConstants.TYPE_LONG:
|
||||
return 2;
|
||||
case CodeConstants.TYPE_VOID:
|
||||
case CodeConstants.TYPE_GROUP2EMPTY:
|
||||
return 0;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
private static int getFamily(int type, int arrayDim) {
|
||||
if (arrayDim > 0) {
|
||||
return CodeConstants.TYPE_FAMILY_OBJECT;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
@@ -397,26 +180,239 @@ public class VarType { // TODO: optimize switch
|
||||
case CodeConstants.TYPE_CHAR:
|
||||
case CodeConstants.TYPE_SHORT:
|
||||
case CodeConstants.TYPE_INT:
|
||||
this.type_family = CodeConstants.TYPE_FAMILY_INTEGER;
|
||||
break;
|
||||
return CodeConstants.TYPE_FAMILY_INTEGER;
|
||||
case CodeConstants.TYPE_DOUBLE:
|
||||
this.type_family = CodeConstants.TYPE_FAMILY_DOUBLE;
|
||||
break;
|
||||
return CodeConstants.TYPE_FAMILY_DOUBLE;
|
||||
case CodeConstants.TYPE_FLOAT:
|
||||
this.type_family = CodeConstants.TYPE_FAMILY_FLOAT;
|
||||
break;
|
||||
return CodeConstants.TYPE_FAMILY_FLOAT;
|
||||
case CodeConstants.TYPE_LONG:
|
||||
this.type_family = CodeConstants.TYPE_FAMILY_LONG;
|
||||
break;
|
||||
return CodeConstants.TYPE_FAMILY_LONG;
|
||||
case CodeConstants.TYPE_BOOLEAN:
|
||||
this.type_family = CodeConstants.TYPE_FAMILY_BOOLEAN;
|
||||
break;
|
||||
return CodeConstants.TYPE_FAMILY_BOOLEAN;
|
||||
case CodeConstants.TYPE_NULL:
|
||||
case CodeConstants.TYPE_OBJECT:
|
||||
this.type_family = CodeConstants.TYPE_FAMILY_OBJECT;
|
||||
break;
|
||||
return CodeConstants.TYPE_FAMILY_OBJECT;
|
||||
default:
|
||||
this.type_family = CodeConstants.TYPE_FAMILY_UNKNOWN;
|
||||
return CodeConstants.TYPE_FAMILY_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
public VarType decreaseArrayDim() {
|
||||
if (arrayDim > 0) {
|
||||
return new VarType(type, arrayDim - 1, value);
|
||||
}
|
||||
else {
|
||||
//throw new RuntimeException("array dimension equals 0!"); FIXME: investigate this case
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public VarType resizeArrayDim(int newArrayDim) {
|
||||
return new VarType(type, newArrayDim, value, typeFamily, stackSize, falseBoolean);
|
||||
}
|
||||
|
||||
public VarType copy() {
|
||||
return copy(false);
|
||||
}
|
||||
|
||||
public VarType copy(boolean forceFalseBoolean) {
|
||||
return new VarType(type, arrayDim, value, typeFamily, stackSize, falseBoolean || forceFalseBoolean);
|
||||
}
|
||||
|
||||
public boolean isFalseBoolean() {
|
||||
return falseBoolean;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder res = new StringBuilder();
|
||||
for (int i = 0; i < arrayDim; i++) {
|
||||
res.append('[');
|
||||
}
|
||||
if (type == CodeConstants.TYPE_OBJECT) {
|
||||
res.append('L').append(value).append(';');
|
||||
}
|
||||
else {
|
||||
res.append(value);
|
||||
}
|
||||
return res.toString();
|
||||
}
|
||||
|
||||
// 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.typeFamily == type2.typeFamily) {
|
||||
switch (type1.typeFamily) {
|
||||
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_SHORTCHAR;
|
||||
}
|
||||
else {
|
||||
return VARTYPE_BYTECHAR;
|
||||
}
|
||||
case CodeConstants.TYPE_FAMILY_OBJECT:
|
||||
return 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.typeFamily == type2.typeFamily) {
|
||||
switch (type1.typeFamily) {
|
||||
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_SHORT;
|
||||
}
|
||||
else {
|
||||
return VARTYPE_INT;
|
||||
}
|
||||
case CodeConstants.TYPE_FAMILY_OBJECT:
|
||||
return VARTYPE_OBJECT;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static VarType getMinTypeInFamily(int family) {
|
||||
switch (family) {
|
||||
case CodeConstants.TYPE_FAMILY_BOOLEAN:
|
||||
return VARTYPE_BOOLEAN;
|
||||
case CodeConstants.TYPE_FAMILY_INTEGER:
|
||||
return VARTYPE_BYTECHAR;
|
||||
case CodeConstants.TYPE_FAMILY_OBJECT:
|
||||
return VARTYPE_NULL;
|
||||
case CodeConstants.TYPE_FAMILY_FLOAT:
|
||||
return VARTYPE_FLOAT;
|
||||
case CodeConstants.TYPE_FAMILY_LONG:
|
||||
return VARTYPE_LONG;
|
||||
case CodeConstants.TYPE_FAMILY_DOUBLE:
|
||||
return VARTYPE_DOUBLE;
|
||||
case CodeConstants.TYPE_FAMILY_UNKNOWN:
|
||||
return VARTYPE_UNKNOWN;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid type family: " + family);
|
||||
}
|
||||
}
|
||||
|
||||
public static 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 IllegalArgumentException("Invalid type: " + c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ public class GenericMain {
|
||||
|
||||
public static String getGenericCastTypeName(GenericType type) {
|
||||
String s = getTypeName(type);
|
||||
int dim = type.arraydim;
|
||||
int dim = type.arrayDim;
|
||||
while (dim-- > 0) {
|
||||
s += "[]";
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.jetbrains.java.decompiler.struct.gen.generics;
|
||||
|
||||
import org.jetbrains.java.decompiler.code.CodeConstants;
|
||||
import org.jetbrains.java.decompiler.struct.gen.VarType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -27,66 +28,59 @@ public class GenericType {
|
||||
public static final int WILDCARD_UNBOUND = 3;
|
||||
public static final int WILDCARD_NO = 4;
|
||||
|
||||
public int type;
|
||||
public final int type;
|
||||
public final int arrayDim;
|
||||
public final String value;
|
||||
|
||||
public int arraydim;
|
||||
private final List<GenericType> enclosingClasses = new ArrayList<GenericType>();
|
||||
private final List<GenericType> arguments = new ArrayList<GenericType>();
|
||||
private final List<Integer> wildcards = new ArrayList<Integer>();
|
||||
|
||||
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) {
|
||||
public GenericType(int type, int arrayDim, String value) {
|
||||
this.type = type;
|
||||
this.arraydim = arraydim;
|
||||
this.arrayDim = arrayDim;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
public GenericType(String strtype) {
|
||||
|
||||
parseSignature(strtype);
|
||||
}
|
||||
|
||||
private void parseSignature(String sig) {
|
||||
public GenericType(String signature) {
|
||||
int type = 0;
|
||||
int arrayDim = 0;
|
||||
String value = null;
|
||||
|
||||
int index = 0;
|
||||
while (index < sig.length()) {
|
||||
|
||||
switch (sig.charAt(index)) {
|
||||
loop:
|
||||
while (index < signature.length()) {
|
||||
switch (signature.charAt(index)) {
|
||||
case '[':
|
||||
arraydim++;
|
||||
arrayDim++;
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
type = CodeConstants.TYPE_GENVAR;
|
||||
value = sig.substring(index + 1, sig.length() - 1);
|
||||
return;
|
||||
value = signature.substring(index + 1, signature.length() - 1);
|
||||
break loop;
|
||||
|
||||
case 'L':
|
||||
type = CodeConstants.TYPE_OBJECT;
|
||||
sig = sig.substring(index + 1, sig.length() - 1);
|
||||
signature = signature.substring(index + 1, signature.length() - 1);
|
||||
|
||||
while (true) {
|
||||
String cl = getNextClassSignature(sig);
|
||||
String cl = getNextClassSignature(signature);
|
||||
|
||||
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);
|
||||
int argStart = cl.indexOf("<");
|
||||
if (argStart >= 0) {
|
||||
name = cl.substring(0, argStart);
|
||||
args = cl.substring(argStart + 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);
|
||||
if (cl.length() < signature.length()) {
|
||||
signature = signature.substring(cl.length() + 1); // skip '.'
|
||||
GenericType type11 = new GenericType(CodeConstants.TYPE_OBJECT, 0, name);
|
||||
parseArgumentsList(args, type11);
|
||||
enclosingClasses.add(type11);
|
||||
}
|
||||
else {
|
||||
value = name;
|
||||
@@ -95,18 +89,22 @@ public class GenericType {
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
break loop;
|
||||
|
||||
default:
|
||||
value = sig.substring(index, index + 1);
|
||||
type = getType(value.charAt(0));
|
||||
value = signature.substring(index, index + 1);
|
||||
type = VarType.getType(value.charAt(0));
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
this.type = type;
|
||||
this.arrayDim = arrayDim;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
private static String getNextClassSignature(String value) {
|
||||
|
||||
int counter = 0;
|
||||
int index = 0;
|
||||
|
||||
@@ -132,18 +130,16 @@ public class GenericType {
|
||||
}
|
||||
|
||||
private static void parseArgumentsList(String value, GenericType type) {
|
||||
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (value.length() > 0) {
|
||||
|
||||
String tstr = getNextType(value);
|
||||
int len = tstr.length();
|
||||
String typeStr = getNextType(value);
|
||||
int len = typeStr.length();
|
||||
int wildcard = WILDCARD_NO;
|
||||
|
||||
switch (tstr.charAt(0)) {
|
||||
switch (typeStr.charAt(0)) {
|
||||
case '*':
|
||||
wildcard = WILDCARD_UNBOUND;
|
||||
break;
|
||||
@@ -158,41 +154,40 @@ public class GenericType {
|
||||
type.getWildcards().add(wildcard);
|
||||
|
||||
if (wildcard != WILDCARD_NO) {
|
||||
tstr = tstr.substring(1);
|
||||
typeStr = typeStr.substring(1);
|
||||
}
|
||||
|
||||
type.getArguments().add(tstr.length() == 0 ? null : new GenericType(tstr));
|
||||
type.getArguments().add(typeStr.length() == 0 ? null : new GenericType(typeStr));
|
||||
|
||||
value = value.substring(len);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getNextType(String value) {
|
||||
|
||||
int counter = 0;
|
||||
int index = 0;
|
||||
|
||||
boolean contmode = false;
|
||||
boolean contMode = false;
|
||||
|
||||
loop:
|
||||
while (index < value.length()) {
|
||||
switch (value.charAt(index)) {
|
||||
case '*':
|
||||
if (!contmode) {
|
||||
if (!contMode) {
|
||||
break loop;
|
||||
}
|
||||
break;
|
||||
case 'L':
|
||||
case 'T':
|
||||
if (!contmode) {
|
||||
contmode = true;
|
||||
if (!contMode) {
|
||||
contMode = true;
|
||||
}
|
||||
case '[':
|
||||
case '+':
|
||||
case '-':
|
||||
break;
|
||||
default:
|
||||
if (!contmode) {
|
||||
if (!contMode) {
|
||||
break loop;
|
||||
}
|
||||
break;
|
||||
@@ -214,54 +209,19 @@ public class GenericType {
|
||||
return value.substring(0, index + 1);
|
||||
}
|
||||
|
||||
private static 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 GenericType decreaseArrayDim() {
|
||||
assert arrayDim > 0 : this;
|
||||
return new GenericType(type, arrayDim - 1, value);
|
||||
}
|
||||
|
||||
|
||||
public List<GenericType> getArguments() {
|
||||
return arguments;
|
||||
}
|
||||
|
||||
|
||||
public List<GenericType> getEnclosingClasses() {
|
||||
return enclosingClasses;
|
||||
}
|
||||
|
||||
|
||||
public List<Integer> getWildcards() {
|
||||
return wildcards;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user