netscape-revival
sun-java/classsrc/netscape/tools/jric/HeaderGenerator.java
// Copyright (c) 1995 Netscape Communications Corporation. All rights reserved.
package netscape.tools.jric;
import netscape.tools.ClassFileParser.*;
import java.io.*;
public
class HeaderGenerator extends NativesGenerator {
public HeaderGenerator(Main global, ClassDef clazz) {
super(global, clazz);
}
protected String getFileName() {
return clazzCName + ".h";
}
protected String getHeaderString() {
return clazz.name + " header file\n * Generated by jric";
}
protected void generateOutput() throws IOException {
int i;
String prefix = clazz.getPrefix();
out.println("#ifndef _" + clazzCName + "_H_");
out.println("#define _" + clazzCName + "_H_\n");
out.println("#include \"jri.h\"\n");
out.println("#ifdef __cplusplus");
out.println("extern \"C\" {");
out.println("#endif /* __cplusplus */\n");
for (i = 0; i < clazz.fields.length; i++) {
FieldDef field = clazz.fields[i];
forwardDeclare(field);
}
for (i = 0; i < clazz.methods.length; i++) {
MethodDef method = clazz.methods[i];
forwardDeclare(method);
}
out.println("struct java_lang_Class;\n");
printBlockComment("Class " + clazz.name);
out.println("typedef struct " + clazzCName + " "
+ clazzCName + ";\n");
out.println("#define classname_" + clazzCName + "\t\""
+ clazz.name + "\"\n");
out.println("#define class_" + clazzCName + "(env)\t\\");
out.println("\t((struct java_lang_Class*)JRI_FindClass(env, classname_"
+ clazzCName + "))\n");
printBlockComment("Public Methods");
out.println("#ifdef DEBUG\n");
// Public Method Functions
for (i = 0; i < clazz.methods.length; i++) {
MethodDef method = clazz.methods[i];
if (method.hasAccess(ClassFileParser.ACC_PUBLIC)) {
method.describe(out);
printMethodFunctionDecl(prefix, method, i, false);
}
}
out.println("#else /* !DEBUG */\n");
// Public Method Macros
for (i = 0; i < clazz.methods.length; i++) {
MethodDef method = clazz.methods[i];
if (method.hasAccess(ClassFileParser.ACC_PUBLIC)) {
method.describe(out);
printMethodMacroDecl(prefix, method, i);
}
}
out.println("#endif /* !DEBUG */\n");
// Public Method Info
for (i = 0; i < clazz.methods.length; i++) {
MethodDef method = clazz.methods[i];
if (method.hasAccess(ClassFileParser.ACC_PUBLIC)) {
method.describe(out);
printMethodInfo(prefix, method, i);
}
}
printBlockComment("Public Fields");
out.println("#ifdef DEBUG\n");
// Public Field Functions
for (i = 0; i < clazz.fields.length; i++) {
FieldDef field = clazz.fields[i];
if (field.hasAccess(ClassFileParser.ACC_PUBLIC)) {
field.describe(out);
printFieldFunctionDecl(field);
}
}
out.println("#else /* !DEBUG */\n");
// Public Field Macros
for (i = 0; i < clazz.fields.length; i++) {
FieldDef field = clazz.fields[i];
if (field.hasAccess(ClassFileParser.ACC_PUBLIC)) {
field.describe(out);
printFieldMacroDecl(field);
}
}
out.println("#endif /* !DEBUG */\n");
// Public Field Info
for (i = 0; i < clazz.fields.length; i++) {
FieldDef field = clazz.fields[i];
if (field.hasAccess(ClassFileParser.ACC_PUBLIC)) {
field.describe(out);
printFieldInfo(field);
}
}
printBlockComment("IMPLEMENTATION SECTION: \n" +
" * Define the IMPLEMENT_" + clazzCName + " symbol \n" +
" * if you intend to implement the native methods of this class. This \n" +
" * symbol makes the private and protected methods available. You should \n" +
" * also call the register_" + clazzCName + " routine \n" +
" * to make your native methods available.");
out.println("extern JRI_PUBLIC_API(struct java_lang_Class*)");
out.println("use_" + clazzCName + "(JRIEnv* env);\n");
out.println("extern JRI_PUBLIC_API(void)");
out.println("unuse_" + clazzCName + "(JRIEnv* env);\n");
out.println("extern JRI_PUBLIC_API(struct java_lang_Class*)");
out.println("register_" + clazzCName + "(JRIEnv* env);\n");
out.println("extern JRI_PUBLIC_API(void)");
out.println("unregister_" + clazzCName + "(JRIEnv* env);\n");
out.println("#ifdef IMPLEMENT_" + clazzCName + "\n");
printBlockComment("Native Methods:\n" +
" * These are the signatures of the native methods which you must implement.");
for (i = 0; i < clazz.methods.length; i++) {
MethodDef method = clazz.methods[i];
if (method.hasAccess(ClassFileParser.ACC_NATIVE)) {
method.describe(out);
printMethodFunctionDecl(prefix, method, i, true);
}
}
printBlockComment("Implementation Methods:\n" +
" * You should only use these from within the native method definitions.");
out.println("#ifdef DEBUG\n");
// Implementation Method Functions
for (i = 0; i < clazz.methods.length; i++) {
MethodDef method = clazz.methods[i];
if (!method.hasAccess(ClassFileParser.ACC_PUBLIC)) {
method.describe(out);
printMethodFunctionDecl(prefix, method, i, false);
}
}
out.println("#else /* !DEBUG */\n");
// Implementation Method Macros
for (i = 0; i < clazz.methods.length; i++) {
MethodDef method = clazz.methods[i];
if (!method.hasAccess(ClassFileParser.ACC_PUBLIC)) {
method.describe(out);
printMethodMacroDecl(prefix, method, i);
}
}
out.println("#endif /* !DEBUG */\n");
// Implementation Method Info
for (i = 0; i < clazz.methods.length; i++) {
MethodDef method = clazz.methods[i];
if (!method.hasAccess(ClassFileParser.ACC_PUBLIC)) {
method.describe(out);
printMethodInfo(prefix, method, i);
}
}
printBlockComment("Implementation Fields:\n" +
" * You should only use these from within the native method definitions.");
out.println("#ifdef DEBUG\n");
// Implementation Field Functions
for (i = 0; i < clazz.fields.length; i++) {
FieldDef field = clazz.fields[i];
if (!field.hasAccess(ClassFileParser.ACC_PUBLIC)) {
field.describe(out);
printFieldFunctionDecl(field);
}
}
out.println("#else /* !DEBUG */\n");
// Implementation Field Macros
for (i = 0; i < clazz.fields.length; i++) {
FieldDef field = clazz.fields[i];
if (!field.hasAccess(ClassFileParser.ACC_PUBLIC)) {
field.describe(out);
printFieldMacroDecl(field);
}
}
out.println("#endif /* !DEBUG */\n");
// Implementation Field Info
for (i = 0; i < clazz.fields.length; i++) {
FieldDef field = clazz.fields[i];
if (!field.hasAccess(ClassFileParser.ACC_PUBLIC)) {
field.describe(out);
printFieldInfo(field);
}
}
out.println("#endif /* IMPLEMENT_" + clazzCName + " */\n");
out.println("#ifdef __cplusplus");
out.println("} /* extern \"C\" */\n");
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
printBlockComment("C++ Definitions");
for (i = 0; i < clazz.interfaces.length; i++) {
ClassDef intf = clazz.interfaces[i];
out.println("#include \"" + intf.getCName()
+ ".h\"");
}
if (clazz.superclass != null) {
out.println("#include \"" +
clazz.superclass.getCName()
+ ".h\"\n");
}
out.print("struct " + clazzCName);
boolean needsColon = true;
for (i = 0; i < clazz.interfaces.length; i++) {
ClassDef intf = clazz.interfaces[i];
out.print((needsColon ? " :" : ",") + " public "
+ intf.getCName());
needsColon = false;
}
if (clazz.superclass != null) {
out.print((needsColon ? " :" : ",") + " public "
+ clazz.superclass.getCName());
needsColon = false;
}
out.println(" {\n");
out.println("\tstatic struct java_lang_Class* _use(JRIEnv* env) {");
out.println("\t\treturn use_" + clazzCName + "(env);\n\t}\n");
out.println("\tstatic void _unuse(JRIEnv* env) {");
out.println("\t\tunuse_" + clazzCName + "(env);\n\t}\n");
out.println("\tstatic struct java_lang_Class* _register(JRIEnv* env) {");
out.println("\t\treturn register_" + clazzCName + "(env);\n\t}\n");
out.println("\tstatic void _unregister(JRIEnv* env) {");
out.println("\t\tunregister_" + clazzCName + "(env);\n\t}\n");
out.println("\tstatic struct java_lang_Class* _class(JRIEnv* env) {");
out.println("\t\treturn class_" + clazzCName + "(env);\n\t}\n");
out.println("\t/* Public Fields */");
for (i = 0; i < clazz.fields.length; i++) {
FieldDef field = clazz.fields[i];
if (field.hasAccess(ClassFileParser.ACC_PUBLIC)
&& !field.hasAccess(ClassFileParser.ACC_STATIC)) {
out.print("\t");
field.describe(out);
printFieldCppDecl(field);
}
}
out.println("\t/* Public Methods */");
for (i = 0; i < clazz.methods.length; i++) {
MethodDef method = clazz.methods[i];
if (method.hasAccess(ClassFileParser.ACC_PUBLIC)) {
out.print("\t");
method.describe(out);
printMethodCppDecl(prefix, method, i);
}
}
out.println("#ifdef IMPLEMENT_" + clazzCName + "\n");
out.println("\t/* Implementation Fields */");
for (i = 0; i < clazz.fields.length; i++) {
FieldDef field = clazz.fields[i];
if (!field.hasAccess(ClassFileParser.ACC_PUBLIC)
&& !field.hasAccess(ClassFileParser.ACC_STATIC)) {
out.print("\t");
field.describe(out);
printFieldCppDecl(field);
}
}
out.println("\t/* Implementation Methods */");
for (i = 0; i < clazz.methods.length; i++) {
MethodDef method = clazz.methods[i];
if (!method.hasAccess(ClassFileParser.ACC_PUBLIC)) {
out.print("\t");
method.describe(out);
printMethodCppDecl(prefix, method, i);
}
}
out.println("#endif /* IMPLEMENT_" + clazzCName + " */\n");
out.println("};\n");
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
out.println("#endif /* __cplusplus */\n");
out.println("#endif /* _" + clazzCName + "_H_ */");
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// C Utilities
protected void printMethodFunctionDecl(String prefix, MethodDef method,
int methodIndex, boolean printAsNative) {
/*
int i;
boolean comment = true;
for (i = 0; i < method.attributes.length; i++) {
if (comment) {
out.println("/"+"*");
comment = false;
}
method.attributes[i].describe(out);
}
System.out.println("method args = "+method.getParamNames());
if (!comment) {
out.println("\n*"+"/");
}
*/
out.print("extern ");
printMethodFunctionSig(prefix, method, methodIndex, printAsNative);
out.println(";\n");
}
protected void printMethodMacroDecl(String prefix, MethodDef method, int methodIndex) {
out.print("#define ");
String fname = method.getCName(methodIndex);
out.print(prefix + "_" + fname);
printMethodArgUse(prefix, method, methodIndex, false, false);
out.print("\t\\\n\t(");
printInvocation(prefix, method, methodIndex);
out.print(")\n\n");
}
protected void printInvocation(String prefix, MethodDef method, int methodIndex) {
String opName;
if (method.hasAccess(ClassFileParser.ACC_STATIC))
opName = "JRI_CallStaticMethod";
else if (method.isConstructor())
opName = "JRI_NewObject";
else
opName = "JRI_CallMethod";
out.print("(" + getResultTypeName(method) + ")"
+ opName + getResultSuffix(method) + "(env)");
printMethodArgUse(prefix, method, methodIndex, true, false);
}
protected void printMethodInfo(String prefix, MethodDef method, int methodIndex) {
String cName = prefix + "_" + method.getCName(methodIndex);
out.println("extern JRIMethodID FAR methodID_" + cName + ";");
out.println("#define name_" + cName + "\t\"" + method.name + "\"");
out.println("#define sig_" + cName + "\t\"" + method.signature + "\"");
out.println("#define use_" + cName + "(env, clazz)\t\\");
out.println("\t(methodID_" + cName + " =\t\\");
out.println("\t\tJRI_GetMethodID(env, clazz,\t\\");
out.println("\t\t\tname_" + cName + ",\t\\");
out.println("\t\t\tsig_" + cName + "))");
out.println("#define unuse_" + cName + "(env, clazz)\t\\");
out.println("\t(methodID_" + cName + " = JRIUninitialized)\n");
}
protected void printFieldFunctionDecl(FieldDef field) {
out.print("extern ");
printGetterFunctionSig(field);
out.println(";");
out.print("extern ");
printSetterFunctionSig(field);
out.println(";\n");
}
protected void printFieldMacroDecl(FieldDef field) {
out.print("#define get_" + field.getCName());
printGetterArgUse(field, false);
out.print("\t\\\n\t(");
printGetter(field);
out.print(")\n");
out.print("#define set_" + field.getCName());
printSetterArgUse(field, false);
out.print("\t\\\n\t(");
printSetter(field);
out.print(")\n\n");
}
protected void printGetter(FieldDef field) {
String opName;
if (field.hasAccess(ClassFileParser.ACC_STATIC))
opName = "JRI_GetStaticField";
else
opName = "JRI_GetField";
out.print("(" + getTypeName(field.signature, 0) + ")" + opName
+ getSuffix(field.signature, 0));
printGetterArgUse(field, true);
}
protected void printSetter(FieldDef field) {
String opName;
if (field.hasAccess(ClassFileParser.ACC_STATIC))
opName = "JRI_SetStaticField";
else
opName = "JRI_SetField";
out.print(opName
+ getSuffix(field.signature, 0));
printSetterArgUse(field, true);
}
protected void printGetterFunctionSig(FieldDef field) {
String fname = field.getCName();
String resultType = getTypeName(field.signature, 0);
out.println("JRI_PUBLIC_API(" + resultType + ")");
out.print("get_" + fname);
printGetterArgDecl(field);
}
protected void printSetterFunctionSig(FieldDef field) {
String fname = field.getCName();
out.println("JRI_PUBLIC_API(void)");
out.print("set_" + fname);
printSetterArgDecl(field);
}
protected void printFieldInfo(FieldDef field) {
String cName = field.getCName();
out.println("extern JRIFieldID FAR fieldID_" + cName + ";");
out.println("#define name_" + cName + "\t\"" + field.name + "\"");
out.println("#define sig_" + cName + "\t\"" + field.signature
+ "\"");
out.println("#define use_" + cName + "(env, clazz)\t\\");
out.println("\t(fieldID_" + cName + " =\t\\");
out.println("\t\tJRI_GetFieldID(env, clazz,\t\\");
out.println("\t\t\tname_" + cName + ",\t\\");
out.println("\t\t\tsig_" + cName + "))");
out.println("#define unuse_" + cName + "(env, clazz)\t\\");
out.println("\t(fieldID_" + cName + " = JRIUninitialized)\n");
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// C++ Utilities
protected void printFieldCppDecl(FieldDef field) {
out.println("\t" + getTypeName(field.signature, 0) + " "
+ field.name + "(JRIEnv* env) {");
out.println("\t\treturn get_" + field.getCName()
+ "(env, this);\n\t}");
out.println("\tvoid " + field.name
+ "(JRIEnv* env, " + getTypeName(field.signature, 0)
+ " v) {");
out.println("\t\tset_" + field.getCName()
+ "(env, this, v);\n\t}\n");
}
protected void printMethodCppDecl(String prefix, MethodDef method, int methodIndex) {
String resultType = getResultTypeName(method);
out.print("\t"
+ (method.hasAccess(ClassFileParser.ACC_STATIC)
|| method.isConstructor() ? "static " : "")
+ resultType + " " + method.getCppName(methodIndex));
printMethodArgDecl(method, true);
out.print(" {\n\t\t");
if (!resultType.equals("void"))
out.print("return ");
out.print(prefix + "_" + method.getCName(methodIndex));
printMethodArgUse(prefix, method, methodIndex, false, true);
out.println(";\n\t}\n");
}
}