// Copyright (c) Corporation for National Research Initiatives
package org.python.compiler;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.python.core.PyObject;
public class JavaMaker extends ProxyMaker implements ClassConstants {
public String pythonClass, pythonModule;
public String[] properties;
public String[] packages;
//Hashtable methods;
PyObject methods;
public boolean frozen, main;
public JavaMaker(Class superclass, Class[] interfaces, String pythonClass, String pythonModule, String myClass,
PyObject methods) {
this(superclass, interfaces, pythonClass, pythonModule, myClass, null, null, methods, false, false);
}
public JavaMaker(Class superclass, Class[] interfaces, String pythonClass, String pythonModule, String myClass,
String[] packages, String[] properties, PyObject methods, boolean frozen, boolean main) {
super(myClass, superclass, interfaces);
// System.out.println("props: "+properties+", "+properties.length);
this.pythonClass = pythonClass;
this.pythonModule = pythonModule;
this.packages = packages;
this.properties = properties;
this.frozen = frozen;
this.main = main;
this.methods = methods;
}
private void makeStrings(Code code, String[] list) throws Exception {
if (list != null) {
int n = list.length;
code.iconst(n);
code.anewarray(code.pool.Class("java/lang/String"));
int strings = code.getLocal("[java/lang/String");
code.astore(strings);
for (int i = 0; i < n; i++) {
code.aload(strings);
code.iconst(i);
code.ldc(list[i]);
code.aastore();
}
code.aload(strings);
code.freeLocal(strings);
} else {
code.aconst_null();
}
}
public void addConstructor(String name, Class[] parameters, Class ret, String sig, int access) throws Exception {
/* Need a fancy constructor for the Java side of things */
Code code = classfile.addMethod("<init>", sig, access);
callSuper(code, "<init>", name, parameters, null, sig);
code.aload(0);
getArgs(code, parameters);
int initProxy = code.pool.Methodref(classfile.name, "__initProxy__", "([Ljava/lang/Object;)V");
code.invokevirtual(initProxy);
code.return_();
}
public void addProxy() throws Exception {
if (methods != null)
super.addProxy();
// _initProxy method
Code code = classfile.addMethod("__initProxy__", "([Ljava/lang/Object;)V", Modifier.PUBLIC);
code.aload(0);
code.ldc(pythonModule);
code.ldc(pythonClass);
code.aload(1);
makeStrings(code, packages);
makeStrings(code, properties);
code.iconst(frozen ? 1 : 0);
int initProxy = code.pool.Methodref("org/python/core/Py", "initProxy", "(" + $pyProxy + $str + $str + $objArr
+ $strArr + $strArr + "Z)V");
code.invokestatic(initProxy);
code.return_();
if (main)
addMain();
}
// public void addMethods(Class c) throws Exception {
// if (methods != null) {
// super.addMethods(c);
// }
// }
public void addMethod(Method method, int access) throws Exception {
//System.out.println("add: "+method.getName()+", "+
// methods.containsKey(method.getName()));
// Check to see if it's an abstract method
if (Modifier.isAbstract(access)) {
// Maybe throw an exception here???
super.addMethod(method, access);
} else if (methods.__finditem__(method.getName().intern()) != null) {
super.addMethod(method, access);
} else if (Modifier.isProtected(method.getModifiers())) {
addSuperMethod(method, access);
}
}
/*
public void addSuperMethod(String methodName, String superName,
String superclass, Class[] parameters,
Class ret, String sig, int access)
throws Exception
{
if (!PyProxy.class.isAssignableFrom(this.superclass)) {
super.addSuperMethod(methodName,superName,superclass,parameters,
ret,sig,access);
}
}
*/
public void addMain() throws Exception {
Code code = classfile.addMethod("main", "(" + $str + ")V", ClassFile.PUBLIC | ClassFile.STATIC);
// Load the class of the Python module to run
int forname = code.pool.Methodref("java/lang/Class", "forName", "(" + $str + ")" + $clss);
code.ldc(pythonModule);
code.invokestatic(forname);
// Load in any command line arguments
code.aload(0);
makeStrings(code, packages);
makeStrings(code, properties);
code.iconst(frozen ? 1 : 0);
int runMain = code.pool.Methodref("org/python/core/Py", "runMain", "(" + $clss + $strArr + $strArr + $strArr
+ "Z)V");
code.invokestatic(runMain);
code.return_();
}
}