* 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:
Jonas Maebe 2011-08-20 07:56:58 +00:00
parent 367daf06ea
commit 8199b2c6a9
29 changed files with 2743 additions and 648 deletions

9
.gitattributes vendored
View File

@ -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

View File

@ -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.*;

View File

@ -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.

View File

@ -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.

View File

@ -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;
}

View 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);
}
}

View 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());
}
}
*/
}

View File

@ -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

View File

@ -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.*;

View File

@ -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);

View File

@ -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

View File

@ -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.*;

View File

@ -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.*;

View File

@ -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());
}
}
}
}

View File

@ -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;
// }
/**

View 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";
}
}

View 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;
}
}

View 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;
}
}

View 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");
}
}

View 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;
}
}

View 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;
}
}

View 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.");
}
}

View File

@ -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 {

View File

@ -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
*/

View File

@ -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
*/

View File

@ -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;

View File

@ -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.*;

View File

@ -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;
}
}