summaryrefslogtreecommitdiffstats
path: root/src/org/jetbrains/java/decompiler/struct
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/jetbrains/java/decompiler/struct')
-rw-r--r--src/org/jetbrains/java/decompiler/struct/ContextUnit.java390
-rw-r--r--src/org/jetbrains/java/decompiler/struct/IDecompiledData.java24
-rw-r--r--src/org/jetbrains/java/decompiler/struct/ISaveClass.java28
-rw-r--r--src/org/jetbrains/java/decompiler/struct/StructClass.java618
-rw-r--r--src/org/jetbrains/java/decompiler/struct/StructContext.java387
-rw-r--r--src/org/jetbrains/java/decompiler/struct/StructField.java173
-rw-r--r--src/org/jetbrains/java/decompiler/struct/StructMethod.java1068
-rw-r--r--src/org/jetbrains/java/decompiler/struct/attr/StructAnnDefaultAttribute.java52
-rw-r--r--src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java337
-rw-r--r--src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationParameterAttribute.java83
-rw-r--r--src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationTypeAttribute.java369
-rw-r--r--src/org/jetbrains/java/decompiler/struct/attr/StructBootstrapMethodsAttribute.java117
-rw-r--r--src/org/jetbrains/java/decompiler/struct/attr/StructConstantValueAttribute.java39
-rw-r--r--src/org/jetbrains/java/decompiler/struct/attr/StructEnclosingMethodAttribute.java87
-rw-r--r--src/org/jetbrains/java/decompiler/struct/attr/StructExceptionsAttribute.java122
-rw-r--r--src/org/jetbrains/java/decompiler/struct/attr/StructGeneralAttribute.java252
-rw-r--r--src/org/jetbrains/java/decompiler/struct/attr/StructGenericSignatureAttribute.java39
-rw-r--r--src/org/jetbrains/java/decompiler/struct/attr/StructInnerClassesAttribute.java117
-rw-r--r--src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTableAttribute.java71
-rw-r--r--src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java602
-rw-r--r--src/org/jetbrains/java/decompiler/struct/consts/LinkConstant.java283
-rw-r--r--src/org/jetbrains/java/decompiler/struct/consts/PooledConstant.java189
-rw-r--r--src/org/jetbrains/java/decompiler/struct/consts/PrimitiveConstant.java218
-rw-r--r--src/org/jetbrains/java/decompiler/struct/consts/VariableTypeEnum.java74
-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
-rw-r--r--src/org/jetbrains/java/decompiler/struct/lazy/LazyLoader.java340
34 files changed, 4203 insertions, 4141 deletions
diff --git a/src/org/jetbrains/java/decompiler/struct/ContextUnit.java b/src/org/jetbrains/java/decompiler/struct/ContextUnit.java
index d859b29..c942e76 100644
--- a/src/org/jetbrains/java/decompiler/struct/ContextUnit.java
+++ b/src/org/jetbrains/java/decompiler/struct/ContextUnit.java
@@ -1,210 +1,210 @@
/*
- * 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;
+import org.jetbrains.java.decompiler.main.extern.IDecompilatSaver;
+import org.jetbrains.java.decompiler.struct.lazy.LazyLoader;
+import org.jetbrains.java.decompiler.struct.lazy.LazyLoader.Link;
+
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.Manifest;
-import org.jetbrains.java.decompiler.main.extern.IDecompilatSaver;
-import org.jetbrains.java.decompiler.struct.lazy.LazyLoader;
-import org.jetbrains.java.decompiler.struct.lazy.LazyLoader.Link;
-
public class ContextUnit {
-
- public static final int TYPE_FOLDER = 0;
- public static final int TYPE_JAR = 1;
- public static final int TYPE_ZIP = 2;
-
- private static final String MANIFEST_ENTRY = "META-INF/MANIFEST.MF";
-
- // *****************************************************************************
- // private fields
- // *****************************************************************************
-
- private int type;
-
- // relative path to jar/zip
- private String archivepath;
-
- // folder: relative path
- // archive: file name
- private String filename;
-
- private List<StructClass> classes = new ArrayList<StructClass>();
-
- // class file or jar/zip entry. Should, but doesn't have to be the same as qualifiedName of the class
- private List<String> classentries = new ArrayList<String>();
-
- private List<String> direntries = new ArrayList<String>();
-
- private List<String[]> otherentries = new ArrayList<String[]>();
-
- private Manifest manifest;
-
- private IDecompilatSaver decompilatSaver;
-
- private IDecompiledData decompiledData;
-
- private boolean own = true;
-
- // *****************************************************************************
- // constructors
- // *****************************************************************************
-
- public ContextUnit(int type, String archivepath, String filename, boolean own,
- IDecompilatSaver decompilatSaver, IDecompiledData decompiledData) {
- this.type = type;
- this.own = own;
- this.archivepath = archivepath;
- this.filename = filename;
- this.decompilatSaver = decompilatSaver;
- this.decompiledData = decompiledData;
- }
-
- // *****************************************************************************
- // public methods
- // *****************************************************************************
-
- public void addClass(StructClass cl, String entryname) {
- classes.add(cl);
- classentries.add(entryname);
- }
-
- public void addDirEntry(String entry) {
- direntries.add(entry);
- }
-
- public void addOtherEntry(String fullpath, String entry) {
- otherentries.add(new String[]{fullpath, entry});
- }
-
- public void reload(LazyLoader loader) throws IOException {
-
- List<StructClass> lstClasses = new ArrayList<StructClass>();
- for(StructClass cl : classes) {
- String oldname = cl.qualifiedName;
- StructClass newcl = new StructClass(loader.getClassStream(oldname), cl.isOwn(), loader);
-
- lstClasses.add(newcl);
-
- Link lnk = loader.getClassLink(oldname);
- loader.removeClassLink(oldname);
- loader.addClassLink(newcl.qualifiedName, lnk);
- }
-
- classes = lstClasses;
- }
-
- public void save() {
-
- switch(type) {
- case TYPE_FOLDER:
-
- // create folder
- decompilatSaver.saveFolder(filename);
-
- // non-class files
- for(String[] arr: otherentries) {
- decompilatSaver.copyFile(arr[0], filename, arr[0]);
- }
-
- // classes
- for(int i=0;i<classes.size();i++) {
-
- StructClass cl = classes.get(i);
- String entryname = classentries.get(i);
-
- entryname = decompiledData.getClassEntryName(cl, entryname);
- if(entryname != null) {
- String content = decompiledData.getClassContent(cl);
- if(content != null) {
- decompilatSaver.saveClassFile(filename, cl.qualifiedName, entryname, content);
- }
- }
- }
-
- break;
- case TYPE_JAR:
- case TYPE_ZIP:
-
- // create archive file
- decompilatSaver.saveFolder(archivepath);
- decompilatSaver.createArchive(archivepath, filename, manifest);
-
- // directory entries
- for(String direntry: direntries) {
- decompilatSaver.saveEntry(archivepath, filename, direntry, null);
- }
-
- // non-class entries
- for(String[] arr: otherentries) {
- // manifest was defined by constructor invocation
- if(type != TYPE_JAR || !MANIFEST_ENTRY.equalsIgnoreCase(arr[1])) {
- decompilatSaver.copyEntry(arr[0], archivepath, filename, arr[1]);
- }
- }
-
- // classes
- for(int i=0;i<classes.size();i++) {
-
- StructClass cl = classes.get(i);
- String entryname = classentries.get(i);
-
- entryname = decompiledData.getClassEntryName(cl, entryname);
- if(entryname != null) {
- String content = decompiledData.getClassContent(cl);
- decompilatSaver.saveClassEntry(archivepath, filename, cl.qualifiedName, entryname, content);
- }
- }
-
- decompilatSaver.closeArchive(archivepath, filename);
- }
- }
-
- // *****************************************************************************
- // private methods
- // *****************************************************************************
-
- // *****************************************************************************
- // getter and setter methods
- // *****************************************************************************
-
- public void setManifest(Manifest manifest) {
- this.manifest = manifest;
- }
-
- public boolean isOwn() {
- return own;
- }
-
- public List<StructClass> getClasses() {
- return classes;
- }
-
- public int getType() {
- return type;
- }
-
- public void setDecompilatSaver(IDecompilatSaver decompilatSaver) {
- this.decompilatSaver = decompilatSaver;
- }
-
- public void setDecompiledData(IDecompiledData decompiledData) {
- this.decompiledData = decompiledData;
- }
+ public static final int TYPE_FOLDER = 0;
+ public static final int TYPE_JAR = 1;
+ public static final int TYPE_ZIP = 2;
+
+ private static final String MANIFEST_ENTRY = "META-INF/MANIFEST.MF";
+
+ // *****************************************************************************
+ // private fields
+ // *****************************************************************************
+
+ private int type;
+
+ // relative path to jar/zip
+ private String archivepath;
+
+ // folder: relative path
+ // archive: file name
+ private String filename;
+
+ private List<StructClass> classes = new ArrayList<StructClass>();
+
+ // class file or jar/zip entry. Should, but doesn't have to be the same as qualifiedName of the class
+ private List<String> classentries = new ArrayList<String>();
+
+ private List<String> direntries = new ArrayList<String>();
+
+ private List<String[]> otherentries = new ArrayList<String[]>();
+
+ private Manifest manifest;
+
+ private IDecompilatSaver decompilatSaver;
+
+ private IDecompiledData decompiledData;
+
+ private boolean own = true;
+
+ // *****************************************************************************
+ // constructors
+ // *****************************************************************************
+
+ public ContextUnit(int type, String archivepath, String filename, boolean own,
+ IDecompilatSaver decompilatSaver, IDecompiledData decompiledData) {
+ this.type = type;
+ this.own = own;
+ this.archivepath = archivepath;
+ this.filename = filename;
+ this.decompilatSaver = decompilatSaver;
+ this.decompiledData = decompiledData;
+ }
+
+ // *****************************************************************************
+ // public methods
+ // *****************************************************************************
+
+ public void addClass(StructClass cl, String entryname) {
+ classes.add(cl);
+ classentries.add(entryname);
+ }
+
+ public void addDirEntry(String entry) {
+ direntries.add(entry);
+ }
+
+ public void addOtherEntry(String fullpath, String entry) {
+ otherentries.add(new String[]{fullpath, entry});
+ }
+
+ public void reload(LazyLoader loader) throws IOException {
+
+ List<StructClass> lstClasses = new ArrayList<StructClass>();
+ for (StructClass cl : classes) {
+ String oldname = cl.qualifiedName;
+ StructClass newcl = new StructClass(loader.getClassStream(oldname), cl.isOwn(), loader);
+
+ lstClasses.add(newcl);
+
+ Link lnk = loader.getClassLink(oldname);
+ loader.removeClassLink(oldname);
+ loader.addClassLink(newcl.qualifiedName, lnk);
+ }
+
+ classes = lstClasses;
+ }
+
+ public void save() {
+
+ switch (type) {
+ case TYPE_FOLDER:
+
+ // create folder
+ decompilatSaver.saveFolder(filename);
+
+ // non-class files
+ for (String[] arr : otherentries) {
+ decompilatSaver.copyFile(arr[0], filename, arr[0]);
+ }
+
+ // classes
+ for (int i = 0; i < classes.size(); i++) {
+
+ StructClass cl = classes.get(i);
+ String entryname = classentries.get(i);
+
+ entryname = decompiledData.getClassEntryName(cl, entryname);
+ if (entryname != null) {
+ String content = decompiledData.getClassContent(cl);
+ if (content != null) {
+ decompilatSaver.saveClassFile(filename, cl.qualifiedName, entryname, content);
+ }
+ }
+ }
+
+ break;
+ case TYPE_JAR:
+ case TYPE_ZIP:
+
+ // create archive file
+ decompilatSaver.saveFolder(archivepath);
+ decompilatSaver.createArchive(archivepath, filename, manifest);
+
+ // directory entries
+ for (String direntry : direntries) {
+ decompilatSaver.saveEntry(archivepath, filename, direntry, null);
+ }
+
+ // non-class entries
+ for (String[] arr : otherentries) {
+ // manifest was defined by constructor invocation
+ if (type != TYPE_JAR || !MANIFEST_ENTRY.equalsIgnoreCase(arr[1])) {
+ decompilatSaver.copyEntry(arr[0], archivepath, filename, arr[1]);
+ }
+ }
+
+ // classes
+ for (int i = 0; i < classes.size(); i++) {
+
+ StructClass cl = classes.get(i);
+ String entryname = classentries.get(i);
+
+ entryname = decompiledData.getClassEntryName(cl, entryname);
+ if (entryname != null) {
+ String content = decompiledData.getClassContent(cl);
+ decompilatSaver.saveClassEntry(archivepath, filename, cl.qualifiedName, entryname, content);
+ }
+ }
+
+ decompilatSaver.closeArchive(archivepath, filename);
+ }
+ }
+
+ // *****************************************************************************
+ // private methods
+ // *****************************************************************************
+
+ // *****************************************************************************
+ // getter and setter methods
+ // *****************************************************************************
+
+ public void setManifest(Manifest manifest) {
+ this.manifest = manifest;
+ }
+
+ public boolean isOwn() {
+ return own;
+ }
+
+ public List<StructClass> getClasses() {
+ return classes;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public void setDecompilatSaver(IDecompilatSaver decompilatSaver) {
+ this.decompilatSaver = decompilatSaver;
+ }
+
+ public void setDecompiledData(IDecompiledData decompiledData) {
+ this.decompiledData = decompiledData;
+ }
}
diff --git a/src/org/jetbrains/java/decompiler/struct/IDecompiledData.java b/src/org/jetbrains/java/decompiler/struct/IDecompiledData.java
index 9c8bc14..1976216 100644
--- a/src/org/jetbrains/java/decompiler/struct/IDecompiledData.java
+++ b/src/org/jetbrains/java/decompiler/struct/IDecompiledData.java
@@ -1,23 +1,23 @@
/*
- * 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;
public interface IDecompiledData {
- public String getClassEntryName(StructClass cl, String entryname);
+ public String getClassEntryName(StructClass cl, String entryname);
- public String getClassContent(StructClass cl);
-
+ public String getClassContent(StructClass cl);
}
diff --git a/src/org/jetbrains/java/decompiler/struct/ISaveClass.java b/src/org/jetbrains/java/decompiler/struct/ISaveClass.java
index 6fbfb9c..69a90f9 100644
--- a/src/org/jetbrains/java/decompiler/struct/ISaveClass.java
+++ b/src/org/jetbrains/java/decompiler/struct/ISaveClass.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;
import java.io.DataOutputStream;
@@ -21,10 +22,9 @@ import java.io.IOException;
public interface ISaveClass {
- public String getClassEntryName(StructClass cl, String entryname);
-
- public void saveClassToFile(StructClass cl, File file) throws FileNotFoundException, IOException;
+ public String getClassEntryName(StructClass cl, String entryname);
+
+ public void saveClassToFile(StructClass cl, File file) throws FileNotFoundException, IOException;
- public void saveClassToStream(StructClass cl, DataOutputStream out);
-
+ public void saveClassToStream(StructClass cl, DataOutputStream out);
}
diff --git a/src/org/jetbrains/java/decompiler/struct/StructClass.java b/src/org/jetbrains/java/decompiler/struct/StructClass.java
index 456cc70..19946a0 100644
--- a/src/org/jetbrains/java/decompiler/struct/StructClass.java
+++ b/src/org/jetbrains/java/decompiler/struct/StructClass.java
@@ -1,27 +1,20 @@
/*
- * 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;
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
import org.jetbrains.java.decompiler.code.CodeConstants;
import org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute;
import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
@@ -31,6 +24,8 @@ import org.jetbrains.java.decompiler.util.DataInputFullStream;
import org.jetbrains.java.decompiler.util.InterpreterUtil;
import org.jetbrains.java.decompiler.util.VBStyleCollection;
+import java.io.*;
+
/*
ClassFile {
u4 magic;
@@ -54,299 +49,298 @@ import org.jetbrains.java.decompiler.util.VBStyleCollection;
public class StructClass {
- // *****************************************************************************
- // public fields
- // *****************************************************************************
-
- public int minor_version;
-
- public int major_version;
-
- public int access_flags;
-
- public int this_class;
-
- public int super_class;
-
- public PrimitiveConstant thisClass;
-
- public PrimitiveConstant superClass;
-
- public String qualifiedName;
-
-
- // *****************************************************************************
- // private fields
- // *****************************************************************************
-
- private ConstantPool pool;
-
- private int[] interfaces;
-
- private String[] interfaceNames;
-
- private VBStyleCollection<StructField, String> fields = new VBStyleCollection<StructField, String>();
-
- private VBStyleCollection<StructMethod, String> methods = new VBStyleCollection<StructMethod, String>();
-
- private VBStyleCollection<StructGeneralAttribute, String> attributes = new VBStyleCollection<StructGeneralAttribute, String>();
-
- private boolean own = true;
-
- private LazyLoader loader;
-
- // *****************************************************************************
- // constructors
- // *****************************************************************************
-
- public StructClass(String filename, boolean own, LazyLoader loader) throws FileNotFoundException, IOException {
- this(new FileInputStream(filename), own, loader);
- }
-
- public StructClass(InputStream inStream, boolean own, LazyLoader loader) throws FileNotFoundException, IOException {
- this(new DataInputFullStream(inStream), own, loader);
- }
-
- public StructClass(DataInputFullStream inStream, boolean own, LazyLoader loader) throws FileNotFoundException, IOException {
- this.own = own;
- this.loader = loader;
-
- initStruct(inStream);
- }
-
- // *****************************************************************************
- // public methods
- // *****************************************************************************
-
- public boolean hasField(String name, String descriptor) {
- return getField(name, descriptor) != null;
- }
-
- public StructField getField(String name, String descriptor) {
- return fields.getWithKey(InterpreterUtil.makeUniqueKey(name, descriptor));
- }
-
- public StructMethod getMethod(String key) {
- return methods.getWithKey(key);
- }
-
- public StructMethod getMethod(String name, String descriptor) {
- return methods.getWithKey(InterpreterUtil.makeUniqueKey(name, descriptor));
- }
-
- public void writeToFile(File file) throws IOException {
- DataOutputStream out = new DataOutputStream(new FileOutputStream(file));
- writeToOutputStream(out);
- out.close();
- }
-
- public void writeToOutputStream(DataOutputStream out) throws IOException {
-
- out.writeInt(0xCAFEBABE);
- out.writeShort(minor_version);
- out.writeShort(major_version);
-
- getPool().writeToOutputStream(out);
-
- out.writeShort(access_flags);
- out.writeShort(this_class);
- out.writeShort(super_class);
-
- out.writeShort(interfaces.length);
- for(int i=0;i<interfaces.length;i++) {
- out.writeShort(interfaces[i]);
- }
-
- out.writeShort(fields.size());
- for(int i=0;i<fields.size();i++) {
- fields.get(i).writeToStream(out);
- }
-
- out.writeShort(methods.size());
- for(int i=0;i<methods.size();i++) {
- methods.get(i).writeToStream(out);
- }
-
- out.writeShort(attributes.size());
- for(StructGeneralAttribute attr: attributes) {
- attr.writeToStream(out);
- }
-
- }
-
- public String getInterface(int i) {
- return interfaceNames[i];
- }
-
- public void releaseResources() {
- if(loader != null) {
- pool = null;
- }
- }
-
- // *****************************************************************************
- // private methods
- // *****************************************************************************
-
- private void initStruct(DataInputFullStream in) throws IOException {
-
- in.skip(4);
-
- this.minor_version = in.readUnsignedShort();
- this.major_version = in.readUnsignedShort();
-
- pool = new ConstantPool(in);
-
- this.access_flags = in.readUnsignedShort();
-
- this_class = in.readUnsignedShort();
- thisClass = pool.getPrimitiveConstant(this_class);
- qualifiedName = thisClass.getString();
-
- super_class = in.readUnsignedShort();
- superClass = pool.getPrimitiveConstant(super_class);
-
- // interfaces
- int length = in.readUnsignedShort();
- int[] arrInterfaces = new int[length];
- String[] arrInterfaceNames = new String[length];
-
- for (int i = 0; i < length; i++) {
- arrInterfaces[i] = in.readUnsignedShort();
- arrInterfaceNames[i] = pool.getPrimitiveConstant(arrInterfaces[i]).getString();
- }
- this.interfaces = arrInterfaces;
- this.interfaceNames = arrInterfaceNames;
-
- // fields
- VBStyleCollection<StructField, String> lstFields = new VBStyleCollection<StructField, String>();
- length = in.readUnsignedShort();
- for (int i = 0; i < length; i++) {
- StructField field = new StructField();
- field.access_flags = in.readUnsignedShort();
- field.name_index = in.readUnsignedShort();
- field.descriptor_index = in.readUnsignedShort();
-
- field.initStrings(pool, this_class);
-
- field.setAttributes(readAttributes(in));
-
- lstFields.addWithKey(field, InterpreterUtil.makeUniqueKey(field.getName(), field.getDescriptor()));
- }
- this.fields = lstFields;
-
- // methods
- length = in.readUnsignedShort();
- for (int i = 0; i < length; i++) {
- StructMethod meth = new StructMethod(in, own, this);
-
- //if(qualifiedName.endsWith("JUnitStatusLine") && !meth.getName().equals("onProcessStarted") && !meth.getName().startsWith("access")) {
- //if(!meth.getName().equals("run")) {
- // continue;
- //}
-
- methods.addWithKey(meth, InterpreterUtil.makeUniqueKey(meth.getName(), meth.getDescriptor()));
- }
-
- // attributes
- this.attributes = readAttributes(in);
-
-
- // release memory
- if(loader != null) {
- pool = null;
- }
- }
-
- private VBStyleCollection<StructGeneralAttribute, String> readAttributes(DataInputFullStream in) throws IOException {
-
- VBStyleCollection<StructGeneralAttribute, String> lstAttribute = new VBStyleCollection<StructGeneralAttribute, String>();
-
- int length = in.readUnsignedShort();
- for (int i = 0; i < length; i++) {
- int attr_nameindex = in.readUnsignedShort();
- String attrname = pool.getPrimitiveConstant(attr_nameindex).getString();
-
- StructGeneralAttribute attr = StructGeneralAttribute.getMatchingAttributeInstance(attr_nameindex, attrname);
-
- if(attr != null) {
- byte[] arr = new byte[in.readInt()];
- in.readFull(arr);
- attr.setInfo(arr);
-
- attr.initContent(pool);
- lstAttribute.addWithKey(attr, attr.getName());
- } else {
- in.skip(in.readInt());
- }
- }
-
- return lstAttribute;
- }
-
-
-
- // *****************************************************************************
- // getter and setter methods
- // *****************************************************************************
-
- public ConstantPool getPool() {
-
- if(pool == null && loader != null) {
- pool = loader.loadPool(qualifiedName);
- }
-
- return pool;
- }
-
- public int[] getInterfaces() {
- return interfaces;
- }
-
- public String[] getInterfaceNames() {
- return interfaceNames;
- }
-
- public VBStyleCollection<StructMethod, String> getMethods() {
- return methods;
- }
-
- public VBStyleCollection<StructField, String> getFields() {
- return fields;
- }
-
- public VBStyleCollection<StructGeneralAttribute, String> getAttributes() {
- return attributes;
- }
-
- public boolean isOwn() {
- return own;
- }
-
- public LazyLoader getLoader() {
- return loader;
- }
-
- public boolean isVersionGE_1_5() {
- return (major_version > 48 || (major_version == 48 && minor_version > 0)); // FIXME: check second condition
- }
-
- public boolean isVersionGE_1_7() {
- return (major_version >= 51);
- }
-
- public int getBytecodeVersion() {
- switch(major_version) {
- case 52:
- return CodeConstants.BYTECODE_JAVA_8;
- case 51:
- return CodeConstants.BYTECODE_JAVA_7;
- case 50:
- return CodeConstants.BYTECODE_JAVA_6;
- case 49:
- return CodeConstants.BYTECODE_JAVA_5;
- }
-
- return CodeConstants.BYTECODE_JAVA_LE_4;
- }
+ // *****************************************************************************
+ // public fields
+ // *****************************************************************************
+
+ public int minor_version;
+
+ public int major_version;
+
+ public int access_flags;
+
+ public int this_class;
+
+ public int super_class;
+
+ public PrimitiveConstant thisClass;
+
+ public PrimitiveConstant superClass;
+
+ public String qualifiedName;
+
+
+ // *****************************************************************************
+ // private fields
+ // *****************************************************************************
+
+ private ConstantPool pool;
+
+ private int[] interfaces;
+
+ private String[] interfaceNames;
+
+ private VBStyleCollection<StructField, String> fields = new VBStyleCollection<StructField, String>();
+
+ private VBStyleCollection<StructMethod, String> methods = new VBStyleCollection<StructMethod, String>();
+
+ private VBStyleCollection<StructGeneralAttribute, String> attributes = new VBStyleCollection<StructGeneralAttribute, String>();
+
+ private boolean own = true;
+
+ private LazyLoader loader;
+
+ // *****************************************************************************
+ // constructors
+ // *****************************************************************************
+
+ public StructClass(String filename, boolean own, LazyLoader loader) throws FileNotFoundException, IOException {
+ this(new FileInputStream(filename), own, loader);
+ }
+
+ public StructClass(InputStream inStream, boolean own, LazyLoader loader) throws FileNotFoundException, IOException {
+ this(new DataInputFullStream(inStream), own, loader);
+ }
+
+ public StructClass(DataInputFullStream inStream, boolean own, LazyLoader loader) throws FileNotFoundException, IOException {
+ this.own = own;
+ this.loader = loader;
+
+ initStruct(inStream);
+ }
+
+ // *****************************************************************************
+ // public methods
+ // *****************************************************************************
+
+ public boolean hasField(String name, String descriptor) {
+ return getField(name, descriptor) != null;
+ }
+
+ public StructField getField(String name, String descriptor) {
+ return fields.getWithKey(InterpreterUtil.makeUniqueKey(name, descriptor));
+ }
+
+ public StructMethod getMethod(String key) {
+ return methods.getWithKey(key);
+ }
+
+ public StructMethod getMethod(String name, String descriptor) {
+ return methods.getWithKey(InterpreterUtil.makeUniqueKey(name, descriptor));
+ }
+
+ public void writeToFile(File file) throws IOException {
+ DataOutputStream out = new DataOutputStream(new FileOutputStream(file));
+ writeToOutputStream(out);
+ out.close();
+ }
+
+ public void writeToOutputStream(DataOutputStream out) throws IOException {
+
+ out.writeInt(0xCAFEBABE);
+ out.writeShort(minor_version);
+ out.writeShort(major_version);
+
+ getPool().writeToOutputStream(out);
+
+ out.writeShort(access_flags);
+ out.writeShort(this_class);
+ out.writeShort(super_class);
+
+ out.writeShort(interfaces.length);
+ for (int i = 0; i < interfaces.length; i++) {
+ out.writeShort(interfaces[i]);
+ }
+
+ out.writeShort(fields.size());
+ for (int i = 0; i < fields.size(); i++) {
+ fields.get(i).writeToStream(out);
+ }
+
+ out.writeShort(methods.size());
+ for (int i = 0; i < methods.size(); i++) {
+ methods.get(i).writeToStream(out);
+ }
+
+ out.writeShort(attributes.size());
+ for (StructGeneralAttribute attr : attributes) {
+ attr.writeToStream(out);
+ }
+ }
+
+ public String getInterface(int i) {
+ return interfaceNames[i];
+ }
+
+ public void releaseResources() {
+ if (loader != null) {
+ pool = null;
+ }
+ }
+
+ // *****************************************************************************
+ // private methods
+ // *****************************************************************************
+
+ private void initStruct(DataInputFullStream in) throws IOException {
+
+ in.skip(4);
+
+ this.minor_version = in.readUnsignedShort();
+ this.major_version = in.readUnsignedShort();
+
+ pool = new ConstantPool(in);
+
+ this.access_flags = in.readUnsignedShort();
+
+ this_class = in.readUnsignedShort();
+ thisClass = pool.getPrimitiveConstant(this_class);
+ qualifiedName = thisClass.getString();
+
+ super_class = in.readUnsignedShort();
+ superClass = pool.getPrimitiveConstant(super_class);
+
+ // interfaces
+ int length = in.readUnsignedShort();
+ int[] arrInterfaces = new int[length];
+ String[] arrInterfaceNames = new String[length];
+
+ for (int i = 0; i < length; i++) {
+ arrInterfaces[i] = in.readUnsignedShort();
+ arrInterfaceNames[i] = pool.getPrimitiveConstant(arrInterfaces[i]).getString();
+ }
+ this.interfaces = arrInterfaces;
+ this.interfaceNames = arrInterfaceNames;
+
+ // fields
+ VBStyleCollection<StructField, String> lstFields = new VBStyleCollection<StructField, String>();
+ length = in.readUnsignedShort();
+ for (int i = 0; i < length; i++) {
+ StructField field = new StructField();
+ field.access_flags = in.readUnsignedShort();
+ field.name_index = in.readUnsignedShort();
+ field.descriptor_index = in.readUnsignedShort();
+
+ field.initStrings(pool, this_class);
+
+ field.setAttributes(readAttributes(in));
+
+ lstFields.addWithKey(field, InterpreterUtil.makeUniqueKey(field.getName(), field.getDescriptor()));
+ }
+ this.fields = lstFields;
+
+ // methods
+ length = in.readUnsignedShort();
+ for (int i = 0; i < length; i++) {
+ StructMethod meth = new StructMethod(in, own, this);
+
+ //if(qualifiedName.endsWith("JUnitStatusLine") && !meth.getName().equals("onProcessStarted") && !meth.getName().startsWith("access")) {
+ //if(!meth.getName().equals("run")) {
+ // continue;
+ //}
+
+ methods.addWithKey(meth, InterpreterUtil.makeUniqueKey(meth.getName(), meth.getDescriptor()));
+ }
+
+ // attributes
+ this.attributes = readAttributes(in);
+
+
+ // release memory
+ if (loader != null) {
+ pool = null;
+ }
+ }
+
+ private VBStyleCollection<StructGeneralAttribute, String> readAttributes(DataInputFullStream in) throws IOException {
+
+ VBStyleCollection<StructGeneralAttribute, String> lstAttribute = new VBStyleCollection<StructGeneralAttribute, String>();
+
+ int length = in.readUnsignedShort();
+ for (int i = 0; i < length; i++) {
+ int attr_nameindex = in.readUnsignedShort();
+ String attrname = pool.getPrimitiveConstant(attr_nameindex).getString();
+
+ StructGeneralAttribute attr = StructGeneralAttribute.getMatchingAttributeInstance(attr_nameindex, attrname);
+
+ if (attr != null) {
+ byte[] arr = new byte[in.readInt()];
+ in.readFull(arr);
+ attr.setInfo(arr);
+
+ attr.initContent(pool);
+ lstAttribute.addWithKey(attr, attr.getName());
+ }
+ else {
+ in.skip(in.readInt());
+ }
+ }
+
+ return lstAttribute;
+ }
+
+
+ // *****************************************************************************
+ // getter and setter methods
+ // *****************************************************************************
+
+ public ConstantPool getPool() {
+
+ if (pool == null && loader != null) {
+ pool = loader.loadPool(qualifiedName);
+ }
+
+ return pool;
+ }
+
+ public int[] getInterfaces() {
+ return interfaces;
+ }
+
+ public String[] getInterfaceNames() {
+ return interfaceNames;
+ }
+
+ public VBStyleCollection<StructMethod, String> getMethods() {
+ return methods;
+ }
+
+ public VBStyleCollection<StructField, String> getFields() {
+ return fields;
+ }
+
+ public VBStyleCollection<StructGeneralAttribute, String> getAttributes() {
+ return attributes;
+ }
+
+ public boolean isOwn() {
+ return own;
+ }
+
+ public LazyLoader getLoader() {
+ return loader;
+ }
+
+ public boolean isVersionGE_1_5() {
+ return (major_version > 48 || (major_version == 48 && minor_version > 0)); // FIXME: check second condition
+ }
+
+ public boolean isVersionGE_1_7() {
+ return (major_version >= 51);
+ }
+
+ public int getBytecodeVersion() {
+ switch (major_version) {
+ case 52:
+ return CodeConstants.BYTECODE_JAVA_8;
+ case 51:
+ return CodeConstants.BYTECODE_JAVA_7;
+ case 50:
+ return CodeConstants.BYTECODE_JAVA_6;
+ case 49:
+ return CodeConstants.BYTECODE_JAVA_5;
+ }
+
+ return CodeConstants.BYTECODE_JAVA_LE_4;
+ }
}
diff --git a/src/org/jetbrains/java/decompiler/struct/StructContext.java b/src/org/jetbrains/java/decompiler/struct/StructContext.java
index c253a10..3728a2a 100644
--- a/src/org/jetbrains/java/decompiler/struct/StructContext.java
+++ b/src/org/jetbrains/java/decompiler/struct/StructContext.java
@@ -1,19 +1,25 @@
/*
- * 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;
+import org.jetbrains.java.decompiler.main.DecompilerContext;
+import org.jetbrains.java.decompiler.main.extern.IDecompilatSaver;
+import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger;
+import org.jetbrains.java.decompiler.struct.lazy.LazyLoader;
+
import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
@@ -22,190 +28,189 @@ import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
-import org.jetbrains.java.decompiler.main.DecompilerContext;
-import org.jetbrains.java.decompiler.main.extern.IDecompilatSaver;
-import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger;
-import org.jetbrains.java.decompiler.struct.lazy.LazyLoader;
-
public class StructContext {
- // *****************************************************************************
- // private fields
- // *****************************************************************************
-
- private LazyLoader loader;
-
- private HashMap<String, StructClass> classes = new HashMap<String, StructClass>();
-
- private HashMap<String, ContextUnit> units = new HashMap<String, ContextUnit>();
-
- private ContextUnit defaultUnit;
-
- private IDecompilatSaver saver;
-
- private IDecompiledData decdata;
-
- public StructContext(IDecompilatSaver saver, IDecompiledData decdata, LazyLoader loader) {
-
- this.saver = saver;
- this.decdata = decdata;
- this.loader = loader;
-
- defaultUnit = new ContextUnit(ContextUnit.TYPE_FOLDER, null, "", true, saver, decdata);
- units.put("", defaultUnit);
- }
-
- // *****************************************************************************
- // public methods
- // *****************************************************************************
-
- public StructClass getClass(String name) {
- return classes.get(name);
- }
-
- public void reloadContext() throws IOException {
-
- for(ContextUnit unit: units.values()) {
-
- for(StructClass cl : unit.getClasses()) {
- classes.remove(cl.qualifiedName);
- }
-
- unit.reload(loader);
-
- // adjust lobal class collection
- for(StructClass cl : unit.getClasses()) {
- classes.put(cl.qualifiedName, cl);
- }
- }
- }
-
- public void saveContext() {
-
- for(ContextUnit unit: units.values()) {
- if(unit.isOwn()) {
- unit.save();
- }
- }
- }
-
- public void addSpace(File file, boolean isOwn) throws IOException {
- addSpace("", file, isOwn);
- }
-
- private void addSpace(String path, File file, boolean isOwn) throws IOException {
-
- if(file.isDirectory()) {
-
- File[] files = file.listFiles();
- path += "/" + (path.length()==0?"":file.getName());
-
- for(int i=files.length-1;i>=0;i--) {
- addSpace(path, files[i], isOwn);
- }
-
- } else {
-
- String filename = file.getName();
-
- boolean isArchive = false;
-
- try {
- if(filename.endsWith(".jar")) {
- addArchive(path, file, ContextUnit.TYPE_JAR, isOwn);
- isArchive = true;
- } else if(filename.endsWith(".zip")) {
- addArchive(path, file, ContextUnit.TYPE_ZIP, isOwn);
- isArchive = true;
- }
- } catch(IOException ex) {
- DecompilerContext.getLogger()
- .writeMessage("Invalid archive file: "+(path.length()>0?path+"/":"")+filename, IFernflowerLogger.ERROR);
- }
-
- if(!isArchive) {
- ContextUnit unit = units.get(path);
- if(unit == null) {
- unit = new ContextUnit(ContextUnit.TYPE_FOLDER, null, path, isOwn, saver, decdata);
- units.put(path, unit);
- }
-
- boolean isClass = false;
-
- if(filename.endsWith(".class")) {
- try {
- StructClass cl = new StructClass(loader.getClassStream(file.getAbsolutePath(), null), isOwn, loader);
-
- classes.put(cl.qualifiedName, cl);
- unit.addClass(cl, filename);
- loader.addClassLink(cl.qualifiedName, new LazyLoader.Link(LazyLoader.Link.CLASS, file.getAbsolutePath(), null));
-
- isClass = true;
- } catch(IOException ex) {
- DecompilerContext.getLogger()
- .writeMessage("Invalid class file: "+(path.length()>0?path+"/":"")+filename, IFernflowerLogger.ERROR);
- }
- }
-
- if(!isClass) {
- unit.addOtherEntry(file.getAbsolutePath(), filename);
- }
- }
- }
- }
-
-
- private void addArchive(String path, File file, int type, boolean isOwn) throws IOException {
-
- ZipFile archive;
-
- if(type == ContextUnit.TYPE_JAR) { // jar
- archive = new JarFile(file);
- } else { // zip
- archive = new ZipFile(file);
- }
-
- Enumeration<? extends ZipEntry> en = archive.entries();
- while(en.hasMoreElements()) {
- ZipEntry entr = en.nextElement();
-
- ContextUnit unit = units.get(path+"/"+file.getName());
- if(unit == null) {
- unit = new ContextUnit(type, path, file.getName(), isOwn, saver, decdata);
- if(type == ContextUnit.TYPE_JAR) {
- unit.setManifest(((JarFile)archive).getManifest());
- }
- units.put(path+"/"+file.getName(), unit);
- }
-
- String name = entr.getName();
- if(!entr.isDirectory()) {
- if(name.endsWith(".class")) {
- StructClass cl = new StructClass(archive.getInputStream(entr), isOwn, loader);
- classes.put(cl.qualifiedName, cl);
-
- unit.addClass(cl, name);
-
- if(loader != null) {
- loader.addClassLink(cl.qualifiedName, new LazyLoader.Link(LazyLoader.Link.ENTRY, file.getAbsolutePath(), name));
- }
-
- } else {
- unit.addOtherEntry(file.getAbsolutePath(), name);
- }
- } else if(entr.isDirectory()) {
- unit.addDirEntry(name);
- }
- }
- }
-
- // *****************************************************************************
- // getter and setter methods
- // *****************************************************************************
-
- public HashMap<String, StructClass> getClasses() {
- return classes;
- }
+ // *****************************************************************************
+ // private fields
+ // *****************************************************************************
+
+ private LazyLoader loader;
+
+ private HashMap<String, StructClass> classes = new HashMap<String, StructClass>();
+
+ private HashMap<String, ContextUnit> units = new HashMap<String, ContextUnit>();
+
+ private ContextUnit defaultUnit;
+
+ private IDecompilatSaver saver;
+
+ private IDecompiledData decdata;
+
+ public StructContext(IDecompilatSaver saver, IDecompiledData decdata, LazyLoader loader) {
+
+ this.saver = saver;
+ this.decdata = decdata;
+ this.loader = loader;
+
+ defaultUnit = new ContextUnit(ContextUnit.TYPE_FOLDER, null, "", true, saver, decdata);
+ units.put("", defaultUnit);
+ }
+
+ // *****************************************************************************
+ // public methods
+ // *****************************************************************************
+
+ public StructClass getClass(String name) {
+ return classes.get(name);
+ }
+
+ public void reloadContext() throws IOException {
+
+ for (ContextUnit unit : units.values()) {
+
+ for (StructClass cl : unit.getClasses()) {
+ classes.remove(cl.qualifiedName);
+ }
+
+ unit.reload(loader);
+
+ // adjust lobal class collection
+ for (StructClass cl : unit.getClasses()) {
+ classes.put(cl.qualifiedName, cl);
+ }
+ }
+ }
+
+ public void saveContext() {
+
+ for (ContextUnit unit : units.values()) {
+ if (unit.isOwn()) {
+ unit.save();
+ }
+ }
+ }
+
+ public void addSpace(File file, boolean isOwn) throws IOException {
+ addSpace("", file, isOwn);
+ }
+
+ private void addSpace(String path, File file, boolean isOwn) throws IOException {
+
+ if (file.isDirectory()) {
+ File[] files = file.listFiles();
+ path += "/" + (path.length() == 0 ? "" : file.getName());
+
+ for (int i = files.length - 1; i >= 0; i--) {
+ addSpace(path, files[i], isOwn);
+ }
+ }
+ else {
+
+ String filename = file.getName();
+
+ boolean isArchive = false;
+
+ try {
+ if (filename.endsWith(".jar")) {
+ addArchive(path, file, ContextUnit.TYPE_JAR, isOwn);
+ isArchive = true;
+ }
+ else if (filename.endsWith(".zip")) {
+ addArchive(path, file, ContextUnit.TYPE_ZIP, isOwn);
+ isArchive = true;
+ }
+ }
+ catch (IOException ex) {
+ DecompilerContext.getLogger()
+ .writeMessage("Invalid archive file: " + (path.length() > 0 ? path + "/" : "") + filename, IFernflowerLogger.ERROR);
+ }
+
+ if (!isArchive) {
+ ContextUnit unit = units.get(path);
+ if (unit == null) {
+ unit = new ContextUnit(ContextUnit.TYPE_FOLDER, null, path, isOwn, saver, decdata);
+ units.put(path, unit);
+ }
+
+ boolean isClass = false;
+
+ if (filename.endsWith(".class")) {
+ try {
+ StructClass cl = new StructClass(loader.getClassStream(file.getAbsolutePath(), null), isOwn, loader);
+
+ classes.put(cl.qualifiedName, cl);
+ unit.addClass(cl, filename);
+ loader.addClassLink(cl.qualifiedName, new LazyLoader.Link(LazyLoader.Link.CLASS, file.getAbsolutePath(), null));
+
+ isClass = true;
+ }
+ catch (IOException ex) {
+ DecompilerContext.getLogger()
+ .writeMessage("Invalid class file: " + (path.length() > 0 ? path + "/" : "") + filename, IFernflowerLogger.ERROR);
+ }
+ }
+
+ if (!isClass) {
+ unit.addOtherEntry(file.getAbsolutePath(), filename);
+ }
+ }
+ }
+ }
+
+
+ private void addArchive(String path, File file, int type, boolean isOwn) throws IOException {
+
+ ZipFile archive;
+
+ if (type == ContextUnit.TYPE_JAR) { // jar
+ archive = new JarFile(file);
+ }
+ else { // zip
+ archive = new ZipFile(file);
+ }
+
+ Enumeration<? extends ZipEntry> en = archive.entries();
+ while (en.hasMoreElements()) {
+ ZipEntry entr = en.nextElement();
+
+ ContextUnit unit = units.get(path + "/" + file.getName());
+ if (unit == null) {
+ unit = new ContextUnit(type, path, file.getName(), isOwn, saver, decdata);
+ if (type == ContextUnit.TYPE_JAR) {
+ unit.setManifest(((JarFile)archive).getManifest());
+ }
+ units.put(path + "/" + file.getName(), unit);
+ }
+
+ String name = entr.getName();
+ if (!entr.isDirectory()) {
+ if (name.endsWith(".class")) {
+ StructClass cl = new StructClass(archive.getInputStream(entr), isOwn, loader);
+ classes.put(cl.qualifiedName, cl);
+
+ unit.addClass(cl, name);
+
+ if (loader != null) {
+ loader.addClassLink(cl.qualifiedName, new LazyLoader.Link(LazyLoader.Link.ENTRY, file.getAbsolutePath(), name));
+ }
+ }
+ else {
+ unit.addOtherEntry(file.getAbsolutePath(), name);
+ }
+ }
+ else if (entr.isDirectory()) {
+ unit.addDirEntry(name);
+ }
+ }
+ }
+
+ // *****************************************************************************
+ // getter and setter methods
+ // *****************************************************************************
+
+ public HashMap<String, StructClass> getClasses() {
+ return classes;
+ }
}
diff --git a/src/org/jetbrains/java/decompiler/struct/StructField.java b/src/org/jetbrains/java/decompiler/struct/StructField.java
index 2537e7b..4c0f25d 100644
--- a/src/org/jetbrains/java/decompiler/struct/StructField.java
+++ b/src/org/jetbrains/java/decompiler/struct/StructField.java
@@ -1,28 +1,29 @@
/*
- * 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;
-import java.io.DataOutputStream;
-import java.io.IOException;
-
import org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute;
import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
import org.jetbrains.java.decompiler.util.VBStyleCollection;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
/*
- field_info {
+ field_info {
u2 access_flags;
u2 name_index;
u2 descriptor_index;
@@ -33,77 +34,77 @@ import org.jetbrains.java.decompiler.util.VBStyleCollection;
public class StructField {
- // *****************************************************************************
- // public fields
- // *****************************************************************************
-
- public int access_flags;
- public int name_index;
- public int descriptor_index;
-
- private String name;
- private String descriptor;
-
- // *****************************************************************************
- // private fields
- // *****************************************************************************
-
- private VBStyleCollection<StructGeneralAttribute, String> attributes;
-
- // *****************************************************************************
- // constructors
- // *****************************************************************************
-
- public StructField() {}
-
- // *****************************************************************************
- // public methods
- // *****************************************************************************
-
- public void writeToStream(DataOutputStream out) throws IOException {
-
- out.writeShort(access_flags);
- out.writeShort(name_index);
- out.writeShort(descriptor_index);
-
- out.writeShort(attributes.size());
- for(StructGeneralAttribute attr: attributes) {
- attr.writeToStream(out);
- }
- }
-
- public void initStrings(ConstantPool pool, int class_index) {
- String[] values = pool.getClassElement(ConstantPool.FIELD, class_index, name_index, descriptor_index);
- name = values[0];
- descriptor = values[1];
- }
-
- // *****************************************************************************
- // getter and setter methods
- // *****************************************************************************
-
- public VBStyleCollection<StructGeneralAttribute, String> getAttributes() {
- return attributes;
- }
-
- public void setAttributes(VBStyleCollection<StructGeneralAttribute, String> attributes) {
- this.attributes = attributes;
- }
-
- public String getDescriptor() {
- return descriptor;
- }
-
- public void setDescriptor(String descriptor) {
- this.descriptor = descriptor;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
+ // *****************************************************************************
+ // public fields
+ // *****************************************************************************
+
+ public int access_flags;
+ public int name_index;
+ public int descriptor_index;
+
+ private String name;
+ private String descriptor;
+
+ // *****************************************************************************
+ // private fields
+ // *****************************************************************************
+
+ private VBStyleCollection<StructGeneralAttribute, String> attributes;
+
+ // *****************************************************************************
+ // constructors
+ // *****************************************************************************
+
+ public StructField() {
+ }
+
+ // *****************************************************************************
+ // public methods
+ // *****************************************************************************
+
+ public void writeToStream(DataOutputStream out) throws IOException {
+
+ out.writeShort(access_flags);
+ out.writeShort(name_index);
+ out.writeShort(descriptor_index);
+
+ out.writeShort(attributes.size());
+ for (StructGeneralAttribute attr : attributes) {
+ attr.writeToStream(out);
+ }
+ }
+
+ public void initStrings(ConstantPool pool, int class_index) {
+ String[] values = pool.getClassElement(ConstantPool.FIELD, class_index, name_index, descriptor_index);
+ name = values[0];
+ descriptor = values[1];
+ }
+
+ // *****************************************************************************
+ // getter and setter methods
+ // *****************************************************************************
+
+ public VBStyleCollection<StructGeneralAttribute, String> getAttributes() {
+ return attributes;
+ }
+
+ public void setAttributes(VBStyleCollection<StructGeneralAttribute, String> attributes) {
+ this.attributes = attributes;
+ }
+
+ public String getDescriptor() {
+ return descriptor;
+ }
+
+ public void setDescriptor(String descriptor) {
+ this.descriptor = descriptor;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
}
diff --git a/src/org/jetbrains/java/decompiler/struct/StructMethod.java b/src/org/jetbrains/java/decompiler/struct/StructMethod.java
index 20fdae9..baaf633 100644
--- a/src/org/jetbrains/java/decompiler/struct/StructMethod.java
+++ b/src/org/jetbrains/java/decompiler/struct/StructMethod.java
@@ -1,19 +1,27 @@
/*
- * 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;
+import org.jetbrains.java.decompiler.code.*;
+import org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute;
+import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTableAttribute;
+import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
+import org.jetbrains.java.decompiler.util.DataInputFullStream;
+import org.jetbrains.java.decompiler.util.VBStyleCollection;
+
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
@@ -21,19 +29,6 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
-import org.jetbrains.java.decompiler.code.CodeConstants;
-import org.jetbrains.java.decompiler.code.ConstantsUtil;
-import org.jetbrains.java.decompiler.code.ExceptionHandler;
-import org.jetbrains.java.decompiler.code.ExceptionTable;
-import org.jetbrains.java.decompiler.code.FullInstructionSequence;
-import org.jetbrains.java.decompiler.code.Instruction;
-import org.jetbrains.java.decompiler.code.InstructionSequence;
-import org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute;
-import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTableAttribute;
-import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
-import org.jetbrains.java.decompiler.util.DataInputFullStream;
-import org.jetbrains.java.decompiler.util.VBStyleCollection;
-
/*
method_info {
u2 access_flags;
@@ -45,516 +40,525 @@ import org.jetbrains.java.decompiler.util.VBStyleCollection;
*/
public class StructMethod implements CodeConstants {
-
- // *****************************************************************************
- // public fields
- // *****************************************************************************
-
- public int name_index;
-
- public int descriptor_index;
-
- // *****************************************************************************
- // private fields
- // *****************************************************************************
-
- private static final int[] opr_iconst = new int[] {-1,0,1,2,3,4,5};
-
- private static final int[] opr_loadstore = new int[] {0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3};
-
- private static final int[] opcs_load = new int[] {opc_iload,opc_lload,opc_fload,opc_dload,opc_aload};
-
- private static final int[] opcs_store = new int[] {opc_istore,opc_lstore,opc_fstore,opc_dstore,opc_astore};
-
-
- private int accessFlags;
-
- private VBStyleCollection<StructGeneralAttribute, String> attributes;
-
- private int localVariables;
-
- private int maxStack;
-
- private String name;
-
- private String descriptor;
-
- private InstructionSequence seq;
-
- private boolean containsCode = false;
-
- private boolean own;
-
- private StructClass classStruct;
-
-
- // lazy properties
- private boolean lazy;
-
- private boolean expanded;
-
- private byte[] code_content;
-
- private int code_length = 0;
-
- private int code_fulllength = 0;
-
- // *****************************************************************************
- // constructors
- // *****************************************************************************
-
- public StructMethod(DataInputFullStream in, boolean own, StructClass clstruct) throws IOException {
- this(in, true, own, clstruct);
- }
-
- public StructMethod(DataInputFullStream in, boolean lazy, boolean own, StructClass clstruct) throws IOException {
-
- this.own = own;
- this.lazy = lazy;
- this.expanded = !lazy;
- this.classStruct = clstruct;
-
- accessFlags = in.readUnsignedShort();
- name_index = in.readUnsignedShort();
- descriptor_index = in.readUnsignedShort();
-
- ConstantPool pool = clstruct.getPool();
-
- initStrings(pool, clstruct.this_class);
-
- VBStyleCollection<StructGeneralAttribute, String> lstAttribute = new VBStyleCollection<StructGeneralAttribute, String>();
- int len = in.readUnsignedShort();
- for(int i=0;i<len;i++) {
-
- int attr_nameindex = in.readUnsignedShort();
- String attrname = pool.getPrimitiveConstant(attr_nameindex).getString();
-
- if(StructGeneralAttribute.ATTRIBUTE_CODE.equals(attrname)) {
- if(!this.own) {
- // skip code in foreign classes
- in.skip(8);
- in.skip(in.readInt());
- in.skip(8*in.readUnsignedShort());
- } else {
- containsCode = true;
-
- in.skip(4);
-
- maxStack = in.readUnsignedShort();
- localVariables = in.readUnsignedShort();
-
- if(lazy) {
- code_length = in.readInt();
-
- in.skip(code_length);
-
- int exc_length = in.readUnsignedShort();
- code_fulllength = code_length + exc_length*8+2;
-
- in.skip(exc_length*8);
-
- } else {
- seq = parseBytecode(in, in.readInt(), pool);
- }
- }
-
- // code attributes
- int length = in.readUnsignedShort();
- for (int j = 0; j < length; j++) {
- int codeattr_nameindex = in.readUnsignedShort();
- String codeattrname = pool.getPrimitiveConstant(codeattr_nameindex).getString();
-
- readAttribute(in, pool, lstAttribute, codeattr_nameindex, codeattrname);
- }
- } else {
- readAttribute(in, pool, lstAttribute, attr_nameindex, attrname);
- }
- }
-
- attributes = lstAttribute;
- }
-
-
-
- // *****************************************************************************
- // public methods
- // *****************************************************************************
-
- public void writeToStream(DataOutputStream out) throws IOException {
-
- out.writeShort(accessFlags);
- out.writeShort(name_index);
- out.writeShort(descriptor_index);
-
- out.writeShort(attributes.size());
-
- for(StructGeneralAttribute attr: attributes) {
- if(StructGeneralAttribute.ATTRIBUTE_CODE.equals(attr.getName())){
- out.writeShort(attr.getAttribute_name_index());
-
- if(lazy && !expanded) {
- out.writeInt(10+code_content.length);
- out.writeShort(maxStack);
- out.writeShort(localVariables);
- out.writeInt(code_length);
- out.write(code_content);
- } else {
- ByteArrayOutputStream codeout = new ByteArrayOutputStream();
- seq.writeCodeToStream(new DataOutputStream(codeout));
-
- ByteArrayOutputStream excout = new ByteArrayOutputStream();
- seq.writeExceptionsToStream(new DataOutputStream(excout));
-
- out.writeInt(10+codeout.size()+excout.size());
-
- out.writeShort(maxStack);
- out.writeShort(localVariables);
- out.writeInt(codeout.size());
- codeout.writeTo(out);
- excout.writeTo(out);
- }
- // no attributes
- out.writeShort(0);
- } else {
- attr.writeToStream(out);
- }
- }
-
- }
-
- private void readAttribute(DataInputFullStream in, ConstantPool pool, VBStyleCollection<StructGeneralAttribute, String> lstAttribute,
- int attr_nameindex, String attrname) throws IOException {
-
- StructGeneralAttribute attribute = StructGeneralAttribute.getMatchingAttributeInstance(attr_nameindex, attrname);
-
- if(attribute != null) {
- attrname = attribute.getName();
-
- byte[] arr = new byte[in.readInt()];
- in.readFull(arr);
- attribute.setInfo(arr);
-
- attribute.initContent(pool);
-
- if(StructGeneralAttribute.ATTRIBUTE_LOCAL_VARIABLE_TABLE.equals(attrname) &&
- lstAttribute.containsKey(attrname)) {
- // merge all variable tables
- StructLocalVariableTableAttribute oldattr = (StructLocalVariableTableAttribute)lstAttribute.getWithKey(attrname);
- oldattr.addLocalVariableTable((StructLocalVariableTableAttribute)attribute);
- } else {
- lstAttribute.addWithKey(attribute, attribute.getName());
- }
- } else {
- in.skip(in.readInt());
- }
- }
-
- private void initStrings(ConstantPool pool, int class_index) {
- String[] values = pool.getClassElement(ConstantPool.METHOD, class_index, name_index, descriptor_index);
- name = values[0];
- descriptor = values[1];
- }
-
- public void expandData() throws IOException {
- if(containsCode && lazy && !expanded) {
-
- byte[] codearr = classStruct.getLoader().loadBytecode(this, code_fulllength);
-
- seq = parseBytecode(new DataInputFullStream(new ByteArrayInputStream(codearr)), code_length, classStruct.getPool());
- expanded = true;
- }
- }
-
- public void releaseResources() throws IOException {
- if(containsCode && lazy && expanded) {
- seq = null;
- expanded = false;
- }
- }
-
- // *****************************************************************************
- // private methods
- // *****************************************************************************
-
- private InstructionSequence parseBytecode(DataInputFullStream in, int length, ConstantPool pool) throws IOException {
-
- VBStyleCollection<Instruction, Integer> collinstr = new VBStyleCollection<Instruction, Integer>();
-
- int bytecode_version = classStruct.getBytecodeVersion();
-
- for(int i=0;i<length;) {
-
- int offset = i;
-
- int opcode = in.readUnsignedByte();
- int group = GROUP_GENERAL;
-
- boolean wide = (opcode == opc_wide);
-
- if(wide) {
- i++;
- opcode = in.readUnsignedByte();
- }
-
- List<Integer> operands = new ArrayList<Integer>();
-
- if(opcode>=opc_iconst_m1 && opcode<=opc_iconst_5) {
- operands.add(new Integer(opr_iconst[opcode-opc_iconst_m1]));
- opcode = opc_bipush;
- }else if(opcode>=opc_iload_0 && opcode<=opc_aload_3) {
- operands.add(new Integer(opr_loadstore[opcode-opc_iload_0]));
- opcode = opcs_load[(opcode-opc_iload_0)/4];
- }else if(opcode>=opc_istore_0 && opcode<=opc_astore_3) {
- operands.add(new Integer(opr_loadstore[opcode-opc_istore_0]));
- opcode = opcs_store[(opcode-opc_istore_0)/4];
- } else {
- switch (opcode) {
- case opc_bipush:
- operands.add(new Integer(in.readByte()));
- i++;
- break;
- case opc_ldc:
- case opc_newarray:
- operands.add(new Integer(in.readUnsignedByte()));
- i++;
- break;
- case opc_sipush:
- case opc_ifeq:
- case opc_ifne:
- case opc_iflt:
- case opc_ifge:
- case opc_ifgt:
- case opc_ifle:
- case opc_if_icmpeq:
- case opc_if_icmpne:
- case opc_if_icmplt:
- case opc_if_icmpge:
- case opc_if_icmpgt:
- case opc_if_icmple:
- case opc_if_acmpeq:
- case opc_if_acmpne:
- case opc_goto:
- case opc_jsr:
- case opc_ifnull:
- case opc_ifnonnull:
- if(opcode!=opc_sipush) {
- group = GROUP_JUMP;
- }
- operands.add(new Integer(in.readShort()));
- i+=2;
- break;
- case opc_ldc_w:
- case opc_ldc2_w:
- case opc_getstatic:
- case opc_putstatic:
- case opc_getfield:
- case opc_putfield:
- case opc_invokevirtual:
- case opc_invokespecial:
- case opc_invokestatic:
- case opc_new:
- case opc_anewarray:
- case opc_checkcast:
- case opc_instanceof:
- operands.add(new Integer(in.readUnsignedShort()));
- i+=2;
- if(opcode>=opc_getstatic && opcode<=opc_putfield) {
- group = GROUP_FIELDACCESS;
- } else if(opcode>=opc_invokevirtual && opcode<=opc_invokestatic) {
- group = GROUP_INVOCATION;
- }
- break;
- case opc_invokedynamic:
- if(classStruct.isVersionGE_1_7()) { // instruction unused in Java 6 and before
- operands.add(new Integer(in.readUnsignedShort()));
- in.skip(2);
- group = GROUP_INVOCATION;
- i+=4;
- }
- break;
- case opc_iload:
- case opc_lload:
- case opc_fload:
- case opc_dload:
- case opc_aload:
- case opc_istore:
- case opc_lstore:
- case opc_fstore:
- case opc_dstore:
- case opc_astore:
- case opc_ret:
- if(wide) {
- operands.add(new Integer(in.readUnsignedShort()));
- i+=2;
- } else {
- operands.add(new Integer(in.readUnsignedByte()));
- i++;
- }
- if(opcode == opc_ret) {
- group = GROUP_RETURN;
- }
- break;
- case opc_iinc:
- if (wide) {
- operands.add(new Integer(in.readUnsignedShort()));
- operands.add(new Integer(in.readShort()));
- i+=4;
- } else {
- operands.add(new Integer(in.readUnsignedByte()));
- operands.add(new Integer(in.readByte()));
- i+=2;
- }
- break;
- case opc_goto_w:
- case opc_jsr_w:
- opcode = opcode == opc_jsr_w?opc_jsr:opc_goto;
- operands.add(new Integer(in.readInt()));
- group = GROUP_JUMP;
- i+=4;
- break;
- case opc_invokeinterface:
- operands.add(new Integer(in.readUnsignedShort()));
- operands.add(new Integer(in.readUnsignedByte()));
- in.skip(1);
- group = GROUP_INVOCATION;
- i+=4;
- break;
- case opc_multianewarray:
- operands.add(new Integer(in.readUnsignedShort()));
- operands.add(new Integer(in.readUnsignedByte()));
- i+=3;
- break;
- case opc_tableswitch:
- in.skip((4-(i+1)%4)%4);
- i+=((4-(i+1)%4)%4); // padding
- operands.add(new Integer(in.readInt()));
- i+=4;
- int low = in.readInt();
- operands.add(new Integer(low));
- i+=4;
- int high = in.readInt();
- operands.add(new Integer(high));
- i+=4;
-
- for(int j=0;j<high-low+1;j++) {
- operands.add(new Integer(in.readInt()));
- i+=4;
- }
- group = GROUP_SWITCH;
-
- break;
- case opc_lookupswitch:
- in.skip((4-(i+1)%4)%4);
- i+=((4-(i+1)%4)%4); // padding
- operands.add(new Integer(in.readInt()));
- i+=4;
- int npairs = in.readInt();
- operands.add(new Integer(npairs));
- i+=4;
-
- for(int j=0;j<npairs;j++) {
- operands.add(new Integer(in.readInt()));
- i+=4;
- operands.add(new Integer(in.readInt()));
- i+=4;
- }
- group = GROUP_SWITCH;
- break;
- case opc_ireturn:
- case opc_lreturn:
- case opc_freturn:
- case opc_dreturn:
- case opc_areturn:
- case opc_return:
- case opc_athrow:
- group = GROUP_RETURN;
- }
- }
-
- int[] ops = new int[operands.size()];
- for(int j=0;j<operands.size();j++) {
- ops[j] = ((Integer)operands.get(j)).intValue();
- }
-
- Instruction instr = ConstantsUtil.getInstructionInstance(opcode, wide, group, bytecode_version, ops);
-
- collinstr.addWithKey(instr, new Integer(offset));
-
- i++;
- }
-
- // initialize exception table
- List<ExceptionHandler> lstHandlers = new ArrayList<ExceptionHandler>();
-
- int exception_count = in.readUnsignedShort();
- for(int i=0;i<exception_count;i++) {
- ExceptionHandler handler = new ExceptionHandler();
- handler.from = in.readUnsignedShort();
- handler.to = in.readUnsignedShort();
- handler.handler = in.readUnsignedShort();
-
- int excclass = in.readUnsignedShort();
- handler.class_index = excclass;
- if(excclass!=0) {
- handler.exceptionClass = pool.getPrimitiveConstant(excclass).getString();
- }
-
- lstHandlers.add(handler);
- }
-
- InstructionSequence seq = new FullInstructionSequence(collinstr, new ExceptionTable(lstHandlers));
-
- // initialize instructions
- int i = seq.length()-1;
- seq.setPointer(i);
-
- while(i>=0) {
- Instruction instr = seq.getInstr(i--);
- if(instr.group!=GROUP_GENERAL) {
- instr.initInstruction(seq);
- }
- seq.addToPointer(-1);
- }
-
- return seq;
-
- }
-
- // *****************************************************************************
- // getter and setter methods
- // *****************************************************************************
-
- public InstructionSequence getInstructionSequence() {
- return seq;
- }
-
- public String getDescriptor() {
- return descriptor;
- }
-
- public String getName() {
- return name;
- }
-
- public int getAccessFlags() {
- return accessFlags;
- }
-
- public int getLocalVariables() {
- return localVariables;
- }
-
- public VBStyleCollection<StructGeneralAttribute, String> getAttributes() {
- return attributes;
- }
-
- public StructClass getClassStruct() {
- return classStruct;
- }
-
- public boolean containsCode() {
- return containsCode;
- }
+
+ // *****************************************************************************
+ // public fields
+ // *****************************************************************************
+
+ public int name_index;
+
+ public int descriptor_index;
+
+ // *****************************************************************************
+ // private fields
+ // *****************************************************************************
+
+ private static final int[] opr_iconst = new int[]{-1, 0, 1, 2, 3, 4, 5};
+
+ private static final int[] opr_loadstore = new int[]{0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3};
+
+ private static final int[] opcs_load = new int[]{opc_iload, opc_lload, opc_fload, opc_dload, opc_aload};
+
+ private static final int[] opcs_store = new int[]{opc_istore, opc_lstore, opc_fstore, opc_dstore, opc_astore};
+
+
+ private int accessFlags;
+
+ private VBStyleCollection<StructGeneralAttribute, String> attributes;
+
+ private int localVariables;
+
+ private int maxStack;
+
+ private String name;
+
+ private String descriptor;
+
+ private InstructionSequence seq;
+
+ private boolean containsCode = false;
+
+ private boolean own;
+
+ private StructClass classStruct;
+
+
+ // lazy properties
+ private boolean lazy;
+
+ private boolean expanded;
+
+ private byte[] code_content;
+
+ private int code_length = 0;
+
+ private int code_fulllength = 0;
+
+ // *****************************************************************************
+ // constructors
+ // *****************************************************************************
+
+ public StructMethod(DataInputFullStream in, boolean own, StructClass clstruct) throws IOException {
+ this(in, true, own, clstruct);
+ }
+
+ public StructMethod(DataInputFullStream in, boolean lazy, boolean own, StructClass clstruct) throws IOException {
+
+ this.own = own;
+ this.lazy = lazy;
+ this.expanded = !lazy;
+ this.classStruct = clstruct;
+
+ accessFlags = in.readUnsignedShort();
+ name_index = in.readUnsignedShort();
+ descriptor_index = in.readUnsignedShort();
+
+ ConstantPool pool = clstruct.getPool();
+
+ initStrings(pool, clstruct.this_class);
+
+ VBStyleCollection<StructGeneralAttribute, String> lstAttribute = new VBStyleCollection<StructGeneralAttribute, String>();
+ int len = in.readUnsignedShort();
+ for (int i = 0; i < len; i++) {
+
+ int attr_nameindex = in.readUnsignedShort();
+ String attrname = pool.getPrimitiveConstant(attr_nameindex).getString();
+
+ if (StructGeneralAttribute.ATTRIBUTE_CODE.equals(attrname)) {
+ if (!this.own) {
+ // skip code in foreign classes
+ in.skip(8);
+ in.skip(in.readInt());
+ in.skip(8 * in.readUnsignedShort());
+ }
+ else {
+ containsCode = true;
+
+ in.skip(4);
+
+ maxStack = in.readUnsignedShort();
+ localVariables = in.readUnsignedShort();
+
+ if (lazy) {
+ code_length = in.readInt();
+
+ in.skip(code_length);
+
+ int exc_length = in.readUnsignedShort();
+ code_fulllength = code_length + exc_length * 8 + 2;
+
+ in.skip(exc_length * 8);
+ }
+ else {
+ seq = parseBytecode(in, in.readInt(), pool);
+ }
+ }
+
+ // code attributes
+ int length = in.readUnsignedShort();
+ for (int j = 0; j < length; j++) {
+ int codeattr_nameindex = in.readUnsignedShort();
+ String codeattrname = pool.getPrimitiveConstant(codeattr_nameindex).getString();
+
+ readAttribute(in, pool, lstAttribute, codeattr_nameindex, codeattrname);
+ }
+ }
+ else {
+ readAttribute(in, pool, lstAttribute, attr_nameindex, attrname);
+ }
+ }
+
+ attributes = lstAttribute;
+ }
+
+
+ // *****************************************************************************
+ // public methods
+ // *****************************************************************************
+
+ public void writeToStream(DataOutputStream out) throws IOException {
+
+ out.writeShort(accessFlags);
+ out.writeShort(name_index);
+ out.writeShort(descriptor_index);
+
+ out.writeShort(attributes.size());
+
+ for (StructGeneralAttribute attr : attributes) {
+ if (StructGeneralAttribute.ATTRIBUTE_CODE.equals(attr.getName())) {
+ out.writeShort(attr.getAttribute_name_index());
+
+ if (lazy && !expanded) {
+ out.writeInt(10 + code_content.length);
+ out.writeShort(maxStack);
+ out.writeShort(localVariables);
+ out.writeInt(code_length);
+ out.write(code_content);
+ }
+ else {
+ ByteArrayOutputStream codeout = new ByteArrayOutputStream();
+ seq.writeCodeToStream(new DataOutputStream(codeout));
+
+ ByteArrayOutputStream excout = new ByteArrayOutputStream();
+ seq.writeExceptionsToStream(new DataOutputStream(excout));
+
+ out.writeInt(10 + codeout.size() + excout.size());
+
+ out.writeShort(maxStack);
+ out.writeShort(localVariables);
+ out.writeInt(codeout.size());
+ codeout.writeTo(out);
+ excout.writeTo(out);
+ }
+ // no attributes
+ out.writeShort(0);
+ }
+ else {
+ attr.writeToStream(out);
+ }
+ }
+ }
+
+ private void readAttribute(DataInputFullStream in, ConstantPool pool, VBStyleCollection<StructGeneralAttribute, String> lstAttribute,
+ int attr_nameindex, String attrname) throws IOException {
+
+ StructGeneralAttribute attribute = StructGeneralAttribute.getMatchingAttributeInstance(attr_nameindex, attrname);
+
+ if (attribute != null) {
+ attrname = attribute.getName();
+
+ byte[] arr = new byte[in.readInt()];
+ in.readFull(arr);
+ attribute.setInfo(arr);
+
+ attribute.initContent(pool);
+
+ if (StructGeneralAttribute.ATTRIBUTE_LOCAL_VARIABLE_TABLE.equals(attrname) &&
+ lstAttribute.containsKey(attrname)) {
+ // merge all variable tables
+ StructLocalVariableTableAttribute oldattr = (StructLocalVariableTableAttribute)lstAttribute.getWithKey(attrname);
+ oldattr.addLocalVariableTable((StructLocalVariableTableAttribute)attribute);
+ }
+ else {
+ lstAttribute.addWithKey(attribute, attribute.getName());
+ }
+ }
+ else {
+ in.skip(in.readInt());
+ }
+ }
+
+ private void initStrings(ConstantPool pool, int class_index) {
+ String[] values = pool.getClassElement(ConstantPool.METHOD, class_index, name_index, descriptor_index);
+ name = values[0];
+ descriptor = values[1];
+ }
+
+ public void expandData() throws IOException {
+ if (containsCode && lazy && !expanded) {
+
+ byte[] codearr = classStruct.getLoader().loadBytecode(this, code_fulllength);
+
+ seq = parseBytecode(new DataInputFullStream(new ByteArrayInputStream(codearr)), code_length, classStruct.getPool());
+ expanded = true;
+ }
+ }
+
+ public void releaseResources() throws IOException {
+ if (containsCode && lazy && expanded) {
+ seq = null;
+ expanded = false;
+ }
+ }
+
+ // *****************************************************************************
+ // private methods
+ // *****************************************************************************
+
+ private InstructionSequence parseBytecode(DataInputFullStream in, int length, ConstantPool pool) throws IOException {
+
+ VBStyleCollection<Instruction, Integer> collinstr = new VBStyleCollection<Instruction, Integer>();
+
+ int bytecode_version = classStruct.getBytecodeVersion();
+
+ for (int i = 0; i < length; ) {
+
+ int offset = i;
+
+ int opcode = in.readUnsignedByte();
+ int group = GROUP_GENERAL;
+
+ boolean wide = (opcode == opc_wide);
+
+ if (wide) {
+ i++;
+ opcode = in.readUnsignedByte();
+ }
+
+ List<Integer> operands = new ArrayList<Integer>();
+
+ if (opcode >= opc_iconst_m1 && opcode <= opc_iconst_5) {
+ operands.add(new Integer(opr_iconst[opcode - opc_iconst_m1]));
+ opcode = opc_bipush;
+ }
+ else if (opcode >= opc_iload_0 && opcode <= opc_aload_3) {
+ operands.add(new Integer(opr_loadstore[opcode - opc_iload_0]));
+ opcode = opcs_load[(opcode - opc_iload_0) / 4];
+ }
+ else if (opcode >= opc_istore_0 && opcode <= opc_astore_3) {
+ operands.add(new Integer(opr_loadstore[opcode - opc_istore_0]));
+ opcode = opcs_store[(opcode - opc_istore_0) / 4];
+ }
+ else {
+ switch (opcode) {
+ case opc_bipush:
+ operands.add(new Integer(in.readByte()));
+ i++;
+ break;
+ case opc_ldc:
+ case opc_newarray:
+ operands.add(new Integer(in.readUnsignedByte()));
+ i++;
+ break;
+ case opc_sipush:
+ case opc_ifeq:
+ case opc_ifne:
+ case opc_iflt:
+ case opc_ifge:
+ case opc_ifgt:
+ case opc_ifle:
+ case opc_if_icmpeq:
+ case opc_if_icmpne:
+ case opc_if_icmplt:
+ case opc_if_icmpge:
+ case opc_if_icmpgt:
+ case opc_if_icmple:
+ case opc_if_acmpeq:
+ case opc_if_acmpne:
+ case opc_goto:
+ case opc_jsr:
+ case opc_ifnull:
+ case opc_ifnonnull:
+ if (opcode != opc_sipush) {
+ group = GROUP_JUMP;
+ }
+ operands.add(new Integer(in.readShort()));
+ i += 2;
+ break;
+ case opc_ldc_w:
+ case opc_ldc2_w:
+ case opc_getstatic:
+ case opc_putstatic:
+ case opc_getfield:
+ case opc_putfield:
+ case opc_invokevirtual:
+ case opc_invokespecial:
+ case opc_invokestatic:
+ case opc_new:
+ case opc_anewarray:
+ case opc_checkcast:
+ case opc_instanceof:
+ operands.add(new Integer(in.readUnsignedShort()));
+ i += 2;
+ if (opcode >= opc_getstatic && opcode <= opc_putfield) {
+ group = GROUP_FIELDACCESS;
+ }
+ else if (opcode >= opc_invokevirtual && opcode <= opc_invokestatic) {
+ group = GROUP_INVOCATION;
+ }
+ break;
+ case opc_invokedynamic:
+ if (classStruct.isVersionGE_1_7()) { // instruction unused in Java 6 and before
+ operands.add(new Integer(in.readUnsignedShort()));
+ in.skip(2);
+ group = GROUP_INVOCATION;
+ i += 4;
+ }
+ break;
+ case opc_iload:
+ case opc_lload:
+ case opc_fload:
+ case opc_dload:
+ case opc_aload:
+ case opc_istore:
+ case opc_lstore:
+ case opc_fstore:
+ case opc_dstore:
+ case opc_astore:
+ case opc_ret:
+ if (wide) {
+ operands.add(new Integer(in.readUnsignedShort()));
+ i += 2;
+ }
+ else {
+ operands.add(new Integer(in.readUnsignedByte()));
+ i++;
+ }
+ if (opcode == opc_ret) {
+ group = GROUP_RETURN;
+ }
+ break;
+ case opc_iinc:
+ if (wide) {
+ operands.add(new Integer(in.readUnsignedShort()));
+ operands.add(new Integer(in.readShort()));
+ i += 4;
+ }
+ else {
+ operands.add(new Integer(in.readUnsignedByte()));
+ operands.add(new Integer(in.readByte()));
+ i += 2;
+ }
+ break;
+ case opc_goto_w:
+ case opc_jsr_w:
+ opcode = opcode == opc_jsr_w ? opc_jsr : opc_goto;
+ operands.add(new Integer(in.readInt()));
+ group = GROUP_JUMP;
+ i += 4;
+ break;
+ case opc_invokeinterface:
+ operands.add(new Integer(in.readUnsignedShort()));
+ operands.add(new Integer(in.readUnsignedByte()));
+ in.skip(1);
+ group = GROUP_INVOCATION;
+ i += 4;
+ break;
+ case opc_multianewarray:
+ operands.add(new Integer(in.readUnsignedShort()));
+ operands.add(new Integer(in.readUnsignedByte()));
+ i += 3;
+ break;
+ case opc_tableswitch:
+ in.skip((4 - (i + 1) % 4) % 4);
+ i += ((4 - (i + 1) % 4) % 4); // padding
+ operands.add(new Integer(in.readInt()));
+ i += 4;
+ int low = in.readInt();
+ operands.add(new Integer(low));
+ i += 4;
+ int high = in.readInt();
+ operands.add(new Integer(high));
+ i += 4;
+
+ for (int j = 0; j < high - low + 1; j++) {
+ operands.add(new Integer(in.readInt()));
+ i += 4;
+ }
+ group = GROUP_SWITCH;
+
+ break;
+ case opc_lookupswitch:
+ in.skip((4 - (i + 1) % 4) % 4);
+ i += ((4 - (i + 1) % 4) % 4); // padding
+ operands.add(new Integer(in.readInt()));
+ i += 4;
+ int npairs = in.readInt();
+ operands.add(new Integer(npairs));
+ i += 4;
+
+ for (int j = 0; j < npairs; j++) {
+ operands.add(new Integer(in.readInt()));
+ i += 4;
+ operands.add(new Integer(in.readInt()));
+ i += 4;
+ }
+ group = GROUP_SWITCH;
+ break;
+ case opc_ireturn:
+ case opc_lreturn:
+ case opc_freturn:
+ case opc_dreturn:
+ case opc_areturn:
+ case opc_return:
+ case opc_athrow:
+ group = GROUP_RETURN;
+ }
+ }
+
+ int[] ops = new int[operands.size()];
+ for (int j = 0; j < operands.size(); j++) {
+ ops[j] = ((Integer)operands.get(j)).intValue();
+ }
+
+ Instruction instr = ConstantsUtil.getInstructionInstance(opcode, wide, group, bytecode_version, ops);
+
+ collinstr.addWithKey(instr, new Integer(offset));
+
+ i++;
+ }
+
+ // initialize exception table
+ List<ExceptionHandler> lstHandlers = new ArrayList<ExceptionHandler>();
+
+ int exception_count = in.readUnsignedShort();
+ for (int i = 0; i < exception_count; i++) {
+ ExceptionHandler handler = new ExceptionHandler();
+ handler.from = in.readUnsignedShort();
+ handler.to = in.readUnsignedShort();
+ handler.handler = in.readUnsignedShort();
+
+ int excclass = in.readUnsignedShort();
+ handler.class_index = excclass;
+ if (excclass != 0) {
+ handler.exceptionClass = pool.getPrimitiveConstant(excclass).getString();
+ }
+
+ lstHandlers.add(handler);
+ }
+
+ InstructionSequence seq = new FullInstructionSequence(collinstr, new ExceptionTable(lstHandlers));
+
+ // initialize instructions
+ int i = seq.length() - 1;
+ seq.setPointer(i);
+
+ while (i >= 0) {
+ Instruction instr = seq.getInstr(i--);
+ if (instr.group != GROUP_GENERAL) {
+ instr.initInstruction(seq);
+ }
+ seq.addToPointer(-1);
+ }
+
+ return seq;
+ }
+
+ // *****************************************************************************
+ // getter and setter methods
+ // *****************************************************************************
+
+ public InstructionSequence getInstructionSequence() {
+ return seq;
+ }
+
+ public String getDescriptor() {
+ return descriptor;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public int getAccessFlags() {
+ return accessFlags;
+ }
+
+ public int getLocalVariables() {
+ return localVariables;
+ }
+
+ public VBStyleCollection<StructGeneralAttribute, String> getAttributes() {
+ return attributes;
+ }
+
+ public StructClass getClassStruct() {
+ return classStruct;
+ }
+
+ public boolean containsCode() {
+ return containsCode;
+ }
}
diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnDefaultAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnDefaultAttribute.java
index d171349..f36df6d 100644
--- a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnDefaultAttribute.java
+++ b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnDefaultAttribute.java
@@ -1,40 +1,40 @@
/*
- * 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.attr;
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-
import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent;
import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+
public class StructAnnDefaultAttribute extends StructGeneralAttribute {
- private Exprent defaultValue;
-
- public void initContent(ConstantPool pool) {
-
- name = ATTRIBUTE_ANNOTATION_DEFAULT;
-
- DataInputStream data = new DataInputStream(new ByteArrayInputStream(info));
- defaultValue = StructAnnotationAttribute.parseAnnotationElement(data, pool);
- }
-
- public Exprent getDefaultValue() {
- return defaultValue;
- }
-
+ private Exprent defaultValue;
+
+ public void initContent(ConstantPool pool) {
+
+ name = ATTRIBUTE_ANNOTATION_DEFAULT;
+
+ DataInputStream data = new DataInputStream(new ByteArrayInputStream(info));
+ defaultValue = StructAnnotationAttribute.parseAnnotationElement(data, pool);
+ }
+
+ public Exprent getDefaultValue() {
+ return defaultValue;
+ }
}
diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java
index 8958299..2a2c74c 100644
--- a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java
+++ b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java
@@ -1,187 +1,182 @@
/*
- * 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.attr;
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
import org.jetbrains.java.decompiler.code.CodeConstants;
-import org.jetbrains.java.decompiler.modules.decompiler.exps.AnnotationExprent;
-import org.jetbrains.java.decompiler.modules.decompiler.exps.ConstExprent;
-import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent;
-import org.jetbrains.java.decompiler.modules.decompiler.exps.FieldExprent;
-import org.jetbrains.java.decompiler.modules.decompiler.exps.NewExprent;
+import org.jetbrains.java.decompiler.modules.decompiler.exps.*;
import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
import org.jetbrains.java.decompiler.struct.consts.PrimitiveConstant;
import org.jetbrains.java.decompiler.struct.gen.FieldDescriptor;
import org.jetbrains.java.decompiler.struct.gen.VarType;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
public class StructAnnotationAttribute extends StructGeneralAttribute {
- private List<AnnotationExprent> annotations;
-
- public void initContent(ConstantPool pool) {
-
- super.initContent(pool);
-
- annotations = new ArrayList<AnnotationExprent>();
- DataInputStream data = new DataInputStream(new ByteArrayInputStream(info, 2, info.length));
-
- int len = (((info[0] & 0xFF)<<8) | (info[1] & 0xFF));
- for(int i=0;i<len;i++) {
- annotations.add(parseAnnotation(data, pool));
- }
-
- }
-
- public static AnnotationExprent parseAnnotation(DataInputStream data, ConstantPool pool) {
-
- try {
-
- String classname = pool.getPrimitiveConstant(data.readUnsignedShort()).getString();
- VarType cltype = new VarType(classname);
-
- int len = data.readUnsignedShort();
-
- List<String> parnames = new ArrayList<String>();
- List<Exprent> parvalues = new ArrayList<Exprent>();
-
- for(int i=0;i<len;i++) {
- parnames.add(pool.getPrimitiveConstant(data.readUnsignedShort()).getString());
- parvalues.add(parseAnnotationElement(data, pool));
- }
-
- return new AnnotationExprent(cltype.value, parnames, parvalues);
-
- } catch(IOException ex) {
- throw new RuntimeException(ex);
- }
-
- }
-
- public static Exprent parseAnnotationElement(DataInputStream data, ConstantPool pool) {
-
- try {
- int tag = data.readUnsignedByte();
-
- switch(tag) {
- case 'e': // enum constant
- String classname = pool.getPrimitiveConstant(data.readUnsignedShort()).getString();
- String constname = pool.getPrimitiveConstant(data.readUnsignedShort()).getString();
-
- FieldDescriptor descr = FieldDescriptor.parseDescriptor(classname);
- return new FieldExprent(constname, descr.type.value, true, null, descr);
- case 'c': // class
- String descriptor = pool.getPrimitiveConstant(data.readUnsignedShort()).getString();
- VarType type = FieldDescriptor.parseDescriptor(descriptor).type;
-
- String value;
- switch(type.type) {
- case CodeConstants.TYPE_OBJECT:
- value = type.value;
- break;
- case CodeConstants.TYPE_BYTE:
- value = byte.class.getName();
- break;
- case CodeConstants.TYPE_CHAR:
- value = char.class.getName();
- break;
- case CodeConstants.TYPE_DOUBLE:
- value = double.class.getName();
- break;
- case CodeConstants.TYPE_FLOAT:
- value = float.class.getName();
- break;
- case CodeConstants.TYPE_INT:
- value = int.class.getName();
- break;
- case CodeConstants.TYPE_LONG:
- value = long.class.getName();
- break;
- case CodeConstants.TYPE_SHORT:
- value = short.class.getName();
- break;
- case CodeConstants.TYPE_BOOLEAN:
- value = boolean.class.getName();
- break;
- case CodeConstants.TYPE_VOID:
- value = void.class.getName();
- break;
- default:
- throw new RuntimeException("invalid class type: " + type.type);
- }
- return new ConstExprent(VarType.VARTYPE_CLASS, value);
- case '[': // array
- int len = data.readUnsignedShort();
- List<Exprent> lst = new ArrayList<Exprent>();
-
- for(int i=0;i<len;i++) {
- lst.add(parseAnnotationElement(data, pool));
- }
-
- VarType newtype;
- if(lst.isEmpty()) {
- newtype = new VarType(CodeConstants.TYPE_OBJECT, 1, "java/lang/Object");
- } else {
- VarType eltype = lst.get(0).getExprType();
- newtype = new VarType(eltype.type, 1, eltype.value);
- }
-
- NewExprent newexpr = new NewExprent(newtype, new ArrayList<Exprent>());
- newexpr.setDirectArrayInit(true);
- newexpr.setLstArrayElements(lst);
- return newexpr;
- case '@': // annotation
- return parseAnnotation(data, pool);
- default:
- PrimitiveConstant cn = pool.getPrimitiveConstant(data.readUnsignedShort());
- switch(tag) {
- case 'B':
- return new ConstExprent(VarType.VARTYPE_BYTE, cn.value);
- case 'C':
- return new ConstExprent(VarType.VARTYPE_CHAR, cn.value);
- case 'D':
- return new ConstExprent(VarType.VARTYPE_DOUBLE, cn.value);
- case 'F':
- return new ConstExprent(VarType.VARTYPE_FLOAT, cn.value);
- case 'I':
- return new ConstExprent(VarType.VARTYPE_INT, cn.value);
- case 'J':
- return new ConstExprent(VarType.VARTYPE_LONG, cn.value);
- case 'S':
- return new ConstExprent(VarType.VARTYPE_SHORT, cn.value);
- case 'Z':
- return new ConstExprent(VarType.VARTYPE_BOOLEAN, cn.value);
- case 's':
- return new ConstExprent(VarType.VARTYPE_STRING, cn.value);
- default:
- throw new RuntimeException("invalid element type!");
- }
- }
- } catch(IOException ex) {
- throw new RuntimeException(ex);
- }
-
- }
-
-
- public List<AnnotationExprent> getAnnotations() {
- return annotations;
- }
-
+ private List<AnnotationExprent> annotations;
+
+ public void initContent(ConstantPool pool) {
+
+ super.initContent(pool);
+
+ annotations = new ArrayList<AnnotationExprent>();
+ DataInputStream data = new DataInputStream(new ByteArrayInputStream(info, 2, info.length));
+
+ int len = (((info[0] & 0xFF) << 8) | (info[1] & 0xFF));
+ for (int i = 0; i < len; i++) {
+ annotations.add(parseAnnotation(data, pool));
+ }
+ }
+
+ public static AnnotationExprent parseAnnotation(DataInputStream data, ConstantPool pool) {
+
+ try {
+
+ String classname = pool.getPrimitiveConstant(data.readUnsignedShort()).getString();
+ VarType cltype = new VarType(classname);
+
+ int len = data.readUnsignedShort();
+
+ List<String> parnames = new ArrayList<String>();
+ List<Exprent> parvalues = new ArrayList<Exprent>();
+
+ for (int i = 0; i < len; i++) {
+ parnames.add(pool.getPrimitiveConstant(data.readUnsignedShort()).getString());
+ parvalues.add(parseAnnotationElement(data, pool));
+ }
+
+ return new AnnotationExprent(cltype.value, parnames, parvalues);
+ }
+ catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ public static Exprent parseAnnotationElement(DataInputStream data, ConstantPool pool) {
+
+ try {
+ int tag = data.readUnsignedByte();
+
+ switch (tag) {
+ case 'e': // enum constant
+ String classname = pool.getPrimitiveConstant(data.readUnsignedShort()).getString();
+ String constname = pool.getPrimitiveConstant(data.readUnsignedShort()).getString();
+
+ FieldDescriptor descr = FieldDescriptor.parseDescriptor(classname);
+ return new FieldExprent(constname, descr.type.value, true, null, descr);
+ case 'c': // class
+ String descriptor = pool.getPrimitiveConstant(data.readUnsignedShort()).getString();
+ VarType type = FieldDescriptor.parseDescriptor(descriptor).type;
+
+ String value;
+ switch (type.type) {
+ case CodeConstants.TYPE_OBJECT:
+ value = type.value;
+ break;
+ case CodeConstants.TYPE_BYTE:
+ value = byte.class.getName();
+ break;
+ case CodeConstants.TYPE_CHAR:
+ value = char.class.getName();
+ break;
+ case CodeConstants.TYPE_DOUBLE:
+ value = double.class.getName();
+ break;
+ case CodeConstants.TYPE_FLOAT:
+ value = float.class.getName();
+ break;
+ case CodeConstants.TYPE_INT:
+ value = int.class.getName();
+ break;
+ case CodeConstants.TYPE_LONG:
+ value = long.class.getName();
+ break;
+ case CodeConstants.TYPE_SHORT:
+ value = short.class.getName();
+ break;
+ case CodeConstants.TYPE_BOOLEAN:
+ value = boolean.class.getName();
+ break;
+ case CodeConstants.TYPE_VOID:
+ value = void.class.getName();
+ break;
+ default:
+ throw new RuntimeException("invalid class type: " + type.type);
+ }
+ return new ConstExprent(VarType.VARTYPE_CLASS, value);
+ case '[': // array
+ int len = data.readUnsignedShort();
+ List<Exprent> lst = new ArrayList<Exprent>();
+
+ for (int i = 0; i < len; i++) {
+ lst.add(parseAnnotationElement(data, pool));
+ }
+
+ VarType newtype;
+ if (lst.isEmpty()) {
+ newtype = new VarType(CodeConstants.TYPE_OBJECT, 1, "java/lang/Object");
+ }
+ else {
+ VarType eltype = lst.get(0).getExprType();
+ newtype = new VarType(eltype.type, 1, eltype.value);
+ }
+
+ NewExprent newexpr = new NewExprent(newtype, new ArrayList<Exprent>());
+ newexpr.setDirectArrayInit(true);
+ newexpr.setLstArrayElements(lst);
+ return newexpr;
+ case '@': // annotation
+ return parseAnnotation(data, pool);
+ default:
+ PrimitiveConstant cn = pool.getPrimitiveConstant(data.readUnsignedShort());
+ switch (tag) {
+ case 'B':
+ return new ConstExprent(VarType.VARTYPE_BYTE, cn.value);
+ case 'C':
+ return new ConstExprent(VarType.VARTYPE_CHAR, cn.value);
+ case 'D':
+ return new ConstExprent(VarType.VARTYPE_DOUBLE, cn.value);
+ case 'F':
+ return new ConstExprent(VarType.VARTYPE_FLOAT, cn.value);
+ case 'I':
+ return new ConstExprent(VarType.VARTYPE_INT, cn.value);
+ case 'J':
+ return new ConstExprent(VarType.VARTYPE_LONG, cn.value);
+ case 'S':
+ return new ConstExprent(VarType.VARTYPE_SHORT, cn.value);
+ case 'Z':
+ return new ConstExprent(VarType.VARTYPE_BOOLEAN, cn.value);
+ case 's':
+ return new ConstExprent(VarType.VARTYPE_STRING, cn.value);
+ default:
+ throw new RuntimeException("invalid element type!");
+ }
+ }
+ }
+ catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+
+ public List<AnnotationExprent> getAnnotations() {
+ return annotations;
+ }
}
diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationParameterAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationParameterAttribute.java
index dd28aa7..432d3b6 100644
--- a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationParameterAttribute.java
+++ b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationParameterAttribute.java
@@ -1,57 +1,58 @@
/*
- * 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.attr;
+import org.jetbrains.java.decompiler.modules.decompiler.exps.AnnotationExprent;
+import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
+
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
-import org.jetbrains.java.decompiler.modules.decompiler.exps.AnnotationExprent;
-import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
-
public class StructAnnotationParameterAttribute extends StructGeneralAttribute {
- private List<List<AnnotationExprent>> paramAnnotations;
-
- public void initContent(ConstantPool pool) {
-
- super.initContent(pool);
-
- paramAnnotations = new ArrayList<List<AnnotationExprent>>();
- DataInputStream data = new DataInputStream(new ByteArrayInputStream(info));
-
- try {
- int len = data.readUnsignedByte();
- for(int i=0;i<len;i++) {
- List<AnnotationExprent> lst = new ArrayList<AnnotationExprent>();
- int annsize = data.readUnsignedShort();
-
- for(int j=0;j<annsize;j++) {
- lst.add(StructAnnotationAttribute.parseAnnotation(data, pool));
- }
- paramAnnotations.add(lst);
- }
- } catch(IOException ex) {
- throw new RuntimeException(ex);
- }
-
- }
-
- public List<List<AnnotationExprent>> getParamAnnotations() {
- return paramAnnotations;
- }
+ private List<List<AnnotationExprent>> paramAnnotations;
+
+ public void initContent(ConstantPool pool) {
+
+ super.initContent(pool);
+
+ paramAnnotations = new ArrayList<List<AnnotationExprent>>();
+ DataInputStream data = new DataInputStream(new ByteArrayInputStream(info));
+
+ try {
+ int len = data.readUnsignedByte();
+ for (int i = 0; i < len; i++) {
+ List<AnnotationExprent> lst = new ArrayList<AnnotationExprent>();
+ int annsize = data.readUnsignedShort();
+
+ for (int j = 0; j < annsize; j++) {
+ lst.add(StructAnnotationAttribute.parseAnnotation(data, pool));
+ }
+ paramAnnotations.add(lst);
+ }
+ }
+ catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ public List<List<AnnotationExprent>> getParamAnnotations() {
+ return paramAnnotations;
+ }
}
diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationTypeAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationTypeAttribute.java
index 9677ddd..f228ed5 100644
--- a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationTypeAttribute.java
+++ b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationTypeAttribute.java
@@ -1,188 +1,203 @@
+/*
+ * 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.attr;
+import org.jetbrains.java.decompiler.modules.decompiler.exps.AnnotationExprent;
+import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
+
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
-import org.jetbrains.java.decompiler.modules.decompiler.exps.AnnotationExprent;
-import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
-
public class StructAnnotationTypeAttribute extends StructGeneralAttribute {
-
- public static final int ANNOTATION_TARGET_TYPE_GENERIC_CLASS = 0x00;
- public static final int ANNOTATION_TARGET_TYPE_GENERIC_METHOD = 0x01;
- public static final int ANNOTATION_TARGET_TYPE_EXTENDS_IMPLEMENTS = 0x10;
- public static final int ANNOTATION_TARGET_TYPE_GENERIC_CLASS_BOUND = 0x11;
- public static final int ANNOTATION_TARGET_TYPE_GENERIC_METHOD_BOUND = 0x12;
- public static final int ANNOTATION_TARGET_TYPE_FIELD = 0x13;
- public static final int ANNOTATION_TARGET_TYPE_RETURN = 0x14;
- public static final int ANNOTATION_TARGET_TYPE_RECEIVER = 0x15;
- public static final int ANNOTATION_TARGET_TYPE_FORMAL = 0x16;
- public static final int ANNOTATION_TARGET_TYPE_THROWS = 0x17;
- public static final int ANNOTATION_TARGET_TYPE_LOCAL_VARIABLE = 0x40;
- public static final int ANNOTATION_TARGET_TYPE_RESOURCE_VARIABLE = 0x41;
- public static final int ANNOTATION_TARGET_TYPE_EXCEPTION = 0x42;
- public static final int ANNOTATION_TARGET_TYPE_INSTANCEOF = 0x43;
- public static final int ANNOTATION_TARGET_TYPE_NEW = 0x44;
- public static final int ANNOTATION_TARGET_TYPE_DOUBLECOLON_NEW = 0x45;
- public static final int ANNOTATION_TARGET_TYPE_DOUBLECOLON_ID = 0x46;
- public static final int ANNOTATION_TARGET_TYPE_CAST = 0x47;
- public static final int ANNOTATION_TARGET_TYPE_INVOKATION_CONSTRUCTOR = 0x48;
- public static final int ANNOTATION_TARGET_TYPE_INVOKATION_METHOD = 0x49;
- public static final int ANNOTATION_TARGET_TYPE_GENERIC_DOUBLECOLON_NEW = 0x4A;
- public static final int ANNOTATION_TARGET_TYPE_GENERIC_DOUBLECOLON_ID = 0x4B;
-
- public static final int ANNOTATION_TARGET_UNION_TYPE_PARAMETER = 1;
- public static final int ANNOTATION_TARGET_UNION_SUPERTYPE = 2;
- public static final int ANNOTATION_TARGET_UNION_TYPE_PARAMETER_BOUND = 3;
- public static final int ANNOTATION_TARGET_UNION_EMPTY = 4;
- public static final int ANNOTATION_TARGET_UNION_FORMAL_PARAMETER = 5;
- public static final int ANNOTATION_TARGET_UNION_THROWS = 6;
- public static final int ANNOTATION_TARGET_UNION_LOCALVAR = 7;
- public static final int ANNOTATION_TARGET_UNION_CATCH = 8;
- public static final int ANNOTATION_TARGET_UNION_OFFSET = 9;
- public static final int ANNOTATION_TARGET_UNION_TYPE_ARGUMENT = 10;
-
-
- List<AnnotationLocation> locations = new ArrayList<AnnotationLocation>();
- List<AnnotationExprent> annotations = new ArrayList<AnnotationExprent>();
-
- public void initContent(ConstantPool pool) {
-
- super.initContent(pool);
-
- DataInputStream data = new DataInputStream(new ByteArrayInputStream(info));
-
- try {
-
- int ann_number = data.readUnsignedByte();
- for(int i = 0; i < ann_number; i++) {
- locations.add(parseAnnotationLocation(data));
- annotations.add(StructAnnotationAttribute.parseAnnotation(data, pool));
- }
-
- } catch(IOException ex) {
- throw new RuntimeException(ex);
- }
- }
-
- public AnnotationLocation parseAnnotationLocation(DataInputStream data) throws IOException {
-
- AnnotationLocation ann_location = new AnnotationLocation();
-
- // target type
-
- ann_location.target_type = data.readUnsignedByte();
-
- // target union
-
- switch(ann_location.target_type) {
- case ANNOTATION_TARGET_TYPE_GENERIC_CLASS:
- case ANNOTATION_TARGET_TYPE_GENERIC_METHOD:
- ann_location.target_union = ANNOTATION_TARGET_UNION_TYPE_PARAMETER;
- break;
- case ANNOTATION_TARGET_TYPE_EXTENDS_IMPLEMENTS:
- ann_location.target_union = ANNOTATION_TARGET_UNION_SUPERTYPE;
- break;
- case ANNOTATION_TARGET_TYPE_GENERIC_CLASS_BOUND:
- case ANNOTATION_TARGET_TYPE_GENERIC_METHOD_BOUND:
- ann_location.target_union = ANNOTATION_TARGET_UNION_TYPE_PARAMETER_BOUND;
- break;
- case ANNOTATION_TARGET_TYPE_FIELD:
- case ANNOTATION_TARGET_TYPE_RETURN:
- case ANNOTATION_TARGET_TYPE_RECEIVER:
- ann_location.target_union = ANNOTATION_TARGET_UNION_EMPTY;
- break;
- case ANNOTATION_TARGET_TYPE_FORMAL:
- ann_location.target_union = ANNOTATION_TARGET_UNION_FORMAL_PARAMETER;
- break;
- case ANNOTATION_TARGET_TYPE_THROWS:
- ann_location.target_union = ANNOTATION_TARGET_UNION_THROWS;
- break;
- case ANNOTATION_TARGET_TYPE_LOCAL_VARIABLE:
- case ANNOTATION_TARGET_TYPE_RESOURCE_VARIABLE:
- ann_location.target_union = ANNOTATION_TARGET_UNION_LOCALVAR;
- break;
- case ANNOTATION_TARGET_TYPE_EXCEPTION:
- ann_location.target_union = ANNOTATION_TARGET_UNION_CATCH;
- break;
- case ANNOTATION_TARGET_TYPE_INSTANCEOF:
- case ANNOTATION_TARGET_TYPE_NEW:
- case ANNOTATION_TARGET_TYPE_DOUBLECOLON_NEW:
- case ANNOTATION_TARGET_TYPE_DOUBLECOLON_ID:
- ann_location.target_union = ANNOTATION_TARGET_UNION_OFFSET;
- break;
- case ANNOTATION_TARGET_TYPE_CAST:
- case ANNOTATION_TARGET_TYPE_INVOKATION_CONSTRUCTOR:
- case ANNOTATION_TARGET_TYPE_INVOKATION_METHOD:
- case ANNOTATION_TARGET_TYPE_GENERIC_DOUBLECOLON_NEW:
- case ANNOTATION_TARGET_TYPE_GENERIC_DOUBLECOLON_ID:
- ann_location.target_union = ANNOTATION_TARGET_UNION_TYPE_ARGUMENT;
- break;
- default:
- throw new RuntimeException("Unknown target type in a type annotation!");
- }
-
- // target union data
-
- switch(ann_location.target_union) {
- case ANNOTATION_TARGET_UNION_TYPE_PARAMETER:
- case ANNOTATION_TARGET_UNION_FORMAL_PARAMETER:
- ann_location.data = new int[] {data.readUnsignedByte()};
- break;
- case ANNOTATION_TARGET_UNION_SUPERTYPE:
- case ANNOTATION_TARGET_UNION_THROWS:
- case ANNOTATION_TARGET_UNION_CATCH:
- case ANNOTATION_TARGET_UNION_OFFSET:
- ann_location.data = new int[] {data.readUnsignedShort()};
- break;
- case ANNOTATION_TARGET_UNION_TYPE_PARAMETER_BOUND:
- ann_location.data = new int[] {data.readUnsignedByte(), data.readUnsignedByte()};
- break;
- case ANNOTATION_TARGET_UNION_EMPTY:
- break;
- case ANNOTATION_TARGET_UNION_LOCALVAR:
- int table_length = data.readUnsignedShort();
-
- ann_location.data = new int[table_length * 3 + 1];
- ann_location.data[0] = table_length;
-
- for(int i = 0; i < table_length; ++i) {
- ann_location.data[3 * i + 1] = data.readUnsignedShort();
- ann_location.data[3 * i + 2] = data.readUnsignedShort();
- ann_location.data[3 * i + 3] = data.readUnsignedShort();
- }
- break;
- case ANNOTATION_TARGET_UNION_TYPE_ARGUMENT:
- ann_location.data = new int[] {data.readUnsignedShort(), data.readUnsignedByte()};
- }
-
- // target path
-
- int path_length = data.readUnsignedByte();
-
- ann_location.target_path_kind = new int[path_length];
- ann_location.target_argument_index = new int[path_length];
-
- for(int i = 0; i < path_length; ++i) {
- ann_location.target_path_kind[i] = data.readUnsignedByte();
- ann_location.target_argument_index[i] = data.readUnsignedByte();
- }
-
- return ann_location;
- }
-
- private static class AnnotationLocation {
-
- public int target_type;
- public int target_union;
-
- public int[] data;
-
- public int[] target_path_kind;
- public int[] target_argument_index;
- }
+
+ public static final int ANNOTATION_TARGET_TYPE_GENERIC_CLASS = 0x00;
+ public static final int ANNOTATION_TARGET_TYPE_GENERIC_METHOD = 0x01;
+ public static final int ANNOTATION_TARGET_TYPE_EXTENDS_IMPLEMENTS = 0x10;
+ public static final int ANNOTATION_TARGET_TYPE_GENERIC_CLASS_BOUND = 0x11;
+ public static final int ANNOTATION_TARGET_TYPE_GENERIC_METHOD_BOUND = 0x12;
+ public static final int ANNOTATION_TARGET_TYPE_FIELD = 0x13;
+ public static final int ANNOTATION_TARGET_TYPE_RETURN = 0x14;
+ public static final int ANNOTATION_TARGET_TYPE_RECEIVER = 0x15;
+ public static final int ANNOTATION_TARGET_TYPE_FORMAL = 0x16;
+ public static final int ANNOTATION_TARGET_TYPE_THROWS = 0x17;
+ public static final int ANNOTATION_TARGET_TYPE_LOCAL_VARIABLE = 0x40;
+ public static final int ANNOTATION_TARGET_TYPE_RESOURCE_VARIABLE = 0x41;
+ public static final int ANNOTATION_TARGET_TYPE_EXCEPTION = 0x42;
+ public static final int ANNOTATION_TARGET_TYPE_INSTANCEOF = 0x43;
+ public static final int ANNOTATION_TARGET_TYPE_NEW = 0x44;
+ public static final int ANNOTATION_TARGET_TYPE_DOUBLECOLON_NEW = 0x45;
+ public static final int ANNOTATION_TARGET_TYPE_DOUBLECOLON_ID = 0x46;
+ public static final int ANNOTATION_TARGET_TYPE_CAST = 0x47;
+ public static final int ANNOTATION_TARGET_TYPE_INVOKATION_CONSTRUCTOR = 0x48;
+ public static final int ANNOTATION_TARGET_TYPE_INVOKATION_METHOD = 0x49;
+ public static final int ANNOTATION_TARGET_TYPE_GENERIC_DOUBLECOLON_NEW = 0x4A;
+ public static final int ANNOTATION_TARGET_TYPE_GENERIC_DOUBLECOLON_ID = 0x4B;
+
+ public static final int ANNOTATION_TARGET_UNION_TYPE_PARAMETER = 1;
+ public static final int ANNOTATION_TARGET_UNION_SUPERTYPE = 2;
+ public static final int ANNOTATION_TARGET_UNION_TYPE_PARAMETER_BOUND = 3;
+ public static final int ANNOTATION_TARGET_UNION_EMPTY = 4;
+ public static final int ANNOTATION_TARGET_UNION_FORMAL_PARAMETER = 5;
+ public static final int ANNOTATION_TARGET_UNION_THROWS = 6;
+ public static final int ANNOTATION_TARGET_UNION_LOCALVAR = 7;
+ public static final int ANNOTATION_TARGET_UNION_CATCH = 8;
+ public static final int ANNOTATION_TARGET_UNION_OFFSET = 9;
+ public static final int ANNOTATION_TARGET_UNION_TYPE_ARGUMENT = 10;
+
+
+ List<AnnotationLocation> locations = new ArrayList<AnnotationLocation>();
+ List<AnnotationExprent> annotations = new ArrayList<AnnotationExprent>();
+
+ public void initContent(ConstantPool pool) {
+
+ super.initContent(pool);
+
+ DataInputStream data = new DataInputStream(new ByteArrayInputStream(info));
+
+ try {
+
+ int ann_number = data.readUnsignedByte();
+ for (int i = 0; i < ann_number; i++) {
+ locations.add(parseAnnotationLocation(data));
+ annotations.add(StructAnnotationAttribute.parseAnnotation(data, pool));
+ }
+ }
+ catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ public AnnotationLocation parseAnnotationLocation(DataInputStream data) throws IOException {
+
+ AnnotationLocation ann_location = new AnnotationLocation();
+
+ // target type
+
+ ann_location.target_type = data.readUnsignedByte();
+
+ // target union
+
+ switch (ann_location.target_type) {
+ case ANNOTATION_TARGET_TYPE_GENERIC_CLASS:
+ case ANNOTATION_TARGET_TYPE_GENERIC_METHOD:
+ ann_location.target_union = ANNOTATION_TARGET_UNION_TYPE_PARAMETER;
+ break;
+ case ANNOTATION_TARGET_TYPE_EXTENDS_IMPLEMENTS:
+ ann_location.target_union = ANNOTATION_TARGET_UNION_SUPERTYPE;
+ break;
+ case ANNOTATION_TARGET_TYPE_GENERIC_CLASS_BOUND:
+ case ANNOTATION_TARGET_TYPE_GENERIC_METHOD_BOUND:
+ ann_location.target_union = ANNOTATION_TARGET_UNION_TYPE_PARAMETER_BOUND;
+ break;
+ case ANNOTATION_TARGET_TYPE_FIELD:
+ case ANNOTATION_TARGET_TYPE_RETURN:
+ case ANNOTATION_TARGET_TYPE_RECEIVER:
+ ann_location.target_union = ANNOTATION_TARGET_UNION_EMPTY;
+ break;
+ case ANNOTATION_TARGET_TYPE_FORMAL:
+ ann_location.target_union = ANNOTATION_TARGET_UNION_FORMAL_PARAMETER;
+ break;
+ case ANNOTATION_TARGET_TYPE_THROWS:
+ ann_location.target_union = ANNOTATION_TARGET_UNION_THROWS;
+ break;
+ case ANNOTATION_TARGET_TYPE_LOCAL_VARIABLE:
+ case ANNOTATION_TARGET_TYPE_RESOURCE_VARIABLE:
+ ann_location.target_union = ANNOTATION_TARGET_UNION_LOCALVAR;
+ break;
+ case ANNOTATION_TARGET_TYPE_EXCEPTION:
+ ann_location.target_union = ANNOTATION_TARGET_UNION_CATCH;
+ break;
+ case ANNOTATION_TARGET_TYPE_INSTANCEOF:
+ case ANNOTATION_TARGET_TYPE_NEW:
+ case ANNOTATION_TARGET_TYPE_DOUBLECOLON_NEW:
+ case ANNOTATION_TARGET_TYPE_DOUBLECOLON_ID:
+ ann_location.target_union = ANNOTATION_TARGET_UNION_OFFSET;
+ break;
+ case ANNOTATION_TARGET_TYPE_CAST:
+ case ANNOTATION_TARGET_TYPE_INVOKATION_CONSTRUCTOR:
+ case ANNOTATION_TARGET_TYPE_INVOKATION_METHOD:
+ case ANNOTATION_TARGET_TYPE_GENERIC_DOUBLECOLON_NEW:
+ case ANNOTATION_TARGET_TYPE_GENERIC_DOUBLECOLON_ID:
+ ann_location.target_union = ANNOTATION_TARGET_UNION_TYPE_ARGUMENT;
+ break;
+ default:
+ throw new RuntimeException("Unknown target type in a type annotation!");
+ }
+
+ // target union data
+
+ switch (ann_location.target_union) {
+ case ANNOTATION_TARGET_UNION_TYPE_PARAMETER:
+ case ANNOTATION_TARGET_UNION_FORMAL_PARAMETER:
+ ann_location.data = new int[]{data.readUnsignedByte()};
+ break;
+ case ANNOTATION_TARGET_UNION_SUPERTYPE:
+ case ANNOTATION_TARGET_UNION_THROWS:
+ case ANNOTATION_TARGET_UNION_CATCH:
+ case ANNOTATION_TARGET_UNION_OFFSET:
+ ann_location.data = new int[]{data.readUnsignedShort()};
+ break;
+ case ANNOTATION_TARGET_UNION_TYPE_PARAMETER_BOUND:
+ ann_location.data = new int[]{data.readUnsignedByte(), data.readUnsignedByte()};
+ break;
+ case ANNOTATION_TARGET_UNION_EMPTY:
+ break;
+ case ANNOTATION_TARGET_UNION_LOCALVAR:
+ int table_length = data.readUnsignedShort();
+
+ ann_location.data = new int[table_length * 3 + 1];
+ ann_location.data[0] = table_length;
+
+ for (int i = 0; i < table_length; ++i) {
+ ann_location.data[3 * i + 1] = data.readUnsignedShort();
+ ann_location.data[3 * i + 2] = data.readUnsignedShort();
+ ann_location.data[3 * i + 3] = data.readUnsignedShort();
+ }
+ break;
+ case ANNOTATION_TARGET_UNION_TYPE_ARGUMENT:
+ ann_location.data = new int[]{data.readUnsignedShort(), data.readUnsignedByte()};
+ }
+
+ // target path
+
+ int path_length = data.readUnsignedByte();
+
+ ann_location.target_path_kind = new int[path_length];
+ ann_location.target_argument_index = new int[path_length];
+
+ for (int i = 0; i < path_length; ++i) {
+ ann_location.target_path_kind[i] = data.readUnsignedByte();
+ ann_location.target_argument_index[i] = data.readUnsignedByte();
+ }
+
+ return ann_location;
+ }
+
+ private static class AnnotationLocation {
+
+ public int target_type;
+ public int target_union;
+
+ public int[] data;
+
+ public int[] target_path_kind;
+ public int[] target_argument_index;
+ }
}
diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructBootstrapMethodsAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructBootstrapMethodsAttribute.java
index ac51027..717bad9 100644
--- a/src/org/jetbrains/java/decompiler/struct/attr/StructBootstrapMethodsAttribute.java
+++ b/src/org/jetbrains/java/decompiler/struct/attr/StructBootstrapMethodsAttribute.java
@@ -1,62 +1,75 @@
+/*
+ * 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.attr;
+import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
+import org.jetbrains.java.decompiler.struct.consts.LinkConstant;
+import org.jetbrains.java.decompiler.struct.consts.PooledConstant;
+
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
-import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
-import org.jetbrains.java.decompiler.struct.consts.LinkConstant;
-import org.jetbrains.java.decompiler.struct.consts.PooledConstant;
-
public class StructBootstrapMethodsAttribute extends StructGeneralAttribute {
-
- private List<LinkConstant> method_refs = new ArrayList<LinkConstant>();
- private List<List<PooledConstant>> method_arguments = new ArrayList<List<PooledConstant>>();
-
- public void initContent(ConstantPool pool) {
-
- name = ATTRIBUTE_BOOTSTRAP_METHODS;
-
- try {
-
- DataInputStream data = new DataInputStream(new ByteArrayInputStream(info, 0, info.length));
-
- int method_number = data.readUnsignedShort();
-
- for(int i = 0; i < method_number; ++i) {
- int bootstrap_method_ref = data.readUnsignedShort();
- int num_bootstrap_arguments = data.readUnsignedShort();
-
- List<PooledConstant> list_arguments = new ArrayList<PooledConstant>();
-
- for(int j = 0; j < num_bootstrap_arguments; ++j) {
- int bootstrap_argument_ref = data.readUnsignedShort();
-
- list_arguments.add(pool.getConstant(bootstrap_argument_ref));
- }
-
- method_refs.add(pool.getLinkConstant(bootstrap_method_ref));
- method_arguments.add(list_arguments);
- }
-
- } catch(IOException ex) {
- throw new RuntimeException(ex);
- }
-
- }
-
- public int getMethodsNumber() {
- return method_refs.size();
- }
-
- public LinkConstant getMethodReference(int index) {
- return method_refs.get(index);
- }
-
- public List<PooledConstant> getMethodArguments(int index) {
- return method_arguments.get(index);
- }
-
+
+ private List<LinkConstant> method_refs = new ArrayList<LinkConstant>();
+ private List<List<PooledConstant>> method_arguments = new ArrayList<List<PooledConstant>>();
+
+ public void initContent(ConstantPool pool) {
+
+ name = ATTRIBUTE_BOOTSTRAP_METHODS;
+
+ try {
+
+ DataInputStream data = new DataInputStream(new ByteArrayInputStream(info, 0, info.length));
+
+ int method_number = data.readUnsignedShort();
+
+ for (int i = 0; i < method_number; ++i) {
+ int bootstrap_method_ref = data.readUnsignedShort();
+ int num_bootstrap_arguments = data.readUnsignedShort();
+
+ List<PooledConstant> list_arguments = new ArrayList<PooledConstant>();
+
+ for (int j = 0; j < num_bootstrap_arguments; ++j) {
+ int bootstrap_argument_ref = data.readUnsignedShort();
+
+ list_arguments.add(pool.getConstant(bootstrap_argument_ref));
+ }
+
+ method_refs.add(pool.getLinkConstant(bootstrap_method_ref));
+ method_arguments.add(list_arguments);
+ }
+ }
+ catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ public int getMethodsNumber() {
+ return method_refs.size();
+ }
+
+ public LinkConstant getMethodReference(int index) {
+ return method_refs.get(index);
+ }
+
+ public List<PooledConstant> getMethodArguments(int index) {
+ return method_arguments.get(index);
+ }
}
diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructConstantValueAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructConstantValueAttribute.java
index f186767..ae3bd1d 100644
--- a/src/org/jetbrains/java/decompiler/struct/attr/StructConstantValueAttribute.java
+++ b/src/org/jetbrains/java/decompiler/struct/attr/StructConstantValueAttribute.java
@@ -1,34 +1,33 @@
/*
- * 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.attr;
import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
public class StructConstantValueAttribute extends StructGeneralAttribute {
- private int index;
+ private int index;
+
+ public void initContent(ConstantPool pool) {
- public void initContent(ConstantPool pool) {
+ name = ATTRIBUTE_CONSTANT_VALUE;
+ index = ((info[0] & 0xFF) << 8) | (info[1] & 0xFF);
+ }
- name = ATTRIBUTE_CONSTANT_VALUE;
- index = ((info[0] & 0xFF)<<8) | (info[1] & 0xFF);
- }
-
- public int getIndex() {
- return index;
- }
-
-
+ public int getIndex() {
+ return index;
+ }
}
diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructEnclosingMethodAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructEnclosingMethodAttribute.java
index 61bb886..ebf9407 100644
--- a/src/org/jetbrains/java/decompiler/struct/attr/StructEnclosingMethodAttribute.java
+++ b/src/org/jetbrains/java/decompiler/struct/attr/StructEnclosingMethodAttribute.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.attr;
import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
@@ -19,39 +20,37 @@ import org.jetbrains.java.decompiler.struct.consts.LinkConstant;
public class StructEnclosingMethodAttribute extends StructGeneralAttribute {
- private String classname;
-
- private String mtname;
-
- private String methodDescriptor;
-
- public void initContent(ConstantPool pool) {
-
- name = ATTRIBUTE_ENCLOSING_METHOD;
-
- int clindex = (((info[0] & 0xFF)<<8) | (info[1] & 0xFF));
- int mtindex = (((info[2] & 0xFF)<<8) | (info[3] & 0xFF));
-
- classname = pool.getPrimitiveConstant(clindex).getString();
- if(mtindex != 0) {
- LinkConstant lk = pool.getLinkConstant(mtindex);
-
- mtname = lk.elementname;
- methodDescriptor = lk.descriptor;
- }
- }
-
- public String getClassname() {
- return classname;
- }
-
- public String getMethodDescriptor() {
- return methodDescriptor;
- }
-
- public String getMethodName() {
- return mtname;
- }
-
-
+ private String classname;
+
+ private String mtname;
+
+ private String methodDescriptor;
+
+ public void initContent(ConstantPool pool) {
+
+ name = ATTRIBUTE_ENCLOSING_METHOD;
+
+ int clindex = (((info[0] & 0xFF) << 8) | (info[1] & 0xFF));
+ int mtindex = (((info[2] & 0xFF) << 8) | (info[3] & 0xFF));
+
+ classname = pool.getPrimitiveConstant(clindex).getString();
+ if (mtindex != 0) {
+ LinkConstant lk = pool.getLinkConstant(mtindex);
+
+ mtname = lk.elementname;
+ methodDescriptor = lk.descriptor;
+ }
+ }
+
+ public String getClassname() {
+ return classname;
+ }
+
+ public String getMethodDescriptor() {
+ return methodDescriptor;
+ }
+
+ public String getMethodName() {
+ return mtname;
+ }
}
diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructExceptionsAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructExceptionsAttribute.java
index 4d6bd4c..930db78 100644
--- a/src/org/jetbrains/java/decompiler/struct/attr/StructExceptionsAttribute.java
+++ b/src/org/jetbrains/java/decompiler/struct/attr/StructExceptionsAttribute.java
@@ -1,78 +1,76 @@
/*
- * 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.attr;
+import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
+
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
-import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
-
public class StructExceptionsAttribute extends StructGeneralAttribute {
- private List<Integer> throwsExceptions = new ArrayList<Integer>();
-
- public void initContent(ConstantPool pool) {
-
- name = ATTRIBUTE_EXCEPTIONS;
-
- int length = 2+(((info[0] & 0xFF)<<8) | (info[1] & 0xFF))*2;
- for(int i=2;i<length;i+=2) {
- int index = ((info[i] & 0xFF)<<8) | (info[i+1] & 0xFF);
- throwsExceptions.add(index);
- }
-
- }
-
- public void writeToStream(DataOutputStream out) throws IOException {
-
- out.writeShort(attribute_name_index);
-
- ByteArrayOutputStream codeout = new ByteArrayOutputStream();
- DataOutputStream dataout = new DataOutputStream(codeout);
-
- int len = throwsExceptions.size();
- dataout.writeShort(len);
-
- if(len>0) {
- info = new byte[len*2];
- for(int i=0,j=0;i<len;i++,j+=2) {
- int index = ((Integer)throwsExceptions.get(i)).intValue();
- info[j] = (byte)(index >> 8);
- info[j+1] = (byte)(index & 0xFF);
- }
- dataout.write(info);
- }
-
- out.writeInt(codeout.size());
- out.write(codeout.toByteArray());
- }
-
- public String getExcClassname(int index, ConstantPool pool) {
- return pool.getPrimitiveConstant(((Integer)throwsExceptions.get(index)).intValue()).getString();
- }
-
- public List<Integer> getThrowsExceptions() {
- return throwsExceptions;
- }
-
- public void setThrowsExceptions(List<Integer> throwsExceptions) {
- this.throwsExceptions = throwsExceptions;
- }
-
-
+ private List<Integer> throwsExceptions = new ArrayList<Integer>();
+
+ public void initContent(ConstantPool pool) {
+
+ name = ATTRIBUTE_EXCEPTIONS;
+
+ int length = 2 + (((info[0] & 0xFF) << 8) | (info[1] & 0xFF)) * 2;
+ for (int i = 2; i < length; i += 2) {
+ int index = ((info[i] & 0xFF) << 8) | (info[i + 1] & 0xFF);
+ throwsExceptions.add(index);
+ }
+ }
+
+ public void writeToStream(DataOutputStream out) throws IOException {
+
+ out.writeShort(attribute_name_index);
+
+ ByteArrayOutputStream codeout = new ByteArrayOutputStream();
+ DataOutputStream dataout = new DataOutputStream(codeout);
+
+ int len = throwsExceptions.size();
+ dataout.writeShort(len);
+
+ if (len > 0) {
+ info = new byte[len * 2];
+ for (int i = 0, j = 0; i < len; i++, j += 2) {
+ int index = ((Integer)throwsExceptions.get(i)).intValue();
+ info[j] = (byte)(index >> 8);
+ info[j + 1] = (byte)(index & 0xFF);
+ }
+ dataout.write(info);
+ }
+
+ out.writeInt(codeout.size());
+ out.write(codeout.toByteArray());
+ }
+
+ public String getExcClassname(int index, ConstantPool pool) {
+ return pool.getPrimitiveConstant(((Integer)throwsExceptions.get(index)).intValue()).getString();
+ }
+
+ public List<Integer> getThrowsExceptions() {
+ return throwsExceptions;
+ }
+
+ public void setThrowsExceptions(List<Integer> throwsExceptions) {
+ this.throwsExceptions = throwsExceptions;
+ }
}
diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructGeneralAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructGeneralAttribute.java
index 2648b3c..bd0596a 100644
--- a/src/org/jetbrains/java/decompiler/struct/attr/StructGeneralAttribute.java
+++ b/src/org/jetbrains/java/decompiler/struct/attr/StructGeneralAttribute.java
@@ -1,24 +1,25 @@
/*
- * 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.attr;
+import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
+
import java.io.DataOutputStream;
import java.io.IOException;
-import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
-
/*
attribute_info {
u2 attribute_name_index;
@@ -29,117 +30,128 @@ import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
public class StructGeneralAttribute {
- public static final String ATTRIBUTE_CODE = "Code";
- public static final String ATTRIBUTE_INNER_CLASSES = "InnerClasses";
- public static final String ATTRIBUTE_SIGNATURE = "Signature";
- public static final String ATTRIBUTE_ANNOTATION_DEFAULT = "AnnotationDefault";
- public static final String ATTRIBUTE_EXCEPTIONS = "Exceptions";
- public static final String ATTRIBUTE_ENCLOSING_METHOD = "EnclosingMethod";
- public static final String ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS = "RuntimeVisibleAnnotations";
- public static final String ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS = "RuntimeInvisibleAnnotations";
- public static final String ATTRIBUTE_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS = "RuntimeVisibleParameterAnnotations";
- public static final String ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS = "RuntimeInvisibleParameterAnnotations";
- public static final String ATTRIBUTE_RUNTIME_VISIBLE_TYPE_ANNOTATIONS = "RuntimeVisibleTypeAnnotations";
- public static final String ATTRIBUTE_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS = "RuntimeInvisibleTypeAnnotations";
- public static final String ATTRIBUTE_LOCAL_VARIABLE_TABLE = "LocalVariableTable";
- public static final String ATTRIBUTE_CONSTANT_VALUE = "ConstantValue";
- public static final String ATTRIBUTE_BOOTSTRAP_METHODS = "BootstrapMethods";
+ public static final String ATTRIBUTE_CODE = "Code";
+ public static final String ATTRIBUTE_INNER_CLASSES = "InnerClasses";
+ public static final String ATTRIBUTE_SIGNATURE = "Signature";
+ public static final String ATTRIBUTE_ANNOTATION_DEFAULT = "AnnotationDefault";
+ public static final String ATTRIBUTE_EXCEPTIONS = "Exceptions";
+ public static final String ATTRIBUTE_ENCLOSING_METHOD = "EnclosingMethod";
+ public static final String ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS = "RuntimeVisibleAnnotations";
+ public static final String ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS = "RuntimeInvisibleAnnotations";
+ public static final String ATTRIBUTE_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS = "RuntimeVisibleParameterAnnotations";
+ public static final String ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS = "RuntimeInvisibleParameterAnnotations";
+ public static final String ATTRIBUTE_RUNTIME_VISIBLE_TYPE_ANNOTATIONS = "RuntimeVisibleTypeAnnotations";
+ public static final String ATTRIBUTE_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS = "RuntimeInvisibleTypeAnnotations";
+ public static final String ATTRIBUTE_LOCAL_VARIABLE_TABLE = "LocalVariableTable";
+ public static final String ATTRIBUTE_CONSTANT_VALUE = "ConstantValue";
+ public static final String ATTRIBUTE_BOOTSTRAP_METHODS = "BootstrapMethods";
public static final String ATTRIBUTE_SYNTHETIC = "Synthetic";
public static final String ATTRIBUTE_DEPRECATED = "Deprecated";
- // *****************************************************************************
- // private fields
- // *****************************************************************************
-
- protected int attribute_name_index;
-
- protected byte[] info;
-
- protected String name;
-
- // *****************************************************************************
- // public methods
- // *****************************************************************************
-
- public void writeToStream(DataOutputStream out) throws IOException {
- out.writeShort(attribute_name_index);
- out.writeInt(info.length);
- if(info.length>0) {
- out.write(info);
- }
- }
-
- public void initContent(ConstantPool pool) {
- name = pool.getPrimitiveConstant(attribute_name_index).getString();
- }
-
- public static StructGeneralAttribute getMatchingAttributeInstance(int nameindex, String attrname) {
-
- StructGeneralAttribute attr;
-
- if(ATTRIBUTE_INNER_CLASSES.equals(attrname)) {
- attr = new StructInnerClassesAttribute();
- } else if(ATTRIBUTE_CONSTANT_VALUE.equals(attrname)) {
- attr = new StructConstantValueAttribute();
- } else if(ATTRIBUTE_SIGNATURE.equals(attrname)) {
- attr = new StructGenericSignatureAttribute();
- } else if(ATTRIBUTE_ANNOTATION_DEFAULT.equals(attrname)) {
- attr = new StructAnnDefaultAttribute();
- } else if(ATTRIBUTE_EXCEPTIONS.equals(attrname)) {
- attr = new StructExceptionsAttribute();
- } else if(ATTRIBUTE_ENCLOSING_METHOD.equals(attrname)) {
- attr = new StructEnclosingMethodAttribute();
- } else if(ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS.equals(attrname) ||
- ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS.equals(attrname)) {
- attr = new StructAnnotationAttribute();
- } else if(ATTRIBUTE_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS.equals(attrname) ||
- ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS.equals(attrname)) {
- attr = new StructAnnotationParameterAttribute();
- } else if(ATTRIBUTE_RUNTIME_VISIBLE_TYPE_ANNOTATIONS.equals(attrname) ||
- ATTRIBUTE_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS.equals(attrname)) {
- attr = new StructAnnotationTypeAttribute();
- } else if(ATTRIBUTE_LOCAL_VARIABLE_TABLE.equals(attrname)) {
- attr = new StructLocalVariableTableAttribute();
- } else if(ATTRIBUTE_BOOTSTRAP_METHODS.equals(attrname)) {
- attr = new StructBootstrapMethodsAttribute();
- } else if(ATTRIBUTE_SYNTHETIC.equals(attrname) || ATTRIBUTE_DEPRECATED.equals(attrname)) {
- attr = new StructGeneralAttribute();
- } else {
- // unsupported attribute
- return null;
- }
-
- attr.setAttribute_name_index(nameindex);
- return attr;
- }
-
- // *****************************************************************************
- // getter and setter methods
- // *****************************************************************************
-
- public byte[] getInfo() {
- return info;
- }
-
- public void setInfo(byte[] info) {
- this.info = info;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public int getAttribute_name_index() {
- return attribute_name_index;
- }
-
- public void setAttribute_name_index(int attribute_name_index) {
- this.attribute_name_index = attribute_name_index;
- }
-
+ // *****************************************************************************
+ // private fields
+ // *****************************************************************************
+
+ protected int attribute_name_index;
+
+ protected byte[] info;
+
+ protected String name;
+
+ // *****************************************************************************
+ // public methods
+ // *****************************************************************************
+
+ public void writeToStream(DataOutputStream out) throws IOException {
+ out.writeShort(attribute_name_index);
+ out.writeInt(info.length);
+ if (info.length > 0) {
+ out.write(info);
+ }
+ }
+
+ public void initContent(ConstantPool pool) {
+ name = pool.getPrimitiveConstant(attribute_name_index).getString();
+ }
+
+ public static StructGeneralAttribute getMatchingAttributeInstance(int nameindex, String attrname) {
+
+ StructGeneralAttribute attr;
+
+ if (ATTRIBUTE_INNER_CLASSES.equals(attrname)) {
+ attr = new StructInnerClassesAttribute();
+ }
+ else if (ATTRIBUTE_CONSTANT_VALUE.equals(attrname)) {
+ attr = new StructConstantValueAttribute();
+ }
+ else if (ATTRIBUTE_SIGNATURE.equals(attrname)) {
+ attr = new StructGenericSignatureAttribute();
+ }
+ else if (ATTRIBUTE_ANNOTATION_DEFAULT.equals(attrname)) {
+ attr = new StructAnnDefaultAttribute();
+ }
+ else if (ATTRIBUTE_EXCEPTIONS.equals(attrname)) {
+ attr = new StructExceptionsAttribute();
+ }
+ else if (ATTRIBUTE_ENCLOSING_METHOD.equals(attrname)) {
+ attr = new StructEnclosingMethodAttribute();
+ }
+ else if (ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS.equals(attrname) ||
+ ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS.equals(attrname)) {
+ attr = new StructAnnotationAttribute();
+ }
+ else if (ATTRIBUTE_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS.equals(attrname) ||
+ ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS.equals(attrname)) {
+ attr = new StructAnnotationParameterAttribute();
+ }
+ else if (ATTRIBUTE_RUNTIME_VISIBLE_TYPE_ANNOTATIONS.equals(attrname) ||
+ ATTRIBUTE_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS.equals(attrname)) {
+ attr = new StructAnnotationTypeAttribute();
+ }
+ else if (ATTRIBUTE_LOCAL_VARIABLE_TABLE.equals(attrname)) {
+ attr = new StructLocalVariableTableAttribute();
+ }
+ else if (ATTRIBUTE_BOOTSTRAP_METHODS.equals(attrname)) {
+ attr = new StructBootstrapMethodsAttribute();
+ }
+ else if (ATTRIBUTE_SYNTHETIC.equals(attrname) || ATTRIBUTE_DEPRECATED.equals(attrname)) {
+ attr = new StructGeneralAttribute();
+ }
+ else {
+ // unsupported attribute
+ return null;
+ }
+
+ attr.setAttribute_name_index(nameindex);
+ return attr;
+ }
+
+ // *****************************************************************************
+ // getter and setter methods
+ // *****************************************************************************
+
+ public byte[] getInfo() {
+ return info;
+ }
+
+ public void setInfo(byte[] info) {
+ this.info = info;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getAttribute_name_index() {
+ return attribute_name_index;
+ }
+
+ public void setAttribute_name_index(int attribute_name_index) {
+ this.attribute_name_index = attribute_name_index;
+ }
}
diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructGenericSignatureAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructGenericSignatureAttribute.java
index 11206e0..6f2224c 100644
--- a/src/org/jetbrains/java/decompiler/struct/attr/StructGenericSignatureAttribute.java
+++ b/src/org/jetbrains/java/decompiler/struct/attr/StructGenericSignatureAttribute.java
@@ -1,34 +1,33 @@
/*
- * 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.attr;
import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
public class StructGenericSignatureAttribute extends StructGeneralAttribute {
- private String signature;
+ private String signature;
+
+ public void initContent(ConstantPool pool) {
- public void initContent(ConstantPool pool) {
+ name = ATTRIBUTE_SIGNATURE;
+ signature = pool.getPrimitiveConstant(((info[0] & 0xFF) << 8) | (info[1] & 0xFF)).getString();
+ }
- name = ATTRIBUTE_SIGNATURE;
- signature = pool.getPrimitiveConstant(((info[0] & 0xFF)<<8) | (info[1] & 0xFF)).getString();
- }
-
- public String getSignature() {
- return signature;
- }
-
-
+ public String getSignature() {
+ return signature;
+ }
}
diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructInnerClassesAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructInnerClassesAttribute.java
index 794da15..14ecd36 100644
--- a/src/org/jetbrains/java/decompiler/struct/attr/StructInnerClassesAttribute.java
+++ b/src/org/jetbrains/java/decompiler/struct/attr/StructInnerClassesAttribute.java
@@ -1,73 +1,72 @@
/*
- * 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.attr;
+import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
+
import java.util.ArrayList;
import java.util.List;
-import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
-
public class StructInnerClassesAttribute extends StructGeneralAttribute {
- private List<int[]> classentries = new ArrayList<int[]>();
-
- private List<String[]> stringentries = new ArrayList<String[]>();
-
- public void initContent(ConstantPool pool) {
-
- name = ATTRIBUTE_INNER_CLASSES;
-
- int length = 2+(((info[0] & 0xFF)<<8) | (info[1] & 0xFF))*8;
- int i=2;
-
- while(i<length) {
-
- int[] arr = new int[4];
- for(int j=0;j<4;j++) {
- arr[j] = ((info[i] & 0xFF)<<8) | (info[i+1] & 0xFF);
- i+=2;
- }
-
- classentries.add(arr);
- }
-
- for(int[] entry: classentries) {
-
- String[] arr = new String[3];
- // inner name
- arr[0] = pool.getPrimitiveConstant(entry[0]).getString();
- //enclosing class
- if(entry[1] != 0) {
- arr[1] = pool.getPrimitiveConstant(entry[1]).getString();
- }
- // original simple name
- if(entry[2]!=0) {
- arr[2] = pool.getPrimitiveConstant(entry[2]).getString();
- }
-
- stringentries.add(arr);
- }
-
- }
-
- public List<int[]> getClassentries() {
- return classentries;
- }
-
- public List<String[]> getStringentries() {
- return stringentries;
- }
+ private List<int[]> classentries = new ArrayList<int[]>();
+
+ private List<String[]> stringentries = new ArrayList<String[]>();
+
+ public void initContent(ConstantPool pool) {
+
+ name = ATTRIBUTE_INNER_CLASSES;
+
+ int length = 2 + (((info[0] & 0xFF) << 8) | (info[1] & 0xFF)) * 8;
+ int i = 2;
+
+ while (i < length) {
+
+ int[] arr = new int[4];
+ for (int j = 0; j < 4; j++) {
+ arr[j] = ((info[i] & 0xFF) << 8) | (info[i + 1] & 0xFF);
+ i += 2;
+ }
+
+ classentries.add(arr);
+ }
+
+ for (int[] entry : classentries) {
+
+ String[] arr = new String[3];
+ // inner name
+ arr[0] = pool.getPrimitiveConstant(entry[0]).getString();
+ //enclosing class
+ if (entry[1] != 0) {
+ arr[1] = pool.getPrimitiveConstant(entry[1]).getString();
+ }
+ // original simple name
+ if (entry[2] != 0) {
+ arr[2] = pool.getPrimitiveConstant(entry[2]).getString();
+ }
+
+ stringentries.add(arr);
+ }
+ }
+
+ public List<int[]> getClassentries() {
+ return classentries;
+ }
+ public List<String[]> getStringentries() {
+ return stringentries;
+ }
}
diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTableAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTableAttribute.java
index 119d1ff..0cf2a89 100644
--- a/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTableAttribute.java
+++ b/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTableAttribute.java
@@ -1,47 +1,48 @@
/*
- * 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.attr;
-import java.util.HashMap;
-
import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
+import java.util.HashMap;
+
public class StructLocalVariableTableAttribute extends StructGeneralAttribute {
- private HashMap<Integer, String> mapVarNames = new HashMap<Integer, String>();
-
- public void initContent(ConstantPool pool) {
-
- name = ATTRIBUTE_LOCAL_VARIABLE_TABLE;
-
- int len = ((info[0] & 0xFF)<<8) | (info[1] & 0xFF);
-
- int ind = 6;
- for(int i=0;i<len;i++, ind+=10) {
- int nindex = ((info[ind] & 0xFF)<<8) | (info[ind+1] & 0xFF);
- int vindex = ((info[ind+4] & 0xFF)<<8) | (info[ind+5] & 0xFF);
-
- mapVarNames.put(vindex, pool.getPrimitiveConstant(nindex).getString());
- }
- }
-
- public void addLocalVariableTable(StructLocalVariableTableAttribute attr) {
- mapVarNames.putAll(attr.getMapVarNames());
- }
-
- public HashMap<Integer, String> getMapVarNames() {
- return mapVarNames;
- }
+ private HashMap<Integer, String> mapVarNames = new HashMap<Integer, String>();
+
+ public void initContent(ConstantPool pool) {
+
+ name = ATTRIBUTE_LOCAL_VARIABLE_TABLE;
+
+ int len = ((info[0] & 0xFF) << 8) | (info[1] & 0xFF);
+
+ int ind = 6;
+ for (int i = 0; i < len; i++, ind += 10) {
+ int nindex = ((info[ind] & 0xFF) << 8) | (info[ind + 1] & 0xFF);
+ int vindex = ((info[ind + 4] & 0xFF) << 8) | (info[ind + 5] & 0xFF);
+
+ mapVarNames.put(vindex, pool.getPrimitiveConstant(nindex).getString());
+ }
+ }
+
+ public void addLocalVariableTable(StructLocalVariableTableAttribute attr) {
+ mapVarNames.putAll(attr.getMapVarNames());
+ }
+
+ public HashMap<Integer, String> getMapVarNames() {
+ return mapVarNames;
+ }
}
diff --git a/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java b/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java
index 8951cd1..5a593af 100644
--- a/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java
+++ b/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java
@@ -1,26 +1,20 @@
/*
- * 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.consts;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-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.modules.renamer.PoolInterceptor;
@@ -28,289 +22,297 @@ import org.jetbrains.java.decompiler.struct.gen.FieldDescriptor;
import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor;
import org.jetbrains.java.decompiler.struct.gen.VarType;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
public class ConstantPool {
-
- public static final int FIELD = 1;
-
- public static final int METHOD = 2;
-
- // *****************************************************************************
- // private fields
- // *****************************************************************************
-
- private List<PooledConstant> pool = new ArrayList<PooledConstant>();
-
- private PoolInterceptor interceptor;
-
- // *****************************************************************************
- // constructors
- // *****************************************************************************
-
- public ConstantPool(DataInputStream in) throws IOException {
-
- int size = in.readUnsignedShort();
-
- int[] pass = new int[size];
-
- // first dummy constant
- pool.add(null);
-
- // first pass: read the elements
- for (int i = 1; i < size; i++) {
-
- byte tag = (byte)in.readUnsignedByte();
-
- switch (tag) {
- case CodeConstants.CONSTANT_Utf8:
- pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Utf8, in.readUTF()));
- break;
- case CodeConstants.CONSTANT_Integer:
- pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Integer, new Integer(in.readInt())));
- break;
- case CodeConstants.CONSTANT_Float:
- pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Float, new Float(in.readFloat())));
- break;
- case CodeConstants.CONSTANT_Long:
- pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Long, new Long(in.readLong())));
- pool.add(null);
- i++;
- break;
- case CodeConstants.CONSTANT_Double:
- pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Double, new Double(in.readDouble())));
- pool.add(null);
- i++;
- break;
- case CodeConstants.CONSTANT_Class:
- case CodeConstants.CONSTANT_String:
- case CodeConstants.CONSTANT_MethodType:
- pool.add(new PrimitiveConstant(tag, in.readUnsignedShort()));
- pass[i] = 1;
- break;
- case CodeConstants.CONSTANT_Fieldref:
- case CodeConstants.CONSTANT_Methodref:
- case CodeConstants.CONSTANT_InterfaceMethodref:
- case CodeConstants.CONSTANT_NameAndType:
- case CodeConstants.CONSTANT_InvokeDynamic:
- pool.add(new LinkConstant(tag, in.readUnsignedShort(), in.readUnsignedShort()));
- if(tag == CodeConstants.CONSTANT_NameAndType) {
- pass[i] = 1;
- } else {
- pass[i] = 2;
- }
- break;
- case CodeConstants.CONSTANT_MethodHandle:
- pool.add(new LinkConstant(tag, in.readUnsignedByte(), in.readUnsignedShort()));
- pass[i] = 3;
- break;
- }
- }
-
-
- // resolving complex pool elements
- for(int pass_index = 1; pass_index <= 3; pass_index++) {
- for(int i = 1; i < size; i++) {
- if(pass[i] == pass_index) {
- pool.get(i).resolveConstant(this);
- }
- }
- }
-
- // get global constant pool interceptor instance, if any available
- interceptor = DecompilerContext.getPoolInterceptor();
- }
-
- // *****************************************************************************
- // public methods
- // *****************************************************************************
-
- public void writeToOutputStream(DataOutputStream out) throws FileNotFoundException, IOException {
-
- out.writeShort(pool.size());
- for(int i=1;i<pool.size();i++) {
- PooledConstant cnst = (PooledConstant)pool.get(i);
- if(cnst!=null) {
- cnst.writeToStream(out);
- }
- }
- }
-
- public static void skipPool(DataInputStream in) throws IOException {
-
- int size = in.readUnsignedShort();
-
- for (int i = 1; i < size; i++) {
- switch (in.readUnsignedByte()) {
- case CodeConstants.CONSTANT_Utf8:
- in.readUTF();
- break;
- case CodeConstants.CONSTANT_Integer:
- case CodeConstants.CONSTANT_Float:
- case CodeConstants.CONSTANT_Fieldref:
- case CodeConstants.CONSTANT_Methodref:
- case CodeConstants.CONSTANT_InterfaceMethodref:
- case CodeConstants.CONSTANT_NameAndType:
- case CodeConstants.CONSTANT_InvokeDynamic:
- in.skip(4);
- break;
- case CodeConstants.CONSTANT_Long:
- case CodeConstants.CONSTANT_Double:
- in.skip(8);
- i++;
- break;
- case CodeConstants.CONSTANT_Class:
- case CodeConstants.CONSTANT_String:
- case CodeConstants.CONSTANT_MethodType:
- in.skip(2);
- break;
- case CodeConstants.CONSTANT_MethodHandle:
- in.skip(3);
- }
- }
- }
-
- public int size() {
- return pool.size();
- }
-
- public String[] getClassElement(int element_type, int class_index, int name_index, int descriptor_index) {
-
- String classname = ((PrimitiveConstant)getConstant(class_index)).getString();
- String elementname = ((PrimitiveConstant)getConstant(name_index)).getString();
- String descriptor = ((PrimitiveConstant)getConstant(descriptor_index)).getString();
-
- if(interceptor != null) {
- String new_element = interceptor.getName(classname+" "+elementname+" "+descriptor);
-
- if(new_element != null) {
- elementname = new_element.split(" ")[1];
- }
-
- String new_descriptor = buildNewDescriptor(element_type == FIELD?CodeConstants.CONSTANT_Fieldref:CodeConstants.CONSTANT_Methodref,
- descriptor);
- if(new_descriptor != null) {
- descriptor = new_descriptor;
- }
- }
-
- return new String[] {elementname, descriptor};
- }
-
- public PooledConstant getConstant(int index) {
- return pool.get(index);
- }
-
- public PrimitiveConstant getPrimitiveConstant(int index) {
- PrimitiveConstant cn = (PrimitiveConstant)getConstant(index);
-
- if(cn != null && interceptor != null) {
- if(cn.type == CodeConstants.CONSTANT_Class) {
- String newname = buildNewClassname(cn.getString());
- if(newname != null) {
- cn = new PrimitiveConstant(CodeConstants.CONSTANT_Class, newname);
- }
- }
- }
-
- return cn;
- }
-
- public LinkConstant getLinkConstant(int index) {
- LinkConstant ln = (LinkConstant)getConstant(index);
-
- if(ln != null && interceptor != null) {
- if(ln.type == CodeConstants.CONSTANT_Fieldref ||
- ln.type == CodeConstants.CONSTANT_Methodref ||
- ln.type == CodeConstants.CONSTANT_InterfaceMethodref) {
-
- String new_classname = buildNewClassname(ln.classname);
- String new_element = interceptor.getName(ln.classname+" "+ln.elementname+" "+ln.descriptor);
- String new_descriptor = buildNewDescriptor(ln.type, ln.descriptor);
-
- if(new_classname != null || new_element != null || new_descriptor != null) {
-
- ln = new LinkConstant(ln.type, new_classname==null?ln.classname:new_classname,
- new_element==null?ln.elementname:new_element.split(" ")[1],
- new_descriptor==null?ln.descriptor:new_descriptor);
- }
- }
- }
-
- return ln;
- }
-
- private 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++) {
- buffer.append("[");
- }
-
- buffer.append("L"+newname+";");
- } else {
- buffer.append(newname);
- }
-
- return buffer.toString();
- }
-
- 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 newclname = buildNewClassname(ftype.value);
- if(newclname != null) {
- ftype.value = newclname;
- updated = true;
- }
- }
-
- if(updated) {
- return fd.getDescriptor();
- }
-
- } else {
-
- MethodDescriptor md = MethodDescriptor.parseDescriptor(descriptor);
- // params
- for(VarType partype : md.params) {
- if(partype.type == CodeConstants.TYPE_OBJECT) {
- String newclname = buildNewClassname(partype.value);
- if(newclname != null) {
- partype.value = newclname;
- updated = true;
- }
- }
- }
-
- // return value
- if(md.ret.type == CodeConstants.TYPE_OBJECT) {
- String newclname = buildNewClassname(md.ret.value);
- if(newclname!=null) {
- md.ret.value = newclname;
- updated = true;
- }
- }
-
- if(updated) {
- return md.getDescriptor();
- }
- }
-
- return null;
- }
-
+
+ public static final int FIELD = 1;
+
+ public static final int METHOD = 2;
+
+ // *****************************************************************************
+ // private fields
+ // *****************************************************************************
+
+ private List<PooledConstant> pool = new ArrayList<PooledConstant>();
+
+ private PoolInterceptor interceptor;
+
+ // *****************************************************************************
+ // constructors
+ // *****************************************************************************
+
+ public ConstantPool(DataInputStream in) throws IOException {
+
+ int size = in.readUnsignedShort();
+
+ int[] pass = new int[size];
+
+ // first dummy constant
+ pool.add(null);
+
+ // first pass: read the elements
+ for (int i = 1; i < size; i++) {
+
+ byte tag = (byte)in.readUnsignedByte();
+
+ switch (tag) {
+ case CodeConstants.CONSTANT_Utf8:
+ pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Utf8, in.readUTF()));
+ break;
+ case CodeConstants.CONSTANT_Integer:
+ pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Integer, new Integer(in.readInt())));
+ break;
+ case CodeConstants.CONSTANT_Float:
+ pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Float, new Float(in.readFloat())));
+ break;
+ case CodeConstants.CONSTANT_Long:
+ pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Long, new Long(in.readLong())));
+ pool.add(null);
+ i++;
+ break;
+ case CodeConstants.CONSTANT_Double:
+ pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Double, new Double(in.readDouble())));
+ pool.add(null);
+ i++;
+ break;
+ case CodeConstants.CONSTANT_Class:
+ case CodeConstants.CONSTANT_String:
+ case CodeConstants.CONSTANT_MethodType:
+ pool.add(new PrimitiveConstant(tag, in.readUnsignedShort()));
+ pass[i] = 1;
+ break;
+ case CodeConstants.CONSTANT_Fieldref:
+ case CodeConstants.CONSTANT_Methodref:
+ case CodeConstants.CONSTANT_InterfaceMethodref:
+ case CodeConstants.CONSTANT_NameAndType:
+ case CodeConstants.CONSTANT_InvokeDynamic:
+ pool.add(new LinkConstant(tag, in.readUnsignedShort(), in.readUnsignedShort()));
+ if (tag == CodeConstants.CONSTANT_NameAndType) {
+ pass[i] = 1;
+ }
+ else {
+ pass[i] = 2;
+ }
+ break;
+ case CodeConstants.CONSTANT_MethodHandle:
+ pool.add(new LinkConstant(tag, in.readUnsignedByte(), in.readUnsignedShort()));
+ pass[i] = 3;
+ break;
+ }
+ }
+
+
+ // resolving complex pool elements
+ for (int pass_index = 1; pass_index <= 3; pass_index++) {
+ for (int i = 1; i < size; i++) {
+ if (pass[i] == pass_index) {
+ pool.get(i).resolveConstant(this);
+ }
+ }
+ }
+
+ // get global constant pool interceptor instance, if any available
+ interceptor = DecompilerContext.getPoolInterceptor();
+ }
+
+ // *****************************************************************************
+ // public methods
+ // *****************************************************************************
+
+ public void writeToOutputStream(DataOutputStream out) throws FileNotFoundException, IOException {
+
+ out.writeShort(pool.size());
+ for (int i = 1; i < pool.size(); i++) {
+ PooledConstant cnst = (PooledConstant)pool.get(i);
+ if (cnst != null) {
+ cnst.writeToStream(out);
+ }
+ }
+ }
+
+ public static void skipPool(DataInputStream in) throws IOException {
+
+ int size = in.readUnsignedShort();
+
+ for (int i = 1; i < size; i++) {
+ switch (in.readUnsignedByte()) {
+ case CodeConstants.CONSTANT_Utf8:
+ in.readUTF();
+ break;
+ case CodeConstants.CONSTANT_Integer:
+ case CodeConstants.CONSTANT_Float:
+ case CodeConstants.CONSTANT_Fieldref:
+ case CodeConstants.CONSTANT_Methodref:
+ case CodeConstants.CONSTANT_InterfaceMethodref:
+ case CodeConstants.CONSTANT_NameAndType:
+ case CodeConstants.CONSTANT_InvokeDynamic:
+ in.skip(4);
+ break;
+ case CodeConstants.CONSTANT_Long:
+ case CodeConstants.CONSTANT_Double:
+ in.skip(8);
+ i++;
+ break;
+ case CodeConstants.CONSTANT_Class:
+ case CodeConstants.CONSTANT_String:
+ case CodeConstants.CONSTANT_MethodType:
+ in.skip(2);
+ break;
+ case CodeConstants.CONSTANT_MethodHandle:
+ in.skip(3);
+ }
+ }
+ }
+
+ public int size() {
+ return pool.size();
+ }
+
+ public String[] getClassElement(int element_type, int class_index, int name_index, int descriptor_index) {
+
+ String classname = ((PrimitiveConstant)getConstant(class_index)).getString();
+ String elementname = ((PrimitiveConstant)getConstant(name_index)).getString();
+ String descriptor = ((PrimitiveConstant)getConstant(descriptor_index)).getString();
+
+ if (interceptor != null) {
+ String new_element = interceptor.getName(classname + " " + elementname + " " + descriptor);
+
+ if (new_element != null) {
+ elementname = new_element.split(" ")[1];
+ }
+
+ String new_descriptor = buildNewDescriptor(element_type == FIELD ? CodeConstants.CONSTANT_Fieldref : CodeConstants.CONSTANT_Methodref,
+ descriptor);
+ if (new_descriptor != null) {
+ descriptor = new_descriptor;
+ }
+ }
+
+ return new String[]{elementname, descriptor};
+ }
+
+ public PooledConstant getConstant(int index) {
+ return pool.get(index);
+ }
+
+ public PrimitiveConstant getPrimitiveConstant(int index) {
+ PrimitiveConstant cn = (PrimitiveConstant)getConstant(index);
+
+ if (cn != null && interceptor != null) {
+ if (cn.type == CodeConstants.CONSTANT_Class) {
+ String newname = buildNewClassname(cn.getString());
+ if (newname != null) {
+ cn = new PrimitiveConstant(CodeConstants.CONSTANT_Class, newname);
+ }
+ }
+ }
+
+ return cn;
+ }
+
+ public LinkConstant getLinkConstant(int index) {
+ LinkConstant ln = (LinkConstant)getConstant(index);
+
+ if (ln != null && interceptor != null) {
+ if (ln.type == CodeConstants.CONSTANT_Fieldref ||
+ ln.type == CodeConstants.CONSTANT_Methodref ||
+ ln.type == CodeConstants.CONSTANT_InterfaceMethodref) {
+
+ String new_classname = buildNewClassname(ln.classname);
+ String new_element = interceptor.getName(ln.classname + " " + ln.elementname + " " + ln.descriptor);
+ String new_descriptor = buildNewDescriptor(ln.type, ln.descriptor);
+
+ if (new_classname != null || new_element != null || new_descriptor != null) {
+
+ ln = new LinkConstant(ln.type, new_classname == null ? ln.classname : new_classname,
+ new_element == null ? ln.elementname : new_element.split(" ")[1],
+ new_descriptor == null ? ln.descriptor : new_descriptor);
+ }
+ }
+ }
+
+ return ln;
+ }
+
+ private 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++) {
+ buffer.append("[");
+ }
+
+ buffer.append("L" + newname + ";");
+ }
+ else {
+ buffer.append(newname);
+ }
+
+ return buffer.toString();
+ }
+
+ 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 newclname = buildNewClassname(ftype.value);
+ if (newclname != null) {
+ ftype.value = newclname;
+ updated = true;
+ }
+ }
+
+ if (updated) {
+ return fd.getDescriptor();
+ }
+ }
+ else {
+
+ MethodDescriptor md = MethodDescriptor.parseDescriptor(descriptor);
+ // params
+ for (VarType partype : md.params) {
+ if (partype.type == CodeConstants.TYPE_OBJECT) {
+ String newclname = buildNewClassname(partype.value);
+ if (newclname != null) {
+ partype.value = newclname;
+ updated = true;
+ }
+ }
+ }
+
+ // return value
+ if (md.ret.type == CodeConstants.TYPE_OBJECT) {
+ String newclname = buildNewClassname(md.ret.value);
+ if (newclname != null) {
+ md.ret.value = newclname;
+ updated = true;
+ }
+ }
+
+ if (updated) {
+ return md.getDescriptor();
+ }
+ }
+
+ return null;
+ }
}
diff --git a/src/org/jetbrains/java/decompiler/struct/consts/LinkConstant.java b/src/org/jetbrains/java/decompiler/struct/consts/LinkConstant.java
index 770a5e3..c20b5af 100644
--- a/src/org/jetbrains/java/decompiler/struct/consts/LinkConstant.java
+++ b/src/org/jetbrains/java/decompiler/struct/consts/LinkConstant.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.consts;
import java.io.DataOutputStream;
@@ -24,136 +25,142 @@ import java.io.IOException;
public class LinkConstant extends PooledConstant {
- // *****************************************************************************
- // public fields
- // *****************************************************************************
-
- public int index1, index2;
-
- public String classname;
-
- public String elementname;
-
- public String descriptor;
-
- public int paramCount = 0;
-
- public boolean isVoid = false;;
-
- public boolean returnCategory2 = false;
-
-
- // *****************************************************************************
- // constructors
- // *****************************************************************************
-
- public LinkConstant(int type, String classname, String elementname, String descriptor) {
- this.type = type;
- this.classname = classname;
- this.elementname = elementname;
- this.descriptor = descriptor;
-
- initConstant();
- }
-
- public LinkConstant(int type, int index1, int index2) {
- this.type = type;
- this.index1 = index1;
- this.index2 = index2;
- }
-
-
- // *****************************************************************************
- // public methods
- // *****************************************************************************
-
- public void resolveConstant(ConstantPool pool) {
-
- if(type == CONSTANT_NameAndType) {
- elementname = pool.getPrimitiveConstant(index1).getString();
- descriptor = pool.getPrimitiveConstant(index2).getString();
- } else if(type == CONSTANT_MethodHandle) {
- LinkConstant ref_info = pool.getLinkConstant(index2);
-
- classname = ref_info.classname;
- elementname = ref_info.elementname;
- descriptor = ref_info.descriptor;
-
- } else {
- if(type != CONSTANT_InvokeDynamic) {
- classname = pool.getPrimitiveConstant(index1).getString();
- }
-
- LinkConstant nametype = pool.getLinkConstant(index2);
- elementname = nametype.elementname;
- descriptor = nametype.descriptor;
- }
-
- initConstant();
- }
-
- public void writeToStream(DataOutputStream out) throws IOException {
- out.writeByte(type);
- if(type == CONSTANT_MethodHandle) {
- out.writeByte(index1);
- } else {
- out.writeShort(index1);
- }
- out.writeShort(index2);
- }
-
-
- public boolean equals(Object o) {
- if(o == this) return true;
- if(o == null || !(o instanceof LinkConstant)) return false;
-
- LinkConstant cn = (LinkConstant)o;
+ // *****************************************************************************
+ // public fields
+ // *****************************************************************************
+
+ public int index1, index2;
+
+ public String classname;
+
+ public String elementname;
+
+ public String descriptor;
+
+ public int paramCount = 0;
+
+ public boolean isVoid = false;
+ ;
+
+ public boolean returnCategory2 = false;
+
+
+ // *****************************************************************************
+ // constructors
+ // *****************************************************************************
+
+ public LinkConstant(int type, String classname, String elementname, String descriptor) {
+ this.type = type;
+ this.classname = classname;
+ this.elementname = elementname;
+ this.descriptor = descriptor;
+
+ initConstant();
+ }
+
+ public LinkConstant(int type, int index1, int index2) {
+ this.type = type;
+ this.index1 = index1;
+ this.index2 = index2;
+ }
+
+
+ // *****************************************************************************
+ // public methods
+ // *****************************************************************************
+
+ public void resolveConstant(ConstantPool pool) {
+
+ if (type == CONSTANT_NameAndType) {
+ elementname = pool.getPrimitiveConstant(index1).getString();
+ descriptor = pool.getPrimitiveConstant(index2).getString();
+ }
+ else if (type == CONSTANT_MethodHandle) {
+ LinkConstant ref_info = pool.getLinkConstant(index2);
+
+ classname = ref_info.classname;
+ elementname = ref_info.elementname;
+ descriptor = ref_info.descriptor;
+ }
+ else {
+ if (type != CONSTANT_InvokeDynamic) {
+ classname = pool.getPrimitiveConstant(index1).getString();
+ }
+
+ LinkConstant nametype = pool.getLinkConstant(index2);
+ elementname = nametype.elementname;
+ descriptor = nametype.descriptor;
+ }
+
+ initConstant();
+ }
+
+ public void writeToStream(DataOutputStream out) throws IOException {
+ out.writeByte(type);
+ if (type == CONSTANT_MethodHandle) {
+ out.writeByte(index1);
+ }
+ else {
+ out.writeShort(index1);
+ }
+ out.writeShort(index2);
+ }
+
+
+ public boolean equals(Object o) {
+ if (o == this) return true;
+ if (o == null || !(o instanceof LinkConstant)) return false;
+
+ LinkConstant cn = (LinkConstant)o;
return this.type == cn.type &&
- this.elementname.equals(cn.elementname) &&
- this.descriptor.equals(cn.descriptor) &&
- (this.type != CONSTANT_NameAndType || this.classname.equals(cn.classname));
+ this.elementname.equals(cn.elementname) &&
+ this.descriptor.equals(cn.descriptor) &&
+ (this.type != CONSTANT_NameAndType || this.classname.equals(cn.classname));
+ }
+
+ // *****************************************************************************
+ // private methods
+ // *****************************************************************************
+
+ private void initConstant() {
+
+ if (type == CONSTANT_Methodref ||
+ type == CONSTANT_InterfaceMethodref ||
+ type == CONSTANT_InvokeDynamic ||
+ type == CONSTANT_MethodHandle) {
+ resolveDescriptor(descriptor);
+ }
+ else if (type == CONSTANT_Fieldref) {
+ returnCategory2 = ("D".equals(descriptor) || "J".equals(descriptor));
+ }
+ }
+
+ private void resolveDescriptor(String descr) {
+
+ String[] arr = descr.split("[()]");
+ String par = arr[1];
+
+ int index = 0, counter = 0;
+ int len = par.length();
+
+ while (index < len) {
+
+ char c = par.charAt(index);
+ if (c == 'L') {
+ index = par.indexOf(";", index);
+ }
+ else if (c == '[') {
+ index++;
+ continue;
+ }
+
+ counter++;
+ index++;
+ }
+
+ paramCount = counter;
+ isVoid = "V".equals(arr[2]);
+ returnCategory2 = ("D".equals(arr[2]) || "J".equals(arr[2]));
}
-
- // *****************************************************************************
- // private methods
- // *****************************************************************************
-
- private void initConstant() {
-
- if(type == CONSTANT_Methodref || type == CONSTANT_InterfaceMethodref || type == CONSTANT_InvokeDynamic || type == CONSTANT_MethodHandle) {
- resolveDescriptor(descriptor);
- } else if(type == CONSTANT_Fieldref) {
- returnCategory2 = ("D".equals(descriptor) || "J".equals(descriptor));
- }
-
- }
-
- private void resolveDescriptor(String descr){
-
- String[] arr = descr.split("[()]");
- String par = arr[1];
-
- int index = 0, counter = 0;
- int len = par.length();
-
- while(index<len) {
-
- char c = par.charAt(index);
- if(c == 'L') {
- index = par.indexOf(";", index);
- } else if (c == '[') {
- index++;
- continue;
- }
-
- counter++;
- index++;
- }
-
- paramCount = counter;
- isVoid = "V".equals(arr[2]);
- returnCategory2 = ("D".equals(arr[2]) || "J".equals(arr[2]));
- }
-
}
diff --git a/src/org/jetbrains/java/decompiler/struct/consts/PooledConstant.java b/src/org/jetbrains/java/decompiler/struct/consts/PooledConstant.java
index ae46604..d3d30c0 100644
--- a/src/org/jetbrains/java/decompiler/struct/consts/PooledConstant.java
+++ b/src/org/jetbrains/java/decompiler/struct/consts/PooledConstant.java
@@ -1,24 +1,25 @@
/*
- * 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.consts;
+import org.jetbrains.java.decompiler.code.CodeConstants;
+
import java.io.DataOutputStream;
import java.io.IOException;
-import org.jetbrains.java.decompiler.code.CodeConstants;
-
/*
cp_info {
u1 tag;
@@ -29,88 +30,88 @@ import org.jetbrains.java.decompiler.code.CodeConstants;
public class PooledConstant implements CodeConstants, VariableTypeEnum {
- // *****************************************************************************
- // public fields
- // *****************************************************************************
-
- public int type;
-
- public boolean own = false;
-
- public int returnType;
-
-
- // *****************************************************************************
- // private fields
- // *****************************************************************************
-
- private Object[] values;
-
- // *****************************************************************************
- // constructors
- // *****************************************************************************
-
- public PooledConstant() {}
-
- public PooledConstant(int type, Object[] values) {
- this.type = type;
- this.values = values;
- this.returnType = poolTypeToIntern(type);
- }
-
- public PooledConstant(int type, boolean own, Object[] values) {
- this.type = type;
- this.own = own;
- this.values = values;
- this.returnType = poolTypeToIntern(type);
- }
-
- // *****************************************************************************
- // public methods
- // *****************************************************************************
-
- public void resolveConstant(ConstantPool pool) {
- // to be overwritten
- }
-
- public void writeToStream(DataOutputStream out) throws IOException {
- // to be overwritten
- }
-
- public int poolTypeToIntern(int type) {
-
- switch(type){
- case CONSTANT_Integer:
- return INT;
- case CONSTANT_Float:
- return FLOAT;
- case CONSTANT_Long:
- return LONG;
- case CONSTANT_Double:
- return DOUBLE;
- case CONSTANT_String:
- case CONSTANT_Class: // 1.5 -> ldc class
- return REFERENCE;
- default:
- throw new RuntimeException("Huh?? What are you trying to load?");
- }
- }
-
- public Object getValue(int index){
- return values[index];
- }
-
-
- // *****************************************************************************
- // getter and setter methods
- // *****************************************************************************
-
- public Object[] getValues() {
- return values;
- }
-
- public void setValues(Object[] values) {
- this.values = values;
- }
+ // *****************************************************************************
+ // public fields
+ // *****************************************************************************
+
+ public int type;
+
+ public boolean own = false;
+
+ public int returnType;
+
+
+ // *****************************************************************************
+ // private fields
+ // *****************************************************************************
+
+ private Object[] values;
+
+ // *****************************************************************************
+ // constructors
+ // *****************************************************************************
+
+ public PooledConstant() {
+ }
+
+ public PooledConstant(int type, Object[] values) {
+ this.type = type;
+ this.values = values;
+ this.returnType = poolTypeToIntern(type);
+ }
+
+ public PooledConstant(int type, boolean own, Object[] values) {
+ this.type = type;
+ this.own = own;
+ this.values = values;
+ this.returnType = poolTypeToIntern(type);
+ }
+
+ // *****************************************************************************
+ // public methods
+ // *****************************************************************************
+
+ public void resolveConstant(ConstantPool pool) {
+ // to be overwritten
+ }
+
+ public void writeToStream(DataOutputStream out) throws IOException {
+ // to be overwritten
+ }
+
+ public int poolTypeToIntern(int type) {
+
+ switch (type) {
+ case CONSTANT_Integer:
+ return INT;
+ case CONSTANT_Float:
+ return FLOAT;
+ case CONSTANT_Long:
+ return LONG;
+ case CONSTANT_Double:
+ return DOUBLE;
+ case CONSTANT_String:
+ case CONSTANT_Class: // 1.5 -> ldc class
+ return REFERENCE;
+ default:
+ throw new RuntimeException("Huh?? What are you trying to load?");
+ }
+ }
+
+ public Object getValue(int index) {
+ return values[index];
+ }
+
+
+ // *****************************************************************************
+ // getter and setter methods
+ // *****************************************************************************
+
+ public Object[] getValues() {
+ return values;
+ }
+ public void setValues(Object[] values) {
+ this.values = values;
+ }
}
diff --git a/src/org/jetbrains/java/decompiler/struct/consts/PrimitiveConstant.java b/src/org/jetbrains/java/decompiler/struct/consts/PrimitiveConstant.java
index f01a695..4cd4dd8 100644
--- a/src/org/jetbrains/java/decompiler/struct/consts/PrimitiveConstant.java
+++ b/src/org/jetbrains/java/decompiler/struct/consts/PrimitiveConstant.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.consts;
import java.io.DataOutputStream;
@@ -23,104 +24,103 @@ import java.io.IOException;
public class PrimitiveConstant extends PooledConstant {
- // *****************************************************************************
- // public fields
- // *****************************************************************************
-
- public int index;
-
- public Object value;
-
- public boolean isArray;
-
- // *****************************************************************************
- // constructors
- // *****************************************************************************
-
- public PrimitiveConstant(int type, Object value) {
- this.type = type;
- this.value = value;
-
- initConstant();
- }
-
- public PrimitiveConstant(int type, int index) {
- this.type = type;
- this.index = index;
- }
-
- // *****************************************************************************
- // public methods
- // *****************************************************************************
-
- public int getInt() {
- return ((Integer)value).intValue();
- }
-
- public long getLong() {
- return ((Long)value).longValue();
- }
-
- public float getFloat() {
- return ((Float)value).floatValue();
- }
-
- public double getDouble() {
- return ((Double)value).doubleValue();
- }
-
- public String getString() {
- return (String)value;
- }
-
- public void resolveConstant(ConstantPool pool) {
-
- if(type == CONSTANT_Class || type == CONSTANT_String || type == CONSTANT_MethodType) {
- value = pool.getPrimitiveConstant(index).getString();
- initConstant();
- }
- }
-
- public void writeToStream(DataOutputStream out) throws IOException {
-
- out.writeByte(type);
- switch(type) {
- case CONSTANT_Integer:
- out.writeInt(getInt());
- break;
- case CONSTANT_Float:
- out.writeFloat(getFloat());
- break;
- case CONSTANT_Long:
- out.writeLong(getLong());
- break;
- case CONSTANT_Double:
- out.writeDouble(getDouble());
- break;
- case CONSTANT_Utf8:
- out.writeUTF(getString());
- break;
- default: // CONSTANT_Class, CONSTANT_String, CONSTANT_MethodType
- out.writeShort(index);
- }
- }
-
- public boolean equals(Object o) {
- if(o == this) return true;
- if(o == null || !(o instanceof PrimitiveConstant)) return false;
-
- PrimitiveConstant cn = (PrimitiveConstant)o;
- return this.type == cn.type &&
- this.isArray == cn.isArray &&
- this.value.equals(cn.value);
-
- }
-
- private void initConstant() {
- if(type == CONSTANT_Class) {
- String className = getString();
- isArray = (className.length() > 0 && className.charAt(0)=='['); // empty string for a class name seems to be possible in some android files
- }
- }
-
+ // *****************************************************************************
+ // public fields
+ // *****************************************************************************
+
+ public int index;
+
+ public Object value;
+
+ public boolean isArray;
+
+ // *****************************************************************************
+ // constructors
+ // *****************************************************************************
+
+ public PrimitiveConstant(int type, Object value) {
+ this.type = type;
+ this.value = value;
+
+ initConstant();
+ }
+
+ public PrimitiveConstant(int type, int index) {
+ this.type = type;
+ this.index = index;
+ }
+
+ // *****************************************************************************
+ // public methods
+ // *****************************************************************************
+
+ public int getInt() {
+ return ((Integer)value).intValue();
+ }
+
+ public long getLong() {
+ return ((Long)value).longValue();
+ }
+
+ public float getFloat() {
+ return ((Float)value).floatValue();
+ }
+
+ public double getDouble() {
+ return ((Double)value).doubleValue();
+ }
+
+ public String getString() {
+ return (String)value;
+ }
+
+ public void resolveConstant(ConstantPool pool) {
+
+ if (type == CONSTANT_Class || type == CONSTANT_String || type == CONSTANT_MethodType) {
+ value = pool.getPrimitiveConstant(index).getString();
+ initConstant();
+ }
+ }
+
+ public void writeToStream(DataOutputStream out) throws IOException {
+
+ out.writeByte(type);
+ switch (type) {
+ case CONSTANT_Integer:
+ out.writeInt(getInt());
+ break;
+ case CONSTANT_Float:
+ out.writeFloat(getFloat());
+ break;
+ case CONSTANT_Long:
+ out.writeLong(getLong());
+ break;
+ case CONSTANT_Double:
+ out.writeDouble(getDouble());
+ break;
+ case CONSTANT_Utf8:
+ out.writeUTF(getString());
+ break;
+ default: // CONSTANT_Class, CONSTANT_String, CONSTANT_MethodType
+ out.writeShort(index);
+ }
+ }
+
+ public boolean equals(Object o) {
+ if (o == this) return true;
+ if (o == null || !(o instanceof PrimitiveConstant)) return false;
+
+ PrimitiveConstant cn = (PrimitiveConstant)o;
+ return this.type == cn.type &&
+ this.isArray == cn.isArray &&
+ this.value.equals(cn.value);
+ }
+
+ private void initConstant() {
+ if (type == CONSTANT_Class) {
+ String className = getString();
+ isArray =
+ (className.length() > 0 && className.charAt(0) == '['); // empty string for a class name seems to be possible in some android files
+ }
+ }
}
diff --git a/src/org/jetbrains/java/decompiler/struct/consts/VariableTypeEnum.java b/src/org/jetbrains/java/decompiler/struct/consts/VariableTypeEnum.java
index fc58c7e..ef949aa 100644
--- a/src/org/jetbrains/java/decompiler/struct/consts/VariableTypeEnum.java
+++ b/src/org/jetbrains/java/decompiler/struct/consts/VariableTypeEnum.java
@@ -1,47 +1,47 @@
/*
- * 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.consts;
public interface VariableTypeEnum {
- public final static int BOOLEAN = 1;
- public final static int BYTE = 2;
- public final static int CHAR = 3;
- public final static int SHORT = 4;
- public final static int INT = 5;
- public final static int FLOAT = 6;
- public final static int LONG = 7;
- public final static int DOUBLE = 8;
- public final static int RETURN_ADDRESS = 9;
- public final static int REFERENCE = 10;
- public final static int INSTANCE_UNINITIALIZED = 11;
- public final static int VALUE_UNKNOWN = 12;
- public final static int VOID = 13;
-
- public final static Integer BOOLEAN_OBJ = new Integer(BOOLEAN);
- public final static Integer BYTE_OBJ = new Integer(BYTE);
- public final static Integer CHAR_OBJ = new Integer(CHAR);
- public final static Integer SHORT_OBJ = new Integer(SHORT);
- public final static Integer INT_OBJ = new Integer(INT);
- public final static Integer FLOAT_OBJ = new Integer(FLOAT);
- public final static Integer LONG_OBJ = new Integer(LONG);
- public final static Integer DOUBLE_OBJ = new Integer(DOUBLE);
- public final static Integer RETURN_ADDRESS_OBJ = new Integer(RETURN_ADDRESS);
- public final static Integer REFERENCE_OBJ = new Integer(REFERENCE);
- public final static Integer INSTANCE_UNINITIALIZED_OBJ = new Integer(INSTANCE_UNINITIALIZED);
- public final static Integer VALUE_UNKNOWN_OBJ = new Integer(VALUE_UNKNOWN);
- public final static Integer VOID_OBJ = new Integer(VOID);
-
+ public final static int BOOLEAN = 1;
+ public final static int BYTE = 2;
+ public final static int CHAR = 3;
+ public final static int SHORT = 4;
+ public final static int INT = 5;
+ public final static int FLOAT = 6;
+ public final static int LONG = 7;
+ public final static int DOUBLE = 8;
+ public final static int RETURN_ADDRESS = 9;
+ public final static int REFERENCE = 10;
+ public final static int INSTANCE_UNINITIALIZED = 11;
+ public final static int VALUE_UNKNOWN = 12;
+ public final static int VOID = 13;
+
+ public final static Integer BOOLEAN_OBJ = new Integer(BOOLEAN);
+ public final static Integer BYTE_OBJ = new Integer(BYTE);
+ public final static Integer CHAR_OBJ = new Integer(CHAR);
+ public final static Integer SHORT_OBJ = new Integer(SHORT);
+ public final static Integer INT_OBJ = new Integer(INT);
+ public final static Integer FLOAT_OBJ = new Integer(FLOAT);
+ public final static Integer LONG_OBJ = new Integer(LONG);
+ public final static Integer DOUBLE_OBJ = new Integer(DOUBLE);
+ public final static Integer RETURN_ADDRESS_OBJ = new Integer(RETURN_ADDRESS);
+ public final static Integer REFERENCE_OBJ = new Integer(REFERENCE);
+ public final static Integer INSTANCE_UNINITIALIZED_OBJ = new Integer(INSTANCE_UNINITIALIZED);
+ public final static Integer VALUE_UNKNOWN_OBJ = new Integer(VALUE_UNKNOWN);
+ public final static Integer VOID_OBJ = new Integer(VOID);
}
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;
+ }
}
diff --git a/src/org/jetbrains/java/decompiler/struct/lazy/LazyLoader.java b/src/org/jetbrains/java/decompiler/struct/lazy/LazyLoader.java
index 94cef9a..46a334e 100644
--- a/src/org/jetbrains/java/decompiler/struct/lazy/LazyLoader.java
+++ b/src/org/jetbrains/java/decompiler/struct/lazy/LazyLoader.java
@@ -1,186 +1,186 @@
/*
- * 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.lazy;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.HashMap;
-
import org.jetbrains.java.decompiler.main.extern.IBytecodeProvider;
import org.jetbrains.java.decompiler.struct.StructMethod;
import org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute;
import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
import org.jetbrains.java.decompiler.util.DataInputFullStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+
public class LazyLoader {
- private HashMap<String, Link> mapClassLinks = new HashMap<String, Link>();
-
- private IBytecodeProvider provider;
-
- public LazyLoader(IBytecodeProvider provider) {
- this.provider = provider;
- }
-
- public void addClassLink(String classname, Link link) {
- mapClassLinks.put(classname, link);
- }
-
- public void removeClassLink(String classname) {
- mapClassLinks.remove(classname);
- }
-
- public Link getClassLink(String classname) {
- return mapClassLinks.get(classname);
- }
-
-
- public ConstantPool loadPool(String classname) {
-
- try {
-
- DataInputFullStream in = getClassStream(classname);
- if(in == null) {
- return null;
- }
-
- in.skip(8);
-
- return new ConstantPool(in);
-
- } catch(IOException ex) {
- throw new RuntimeException(ex);
- }
- }
-
- public byte[] loadBytecode(StructMethod mt, int code_fulllength) {
-
- try {
-
- DataInputFullStream in = getClassStream(mt.getClassStruct().qualifiedName);
- if(in == null) {
- return null;
- }
-
- byte[] res = null;
-
- in.skip(8);
-
- ConstantPool pool = mt.getClassStruct().getPool();
- if(pool == null) {
- pool = new ConstantPool(in);
- } else {
- ConstantPool.skipPool(in);
- }
-
- in.skip(2);
- int this_class = in.readUnsignedShort();
- in.skip(2);
-
- // interfaces
- in.skip(in.readUnsignedShort() * 2);
-
- // fields
- int size = in.readUnsignedShort();
- for (int i = 0; i < size; i++) {
- in.skip(6);
- skipAttributes(in);
- }
-
- // methods
- size = in.readUnsignedShort();
- for (int i = 0; i < size; i++) {
- in.skip(2);
-
- int name_index = in.readUnsignedShort();
- int descriptor_index = in.readUnsignedShort();
-
- String elem_arr[] = pool.getClassElement(ConstantPool.METHOD, this_class, name_index, descriptor_index);
- String name = elem_arr[0];
-
- if(mt.getName().equals(name)) {
- String descriptor = elem_arr[1];
- if(mt.getDescriptor().equals(descriptor)) {
-
- int len = in.readUnsignedShort();
- for(int j=0;j<len;j++) {
-
- int attr_nameindex = in.readUnsignedShort();
- String attrname = pool.getPrimitiveConstant(attr_nameindex).getString();
-
- if(StructGeneralAttribute.ATTRIBUTE_CODE.equals(attrname)) {
- in.skip(12);
-
- res = new byte[code_fulllength];
- in.readFull(res);
- return res;
- } else {
- in.skip(in.readInt());
- }
- }
-
- return null;
- }
- }
-
- skipAttributes(in);
- }
-
- return null;
-
- } catch(IOException ex) {
- throw new RuntimeException(ex);
- }
-
- }
-
- public DataInputFullStream getClassStream(String externPath, String internPath) throws IOException {
- InputStream instream = provider.getBytecodeStream(externPath, internPath);
- return instream == null?null:new DataInputFullStream(instream);
- }
-
- public DataInputFullStream getClassStream(String qualifiedClassName) throws IOException {
- Link link = mapClassLinks.get(qualifiedClassName);
- return link == null?null:getClassStream(link.externPath, link.internPath);
- }
-
- private void skipAttributes(DataInputFullStream in) throws IOException {
-
- int length = in.readUnsignedShort();
- for (int i = 0; i < length; i++) {
- in.skip(2);
- in.skip(in.readInt());
- }
-
- }
-
-
- public static class Link {
-
- public static final int CLASS = 1;
- public static final int ENTRY = 2;
-
- public int type;
- public String externPath;
- public String internPath;
-
- public Link(int type, String externPath, String internPath) {
- this.type = type;
- this.externPath = externPath;
- this.internPath = internPath;
- }
- }
-
+ private HashMap<String, Link> mapClassLinks = new HashMap<String, Link>();
+
+ private IBytecodeProvider provider;
+
+ public LazyLoader(IBytecodeProvider provider) {
+ this.provider = provider;
+ }
+
+ public void addClassLink(String classname, Link link) {
+ mapClassLinks.put(classname, link);
+ }
+
+ public void removeClassLink(String classname) {
+ mapClassLinks.remove(classname);
+ }
+
+ public Link getClassLink(String classname) {
+ return mapClassLinks.get(classname);
+ }
+
+
+ public ConstantPool loadPool(String classname) {
+
+ try {
+
+ DataInputFullStream in = getClassStream(classname);
+ if (in == null) {
+ return null;
+ }
+
+ in.skip(8);
+
+ return new ConstantPool(in);
+ }
+ catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ public byte[] loadBytecode(StructMethod mt, int code_fulllength) {
+
+ try {
+
+ DataInputFullStream in = getClassStream(mt.getClassStruct().qualifiedName);
+ if (in == null) {
+ return null;
+ }
+
+ byte[] res = null;
+
+ in.skip(8);
+
+ ConstantPool pool = mt.getClassStruct().getPool();
+ if (pool == null) {
+ pool = new ConstantPool(in);
+ }
+ else {
+ ConstantPool.skipPool(in);
+ }
+
+ in.skip(2);
+ int this_class = in.readUnsignedShort();
+ in.skip(2);
+
+ // interfaces
+ in.skip(in.readUnsignedShort() * 2);
+
+ // fields
+ int size = in.readUnsignedShort();
+ for (int i = 0; i < size; i++) {
+ in.skip(6);
+ skipAttributes(in);
+ }
+
+ // methods
+ size = in.readUnsignedShort();
+ for (int i = 0; i < size; i++) {
+ in.skip(2);
+
+ int name_index = in.readUnsignedShort();
+ int descriptor_index = in.readUnsignedShort();
+
+ String elem_arr[] = pool.getClassElement(ConstantPool.METHOD, this_class, name_index, descriptor_index);
+ String name = elem_arr[0];
+
+ if (mt.getName().equals(name)) {
+ String descriptor = elem_arr[1];
+ if (mt.getDescriptor().equals(descriptor)) {
+
+ int len = in.readUnsignedShort();
+ for (int j = 0; j < len; j++) {
+
+ int attr_nameindex = in.readUnsignedShort();
+ String attrname = pool.getPrimitiveConstant(attr_nameindex).getString();
+
+ if (StructGeneralAttribute.ATTRIBUTE_CODE.equals(attrname)) {
+ in.skip(12);
+
+ res = new byte[code_fulllength];
+ in.readFull(res);
+ return res;
+ }
+ else {
+ in.skip(in.readInt());
+ }
+ }
+
+ return null;
+ }
+ }
+
+ skipAttributes(in);
+ }
+
+ return null;
+ }
+ catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ public DataInputFullStream getClassStream(String externPath, String internPath) throws IOException {
+ InputStream instream = provider.getBytecodeStream(externPath, internPath);
+ return instream == null ? null : new DataInputFullStream(instream);
+ }
+
+ public DataInputFullStream getClassStream(String qualifiedClassName) throws IOException {
+ Link link = mapClassLinks.get(qualifiedClassName);
+ return link == null ? null : getClassStream(link.externPath, link.internPath);
+ }
+
+ private void skipAttributes(DataInputFullStream in) throws IOException {
+
+ int length = in.readUnsignedShort();
+ for (int i = 0; i < length; i++) {
+ in.skip(2);
+ in.skip(in.readInt());
+ }
+ }
+
+
+ public static class Link {
+
+ public static final int CLASS = 1;
+ public static final int ENTRY = 2;
+
+ public int type;
+ public String externPath;
+ public String internPath;
+
+ public Link(int type, String externPath, String internPath) {
+ this.type = type;
+ this.externPath = externPath;
+ this.internPath = internPath;
+ }
+ }
}