summaryrefslogtreecommitdiffstats
path: root/src/org/jetbrains/java/decompiler/struct/gen/VarType.java
diff options
context:
space:
mode:
authorRoman Shevchenko <roman.shevchenko@jetbrains.com>2014-08-28 21:34:14 +0400
committerRoman Shevchenko <roman.shevchenko@jetbrains.com>2014-08-28 21:34:19 +0400
commit076e4393f25bf1ad1ff1bd2853153e2b595dd90b (patch)
treef1a17a12ea762525b5efbc0778b0945d906c68c9 /src/org/jetbrains/java/decompiler/struct/gen/VarType.java
parent663631f0456fcc245dd835889f86541d75161c53 (diff)
downloadfernflower-076e4393f25bf1ad1ff1bd2853153e2b595dd90b.tar
fernflower-076e4393f25bf1ad1ff1bd2853153e2b595dd90b.tar.gz
fernflower-076e4393f25bf1ad1ff1bd2853153e2b595dd90b.tar.lz
fernflower-076e4393f25bf1ad1ff1bd2853153e2b595dd90b.tar.xz
fernflower-076e4393f25bf1ad1ff1bd2853153e2b595dd90b.zip
java-decompiler: post-import cleanup (formatting and copyright)
Diffstat (limited to 'src/org/jetbrains/java/decompiler/struct/gen/VarType.java')
-rw-r--r--src/org/jetbrains/java/decompiler/struct/gen/VarType.java808
1 files changed, 410 insertions, 398 deletions
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;
+ }
+ }
}