mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-12-04 20:27:12 +01:00
* first version of javapp that can create a compilable Pascal import
unit for at least java.lang.*, java.util.* java.io.* and java.security.*,
using the following command line paramters:
-a sun. -a com.sun. -a javax. -protected java.lang. java.util. java.io. java.security. -o java_base
git-svn-id: branches/jvmbackend@18405 -
This commit is contained in:
parent
367daf06ea
commit
8199b2c6a9
9
.gitattributes
vendored
9
.gitattributes
vendored
@ -12907,6 +12907,8 @@ utils/javapp/src/fpc/tools/javapp/AttrData.java svneol=native#text/plain
|
||||
utils/javapp/src/fpc/tools/javapp/CPX.java svneol=native#text/plain
|
||||
utils/javapp/src/fpc/tools/javapp/CPX2.java svneol=native#text/plain
|
||||
utils/javapp/src/fpc/tools/javapp/ClassData.java svneol=native#text/plain
|
||||
utils/javapp/src/fpc/tools/javapp/ClassIdentifierInfo.java svneol=native#text/plain
|
||||
utils/javapp/src/fpc/tools/javapp/ClassListBuilder.java svneol=native#text/plain
|
||||
utils/javapp/src/fpc/tools/javapp/Constants.java svneol=native#text/plain
|
||||
utils/javapp/src/fpc/tools/javapp/FieldData.java svneol=native#text/plain
|
||||
utils/javapp/src/fpc/tools/javapp/InnerClassData.java svneol=native#text/plain
|
||||
@ -12916,6 +12918,13 @@ utils/javapp/src/fpc/tools/javapp/LineNumData.java svneol=native#text/plain
|
||||
utils/javapp/src/fpc/tools/javapp/LocVarData.java svneol=native#text/plain
|
||||
utils/javapp/src/fpc/tools/javapp/Main.java svneol=native#text/plain
|
||||
utils/javapp/src/fpc/tools/javapp/MethodData.java svneol=native#text/plain
|
||||
utils/javapp/src/fpc/tools/javapp/PascalClassData.java svneol=native#text/plain
|
||||
utils/javapp/src/fpc/tools/javapp/PascalFieldData.java svneol=native#text/plain
|
||||
utils/javapp/src/fpc/tools/javapp/PascalInnerClassData.java svneol=native#text/plain
|
||||
utils/javapp/src/fpc/tools/javapp/PascalKeywords.java svneol=native#text/plain
|
||||
utils/javapp/src/fpc/tools/javapp/PascalMethodData.java svneol=native#text/plain
|
||||
utils/javapp/src/fpc/tools/javapp/PascalTypeSignature.java svneol=native#text/plain
|
||||
utils/javapp/src/fpc/tools/javapp/PascalUnit.java svneol=native#text/plain
|
||||
utils/javapp/src/fpc/tools/javapp/RuntimeConstants.java svneol=native#text/plain
|
||||
utils/javapp/src/fpc/tools/javapp/StackMapData.java svneol=native#text/plain
|
||||
utils/javapp/src/fpc/tools/javapp/StackMapTableData.java svneol=native#text/plain
|
||||
|
||||
@ -22,10 +22,12 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* Portions Copyright (c) 2011 Jonas Maebe
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sun.tools.javap;
|
||||
package fpc.tools.javapp;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
|
||||
@ -22,9 +22,12 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* Portions Copyright (c) 2011 Jonas Maebe
|
||||
*/
|
||||
|
||||
|
||||
package sun.tools.javap;
|
||||
package fpc.tools.javapp;
|
||||
|
||||
/**
|
||||
* Stores constant pool entry information with one field.
|
||||
|
||||
@ -22,9 +22,12 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* Portions Copyright (c) 2011 Jonas Maebe
|
||||
*/
|
||||
|
||||
|
||||
package sun.tools.javap;
|
||||
package fpc.tools.javapp;
|
||||
|
||||
/**
|
||||
* Stores constant pool entry information with two fields.
|
||||
|
||||
@ -22,9 +22,12 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* Portions Copyright (c) 2011 Jonas Maebe
|
||||
*/
|
||||
|
||||
|
||||
package sun.tools.javap;
|
||||
package fpc.tools.javapp;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
@ -41,23 +44,23 @@ public class ClassData implements RuntimeConstants {
|
||||
private int minor_version;
|
||||
private int major_version;
|
||||
private int cpool_count;
|
||||
private Object cpool[];
|
||||
private int access;
|
||||
protected Object cpool[];
|
||||
protected int access;
|
||||
private int this_class = 0;;
|
||||
private int super_class;
|
||||
private int interfaces_count;
|
||||
private int[] interfaces = new int[0];;
|
||||
private int fields_count;
|
||||
private FieldData[] fields;
|
||||
protected FieldData[] fields;
|
||||
private int methods_count;
|
||||
private MethodData[] methods;
|
||||
private InnerClassData[] innerClasses;
|
||||
protected MethodData[] methods;
|
||||
protected InnerClassData[] innerClasses;
|
||||
private int attributes_count;
|
||||
private AttrData[] attrs;
|
||||
private String classname;
|
||||
private String superclassname;
|
||||
private int source_cpx=0;
|
||||
private byte tags[];
|
||||
protected byte tags[];
|
||||
private Hashtable indexHashAscii = new Hashtable();
|
||||
private String pkgPrefix="";
|
||||
private int pkgPrefixLen=0;
|
||||
@ -79,6 +82,10 @@ public class ClassData implements RuntimeConstants {
|
||||
}
|
||||
}
|
||||
|
||||
protected InnerClassData NewInnerClassData() {
|
||||
return new InnerClassData(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads and stores class file information.
|
||||
*/
|
||||
@ -138,7 +145,7 @@ public class ClassData implements RuntimeConstants {
|
||||
throw new ClassFormatError("invalid attr length");
|
||||
innerClasses=new InnerClassData[num];
|
||||
for (int j = 0; j < num; j++) {
|
||||
InnerClassData innerClass=new InnerClassData(this);
|
||||
InnerClassData innerClass=NewInnerClassData();
|
||||
innerClass.read(in);
|
||||
innerClasses[j]=innerClass;
|
||||
}
|
||||
|
||||
84
utils/javapp/src/fpc/tools/javapp/ClassIdentifierInfo.java
Normal file
84
utils/javapp/src/fpc/tools/javapp/ClassIdentifierInfo.java
Normal file
@ -0,0 +1,84 @@
|
||||
package fpc.tools.javapp;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class ClassIdentifierInfo {
|
||||
|
||||
protected static HashMap<String,ClassIdentifierInfo> identifierStore = new HashMap<String,ClassIdentifierInfo>();
|
||||
|
||||
String[] superClasses;
|
||||
HashMap<String,String> identifiers;
|
||||
|
||||
protected ClassIdentifierInfo(String[] superClasses) {
|
||||
identifiers = new HashMap<String,String>();
|
||||
this.superClasses = superClasses;
|
||||
}
|
||||
|
||||
public static void registerClassInfo(String className, String superClass, String[] superIntf) {
|
||||
if (identifierStore.get(className) == null) {
|
||||
String[] combinedSuperInfo;
|
||||
if (superIntf.length==0) {
|
||||
combinedSuperInfo = new String[superClass!=null?1:0];
|
||||
} else {
|
||||
combinedSuperInfo = new String[superIntf.length+1];
|
||||
for (int i = 0; i < superIntf.length; i++)
|
||||
combinedSuperInfo[i] = superIntf[i];
|
||||
}
|
||||
// also sets java.lang.Object for interfaces, but doesn't matter since those
|
||||
// identifiers cannot be used by any class implementing this interface anyway
|
||||
// (since they will inherit from java.lang.Interface)
|
||||
if (superClass != null)
|
||||
combinedSuperInfo[combinedSuperInfo.length-1] = superClass;
|
||||
|
||||
ClassIdentifierInfo classIdInfo = new ClassIdentifierInfo(combinedSuperInfo);
|
||||
identifierStore.put(className,classIdInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private String checkSafeIdentifierName(String id) {
|
||||
for (int i = 0; i < superClasses.length; i++) {
|
||||
id = getSafeIdentifierNameForClass(superClasses[i],id);
|
||||
}
|
||||
id = PascalKeywords.escapeIfPascalKeyword(id);
|
||||
String testName = id.toUpperCase();
|
||||
String orgName;
|
||||
if (id.indexOf('$') != -1) {
|
||||
System.out.println(" Warning, cannot represent identifier '"+id+"', hiding");
|
||||
id = id.replace("$","__");
|
||||
}
|
||||
while (((orgName = identifiers.get(testName)) != null) &&
|
||||
!orgName.equals(id)) {
|
||||
id = id + "_";
|
||||
testName = testName + "_";
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
private String addIdentifier(String id) {
|
||||
String testName = id.toUpperCase();
|
||||
for (int i = 0; i < superClasses.length; i++) {
|
||||
id = getSafeIdentifierNameForClass(superClasses[i],id);
|
||||
}
|
||||
id = checkSafeIdentifierName(id);
|
||||
identifiers.put(testName, id);
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
public static String AddIdentifierNameForClass(String className, String identifier) {
|
||||
ClassIdentifierInfo classIdInfo = identifierStore.get(className);
|
||||
if (classIdInfo == null) {
|
||||
throw new IllegalStateException("Class info for "+className+" not registered");
|
||||
}
|
||||
return classIdInfo.addIdentifier(identifier);
|
||||
}
|
||||
|
||||
public static String getSafeIdentifierNameForClass(String className, String identifier) {
|
||||
ClassIdentifierInfo classIdInfo = identifierStore.get(className);
|
||||
if (classIdInfo == null) {
|
||||
throw new IllegalStateException("Class info for "+className+" not registered");
|
||||
}
|
||||
return classIdInfo.checkSafeIdentifierName(identifier);
|
||||
}
|
||||
|
||||
}
|
||||
71
utils/javapp/src/fpc/tools/javapp/ClassListBuilder.java
Normal file
71
utils/javapp/src/fpc/tools/javapp/ClassListBuilder.java
Normal file
@ -0,0 +1,71 @@
|
||||
package fpc.tools.javapp;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
|
||||
public class ClassListBuilder {
|
||||
|
||||
public static Class[] getClassesInPackage(String pckgname) {
|
||||
File directory = getPackageDirectory(pckgname);
|
||||
if (!directory.exists()) {
|
||||
throw new IllegalArgumentException("Could not get directory resource for package " + pckgname + ".");
|
||||
}
|
||||
|
||||
return getClassesInPackage(pckgname, directory);
|
||||
}
|
||||
|
||||
private static Class[] getClassesInPackage(String pckgname, File directory) {
|
||||
List<Class> classes = new ArrayList<Class>();
|
||||
for (String filename : directory.list()) {
|
||||
if (filename.endsWith(".class")) {
|
||||
String classname = buildClassname(pckgname, filename);
|
||||
try {
|
||||
classes.add(Class.forName(classname));
|
||||
} catch (ClassNotFoundException e) {
|
||||
System.err.println("Error creating class " + classname);
|
||||
}
|
||||
}
|
||||
}
|
||||
return classes.toArray(new Class[classes.size()]);
|
||||
}
|
||||
|
||||
private static String buildClassname(String pckgname, String filename) {
|
||||
return pckgname + '.' + filename.replace(".class", "");
|
||||
}
|
||||
|
||||
private static File getPackageDirectory(String pckgname) {
|
||||
ClassLoader cld = Thread.currentThread().getContextClassLoader();
|
||||
if (cld == null) {
|
||||
throw new IllegalStateException("Can't get class loader.");
|
||||
}
|
||||
Enumeration<URL> resources;
|
||||
try {
|
||||
resources = cld.getResources(pckgname.replace('.', '/'));
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("can't get resourcs.");
|
||||
}
|
||||
System.out.println("Found any elements: "+resources.hasMoreElements());
|
||||
while (resources.hasMoreElements()) {
|
||||
System.out.println(resources.nextElement().getPath());
|
||||
}
|
||||
|
||||
URL resource = cld.getResource(pckgname.replace('.', '/'));
|
||||
if (resource == null) {
|
||||
throw new RuntimeException("Package " + pckgname + " not found on classpath.");
|
||||
}
|
||||
|
||||
return new File(resource.getFile());
|
||||
}
|
||||
/*
|
||||
public static void main(String[] args) {
|
||||
Class[] classes = getClassesInPackage("com.mycomp");
|
||||
for (Class c : classes) {
|
||||
System.out.println("Found: " + c.getCanonicalName());
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
@ -22,10 +22,13 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* Portions Copyright (c) 2011 Jonas Maebe
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sun.tools.javap;
|
||||
package fpc.tools.javapp;
|
||||
|
||||
/**
|
||||
* This interface defines constant that are used
|
||||
|
||||
@ -22,9 +22,12 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* Portions Copyright (c) 2011 Jonas Maebe
|
||||
*/
|
||||
|
||||
|
||||
package sun.tools.javap;
|
||||
package fpc.tools.javapp;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
@ -22,9 +22,12 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* Portions Copyright (c) 2011 Jonas Maebe
|
||||
*/
|
||||
|
||||
|
||||
package sun.tools.javap;
|
||||
package fpc.tools.javapp;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
@ -63,9 +66,11 @@ class InnerClassData implements RuntimeConstants {
|
||||
* Returns the access of this class or interface.
|
||||
*/
|
||||
public String[] getAccess(){
|
||||
Vector v = new Vector();
|
||||
Vector<String> v = new Vector<String>();
|
||||
if ((access & ACC_PUBLIC) !=0) v.addElement("public");
|
||||
if ((access & ACC_FINAL) !=0) v.addElement("final");
|
||||
if ((access & ACC_PROTECTED) !=0) v.addElement("protected");
|
||||
if ((access & ACC_PRIVATE) !=0) v.addElement("private");
|
||||
if ((access & ACC_FINAL) !=0) v.addElement("final");
|
||||
if ((access & ACC_ABSTRACT) !=0) v.addElement("abstract");
|
||||
String[] accflags = new String[v.size()];
|
||||
v.copyInto(accflags);
|
||||
|
||||
@ -22,9 +22,12 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* Portions Copyright (c) 2011 Jonas Maebe
|
||||
*/
|
||||
|
||||
|
||||
package sun.tools.javap;
|
||||
package fpc.tools.javapp;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
@ -61,18 +64,23 @@ public class JavapEnvironment {
|
||||
// JavapEnvironment flag settings
|
||||
boolean showLineAndLocal = false;
|
||||
int showAccess = PACKAGE;
|
||||
boolean showDisassembled = false;
|
||||
boolean showVerbose = false;
|
||||
boolean showInternalSigs = false;
|
||||
String classPathString = null;
|
||||
String bootClassPathString = null;
|
||||
String extDirsString = null;
|
||||
boolean extDirflag = false;
|
||||
boolean extDirflag;
|
||||
boolean nothingToDo = true;
|
||||
boolean showallAttr = false;
|
||||
String classpath = null;
|
||||
int searchpath = start;
|
||||
String outputName = "java";
|
||||
ArrayList<String> excludePrefixes;
|
||||
ArrayList<String> skelPrefixes;
|
||||
|
||||
public JavapEnvironment() {
|
||||
excludePrefixes = new ArrayList<String>();
|
||||
skelPrefixes = new ArrayList<String>();
|
||||
}
|
||||
|
||||
/**
|
||||
* According to which flags are set,
|
||||
* returns file input stream for classfile to disassemble.
|
||||
@ -80,7 +88,8 @@ public class JavapEnvironment {
|
||||
|
||||
public InputStream getFileInputStream(String Name){
|
||||
InputStream fileInStream = null;
|
||||
searchpath = cmdboot;
|
||||
int searchpath = cmdboot;
|
||||
extDirflag = false;
|
||||
try{
|
||||
if(searchpath == cmdboot){
|
||||
if(bootClassPathString != null){
|
||||
@ -259,7 +268,7 @@ public class JavapEnvironment {
|
||||
}
|
||||
else return (resolveclasspathhelper(classpath, classname));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns file input stream for classfile to disassemble if exdir is set.
|
||||
@ -352,4 +361,239 @@ public class JavapEnvironment {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected SortedSet<String> getJarEntries(String jarname) {
|
||||
SortedSet<String> res = new TreeSet<String>();
|
||||
|
||||
try{
|
||||
JarFile jfile = new JarFile(jarname);
|
||||
Enumeration<JarEntry> entries = jfile.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
JarEntry entry = entries.nextElement();
|
||||
String name = entry.getName();
|
||||
int classpos = name.lastIndexOf(".class");
|
||||
if ((classpos != -1) &&
|
||||
!PascalClassData.isInnerClass(name.substring(0, classpos)) &&
|
||||
!entry.isDirectory()) {
|
||||
res.add(name.substring(0, classpos));
|
||||
}
|
||||
}
|
||||
}catch(FileNotFoundException fnexce){
|
||||
// fnexce.printStackTrace();
|
||||
// error("cant read file");
|
||||
// error("fatal exception");
|
||||
}catch(IOException ioexc){
|
||||
// ioexc.printStackTrace();
|
||||
// error("fatal exception");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
protected SortedSet<String> getDirEntries(File fileobj, boolean includeJarEntries) {
|
||||
SortedSet<String> res = new TreeSet<String>();
|
||||
|
||||
File[] filelist = fileobj.listFiles();
|
||||
for(int i = 0; i < filelist.length; i++){
|
||||
//file is a jar file.
|
||||
String fname = filelist[i].toString();
|
||||
if(includeJarEntries &&
|
||||
fname.endsWith(".jar")){
|
||||
res.addAll(getJarEntries(fname));
|
||||
}
|
||||
else if (fname.endsWith(".class")) {
|
||||
int classpos = fname.lastIndexOf(".class");
|
||||
if (classpos != -1)
|
||||
fname = fname.substring(0, classpos);
|
||||
if (!PascalClassData.isInnerClass(fname))
|
||||
res.add(fname);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of non-nested classes found in a path
|
||||
*/
|
||||
public SortedSet<String> getExdirEntries(String path){
|
||||
File fileobj = new File(path);
|
||||
if(fileobj.isDirectory()){
|
||||
return getDirEntries(fileobj,true);
|
||||
}
|
||||
return new TreeSet<String>();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns list of non-nested classes found in class path
|
||||
*/
|
||||
public SortedSet<String> getClasspathEntries(String path){
|
||||
File fileobj = new File(path);
|
||||
if(fileobj.isDirectory()){
|
||||
return getDirEntries(fileobj, false);
|
||||
|
||||
}else if(fileobj.toString().endsWith(".jar")){
|
||||
return getJarEntries(fileobj.toString());
|
||||
}
|
||||
return new TreeSet<String>();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a list of all non-nested classes in the currently set exdir classpath
|
||||
*/
|
||||
public SortedSet<String> getAllExdirEntries(){
|
||||
SortedSet<String> res;
|
||||
if(classpath.indexOf(File.pathSeparator) != -1){
|
||||
res = new TreeSet<String>();
|
||||
//separates path
|
||||
StringTokenizer st = new StringTokenizer(classpath, File.pathSeparator);
|
||||
while(st.hasMoreTokens()){
|
||||
String path = st.nextToken();
|
||||
res.addAll(getExdirEntries(path));
|
||||
}
|
||||
}else res = getExdirEntries(classpath);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of all non-nested classes in the currently set classpath
|
||||
*/
|
||||
public SortedSet<String> getAllClasspathEntries(){
|
||||
SortedSet<String> res;
|
||||
if(classpath.indexOf(File.pathSeparator) != -1){
|
||||
res = new TreeSet<String>();
|
||||
StringTokenizer st = new StringTokenizer(classpath, File.pathSeparator);
|
||||
//separates path.
|
||||
while(st.hasMoreTokens()){
|
||||
String path = (st.nextToken()).trim();
|
||||
res.addAll(getClasspathEntries(path));
|
||||
}
|
||||
}
|
||||
else res = getClasspathEntries(classpath);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
public SortedSet<String> getAllEntries(){
|
||||
if (extDirflag)
|
||||
return getAllExdirEntries();
|
||||
else
|
||||
return getAllClasspathEntries();
|
||||
}
|
||||
|
||||
|
||||
public SortedSet<String> getClassesList(){
|
||||
SortedSet<String> res = new TreeSet<String>();
|
||||
int searchpath = cmdboot;
|
||||
extDirflag = false;
|
||||
try{
|
||||
if(searchpath == cmdboot){
|
||||
if(bootClassPathString != null){
|
||||
//search in specified bootclasspath.
|
||||
classpath = bootClassPathString;
|
||||
res.addAll(getAllEntries());
|
||||
searchpath = cmdextdir;
|
||||
}
|
||||
else searchpath = sunboot;
|
||||
}
|
||||
|
||||
if(searchpath == sunboot){
|
||||
if(System.getProperty("sun.boot.class.path") != null){
|
||||
//search in sun.boot.class.path
|
||||
classpath = System.getProperty("sun.boot.class.path");
|
||||
res.addAll(getAllEntries());
|
||||
searchpath = cmdextdir;
|
||||
}
|
||||
else searchpath = javaclass;
|
||||
}
|
||||
|
||||
if(searchpath == javaclass){
|
||||
if(System.getProperty("java.class.path") != null){
|
||||
//search in java.class.path
|
||||
classpath =System.getProperty("java.class.path");
|
||||
res.addAll(getAllEntries());
|
||||
searchpath = cmdextdir;
|
||||
}
|
||||
else searchpath = cmdextdir;
|
||||
}
|
||||
|
||||
if(searchpath == cmdextdir){
|
||||
if(extDirsString != null){
|
||||
//search in specified extdir.
|
||||
classpath = extDirsString;
|
||||
extDirflag = true;
|
||||
res.addAll(getAllEntries());
|
||||
searchpath = cmdclasspath;
|
||||
extDirflag = false;
|
||||
}
|
||||
else searchpath = javaext;
|
||||
}
|
||||
|
||||
if(searchpath == javaext){
|
||||
if(System.getProperty("java.ext.dirs") != null){
|
||||
//search in java.ext.dirs
|
||||
classpath = System.getProperty("java.ext.dirs");
|
||||
extDirflag = true;
|
||||
res.addAll(getAllEntries());
|
||||
searchpath = cmdclasspath;
|
||||
extDirflag = false;
|
||||
}
|
||||
else searchpath = cmdclasspath;
|
||||
}
|
||||
if(searchpath == cmdclasspath){
|
||||
if(classPathString != null){
|
||||
//search in specified classpath.
|
||||
classpath = classPathString;
|
||||
res.addAll(getAllEntries());
|
||||
searchpath = 8;
|
||||
}
|
||||
else searchpath = envclasspath;
|
||||
}
|
||||
|
||||
if(searchpath == envclasspath){
|
||||
if(System.getProperty("env.class.path")!= null){
|
||||
//search in env.class.path
|
||||
classpath = System.getProperty("env.class.path");
|
||||
res.addAll(getAllEntries());
|
||||
searchpath = javaclasspath;
|
||||
}
|
||||
else searchpath = javaclasspath;
|
||||
}
|
||||
|
||||
if(searchpath == javaclasspath){
|
||||
if(("application.home") == null){
|
||||
//search in java.class.path
|
||||
classpath = System.getProperty("java.class.path");
|
||||
res.addAll(getAllEntries());
|
||||
searchpath = currentdir;
|
||||
}
|
||||
else searchpath = currentdir;
|
||||
}
|
||||
|
||||
if(searchpath == currentdir){
|
||||
classpath = ".";
|
||||
//search in current dir.
|
||||
res.addAll(getAllEntries());
|
||||
}
|
||||
}catch(SecurityException excsec){
|
||||
excsec.printStackTrace();
|
||||
error("fatal exception");
|
||||
}catch(NullPointerException excnull){
|
||||
excnull.printStackTrace();
|
||||
error("fatal exception");
|
||||
}catch(IllegalArgumentException excill){
|
||||
excill.printStackTrace();
|
||||
error("fatal exception");
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -22,9 +22,12 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* Portions Copyright (c) 2011 Jonas Maebe
|
||||
*/
|
||||
|
||||
|
||||
package sun.tools.javap;
|
||||
package fpc.tools.javapp;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
@ -22,9 +22,12 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* Portions Copyright (c) 2011 Jonas Maebe
|
||||
*/
|
||||
|
||||
|
||||
package sun.tools.javap;
|
||||
package fpc.tools.javapp;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
@ -22,14 +22,21 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* Portions Copyright (c) 2011 Jonas Maebe
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sun.tools.javap;
|
||||
package fpc.tools.javapp;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
import org.jgrapht.alg.CycleDetector;
|
||||
import org.jgrapht.graph.*;
|
||||
import org.jgrapht.traverse.*;
|
||||
|
||||
/**
|
||||
* Entry point for javap, class file disassembler.
|
||||
*
|
||||
@ -37,180 +44,365 @@ import java.io.*;
|
||||
*/
|
||||
public class Main{
|
||||
|
||||
private Vector classList = new Vector();
|
||||
private PrintWriter out;
|
||||
JavapEnvironment env = new JavapEnvironment();
|
||||
private static boolean errorOccurred = false;
|
||||
private static final String progname = "javap";
|
||||
private ArrayList<String> pkgList = new ArrayList<String>();
|
||||
JavapEnvironment env = new JavapEnvironment();
|
||||
private static boolean errorOccurred = false;
|
||||
private static final String progname = "javapp";
|
||||
|
||||
|
||||
public Main(PrintWriter out){
|
||||
this.out = out;
|
||||
}
|
||||
public Main(){
|
||||
}
|
||||
|
||||
public static void main(String argv[]) {
|
||||
entry(argv);
|
||||
if (errorOccurred) {
|
||||
System.exit(1);
|
||||
public static void main(String argv[]) {
|
||||
entry(argv);
|
||||
if (errorOccurred) {
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Entry point for tool if you don't want System.exit() called.
|
||||
*/
|
||||
public static void entry(String argv[]) {
|
||||
Main jpmain = new Main();
|
||||
jpmain.perform(argv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the arguments and perform the desired action
|
||||
*/
|
||||
private void perform(String argv[]) {
|
||||
if (parseArguments(argv)) {
|
||||
displayResults();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void error(String msg) {
|
||||
errorOccurred = true;
|
||||
System.err.println(msg);
|
||||
System.err.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print usage information
|
||||
*/
|
||||
private void usage() {
|
||||
java.io.PrintStream out = System.out;
|
||||
out.println("Usage: " + progname + " <options> [<packages>] [<individual_classes>]");
|
||||
out.println(" Suffix package names with '.'");
|
||||
out.println();
|
||||
out.println("where options include:");
|
||||
out.println(" -a <class_or_pkgename> Create empty skeleton versions of these classes");
|
||||
out.println(" -classpath <pathlist> Specify where to find user class files");
|
||||
out.println(" -help Print this usage message");
|
||||
out.println(" -J<flag> Pass <flag> directly to the runtime system");
|
||||
out.println(" -l Print line number and local variable tables");
|
||||
out.println(" -o <output_base_name> Base name of output unit (default: java");
|
||||
out.println(" -public Print only public classes and members");
|
||||
out.println(" -protected Print protected/public classes and members");
|
||||
out.println(" -private Show all classes and members");
|
||||
out.println(" -x <class_or_pkgename> Do not print a certain classes or package (suffix package names with '.'");
|
||||
out.println(" -s Print internal type signatures");
|
||||
out.println(" -bootclasspath <pathlist> Override location of class files loaded");
|
||||
out.println(" by the bootstrap class loader");
|
||||
out.println(" -verbose Print stack size, number of locals and args for methods");
|
||||
out.println(" If verifying, print reasons for failure");
|
||||
out.println();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the command line arguments.
|
||||
* Set flags, construct the class list and create environment.
|
||||
*/
|
||||
private boolean parseArguments(String argv[]) {
|
||||
for (int i = 0 ; i < argv.length ; i++) {
|
||||
String arg = argv[i];
|
||||
if (arg.startsWith("-")) {
|
||||
if (arg.equals("-l")) {
|
||||
env.showLineAndLocal = true;
|
||||
} else if (arg.equals("-private") || arg.equals("-p")) {
|
||||
env.showAccess = env.PRIVATE;
|
||||
} else if (arg.equals("-package")) {
|
||||
env.showAccess = env.PACKAGE;
|
||||
} else if (arg.equals("-protected")) {
|
||||
env.showAccess = env.PROTECTED;
|
||||
} else if (arg.equals("-public")) {
|
||||
env.showAccess = env.PUBLIC;
|
||||
} else if (arg.equals("-verbose")) {
|
||||
env.showVerbose = true;
|
||||
} else if (arg.equals("-v")) {
|
||||
env.showVerbose = true;
|
||||
} else if (arg.equals("-h")) {
|
||||
error("-h is no longer available - use the 'javah' program");
|
||||
return false;
|
||||
} else if (arg.equals("-verify")) {
|
||||
error("-verify is no longer available - use 'java -verify'");
|
||||
return false;
|
||||
} else if (arg.equals("-verify-verbose")) {
|
||||
error("-verify is no longer available - use 'java -verify'");
|
||||
return false;
|
||||
} else if (arg.equals("-help")) {
|
||||
usage();
|
||||
return false;
|
||||
} else if (arg.equals("-classpath")) {
|
||||
if ((i + 1) < argv.length) {
|
||||
env.classPathString = argv[++i];
|
||||
} else {
|
||||
error("-classpath requires argument");
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
} else if (arg.equals("-bootclasspath")) {
|
||||
if ((i + 1) < argv.length) {
|
||||
env.bootClassPathString = argv[++i];
|
||||
} else {
|
||||
error("-bootclasspath requires argument");
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
} else if (arg.equals("-extdirs")) {
|
||||
if ((i + 1) < argv.length) {
|
||||
env.extDirsString = argv[++i];
|
||||
} else {
|
||||
error("-extdirs requires argument");
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
} else if (arg.equals("-o")) {
|
||||
if ((i + 1) < argv.length) {
|
||||
env.outputName = argv[++i];
|
||||
} else {
|
||||
error("-o requires argument");
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
} else if (arg.equals("-x")) {
|
||||
if ((i + 1) < argv.length) {
|
||||
env.excludePrefixes.add(argv[++i].replace('.','/'));
|
||||
} else {
|
||||
error("-x requires argument");
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
} else if (arg.equals("-a")) {
|
||||
if ((i + 1) < argv.length) {
|
||||
env.skelPrefixes.add(argv[++i].replace('.','/'));
|
||||
} else {
|
||||
error("-a requires argument");
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
} else if (arg.equals("-all")) {
|
||||
env.showallAttr = true;
|
||||
} else {
|
||||
error("invalid flag: " + arg);
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
pkgList.add(arg);
|
||||
env.nothingToDo = false;
|
||||
}
|
||||
}
|
||||
if (env.nothingToDo) {
|
||||
System.out.println("No classes were specified on the command line. Try -help.");
|
||||
errorOccurred = true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private PrintWriter createFile(String fname) {
|
||||
PrintWriter res = null;
|
||||
try {
|
||||
res = new PrintWriter(new OutputStreamWriter(new PrintStream(new File(fname))));
|
||||
} catch (FileNotFoundException e) {
|
||||
System.out.println("Unable to create file "+fname+", aborting...");
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display results
|
||||
*/
|
||||
private void displayResults() {
|
||||
|
||||
if (pkgList.isEmpty())
|
||||
return;
|
||||
|
||||
// collect all class names in the environment (format: /package/name/classname)
|
||||
SortedSet<String> classes = env.getClassesList();
|
||||
// same for arguments
|
||||
Collections.sort(pkgList);
|
||||
Collections.sort(env.excludePrefixes);
|
||||
// create the unit
|
||||
PrintWriter includeFile;
|
||||
PrintWriter mainUnitFile;
|
||||
PascalUnit thisUnit;
|
||||
String includeName, mainUnitName;
|
||||
|
||||
mainUnitName = env.outputName+".pas";
|
||||
includeName = env.outputName+".inc";
|
||||
|
||||
includeFile = createFile(includeName);
|
||||
mainUnitFile = createFile(mainUnitName);
|
||||
thisUnit = new PascalUnit(mainUnitFile, env, pkgList, includeName);
|
||||
PascalClassData.currentUnit = thisUnit;
|
||||
|
||||
// create unique short names for all classes we may need
|
||||
System.out.println("Determining short Pascal class names...");
|
||||
for (Iterator<String> iter = classes.iterator(); iter.hasNext(); ) {
|
||||
thisUnit.registerClassName(iter.next());
|
||||
}
|
||||
|
||||
// first read all requested classes and build dependency graph
|
||||
Iterator<String> classStepper = classes.iterator();
|
||||
Iterator<String> argStepper = pkgList.iterator();
|
||||
Iterator<String> skipPkgsStepper = env.excludePrefixes.iterator();
|
||||
HashSet<String> classesToPrintList = new HashSet<String>();
|
||||
SimpleDirectedGraph<String,DefaultEdge> classDependencies = new SimpleDirectedGraph<String, DefaultEdge>(DefaultEdge.class);
|
||||
|
||||
try {
|
||||
String currentExcludePkg;
|
||||
String currentPkgPrefix;
|
||||
if (skipPkgsStepper.hasNext())
|
||||
currentExcludePkg = skipPkgsStepper.next();
|
||||
else
|
||||
currentExcludePkg = ".......";
|
||||
if (argStepper.hasNext())
|
||||
currentPkgPrefix = argStepper.next().replace('.', '/');
|
||||
else
|
||||
currentPkgPrefix = ".......";
|
||||
System.out.println("Indexing classes under "+currentPkgPrefix+"...");
|
||||
do {
|
||||
String currentClass = classStepper.next();
|
||||
// if the current class name is > the current package name, skip packages
|
||||
// until we have a package to which the current class belongs, or the
|
||||
// next in line
|
||||
while (argStepper.hasNext() &&
|
||||
!currentClass.startsWith(currentPkgPrefix) &&
|
||||
(currentClass.compareTo(currentPkgPrefix) > 0)) {
|
||||
String currentArg = argStepper.next();
|
||||
// convention: '.' as package name = no package name, otherwise actual package name
|
||||
if (!currentArg.equals(".")) {
|
||||
currentArg = currentArg.replace('.', '/');
|
||||
currentPkgPrefix = currentArg;
|
||||
} else {
|
||||
currentArg = "./";
|
||||
currentPkgPrefix = currentArg;
|
||||
}
|
||||
System.out.println("Indexing classes under "+currentPkgPrefix+"...");
|
||||
currentPkgPrefix = currentArg;
|
||||
}
|
||||
boolean doPrintClass = false;
|
||||
// should check whether the class is explicitly excluded from being printed
|
||||
if (currentClass.startsWith(currentPkgPrefix)) {
|
||||
while (skipPkgsStepper.hasNext() &&
|
||||
!currentClass.startsWith(currentExcludePkg) &&
|
||||
(currentClass.compareTo(currentExcludePkg) > 0)) {
|
||||
currentExcludePkg = skipPkgsStepper.next();
|
||||
}
|
||||
if (!currentClass.startsWith(currentExcludePkg)) {
|
||||
doPrintClass = true;
|
||||
}
|
||||
}
|
||||
// always construct the class to record the identifiers
|
||||
// (so we can properly rename identifiers in subclasses),
|
||||
// but only collect dependency information if we actually
|
||||
// have to print the class
|
||||
InputStream classin = env.getFileInputStream(currentClass);
|
||||
JavapPrinter printer = new JavapPrinter(classin, includeFile, env, " ",null,doPrintClass);
|
||||
if (doPrintClass) {
|
||||
if (!classDependencies.containsVertex(currentClass))
|
||||
classDependencies.addVertex(currentClass);
|
||||
|
||||
HashSet<String> dependencies = printer.cls.getDependencies();
|
||||
Iterator<String> depStepper = dependencies.iterator();
|
||||
while (depStepper.hasNext()) {
|
||||
String dep = depStepper.next();
|
||||
thisUnit.registerUsedClass(dep);
|
||||
if (!classDependencies.containsVertex(dep))
|
||||
classDependencies.addVertex(dep);
|
||||
/*
|
||||
if (currentClass.equals("java/awt/Window"))
|
||||
System.out.println(" java/awt/Window depends on "+dep);
|
||||
if (dep.equals("java/awt/Window"))
|
||||
System.out.println("dep = java/awt/Window for "+currentClass);
|
||||
*/
|
||||
classDependencies.addEdge(dep, currentClass);
|
||||
}
|
||||
|
||||
classesToPrintList.add(currentClass);
|
||||
|
||||
// JavapClassPrinter.PrintClass(env,includeFile,currentClass," ");
|
||||
}
|
||||
} while (classStepper.hasNext());
|
||||
// no longer needed
|
||||
classes = null;
|
||||
pkgList = null;
|
||||
System.out.println("Printing classes...");
|
||||
// Iterator<String> printerStepper = classesToPrintList.iterator();
|
||||
TopologicalOrderIterator<String,DefaultEdge> printerStepper = new TopologicalOrderIterator<String,DefaultEdge>(classDependencies);
|
||||
while (printerStepper.hasNext()) {
|
||||
String currentClass = printerStepper.next();
|
||||
// also contains external classes
|
||||
if (!classesToPrintList.remove(currentClass))
|
||||
continue;
|
||||
try {
|
||||
InputStream classin = env.getFileInputStream(currentClass);
|
||||
JavapPrinter printer = new JavapPrinter(classin, includeFile, env, " ",null, true);
|
||||
printer.print();
|
||||
|
||||
// JavapClassPrinter.PrintClass(env,includeFile,currentClass," ");
|
||||
} catch (IllegalArgumentException exc) {
|
||||
error(exc.getMessage());
|
||||
exc.printStackTrace();
|
||||
System.out.println("Error while processing class "+currentClass+", aborting...");
|
||||
includeFile.close();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// the iterator
|
||||
if (!classesToPrintList.isEmpty()) {
|
||||
Iterator<String> leftOvers = classesToPrintList.iterator();
|
||||
System.out.println("Classes part of dependency cycles, or related to these classes:");
|
||||
CycleDetector<String, DefaultEdge> cycles = new CycleDetector<String, DefaultEdge>(classDependencies);
|
||||
while (leftOvers.hasNext()) {
|
||||
String currentClass = leftOvers.next();
|
||||
System.out.println(" "+currentClass+" is part of cycle "+cycles.findCyclesContainingVertex(currentClass));
|
||||
|
||||
try {
|
||||
InputStream classin = env.getFileInputStream(currentClass);
|
||||
JavapPrinter printer = new JavapPrinter(classin, includeFile, env, " ",null,true);
|
||||
printer.print();
|
||||
|
||||
// JavapClassPrinter.PrintClass(env,includeFile,currentClass," ");
|
||||
} catch (IllegalArgumentException exc) {
|
||||
error(exc.getMessage());
|
||||
exc.printStackTrace();
|
||||
System.out.println("Error while processing class "+currentClass+", aborting...");
|
||||
includeFile.close();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} finally {
|
||||
includeFile.close();
|
||||
thisUnit.printUnit();
|
||||
mainUnitFile.close();
|
||||
}
|
||||
/* Class[] classes = ClassListBuilder.getClassesInPackage("fpc.tools.javapp");
|
||||
for (Class c : classes) {
|
||||
System.out.println("Found: " + c.getCanonicalName());
|
||||
}
|
||||
}
|
||||
*/
|
||||
System.out.println("Done!");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Entry point for tool if you don't want System.exit() called.
|
||||
*/
|
||||
public static void entry(String argv[]) {
|
||||
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
|
||||
try {
|
||||
|
||||
Main jpmain = new Main(out);
|
||||
jpmain.perform(argv);
|
||||
|
||||
} finally {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the arguments and perform the desired action
|
||||
*/
|
||||
private void perform(String argv[]) {
|
||||
if (parseArguments(argv)) {
|
||||
displayResults();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void error(String msg) {
|
||||
errorOccurred = true;
|
||||
System.err.println(msg);
|
||||
System.err.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print usage information
|
||||
*/
|
||||
private void usage() {
|
||||
java.io.PrintStream out = System.out;
|
||||
out.println("Usage: " + progname + " <options> <classes>...");
|
||||
out.println();
|
||||
out.println("where options include:");
|
||||
out.println(" -c Disassemble the code");
|
||||
out.println(" -classpath <pathlist> Specify where to find user class files");
|
||||
out.println(" -extdirs <dirs> Override location of installed extensions");
|
||||
out.println(" -help Print this usage message");
|
||||
out.println(" -J<flag> Pass <flag> directly to the runtime system");
|
||||
out.println(" -l Print line number and local variable tables");
|
||||
out.println(" -public Show only public classes and members");
|
||||
out.println(" -protected Show protected/public classes and members");
|
||||
out.println(" -package Show package/protected/public classes");
|
||||
out.println(" and members (default)");
|
||||
out.println(" -private Show all classes and members");
|
||||
out.println(" -s Print internal type signatures");
|
||||
out.println(" -bootclasspath <pathlist> Override location of class files loaded");
|
||||
out.println(" by the bootstrap class loader");
|
||||
out.println(" -verbose Print stack size, number of locals and args for methods");
|
||||
out.println(" If verifying, print reasons for failure");
|
||||
out.println();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the command line arguments.
|
||||
* Set flags, construct the class list and create environment.
|
||||
*/
|
||||
private boolean parseArguments(String argv[]) {
|
||||
for (int i = 0 ; i < argv.length ; i++) {
|
||||
String arg = argv[i];
|
||||
if (arg.startsWith("-")) {
|
||||
if (arg.equals("-l")) {
|
||||
env.showLineAndLocal = true;
|
||||
} else if (arg.equals("-private") || arg.equals("-p")) {
|
||||
env.showAccess = env.PRIVATE;
|
||||
} else if (arg.equals("-package")) {
|
||||
env.showAccess = env.PACKAGE;
|
||||
} else if (arg.equals("-protected")) {
|
||||
env.showAccess = env.PROTECTED;
|
||||
} else if (arg.equals("-public")) {
|
||||
env.showAccess = env.PUBLIC;
|
||||
} else if (arg.equals("-c")) {
|
||||
env.showDisassembled = true;
|
||||
} else if (arg.equals("-s")) {
|
||||
env.showInternalSigs = true;
|
||||
} else if (arg.equals("-verbose")) {
|
||||
env.showVerbose = true;
|
||||
} else if (arg.equals("-v")) {
|
||||
env.showVerbose = true;
|
||||
} else if (arg.equals("-h")) {
|
||||
error("-h is no longer available - use the 'javah' program");
|
||||
return false;
|
||||
} else if (arg.equals("-verify")) {
|
||||
error("-verify is no longer available - use 'java -verify'");
|
||||
return false;
|
||||
} else if (arg.equals("-verify-verbose")) {
|
||||
error("-verify is no longer available - use 'java -verify'");
|
||||
return false;
|
||||
} else if (arg.equals("-help")) {
|
||||
usage();
|
||||
return false;
|
||||
} else if (arg.equals("-classpath")) {
|
||||
if ((i + 1) < argv.length) {
|
||||
env.classPathString = argv[++i];
|
||||
} else {
|
||||
error("-classpath requires argument");
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
} else if (arg.equals("-bootclasspath")) {
|
||||
if ((i + 1) < argv.length) {
|
||||
env.bootClassPathString = argv[++i];
|
||||
} else {
|
||||
error("-bootclasspath requires argument");
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
} else if (arg.equals("-extdirs")) {
|
||||
if ((i + 1) < argv.length) {
|
||||
env.extDirsString = argv[++i];
|
||||
} else {
|
||||
error("-extdirs requires argument");
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
} else if (arg.equals("-all")) {
|
||||
env.showallAttr = true;
|
||||
} else {
|
||||
error("invalid flag: " + arg);
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
classList.addElement(arg);
|
||||
env.nothingToDo = false;
|
||||
}
|
||||
}
|
||||
if (env.nothingToDo) {
|
||||
System.out.println("No classes were specified on the command line. Try -help.");
|
||||
errorOccurred = true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display results
|
||||
*/
|
||||
private void displayResults() {
|
||||
for (int i = 0; i < classList.size() ; i++ ) {
|
||||
String Name = (String)classList.elementAt(i);
|
||||
InputStream classin = env.getFileInputStream(Name);
|
||||
|
||||
try {
|
||||
JavapPrinter printer = new JavapPrinter(classin, out, env);
|
||||
printer.print(); // actual do display
|
||||
|
||||
} catch (IllegalArgumentException exc) {
|
||||
error(exc.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,13 +22,16 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* Portions Copyright (c) 2011 Jonas Maebe
|
||||
*/
|
||||
|
||||
package sun.tools.javap;
|
||||
package fpc.tools.javapp;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
import static sun.tools.javap.RuntimeConstants.*;
|
||||
import static fpc.tools.javapp.RuntimeConstants.*;
|
||||
|
||||
/**
|
||||
* Strores method data informastion.
|
||||
@ -42,16 +45,20 @@ public class MethodData {
|
||||
int name_index;
|
||||
int descriptor_index;
|
||||
int attributes_count;
|
||||
/*
|
||||
byte[] code;
|
||||
Vector exception_table = new Vector(0);
|
||||
Vector lin_num_tb = new Vector(0);
|
||||
Vector loc_var_tb = new Vector(0);
|
||||
StackMapTableData[] stackMapTable;
|
||||
StackMapData[] stackMap;
|
||||
*/
|
||||
int[] exc_index_table=null;
|
||||
Vector attrs=new Vector(0);
|
||||
/*
|
||||
Vector code_attrs=new Vector(0);
|
||||
int max_stack, max_locals;
|
||||
*/
|
||||
boolean isSynthetic=false;
|
||||
boolean isDeprecated=false;
|
||||
|
||||
@ -116,24 +123,28 @@ public class MethodData {
|
||||
public void readCode(DataInputStream in) throws IOException {
|
||||
|
||||
int attr_length = in.readInt();
|
||||
max_stack=in.readUnsignedShort();
|
||||
max_locals=in.readUnsignedShort();
|
||||
// max_stack=in.readUnsignedShort();
|
||||
// max_locals=in.readUnsignedShort();
|
||||
int max_stack=in.readUnsignedShort();
|
||||
int max_locals=in.readUnsignedShort();
|
||||
int codelen=in.readInt();
|
||||
|
||||
code=new byte[codelen];
|
||||
// code=new byte[codelen];
|
||||
int totalread = 0;
|
||||
while(totalread < codelen){
|
||||
totalread += in.read(code, totalread, codelen-totalread);
|
||||
// totalread += in.read(code, totalread, codelen-totalread);
|
||||
totalread += in.skipBytes(codelen-totalread);
|
||||
}
|
||||
// in.read(code, 0, codelen);
|
||||
int clen = 0;
|
||||
readExceptionTable(in);
|
||||
int code_attributes_count = in.readUnsignedShort();
|
||||
|
||||
AttrData attr=new AttrData(cls);
|
||||
for (int k = 0 ; k < code_attributes_count ; k++) {
|
||||
int table_name_index=in.readUnsignedShort();
|
||||
int table_name_tag=cls.getTag(table_name_index);
|
||||
AttrData attr=new AttrData(cls);
|
||||
// AttrData attr=new AttrData(cls);
|
||||
if (table_name_tag==CONSTANT_UTF8) {
|
||||
String table_name_tstr=cls.getString(table_name_index);
|
||||
if (table_name_tstr.equals("LineNumberTable")) {
|
||||
@ -151,12 +162,12 @@ public class MethodData {
|
||||
} else {
|
||||
attr.read(table_name_index, in);
|
||||
}
|
||||
code_attrs.addElement(attr);
|
||||
// code_attrs.addElement(attr);
|
||||
continue;
|
||||
}
|
||||
|
||||
attr.read(table_name_index, in);
|
||||
code_attrs.addElement(attr);
|
||||
// code_attrs.addElement(attr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,7 +176,8 @@ public class MethodData {
|
||||
*/
|
||||
void readExceptionTable (DataInputStream in) throws IOException {
|
||||
int exception_table_len=in.readUnsignedShort();
|
||||
exception_table=new Vector(exception_table_len);
|
||||
// exception_table=new Vector(exception_table_len);
|
||||
Vector exception_table=new Vector(exception_table_len);
|
||||
for (int l = 0; l < exception_table_len; l++) {
|
||||
exception_table.addElement(new TrapData(in, l));
|
||||
}
|
||||
@ -177,7 +189,8 @@ public class MethodData {
|
||||
void readLineNumTable (DataInputStream in) throws IOException {
|
||||
int attr_len = in.readInt(); // attr_length
|
||||
int lin_num_tb_len = in.readUnsignedShort();
|
||||
lin_num_tb=new Vector(lin_num_tb_len);
|
||||
// lin_num_tb=new Vector(lin_num_tb_len);
|
||||
Vector lin_num_tb=new Vector(lin_num_tb_len);
|
||||
for (int l = 0; l < lin_num_tb_len; l++) {
|
||||
lin_num_tb.addElement(new LineNumData(in));
|
||||
}
|
||||
@ -189,7 +202,8 @@ public class MethodData {
|
||||
void readLocVarTable (DataInputStream in) throws IOException {
|
||||
int attr_len=in.readInt(); // attr_length
|
||||
int loc_var_tb_len = in.readUnsignedShort();
|
||||
loc_var_tb = new Vector(loc_var_tb_len);
|
||||
// loc_var_tb = new Vector(loc_var_tb_len);
|
||||
Vector loc_var_tb = new Vector(loc_var_tb_len);
|
||||
for (int l = 0; l < loc_var_tb_len; l++) {
|
||||
loc_var_tb.addElement(new LocVarData(in));
|
||||
}
|
||||
@ -202,6 +216,7 @@ public class MethodData {
|
||||
int attr_len=in.readInt(); // attr_length in prog
|
||||
int num_exceptions = in.readUnsignedShort();
|
||||
exc_index_table=new int[num_exceptions];
|
||||
int[] exc_index_table=new int[num_exceptions];
|
||||
for (int l = 0; l < num_exceptions; l++) {
|
||||
int exc=in.readShort();
|
||||
exc_index_table[l]=exc;
|
||||
@ -214,7 +229,8 @@ public class MethodData {
|
||||
void readStackMapTable(DataInputStream in) throws IOException {
|
||||
int attr_len = in.readInt(); //attr_length
|
||||
int stack_map_tb_len = in.readUnsignedShort();
|
||||
stackMapTable = new StackMapTableData[stack_map_tb_len];
|
||||
// stackMapTable = new StackMapTableData[stack_map_tb_len];
|
||||
StackMapTableData[] stackMapTable = new StackMapTableData[stack_map_tb_len];
|
||||
for (int i=0; i<stack_map_tb_len; i++) {
|
||||
stackMapTable[i] = StackMapTableData.getInstance(in, this);
|
||||
}
|
||||
@ -226,7 +242,8 @@ public class MethodData {
|
||||
void readStackMap(DataInputStream in) throws IOException {
|
||||
int attr_len = in.readInt(); //attr_length
|
||||
int stack_map_len = in.readUnsignedShort();
|
||||
stackMap = new StackMapData[stack_map_len];
|
||||
// stackMap = new StackMapData[stack_map_len];
|
||||
StackMapData[] stackMap = new StackMapData[stack_map_len];
|
||||
for (int i = 0; i<stack_map_len; i++) {
|
||||
stackMap[i] = new StackMapData(in, this);
|
||||
}
|
||||
@ -288,52 +305,52 @@ public class MethodData {
|
||||
/**
|
||||
* Return code attribute data of a method.
|
||||
*/
|
||||
public byte[] getCode(){
|
||||
return code;
|
||||
}
|
||||
// public byte[] getCode(){
|
||||
// return code;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Return LineNumberTable size.
|
||||
*/
|
||||
public int getnumlines(){
|
||||
return lin_num_tb.size();
|
||||
}
|
||||
// public int getnumlines(){
|
||||
// return lin_num_tb.size();
|
||||
// }
|
||||
|
||||
/**
|
||||
* Return LineNumberTable
|
||||
*/
|
||||
public Vector getlin_num_tb(){
|
||||
return lin_num_tb;
|
||||
}
|
||||
// public Vector getlin_num_tb(){
|
||||
// return lin_num_tb;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Return LocalVariableTable size.
|
||||
*/
|
||||
public int getloc_var_tbsize(){
|
||||
return loc_var_tb.size();
|
||||
}
|
||||
// public int getloc_var_tbsize(){
|
||||
// return loc_var_tb.size();
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* Return LocalVariableTable.
|
||||
*/
|
||||
public Vector getloc_var_tb(){
|
||||
return loc_var_tb;
|
||||
}
|
||||
// public Vector getloc_var_tb(){
|
||||
// return loc_var_tb;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Return StackMap.
|
||||
*/
|
||||
public StackMapData[] getStackMap() {
|
||||
return stackMap;
|
||||
}
|
||||
// public StackMapData[] getStackMap() {
|
||||
// return stackMap;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Return StackMapTable.
|
||||
*/
|
||||
public StackMapTableData[] getStackMapTable() {
|
||||
return stackMapTable;
|
||||
}
|
||||
// public StackMapTableData[] getStackMapTable() {
|
||||
// return stackMapTable;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Return number of arguments of that method.
|
||||
@ -354,17 +371,17 @@ public class MethodData {
|
||||
/**
|
||||
* Return max depth of operand stack.
|
||||
*/
|
||||
public int getMaxStack(){
|
||||
return max_stack;
|
||||
}
|
||||
// public int getMaxStack(){
|
||||
// return max_stack;
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* Return number of local variables.
|
||||
*/
|
||||
public int getMaxLocals(){
|
||||
return max_locals;
|
||||
}
|
||||
// public int getMaxLocals(){
|
||||
// return max_locals;
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
@ -378,9 +395,9 @@ public class MethodData {
|
||||
/**
|
||||
* Return exception table in code attributre.
|
||||
*/
|
||||
public Vector getexception_table(){
|
||||
return exception_table;
|
||||
}
|
||||
// public Vector getexception_table(){
|
||||
// return exception_table;
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
@ -394,9 +411,9 @@ public class MethodData {
|
||||
/**
|
||||
* Return code attributes.
|
||||
*/
|
||||
public Vector getCodeAttributes(){
|
||||
return code_attrs;
|
||||
}
|
||||
// public Vector getCodeAttributes(){
|
||||
// return code_attrs;
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
|
||||
426
utils/javapp/src/fpc/tools/javapp/PascalClassData.java
Normal file
426
utils/javapp/src/fpc/tools/javapp/PascalClassData.java
Normal file
@ -0,0 +1,426 @@
|
||||
package fpc.tools.javapp;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.Vector;
|
||||
|
||||
public class PascalClassData extends ClassData {
|
||||
|
||||
private JavapEnvironment env;
|
||||
public PascalClassData outerClass;
|
||||
private HashSet<String> nestedDependencies;
|
||||
boolean setOuterDependencies;
|
||||
|
||||
static public PascalUnit currentUnit;
|
||||
|
||||
static final String[] nonNestedDollarClasses;
|
||||
|
||||
|
||||
|
||||
public PascalClassData(InputStream infile, PascalClassData outerClass, JavapEnvironment env, boolean doCollectDependencies) {
|
||||
super (infile);
|
||||
this.outerClass = outerClass;
|
||||
this.nestedDependencies = new HashSet<String>();
|
||||
this.env = env;
|
||||
ClassIdentifierInfo.registerClassInfo(getClassName(),getSuperClassName(),getSuperInterfaces());
|
||||
if (doCollectDependencies) {
|
||||
collectDependencies();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private void collectDependencies() {
|
||||
if (this.outerClass != null) {
|
||||
HashSet<String> myDeps = getDependencies();
|
||||
String mySuperClass = getSuperClassName();
|
||||
boolean foundMatch = false;
|
||||
PascalClassData outerMostClass = this;
|
||||
while (outerMostClass.outerClass != null) {
|
||||
/**
|
||||
* adjust dependencies for inner types, e.g.
|
||||
* CSNHAuthenticator = class abstract external 'com.sun.net.httpserver' name 'Authenticator' (JLObject)
|
||||
* type
|
||||
* Retry = class external 'com.sun.net.httpserver' name 'Authenticator$Retry' (Result)
|
||||
* ..
|
||||
* end;
|
||||
*
|
||||
* Result = class abstract external 'com.sun.net.httpserver' name 'Authenticator$Result' (JLObject)
|
||||
* ..
|
||||
* end;
|
||||
*
|
||||
* end;
|
||||
* -> Retry must depend on Result
|
||||
*/
|
||||
if (!foundMatch &&
|
||||
mySuperClass.startsWith(outerMostClass.outerClass.getClassName()) &&
|
||||
!mySuperClass.equals(outerMostClass.outerClass.getClassName())) {
|
||||
foundMatch = true;
|
||||
outerMostClass.addNestedDepdency(mySuperClass);
|
||||
}
|
||||
outerMostClass = outerMostClass.outerClass;
|
||||
}
|
||||
myDeps.remove(outerMostClass.getMasterClassName());
|
||||
outerMostClass.addNestedDepdencies(myDeps);
|
||||
}
|
||||
}
|
||||
|
||||
public void addNestedDepdencies(HashSet<String> nestedDeps) {
|
||||
this.nestedDependencies.addAll(nestedDeps);
|
||||
}
|
||||
|
||||
public void addNestedDepdency(String nestedDep) {
|
||||
this.nestedDependencies.add(nestedDep);
|
||||
}
|
||||
|
||||
/*
|
||||
public String getSafeMethodIdentifer(String id) {
|
||||
if (id.charAt(0) == '<')
|
||||
return id;
|
||||
id = PascalKeywords.escapeIfPascalKeyword(id);
|
||||
String testName = id.toUpperCase();
|
||||
while (usedIdentifiers.contains(testName)) {
|
||||
id = id + "_";
|
||||
testName = testName + "_";
|
||||
}
|
||||
if (id.indexOf('$') != -1) {
|
||||
System.out.println(" Warning, cannot represent identifier '"+id+"', hiding");
|
||||
id = id.replace("$","__");
|
||||
}
|
||||
return id;
|
||||
}
|
||||
*/
|
||||
public boolean isStatic() {
|
||||
return (access & ACC_STATIC) != 0;
|
||||
}
|
||||
|
||||
public static boolean isInnerClass(String className) {
|
||||
if (className.indexOf('$') == -1)
|
||||
return false;
|
||||
className = className.replace('.', '/');
|
||||
for (String name : nonNestedDollarClasses) {
|
||||
if (className.equals(name))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isInnerClass() {
|
||||
return outerClass != null;
|
||||
}
|
||||
|
||||
public static String getShortClassName(String className) {
|
||||
int index;
|
||||
className = className.replace('-', '_');
|
||||
if (isInnerClass(className)) {
|
||||
index=className.lastIndexOf("$")+1;
|
||||
return "Inner"+className.substring(index);
|
||||
}
|
||||
else
|
||||
className = className.replace("$","__");
|
||||
index=className.lastIndexOf("/")+1;
|
||||
if (index==0) {
|
||||
index=className.lastIndexOf(".")+1;
|
||||
}
|
||||
if (index!=0) {
|
||||
return className.substring(index);
|
||||
}
|
||||
return className;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a non-nested class, returns the name of the class itself
|
||||
* For a nested class, returns the name of the outermost class
|
||||
*
|
||||
*/
|
||||
public static String getMasterClassName(String className) {
|
||||
int index;
|
||||
// className = className.replace('-', '_');
|
||||
if (!isInnerClass(className.replace('.','/')))
|
||||
return className;
|
||||
index=className.indexOf('$');
|
||||
if (index!=-1) {
|
||||
return className.substring(0,index);
|
||||
}
|
||||
return className;
|
||||
}
|
||||
|
||||
public static String getShortPascalClassName(String className) {
|
||||
currentUnit.registerUsedClass(className);
|
||||
return currentUnit.getShortPascalName(className);
|
||||
|
||||
/*
|
||||
|
||||
String shortname = getShortClassName(classname);
|
||||
// inner class -> done (no naming problems)
|
||||
if (classname.indexOf('$') != -1)
|
||||
return shortname;
|
||||
|
||||
// no package?
|
||||
if (shortname.equals(classname))
|
||||
return shortname;
|
||||
// add package component prefixes
|
||||
String pkgname = getClassPackageName(classname);
|
||||
String prefix = Character.toString(classname.charAt(0)).toUpperCase();
|
||||
for (int i = 1; i < pkgname.length(); i++)
|
||||
if ((pkgname.charAt(i) == '.'))
|
||||
prefix = prefix + Character.toString(pkgname.charAt(i+1)).toUpperCase();
|
||||
return prefix+shortname;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
public static String getClassPackageName(String className) {
|
||||
int index;
|
||||
index=className.lastIndexOf("/");
|
||||
if (index==-1) {
|
||||
index=className.lastIndexOf(".");
|
||||
}
|
||||
if (index!=-1) {
|
||||
return className.substring(0,index).replace('/', '.');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getFullPascalClassName(String className) {
|
||||
return getShortPascalClassName(className);
|
||||
/*
|
||||
if (isInnerClass(className)) {
|
||||
int nestedIndex = className.indexOf('$');
|
||||
String res = getShortPascalClassName(className.substring(0,nestedIndex));
|
||||
StringTokenizer innerTypes = new StringTokenizer(className.substring(nestedIndex+1), "$");
|
||||
while (innerTypes.hasMoreTokens()) {
|
||||
res = res + "." + PascalKeywords.escapeIfPascalKeyword(innerTypes.nextToken());
|
||||
}
|
||||
return res;
|
||||
} else
|
||||
return getShortPascalClassName(className);
|
||||
*/
|
||||
}
|
||||
|
||||
public static String getExternalClassName(String className) {
|
||||
int index = className.lastIndexOf('/');
|
||||
if (index != -1) {
|
||||
return className.substring(index+1);
|
||||
}
|
||||
else
|
||||
return className;
|
||||
}
|
||||
|
||||
public String getShortClassName() {
|
||||
return getShortClassName(getClassName());
|
||||
}
|
||||
|
||||
public String getShortPascalClassName() {
|
||||
return getShortPascalClassName(getClassName());
|
||||
}
|
||||
|
||||
public String getClassPackageName() {
|
||||
return getClassPackageName(getClassName());
|
||||
}
|
||||
|
||||
public String getFullPascalClassName() {
|
||||
return getFullPascalClassName(getClassName());
|
||||
}
|
||||
|
||||
public String getMasterClassName() {
|
||||
return getMasterClassName(getClassName());
|
||||
}
|
||||
|
||||
public String getExternalClassName() {
|
||||
return getExternalClassName(getClassName());
|
||||
}
|
||||
|
||||
public String[] getPascalSuperInterfaces(){
|
||||
String[] res = super.getSuperInterfaces();
|
||||
for (int i=0; i<res.length; i++)
|
||||
res[i] = getFullPascalClassName(res[i]);
|
||||
return res;
|
||||
}
|
||||
/**
|
||||
* Returns the visibility of this class or interface.
|
||||
*/
|
||||
public String getVisibilitySectionName(){
|
||||
if (isInnerClass()) {
|
||||
if (isPublic()) {
|
||||
return "public";
|
||||
}
|
||||
else {
|
||||
return "strict private";
|
||||
}
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String[] getModifiers(){
|
||||
Vector<String> v = new Vector<String>();
|
||||
if ((access & ACC_FINAL) !=0) v.addElement("sealed");
|
||||
if ((access & ACC_ABSTRACT) !=0) v.addElement("abstract");
|
||||
String[] accflags = new String[v.size()];
|
||||
v.copyInto(accflags);
|
||||
return accflags;
|
||||
}
|
||||
|
||||
|
||||
protected void readFields(DataInputStream in) throws IOException {
|
||||
int fields_count = in.readUnsignedShort();
|
||||
fields=new FieldData[fields_count];
|
||||
for (int k = 0; k < fields_count; k++) {
|
||||
FieldData field=new PascalFieldData(this);
|
||||
field.read(in);
|
||||
fields[k]=field;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads and stores Method info.
|
||||
*/
|
||||
protected void readMethods(DataInputStream in) throws IOException {
|
||||
int methods_count = in.readUnsignedShort();
|
||||
methods=new PascalMethodData[methods_count];
|
||||
for (int k = 0; k < methods_count ; k++) {
|
||||
MethodData method=new PascalMethodData(this);
|
||||
method.read(in);
|
||||
methods[k]=method;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns string at that index.
|
||||
*/
|
||||
public String StringValue(int cpx) {
|
||||
if (cpx==0) throw new ClassFormatError("Invalid CP index: 0");
|
||||
int tag;
|
||||
Object x;
|
||||
try {
|
||||
tag=tags[cpx];
|
||||
x=cpool[cpx];
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
throw new ClassFormatError("<Incorrect CP index:"+cpx+">");
|
||||
}
|
||||
|
||||
if (x==null) return "nil";
|
||||
switch (tag) {
|
||||
case CONSTANT_UTF8: {
|
||||
StringBuffer sb=new StringBuffer();
|
||||
String s=(String)x;
|
||||
sb.append('\'');
|
||||
for (int k=0; k<s.length(); k++) {
|
||||
char c=s.charAt(k);
|
||||
if (c == '\'')
|
||||
sb.append("''");
|
||||
else if ((c >= ' ') &&
|
||||
(c <= '~'))
|
||||
sb.append(c);
|
||||
else
|
||||
sb.append("'#$"+String.format("%04x",(int)c)+"'");
|
||||
}
|
||||
sb.append('\'');
|
||||
return sb.toString();
|
||||
}
|
||||
case CONSTANT_DOUBLE: {
|
||||
Double d=(Double)x;
|
||||
String sd=d.toString();
|
||||
sd = sd.replace("Infinity", "1.0/0.0").replace("NaN", "0.0/0.0");
|
||||
return "jdouble("+sd+")";
|
||||
}
|
||||
case CONSTANT_FLOAT: {
|
||||
Float f=(Float)x;
|
||||
String sf=(f).toString();
|
||||
sf = sf.replace("Infinity", "1.0/0.0").replace("NaN", "0.0/0.0");
|
||||
return "jfloat("+sf+")";
|
||||
}
|
||||
case CONSTANT_LONG: {
|
||||
Long ln = (Long)x;
|
||||
return "jlong("+ln.toString()+')';
|
||||
}
|
||||
case CONSTANT_INTEGER: {
|
||||
Integer in = (Integer)x;
|
||||
return in.toString();
|
||||
}
|
||||
case CONSTANT_CLASS:
|
||||
return javaName(getClassName(cpx));
|
||||
case CONSTANT_STRING:
|
||||
return StringValue(((CPX)x).cpx);
|
||||
case CONSTANT_FIELD:
|
||||
case CONSTANT_METHOD:
|
||||
case CONSTANT_INTERFACEMETHOD:
|
||||
//return getShortClassName(((CPX2)x).cpx1)+"."+StringValue(((CPX2)x).cpx2);
|
||||
return javaName(getClassName(((CPX2)x).cpx1))+"."+StringValue(((CPX2)x).cpx2);
|
||||
|
||||
case CONSTANT_NAMEANDTYPE:
|
||||
throw new ClassFormatError("Don't try to print out field/method/interfacemethod constant values");
|
||||
default:
|
||||
throw new ClassFormatError("Unknown constant tag: "+tag);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected InnerClassData NewInnerClassData() {
|
||||
return new PascalInnerClassData(this);
|
||||
}
|
||||
|
||||
public HashSet<String> getDependencies() {
|
||||
HashSet<String> res = new HashSet<String>();
|
||||
// inheritance dependencies (superclass and implemented interfaces)
|
||||
String superClass = getSuperClassName();
|
||||
if (superClass != null)
|
||||
res.add(getMasterClassName(superClass));
|
||||
String []interfacelist = getSuperInterfaces();
|
||||
for (String intf : interfacelist)
|
||||
res.add(getMasterClassName(intf));
|
||||
/** most dependencies in parameters/result types/field types can be
|
||||
* handled via forward declarations, but there is one exception:
|
||||
* dependencies on nested classes declared in another class
|
||||
*/
|
||||
// field types
|
||||
FieldData[] fields = getFields();
|
||||
for (FieldData field : fields) {
|
||||
if (TypeSignature.checkAccess(field.getAccess(),env)) {
|
||||
String fieldType = ((PascalFieldData)field).getRawBaseType();
|
||||
if (isInnerClass(fieldType))
|
||||
res.add(getMasterClassName(fieldType.replace('.', '/')));
|
||||
}
|
||||
}
|
||||
|
||||
// method parameter/return types
|
||||
MethodData[] methods = getMethods();
|
||||
for (MethodData method : methods) {
|
||||
if (TypeSignature.checkAccess(method.getAccess(),env)) {
|
||||
String retType = ((PascalMethodData)method).getRawBaseReturnType();
|
||||
if (isInnerClass(retType))
|
||||
res.add(getMasterClassName(retType.replace('.', '/')));
|
||||
TypeSignature methodSig = new TypeSignature(method.getInternalSig());
|
||||
Vector<String> paras = methodSig.getParametersList(methodSig.parameterdes);
|
||||
for (int i = 0; i < paras.size(); i++) {
|
||||
String paraType = paras.get(i);
|
||||
int arrPos = paraType.indexOf('[');
|
||||
if (arrPos != -1)
|
||||
paraType = paraType.substring(0,arrPos);
|
||||
if (isInnerClass(paraType))
|
||||
res.add(getMasterClassName(paraType.replace('.', '/')));
|
||||
}
|
||||
}
|
||||
}
|
||||
// dependencies added by nested classes (in case we are a top-level class/interface)
|
||||
res.addAll(nestedDependencies);
|
||||
// remove ourselves
|
||||
res.remove(getClassName());
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static {
|
||||
nonNestedDollarClasses = new String[1];
|
||||
nonNestedDollarClasses[0] = "com/sun/org/apache/xalan/internal/xsltc/compiler/CUP$XPathParser$actions";
|
||||
}
|
||||
}
|
||||
74
utils/javapp/src/fpc/tools/javapp/PascalFieldData.java
Normal file
74
utils/javapp/src/fpc/tools/javapp/PascalFieldData.java
Normal file
@ -0,0 +1,74 @@
|
||||
package fpc.tools.javapp;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Vector;
|
||||
|
||||
public class PascalFieldData extends FieldData {
|
||||
|
||||
private String cachedName;
|
||||
|
||||
public PascalFieldData(ClassData cls){
|
||||
super(cls);
|
||||
}
|
||||
|
||||
public String getVisibilitySectionName(){
|
||||
if ((access & ACC_PUBLIC) !=0) return "public";
|
||||
if ((access & ACC_PRIVATE) !=0) return "strict private";
|
||||
if ((access & ACC_PROTECTED) !=0) return "strict protected";
|
||||
/* package visibility = visible in this unit */
|
||||
return "private";
|
||||
}
|
||||
|
||||
public boolean isFormalConst() {
|
||||
for (int i=0; i < attrs.size(); i++)
|
||||
if(((AttrData)attrs.elementAt(i)).getAttrName().equals("ConstantValue"))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getModifiers() {
|
||||
Vector<String> v = new Vector<String>();
|
||||
if (isFormalConst()) return "const";
|
||||
else {
|
||||
if ((access & ACC_FINAL) !=0) v.addElement("final");
|
||||
if ((access & ACC_STATIC) !=0) v.addElement("class var");
|
||||
else
|
||||
v.addElement("var");
|
||||
}
|
||||
String res = v.elementAt(0);
|
||||
for (int i=1; i < v.size(); i++)
|
||||
res=res+" "+v.elementAt(i);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Pascal type signature of a field.
|
||||
*/
|
||||
public String getType(){
|
||||
return new PascalTypeSignature(getInternalSig(),cls).getFieldType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Java type signature of a field.
|
||||
*/
|
||||
public String getRawBaseType(){
|
||||
String res = new TypeSignature(getInternalSig()).getFieldType();
|
||||
int arrIndex = res.indexOf('[');
|
||||
if (arrIndex != -1)
|
||||
res = res.substring(0,arrIndex);
|
||||
return res;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
if (cachedName == null) {
|
||||
String realName = super.getName();
|
||||
// we prepend an "f" for fields to prevent name clashes
|
||||
if (!isFormalConst())
|
||||
realName = "f" + realName;
|
||||
cachedName = ClassIdentifierInfo.AddIdentifierNameForClass(cls.getClassName(),realName);
|
||||
}
|
||||
return cachedName;
|
||||
}
|
||||
|
||||
}
|
||||
12
utils/javapp/src/fpc/tools/javapp/PascalInnerClassData.java
Normal file
12
utils/javapp/src/fpc/tools/javapp/PascalInnerClassData.java
Normal file
@ -0,0 +1,12 @@
|
||||
package fpc.tools.javapp;
|
||||
|
||||
public class PascalInnerClassData extends InnerClassData {
|
||||
|
||||
public PascalInnerClassData(ClassData cls) {
|
||||
super(cls);
|
||||
}
|
||||
|
||||
public boolean isStatic() {
|
||||
return (access & ACC_STATIC) != 0;
|
||||
}
|
||||
}
|
||||
95
utils/javapp/src/fpc/tools/javapp/PascalKeywords.java
Normal file
95
utils/javapp/src/fpc/tools/javapp/PascalKeywords.java
Normal file
@ -0,0 +1,95 @@
|
||||
package fpc.tools.javapp;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
public class PascalKeywords {
|
||||
static private HashSet<String> pascalKeywords;
|
||||
|
||||
static public boolean isPascalKeyword(String str) {
|
||||
return pascalKeywords.contains(str.toUpperCase());
|
||||
}
|
||||
|
||||
static public String escapeIfPascalKeyword(String str) {
|
||||
if (isPascalKeyword(str))
|
||||
return "&"+str;
|
||||
return str;
|
||||
}
|
||||
|
||||
static {
|
||||
pascalKeywords = new HashSet<String>();
|
||||
pascalKeywords.add("AS");
|
||||
pascalKeywords.add("DO");
|
||||
pascalKeywords.add("IF");
|
||||
pascalKeywords.add("IN");
|
||||
pascalKeywords.add("IS");
|
||||
pascalKeywords.add("OF");
|
||||
pascalKeywords.add("ON");
|
||||
pascalKeywords.add("OR");
|
||||
pascalKeywords.add("TO");
|
||||
pascalKeywords.add("AND");
|
||||
pascalKeywords.add("ASM");
|
||||
pascalKeywords.add("DIV");
|
||||
pascalKeywords.add("END");
|
||||
pascalKeywords.add("FOR");
|
||||
pascalKeywords.add("MOD");
|
||||
pascalKeywords.add("NIL");
|
||||
pascalKeywords.add("NOT");
|
||||
pascalKeywords.add("SET");
|
||||
pascalKeywords.add("SHL");
|
||||
pascalKeywords.add("SHR");
|
||||
pascalKeywords.add("TRY");
|
||||
pascalKeywords.add("VAR");
|
||||
pascalKeywords.add("XOR");
|
||||
pascalKeywords.add("CASE");
|
||||
pascalKeywords.add("ELSE");
|
||||
pascalKeywords.add("FILE");
|
||||
pascalKeywords.add("GOTO");
|
||||
pascalKeywords.add("THEN");
|
||||
pascalKeywords.add("TRUE");
|
||||
pascalKeywords.add("TYPE");
|
||||
pascalKeywords.add("UNIT");
|
||||
pascalKeywords.add("USES");
|
||||
pascalKeywords.add("WITH");
|
||||
pascalKeywords.add("ARRAY");
|
||||
pascalKeywords.add("BEGIN");
|
||||
pascalKeywords.add("CLASS");
|
||||
pascalKeywords.add("CONST");
|
||||
pascalKeywords.add("FALSE");
|
||||
pascalKeywords.add("FINAL");
|
||||
pascalKeywords.add("LABEL");
|
||||
pascalKeywords.add("UNTIL");
|
||||
pascalKeywords.add("RAISE");
|
||||
pascalKeywords.add("WHILE");
|
||||
pascalKeywords.add("EXCEPT");
|
||||
pascalKeywords.add("DOWNTO");
|
||||
pascalKeywords.add("OBJECT");
|
||||
pascalKeywords.add("PACKED");
|
||||
pascalKeywords.add("PUBLIC");
|
||||
pascalKeywords.add("RECORD");
|
||||
pascalKeywords.add("REPEAT");
|
||||
pascalKeywords.add("STRING");
|
||||
pascalKeywords.add("STRICT");
|
||||
pascalKeywords.add("EXPORTS");
|
||||
pascalKeywords.add("FINALLY");
|
||||
pascalKeywords.add("LIBRARY");
|
||||
pascalKeywords.add("PROGRAM");
|
||||
pascalKeywords.add("PRIVATE");
|
||||
pascalKeywords.add("ABSTRACT");
|
||||
pascalKeywords.add("CPPCLASS");
|
||||
pascalKeywords.add("FUNCTION");
|
||||
pascalKeywords.add("OPERATOR");
|
||||
pascalKeywords.add("PROPERTY");
|
||||
pascalKeywords.add("BITPACKED");
|
||||
pascalKeywords.add("INHERITED");
|
||||
pascalKeywords.add("INTERFACE");
|
||||
pascalKeywords.add("OTHERWISE");
|
||||
pascalKeywords.add("PROCEDURE");
|
||||
pascalKeywords.add("PROTECTED");
|
||||
pascalKeywords.add("THREADVAR");
|
||||
pascalKeywords.add("DESTRUCTOR");
|
||||
pascalKeywords.add("CONSTRUCTOR");
|
||||
pascalKeywords.add("DISPINTERFACE");
|
||||
pascalKeywords.add("IMPLEMENTATION");
|
||||
pascalKeywords.add("RESOURCESTRING");
|
||||
}
|
||||
}
|
||||
79
utils/javapp/src/fpc/tools/javapp/PascalMethodData.java
Normal file
79
utils/javapp/src/fpc/tools/javapp/PascalMethodData.java
Normal file
@ -0,0 +1,79 @@
|
||||
package fpc.tools.javapp;
|
||||
|
||||
import fpc.tools.javapp.MethodData;
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
import static fpc.tools.javapp.RuntimeConstants.*;
|
||||
|
||||
public class PascalMethodData extends MethodData {
|
||||
|
||||
private String cachedName;
|
||||
|
||||
public PascalMethodData(ClassData cls) {
|
||||
super(cls);
|
||||
}
|
||||
|
||||
public String getVisibilitySectionName(){
|
||||
if ((access & ACC_PUBLIC) !=0) return "public";
|
||||
if ((access & ACC_PRIVATE) !=0) return "strict private";
|
||||
if ((access & ACC_PROTECTED) !=0) return "strict protected";
|
||||
/* package visibility = visible in this unit */
|
||||
return "private";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return modifiers of the method that matter to Pascal import.
|
||||
*/
|
||||
public String getModifiers(){
|
||||
if ((access & ACC_FINAL) !=0) return " final;";
|
||||
if ((access & ACC_ABSTRACT) !=0) return " abstract;";
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return java return type signature of method.
|
||||
*/
|
||||
public String getReturnType(){
|
||||
|
||||
String rttype = (new PascalTypeSignature(getInternalSig(), cls)).getReturnType();
|
||||
return rttype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return java return type signature of method.
|
||||
*/
|
||||
public String getRawBaseReturnType(){
|
||||
|
||||
String rttype = (new TypeSignature(getInternalSig())).getReturnType();
|
||||
int arrPos = rttype.indexOf('[');
|
||||
if (arrPos != -1)
|
||||
rttype = rttype.substring(0,arrPos);
|
||||
return rttype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return java type parameter signature.
|
||||
*/
|
||||
public String getParameters(){
|
||||
String ptype = (new PascalTypeSignature(getInternalSig(),cls)).getParameters();
|
||||
|
||||
return ptype;
|
||||
}
|
||||
|
||||
|
||||
public String getName(){
|
||||
if (cachedName == null) {
|
||||
String realName = super.getName();
|
||||
cachedName = ClassIdentifierInfo.AddIdentifierNameForClass(cls.getClassName(),realName);
|
||||
// this will require compiler support for remapping field names
|
||||
// (we also need it for Objective-C and C++ anyway)
|
||||
if ((cachedName.charAt(0) != '&') &&
|
||||
!cachedName.equals(realName)) {
|
||||
System.out.println(" Duplicate identifier conflict in "+cls.getClassName()+" for method '"+realName+"', disabled");
|
||||
}
|
||||
|
||||
}
|
||||
return cachedName;
|
||||
}
|
||||
}
|
||||
100
utils/javapp/src/fpc/tools/javapp/PascalTypeSignature.java
Normal file
100
utils/javapp/src/fpc/tools/javapp/PascalTypeSignature.java
Normal file
@ -0,0 +1,100 @@
|
||||
package fpc.tools.javapp;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
public class PascalTypeSignature extends TypeSignature {
|
||||
|
||||
public PascalTypeSignature(String JVMSignature, ClassData cls) {
|
||||
init(JVMSignature);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Pascal type signature for a base type.
|
||||
*/
|
||||
public String getBaseType(String baseType){
|
||||
if(baseType != null){
|
||||
if(baseType.equals("B")) return "jbyte";
|
||||
else if(baseType.equals("C")) return "jchar";
|
||||
else if(baseType.equals("D")) return "jdouble";
|
||||
else if(baseType.equals("F")) return "jfloat";
|
||||
else if(baseType.equals("I")) return "jint";
|
||||
else if(baseType.equals("J")) return "jlong";
|
||||
else if(baseType.equals("S")) return "jshort";
|
||||
else if(baseType.equals("Z")) return "jboolean";
|
||||
else if(baseType.equals("V")) return "";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns Pascal type signature for a object type.
|
||||
*/
|
||||
public String getObjectType(String JVMobjectType) {
|
||||
String objectType = super.getObjectType(JVMobjectType).replace('.','/');
|
||||
if (objectType != null) {
|
||||
if (!PascalClassData.currentUnit.isExternalInnerClass(objectType)) {
|
||||
objectType = PascalClassData.getFullPascalClassName(objectType);
|
||||
} else
|
||||
objectType = PascalClassData.getShortPascalClassName(objectType);
|
||||
}
|
||||
if (PascalKeywords.isPascalKeyword(objectType))
|
||||
objectType = "&" + objectType;
|
||||
return objectType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Pascal type signature for array type.
|
||||
*/
|
||||
public String getArrayType(String arrayType) {
|
||||
if(arrayType != null){
|
||||
int dimCount = 0;
|
||||
|
||||
for (int i = 0; i < arrayType.length(); i++) {
|
||||
if (arrayType.charAt(i) != '[') {
|
||||
arrayType = arrayType.substring(i);
|
||||
break;
|
||||
}
|
||||
dimCount++;
|
||||
}
|
||||
|
||||
String componentType = "";
|
||||
String outerClass = "";
|
||||
if(arrayType.startsWith("L")){
|
||||
String baseType = arrayType.substring(1, arrayType.length()-1);
|
||||
if (PascalClassData.isInnerClass(baseType) &&
|
||||
!PascalClassData.currentUnit.isExternalInnerClass(baseType)) {
|
||||
int index = baseType.lastIndexOf('$');
|
||||
outerClass = PascalClassData.getShortPascalClassName(baseType.substring(0,index))+".";
|
||||
componentType = "Inner"+baseType.substring(index+1).replace('$', '.');
|
||||
} else {
|
||||
outerClass = "";
|
||||
componentType = PascalClassData.getShortPascalClassName(baseType);
|
||||
}
|
||||
}else {
|
||||
componentType = getBaseType(arrayType);
|
||||
}
|
||||
return outerClass+"Arr"+dimCount+componentType;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
protected String parameterSignatureFromParameters(Vector<String> parameters){
|
||||
/* number of arguments of a method.*/
|
||||
argumentlength = parameters.size();
|
||||
/* Pascal type signature.*/
|
||||
String parametersignature = "(";
|
||||
int i;
|
||||
|
||||
for(i = 0; i < argumentlength; i++){
|
||||
parametersignature += "para"+(i+1)+": "+(String)parameters.elementAt(i);
|
||||
if(i != parameters.size()-1){
|
||||
parametersignature += "; ";
|
||||
}
|
||||
}
|
||||
parametersignature += ")";
|
||||
return parametersignature;
|
||||
}
|
||||
|
||||
}
|
||||
410
utils/javapp/src/fpc/tools/javapp/PascalUnit.java
Normal file
410
utils/javapp/src/fpc/tools/javapp/PascalUnit.java
Normal file
@ -0,0 +1,410 @@
|
||||
package fpc.tools.javapp;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.*;
|
||||
|
||||
public class PascalUnit {
|
||||
|
||||
private static class SkelItem implements Comparable<SkelItem> {
|
||||
String className;
|
||||
String kind;
|
||||
|
||||
public SkelItem(String className, String kind) {
|
||||
this.className = className;
|
||||
this.kind = kind;
|
||||
}
|
||||
|
||||
public int compareTo(SkelItem o) {
|
||||
return className.compareTo(o.className);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return className;
|
||||
}
|
||||
}
|
||||
|
||||
private PrintWriter unitFile;
|
||||
private String[] pkgPrefixes;
|
||||
private String[] excludePrefixes;
|
||||
private String[] skelPrefixes;
|
||||
private String includeName;
|
||||
private HashSet<String> registeredExternalClasses, registeredInternalClasses;
|
||||
private SortedSet<SkelItem> registeredSkelObjs;
|
||||
private HashSet<String> registeredExternalInterfaces, registeredInternalInterfaces;
|
||||
// maps full java class names (pkg.classname) to unique "short" Pascal names in the current unit
|
||||
// maps from short to full name
|
||||
private HashMap<String,String> classShortToLong, classLongToShort;
|
||||
private JavapEnvironment env;
|
||||
|
||||
public PascalUnit(PrintWriter unitFile, JavapEnvironment env, ArrayList<String> pkgPrefixes, String includeName) {
|
||||
this.unitFile = unitFile;
|
||||
this.env = env;
|
||||
this.pkgPrefixes = new String[pkgPrefixes.size()];
|
||||
for (int i = 0; i < pkgPrefixes.size(); i++) {
|
||||
this.pkgPrefixes[i] = pkgPrefixes.get(i).replace('.', '/');
|
||||
}
|
||||
this.excludePrefixes = new String[env.excludePrefixes.size()];
|
||||
for (int i = 0; i < env.excludePrefixes.size(); i++) {
|
||||
this.excludePrefixes[i] = env.excludePrefixes.get(i).replace('.', '/');
|
||||
}
|
||||
this.skelPrefixes = new String[env.skelPrefixes.size()];
|
||||
for (int i = 0; i < env.skelPrefixes.size(); i++) {
|
||||
this.skelPrefixes[i] = env.skelPrefixes.get(i).replace('.', '/');
|
||||
}
|
||||
this.includeName = includeName;
|
||||
registeredExternalClasses = new HashSet<String>();
|
||||
registeredInternalClasses = new HashSet<String>();
|
||||
registeredExternalInterfaces = new HashSet<String>();
|
||||
registeredInternalInterfaces = new HashSet<String>();
|
||||
registeredSkelObjs = new TreeSet<SkelItem>();
|
||||
classShortToLong = new HashMap<String,String>();
|
||||
classLongToShort = new HashMap<String,String>();
|
||||
}
|
||||
|
||||
|
||||
public void registerClassName(String fullName) {
|
||||
String newClassShortName = getDefaultShortPascalName(fullName);
|
||||
String prevVal = classShortToLong.put(newClassShortName,fullName);
|
||||
while (prevVal != null) {
|
||||
// remove the old shortname item
|
||||
classShortToLong.remove(newClassShortName);
|
||||
// make the two shortnames unique
|
||||
newClassShortName = "";
|
||||
String oldClassShortName = "";
|
||||
StringTokenizer name1tok = new StringTokenizer(fullName.replace("$", "__").replace('-', '_'), "/.");
|
||||
StringTokenizer name2tok = new StringTokenizer(prevVal.replace("$", "__").replace('-', '_'), "/.");
|
||||
String name1elem = "";
|
||||
String name2elem = "";
|
||||
// create new short names that contain the differing characters in
|
||||
// addition to just the first characters
|
||||
while (name1tok.hasMoreTokens()) {
|
||||
name1elem = name1tok.nextToken();
|
||||
name2elem = name2tok.nextToken();
|
||||
// ignore class name itself }
|
||||
if (!name1tok.hasMoreTokens() ||
|
||||
!name2tok.hasMoreTokens())
|
||||
break;
|
||||
newClassShortName = newClassShortName + Character.toUpperCase(name1elem.charAt(0));
|
||||
oldClassShortName = oldClassShortName + Character.toUpperCase(name2elem.charAt(0));
|
||||
if (!name1elem.equals(name2elem)) {
|
||||
int minlen = Math.min(name1elem.length(),name2elem.length());
|
||||
for (int i = 1; i < minlen; i++) {
|
||||
if (name1elem.charAt(i) != name2elem.charAt(i)) {
|
||||
newClassShortName = newClassShortName + name1elem.charAt(i);
|
||||
oldClassShortName = oldClassShortName + name2elem.charAt(i);
|
||||
}
|
||||
}
|
||||
for (int i = minlen; i < name1elem.length(); i++)
|
||||
newClassShortName = newClassShortName + name1elem.charAt(i);
|
||||
for (int i = minlen; i < name2elem.length(); i++)
|
||||
oldClassShortName = oldClassShortName + name2elem.charAt(i);
|
||||
}
|
||||
}
|
||||
newClassShortName = newClassShortName + name1elem.replace('.','_');
|
||||
oldClassShortName = oldClassShortName + name2elem.replace('.', '_');
|
||||
assert (!newClassShortName.equals(oldClassShortName));
|
||||
// return the previous shortname, ignore
|
||||
classLongToShort.put(prevVal,oldClassShortName);
|
||||
prevVal = classShortToLong.put(oldClassShortName,prevVal);
|
||||
// we don't support a collision for the new shortname of the old class
|
||||
assert(prevVal==null);
|
||||
prevVal = classShortToLong.put(newClassShortName,fullName);
|
||||
}
|
||||
classLongToShort.put(fullName,newClassShortName);
|
||||
}
|
||||
|
||||
private String getDefaultShortPascalName(String classname) {
|
||||
String shortname = PascalClassData.getShortClassName(classname);
|
||||
// inner class -> done (no naming problems)
|
||||
if (classname.indexOf('$') != -1)
|
||||
return "Inner"+shortname;
|
||||
|
||||
// no package?
|
||||
if (shortname.equals(classname))
|
||||
return shortname;
|
||||
// add package component prefixes
|
||||
String pkgname = PascalClassData.getClassPackageName(classname);
|
||||
String prefix = Character.toString(Character.toUpperCase(classname.charAt(0)));
|
||||
for (int i = 1; i < pkgname.length(); i++)
|
||||
if ((pkgname.charAt(i) == '.'))
|
||||
prefix = prefix + Character.toUpperCase(pkgname.charAt(i+1));
|
||||
return prefix+shortname;
|
||||
}
|
||||
|
||||
public boolean isExternalInnerClass(String className) {
|
||||
return registeredExternalClasses.contains(className) || registeredExternalInterfaces.contains(className);
|
||||
}
|
||||
|
||||
public String getShortPascalName(String className) {
|
||||
if (PascalClassData.isInnerClass(className)) {
|
||||
int nestedIndex = className.indexOf('$');
|
||||
// get the abbreviated Pascal name of the top-level class, followed by
|
||||
// "Inner" + the nested class names (to avoid identifier conflicts)
|
||||
String res = getShortPascalName(className.substring(0,nestedIndex));
|
||||
// create valid identifier for inner classes that only exist in external version
|
||||
if (isExternalInnerClass(className)) {
|
||||
res = res + className.substring(nestedIndex);
|
||||
res = res.replace('.', '_').replace("$","__");
|
||||
} else {
|
||||
StringTokenizer innerTypes = new StringTokenizer(className.substring(nestedIndex+1), "$");
|
||||
while (innerTypes.hasMoreTokens()) {
|
||||
res = res + "." + "Inner"+innerTypes.nextToken();
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
else className = className.replace("$", "__");
|
||||
String res = classLongToShort.get(className.replace('.','/'));
|
||||
// happens with one class in classes.jar: com.sun.org.apache.xalan.internal.xsltc.compiler.CUP$XPathParser$actions
|
||||
// unlike what the name suggests, it's not an inner class, and com.sun.org.apache.xalan.internal.xsltc.compiler.CUP
|
||||
// does not exist
|
||||
if (res == null)
|
||||
res = getDefaultShortPascalName(className);
|
||||
return res;
|
||||
}
|
||||
|
||||
public void registerInnerClassAsExternalClass(String className) {
|
||||
if (!registeredExternalClasses.contains(className)) {
|
||||
registerClassName(className);
|
||||
registeredExternalClasses.add(className);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void registerUsedClass(String className) {
|
||||
className = className.replace('.','/');
|
||||
PascalClassData classData;
|
||||
boolean isLocal;
|
||||
boolean isSkel;
|
||||
|
||||
isLocal = false;
|
||||
isSkel = false;
|
||||
// first check for skeleton classes/packages
|
||||
for (int i = 0; i < skelPrefixes.length; i++) {
|
||||
if (className.startsWith(skelPrefixes[i])) {
|
||||
isSkel = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isSkel) {
|
||||
// we cannot create forward definitions in the global scope for nested classes
|
||||
if (PascalClassData.isInnerClass(className))
|
||||
return;
|
||||
|
||||
// check whether we should fully print it; if not,
|
||||
// declare as anonymous external
|
||||
for (int i = 0; i < pkgPrefixes.length; i++) {
|
||||
if (className.startsWith(pkgPrefixes[i])) {
|
||||
boolean excluded = false;
|
||||
// then excluded
|
||||
for (int j = 0; j < excludePrefixes.length; j++) {
|
||||
if (className.startsWith(excludePrefixes[j])) {
|
||||
excluded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!excluded) {
|
||||
isLocal = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
StringTokenizer classComponents = new StringTokenizer(className,"$");
|
||||
String completeName = "";
|
||||
|
||||
if (isSkel) {
|
||||
do {
|
||||
SkelItem item;
|
||||
boolean isClass;
|
||||
completeName += classComponents.nextToken();
|
||||
item = new SkelItem(completeName, "");
|
||||
classData = new PascalClassData(env.getFileInputStream(completeName),null,env,false);
|
||||
if (registeredSkelObjs.contains(item)) {
|
||||
completeName += "$";
|
||||
continue;
|
||||
}
|
||||
isClass = classData.isClass();
|
||||
item.kind = isClass?"class":"interface";
|
||||
registeredSkelObjs.add(item);
|
||||
completeName += "$";
|
||||
} while (classComponents.hasMoreTokens());
|
||||
} else {
|
||||
Set<String> pickedSet = null;
|
||||
do {
|
||||
completeName += classComponents.nextToken();
|
||||
if (isLocal) {
|
||||
if (registeredInternalClasses.contains(completeName) ||
|
||||
registeredInternalInterfaces.contains(completeName))
|
||||
continue;
|
||||
if (pickedSet == null) {
|
||||
classData = new PascalClassData(env.getFileInputStream(completeName),null,env,false);
|
||||
if (classData.isClass())
|
||||
pickedSet = registeredInternalClasses;
|
||||
else
|
||||
pickedSet = registeredInternalInterfaces;
|
||||
}
|
||||
} else {
|
||||
if (registeredInternalClasses.contains(completeName) ||
|
||||
registeredInternalInterfaces.contains(completeName))
|
||||
continue;
|
||||
if (pickedSet == null) {
|
||||
classData = new PascalClassData(env.getFileInputStream(completeName),null,env,false);
|
||||
if (classData.isClass())
|
||||
pickedSet= registeredExternalClasses;
|
||||
else
|
||||
pickedSet = registeredExternalInterfaces;
|
||||
}
|
||||
}
|
||||
pickedSet.add(completeName);
|
||||
completeName += "$";
|
||||
} while (classComponents.hasMoreTokens());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean parentIsKnownInterface(String className) {
|
||||
className = className.substring(0,className.lastIndexOf('$'));
|
||||
className = className.replace('.','/');
|
||||
return
|
||||
registeredInternalInterfaces.contains(className) ||
|
||||
registeredExternalInterfaces.contains(className);
|
||||
}
|
||||
|
||||
public static void printArrayTypes(PrintWriter out, String prefix, String shortName, String shortSafeName) {
|
||||
out.println(prefix+"Arr1"+shortName+" = array of "+shortSafeName+";");
|
||||
out.println(prefix+"Arr2"+shortName+" = array of Arr1"+shortName+";");
|
||||
out.println(prefix+"Arr3"+shortName+" = array of Arr2"+shortName+";");
|
||||
}
|
||||
|
||||
private void printArrayTypes(String prefix, String shortname) {
|
||||
printArrayTypes(unitFile,prefix,shortname, shortname);
|
||||
}
|
||||
|
||||
private String RealPkgName(String name) {
|
||||
if (name.equals("./"))
|
||||
return "<nameless package>";
|
||||
else
|
||||
return name.replace('/', '.');
|
||||
}
|
||||
|
||||
private void printInternalObjs(Enumeration<String> iterator, String kind) {
|
||||
while (iterator.hasMoreElements()) {
|
||||
String curClass = iterator.nextElement();
|
||||
unitFile.println(" "+getShortPascalName(curClass)+" = "+kind+";");
|
||||
// create formal array types for array parameters
|
||||
printArrayTypes(" ",getShortPascalName(curClass));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param iterator
|
||||
*/
|
||||
private void printExternalObjs(Enumeration<String> iterator, String kind) {
|
||||
while (iterator.hasMoreElements()) {
|
||||
String curClass = iterator.nextElement();
|
||||
String shortPascalName = getShortPascalName(curClass);
|
||||
String shortExternalName = PascalClassData.getExternalClassName(curClass);
|
||||
String pkgExternalName = PascalClassData.getClassPackageName(curClass).replace('/', '.');
|
||||
unitFile.println(" "+shortPascalName+" = "+kind+" external '"+pkgExternalName+"' name '"+shortExternalName+"';");
|
||||
// create formal array types for array parameters
|
||||
printArrayTypes(" ",shortPascalName);
|
||||
}
|
||||
}
|
||||
|
||||
private void printSkelObjs(Enumeration<SkelItem> iterator) {
|
||||
String prefix=" ";
|
||||
ArrayList<String> nestedClasses = new ArrayList<String>();
|
||||
String curClass = " ";
|
||||
if (!iterator.hasMoreElements())
|
||||
return;
|
||||
while (iterator.hasMoreElements()) {
|
||||
SkelItem curSkelItem = iterator.nextElement();
|
||||
curClass = curSkelItem.className;
|
||||
String shortPascalName;
|
||||
String shortExternalName = PascalClassData.getExternalClassName(curClass);
|
||||
String pkgExternalName = PascalClassData.getClassPackageName(curClass).replace('/', '.');
|
||||
|
||||
// finish earlier nested types if needed
|
||||
if (nestedClasses.size()>0) {
|
||||
while ((nestedClasses.size()>0) &&
|
||||
!curClass.startsWith(nestedClasses.get(nestedClasses.size()-1))) {
|
||||
String finishingName = nestedClasses.get(nestedClasses.size()-1);
|
||||
// remove added '$' again
|
||||
finishingName = finishingName.substring(0,finishingName.length()-1);
|
||||
if (nestedClasses.size()>1) {
|
||||
finishingName = PascalClassData.getShortClassName(finishingName);
|
||||
} else {
|
||||
finishingName = PascalClassData.getShortPascalClassName(finishingName);
|
||||
}
|
||||
unitFile.println(prefix+"end;");
|
||||
printArrayTypes(prefix,finishingName);
|
||||
nestedClasses.remove(nestedClasses.size()-1);
|
||||
if (prefix.length()>4)
|
||||
prefix = prefix.substring(4);
|
||||
}
|
||||
}
|
||||
if (nestedClasses.size()>0) {
|
||||
unitFile.println(prefix+" type");
|
||||
prefix = prefix + " ";
|
||||
shortPascalName = PascalClassData.getShortClassName(curClass);
|
||||
} else {
|
||||
shortPascalName = PascalClassData.getShortPascalClassName(curClass);
|
||||
}
|
||||
unitFile.println(prefix+shortPascalName+" = "+curSkelItem.kind+" external '"+pkgExternalName+"' name '"+shortExternalName+"'");
|
||||
// make sure we only match inner classes, not classes that start with the word in the current package
|
||||
nestedClasses.add(curClass+"$");
|
||||
}
|
||||
while (nestedClasses.size()>0) {
|
||||
String finishingName = nestedClasses.get(nestedClasses.size()-1);
|
||||
// remove added '$' again
|
||||
finishingName = finishingName.substring(0,finishingName.length()-1);
|
||||
if (nestedClasses.size()>1) {
|
||||
finishingName = PascalClassData.getShortClassName(finishingName);
|
||||
} else {
|
||||
finishingName = PascalClassData.getShortPascalClassName(finishingName);
|
||||
}
|
||||
unitFile.println(prefix+"end;");
|
||||
printArrayTypes(prefix,finishingName);
|
||||
nestedClasses.remove(nestedClasses.size()-1);
|
||||
if (prefix.length()>4)
|
||||
prefix = prefix.substring(4);
|
||||
}
|
||||
}
|
||||
|
||||
public void printUnit() {
|
||||
Enumeration<String> strIterator;
|
||||
Enumeration<SkelItem> skelIterator;
|
||||
|
||||
unitFile.print("{ Imports for Java packages: "+RealPkgName(pkgPrefixes[0]));
|
||||
for (int i = 1; i < pkgPrefixes.length; i++) {
|
||||
unitFile.print(", "+RealPkgName(pkgPrefixes[i]));
|
||||
}
|
||||
unitFile.println(" }");
|
||||
unitFile.println("unit "+env.outputName+";");
|
||||
unitFile.println("{$mode objfpc}");
|
||||
unitFile.println();
|
||||
unitFile.println("interface");
|
||||
unitFile.println();
|
||||
unitFile.println("type");
|
||||
// forward declaration for all classes/interfaces in this package
|
||||
strIterator = Collections.enumeration(registeredInternalClasses);
|
||||
printInternalObjs(strIterator,"class");
|
||||
strIterator = Collections.enumeration(registeredInternalInterfaces);
|
||||
printInternalObjs(strIterator,"interface");
|
||||
// anonymous external declaration for all classes/interfaces from other packages
|
||||
strIterator = Collections.enumeration(registeredExternalClasses);
|
||||
printExternalObjs(strIterator,"class");
|
||||
strIterator = Collections.enumeration(registeredExternalInterfaces);
|
||||
printExternalObjs(strIterator,"interface");
|
||||
skelIterator = Collections.enumeration(registeredSkelObjs);
|
||||
printSkelObjs(skelIterator);
|
||||
unitFile.println();
|
||||
unitFile.println("{$include "+includeName+"}");
|
||||
unitFile.println();
|
||||
unitFile.println("implementation");
|
||||
unitFile.println();
|
||||
unitFile.println("end.");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -22,9 +22,12 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* Portions Copyright (c) 2011 Jonas Maebe
|
||||
*/
|
||||
|
||||
|
||||
package sun.tools.javap;
|
||||
package fpc.tools.javapp;
|
||||
|
||||
public interface RuntimeConstants {
|
||||
|
||||
|
||||
@ -22,14 +22,17 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* Portions Copyright (c) 2011 Jonas Maebe
|
||||
*/
|
||||
|
||||
|
||||
package sun.tools.javap;
|
||||
package fpc.tools.javapp;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
import static sun.tools.javap.RuntimeConstants.*;
|
||||
import static fpc.tools.javapp.RuntimeConstants.*;
|
||||
|
||||
/* represents one entry of StackMap attribute
|
||||
*/
|
||||
|
||||
@ -22,14 +22,17 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* Portions Copyright (c) 2011 Jonas Maebe
|
||||
*/
|
||||
|
||||
|
||||
package sun.tools.javap;
|
||||
package fpc.tools.javapp;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
import static sun.tools.javap.RuntimeConstants.*;
|
||||
import static fpc.tools.javapp.RuntimeConstants.*;
|
||||
|
||||
/* represents one entry of StackMapTable attribute
|
||||
*/
|
||||
|
||||
@ -22,9 +22,12 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* Portions Copyright (c) 2011 Jonas Maebe
|
||||
*/
|
||||
|
||||
|
||||
package sun.tools.javap;
|
||||
package fpc.tools.javapp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
@ -22,9 +22,12 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* Portions Copyright (c) 2011 Jonas Maebe
|
||||
*/
|
||||
|
||||
|
||||
package sun.tools.javap;
|
||||
package fpc.tools.javapp;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
@ -22,9 +22,12 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* Portions Copyright (c) 2011 Jonas Maebe
|
||||
*/
|
||||
|
||||
|
||||
package sun.tools.javap;
|
||||
package fpc.tools.javapp;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
@ -37,18 +40,26 @@ import java.io.*;
|
||||
public class TypeSignature {
|
||||
|
||||
String parameters = null;
|
||||
String parameterdes = null;
|
||||
String returntype = null;
|
||||
String fieldtype = null;
|
||||
int argumentlength = 0;
|
||||
|
||||
protected TypeSignature() {
|
||||
|
||||
}
|
||||
|
||||
public TypeSignature(String JVMSignature){
|
||||
init(JVMSignature);
|
||||
}
|
||||
|
||||
protected void init(String JVMSignature){
|
||||
|
||||
if(JVMSignature != null){
|
||||
if(JVMSignature.indexOf("(") == -1){
|
||||
//This is a field type.
|
||||
this.fieldtype = getFieldTypeSignature(JVMSignature);
|
||||
}else {
|
||||
String parameterdes = null;
|
||||
if((JVMSignature.indexOf(")")-1) > (JVMSignature.indexOf("("))){
|
||||
//Get parameter signature.
|
||||
parameterdes =
|
||||
@ -63,6 +74,30 @@ public class TypeSignature {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks access of class, field or method.
|
||||
*/
|
||||
public static boolean checkAccess(String accflags[], JavapEnvironment env){
|
||||
|
||||
boolean ispublic = false;
|
||||
boolean isprotected = false;
|
||||
boolean isprivate = false;
|
||||
boolean ispackage = false;
|
||||
|
||||
for(int i= 0; i < accflags.length; i++){
|
||||
if(accflags[i].equals("public")) ispublic = true;
|
||||
else if (accflags[i].indexOf("protected")!=-1) isprotected = true;
|
||||
else if (accflags[i].indexOf("private")!=-1) isprivate = true;
|
||||
}
|
||||
|
||||
if(!(ispublic || isprotected || isprivate)) ispackage = true;
|
||||
|
||||
if((env.showAccess == JavapEnvironment.PUBLIC) && (isprotected || isprivate || ispackage)) return false;
|
||||
else if((env.showAccess == JavapEnvironment.PROTECTED) && (isprivate || ispackage)) return false;
|
||||
else if((env.showAccess == JavapEnvironment.PACKAGE) && (isprivate)) return false;
|
||||
else return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns java type signature of a field.
|
||||
*/
|
||||
@ -78,8 +113,8 @@ public class TypeSignature {
|
||||
/**
|
||||
* Returns java type signature of a parameter.
|
||||
*/
|
||||
public String getParametersHelper(String parameterdes){
|
||||
Vector parameters = new Vector();
|
||||
public Vector<String> getParametersList(String parameterdes){
|
||||
Vector<String> parameters = new Vector<String>();
|
||||
int startindex = -1;
|
||||
int endindex = -1;
|
||||
String param = "";
|
||||
@ -179,20 +214,15 @@ public class TypeSignature {
|
||||
}
|
||||
}
|
||||
|
||||
/* number of arguments of a method.*/
|
||||
argumentlength = parameters.size();
|
||||
return parameters;
|
||||
}
|
||||
|
||||
/* java type signature.*/
|
||||
String parametersignature = "(";
|
||||
int i;
|
||||
|
||||
for(i = 0; i < parameters.size(); i++){
|
||||
parametersignature += (String)parameters.elementAt(i);
|
||||
if(i != parameters.size()-1){
|
||||
parametersignature += ", ";
|
||||
}
|
||||
}
|
||||
parametersignature += ")";
|
||||
/**
|
||||
* Returns java type signature of a parameter.
|
||||
*/
|
||||
public String getParametersHelper(String parameterdes){
|
||||
Vector<String> parameters = getParametersList(parameterdes);
|
||||
String parametersignature = parameterSignatureFromParameters(parameters);
|
||||
return parametersignature;
|
||||
}
|
||||
|
||||
@ -292,4 +322,24 @@ public class TypeSignature {
|
||||
public int getArgumentlength(){
|
||||
return argumentlength;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected String parameterSignatureFromParameters(Vector<String> parameters){
|
||||
/* number of arguments of a method.*/
|
||||
argumentlength = parameters.size();
|
||||
/* java type signature.*/
|
||||
String parametersignature = "(";
|
||||
int i;
|
||||
|
||||
for(i = 0; i < parameters.size(); i++){
|
||||
parametersignature += (String)parameters.elementAt(i);
|
||||
if(i != parameters.size()-1){
|
||||
parametersignature += ", ";
|
||||
}
|
||||
}
|
||||
parametersignature += ")";
|
||||
return parametersignature;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user