java-gobject-introspection r10 - trunk/src/org/gnome/gir/compiler
- From: walters svn gnome org
- To: svn-commits-list gnome org
- Subject: java-gobject-introspection r10 - trunk/src/org/gnome/gir/compiler
- Date: Mon, 1 Sep 2008 03:01:23 +0000 (UTC)
Author: walters
Date: Mon Sep 1 03:01:23 2008
New Revision: 10
URL: http://svn.gnome.org/viewvc/java-gobject-introspection?rev=10&view=rev
Log:
Callbacks and Structure work; clean up type mapping
Modified:
trunk/src/org/gnome/gir/compiler/CodeFactory.java
Modified: trunk/src/org/gnome/gir/compiler/CodeFactory.java
==============================================================================
--- trunk/src/org/gnome/gir/compiler/CodeFactory.java (original)
+++ trunk/src/org/gnome/gir/compiler/CodeFactory.java Mon Sep 1 03:01:23 2008
@@ -68,8 +68,10 @@
import org.gnome.gir.repository.BaseInfo;
import org.gnome.gir.repository.BoxedInfo;
import org.gnome.gir.repository.CallableInfo;
+import org.gnome.gir.repository.CallbackInfo;
import org.gnome.gir.repository.Direction;
import org.gnome.gir.repository.EnumInfo;
+import org.gnome.gir.repository.FieldInfo;
import org.gnome.gir.repository.FlagsInfo;
import org.gnome.gir.repository.FunctionInfo;
import org.gnome.gir.repository.FunctionInfoFlags;
@@ -149,16 +151,43 @@
return toTypeBase(tag);
}
- public static Type toJava(ArgInfo arg) {
+ private Type typeFromInfo(TypeInfo info) {
+ BaseInfo base = info.getInterface();
+ return typeFromInfo(base);
+ }
+
+ private Type typeFromInfo(BaseInfo info) {
+ requireNamespaceOf(info);
+ /* Unfortunately, flags are best mapped as plain Integer for now */
+ if (info instanceof FlagsInfo)
+ return Type.getObjectType("java/lang/Integer");
+ return Type.getObjectType(getInternalNameMapped(info.getNamespace(), info.getName()));
+ }
+
+ public Type toJava(TypeInfo type) {
//Transfer transfer = arg.getOwnershipTransfer();
- TypeInfo type = arg.getType();
TypeTag tag = type.getTag();
- if (!type.isPointer() || (tag.equals(TypeTag.UTF8) || tag.equals(TypeTag.FILENAME))) {
+
+ if (tag.equals(TypeTag.INTERFACE))
+ return typeFromInfo(type.getInterface());
+ else if (!type.isPointer() || (tag.equals(TypeTag.UTF8) || tag.equals(TypeTag.FILENAME))) {
return toTypeBase(tag);
} else if (type.isPointer()) {
return toJavaRef(tag);
} else {
return toTypeBase(tag);
+ }
+ }
+
+ public Type toJava(FieldInfo arg) {
+ return toJava(arg.getType());
+ }
+
+ public Type toJava(ArgInfo arg) {
+ if (arg.getDirection() == Direction.IN) {
+ return toJava(arg.getType());
+ } else {
+ return Type.getType(PointerType.class);
}
}
@@ -180,6 +209,8 @@
return Type.getType(Double.class);
if (t.equals(Type.getType(String.class)) || t.equals(Type.getType(File.class)))
return Type.getType(PointerByReference.class);
+ if (t.equals(Type.VOID_TYPE))
+ return Type.getType(Pointer.class);
return t;
}
@@ -195,7 +226,8 @@
if (tag == TypeTag.INT32 || tag == TypeTag.UINT32 ||
tag == TypeTag.INT || tag == TypeTag.UINT)
return Type.getType(Integer.class);
- if (tag == TypeTag.INT64 || tag == TypeTag.UINT64)
+ if (tag == TypeTag.INT64 || tag == TypeTag.UINT64
+ || tag == TypeTag.SIZE || tag == TypeTag.SSIZE)
return Type.getType(Long.class);
if (tag == TypeTag.FLOAT)
return Type.getType(Float.class);
@@ -217,26 +249,13 @@
if (!requireNamespaceOf(info.getInterface()))
return Type.getType(Pointer.class);
else
- return typeFromInterface(info);
+ return typeFromInfo(info);
}
return toJava(info.getTag());
}
- private Type typeFromInterface(TypeInfo info) {
- BaseInfo interfaceInfo = info.getInterface();
- return typeFromInfo(interfaceInfo);
- }
-
- private Type typeFromInfo(BaseInfo info) {
- requireNamespaceOf(info);
- /* Unfortunately, flags are best mapped as plain Integer for now */
- if (info instanceof FlagsInfo)
- return Type.getObjectType("java/lang/Integer");
- return Type.getObjectType(getInternalNameMapped(info.getNamespace(), info.getName()));
- }
-
private List<Type> getCallableArgs(CallableInfo callable, boolean isMethod,
- boolean allowError) {
+ boolean allowError, boolean allowUserData) {
ArgInfo[] args = callable.getArgs();
List<Type> types = new ArrayList<Type>();
boolean skipFirst = isMethod;
@@ -250,19 +269,17 @@
continue;
return null;
}
- if (arg.getDirection() == Direction.IN) {
- if (tag.equals(TypeTag.INTERFACE)) {
- t = typeFromInterface(info);
- } else {
- t = toJava(arg);
- }
- } else {
- t = Type.getType(PointerType.class);
- }
- if (t == null)
+ t = toJava(arg);
+ if (t == null) {
+ logger.warning("Unhandled argument: " + arg);
return null;
- if (t.equals(Type.VOID_TYPE))
+ }
+ // Skip user data parameters
+ boolean isLast = i == args.length-1;
+ if (t.equals(Type.VOID_TYPE) && (!allowUserData || !isLast)) {
+ logger.warning("Found void in middle of argument list: " + arg);
return null;
+ }
if (skipFirst)
skipFirst = false;
else
@@ -595,8 +612,10 @@
private String ucaseToCamel(String ucase) {
String[] components = ucase.split("_");
- for (int i = 1; i < components.length; i++)
- components[i] = "" + Character.toUpperCase(components[i].charAt(0)) + components[i].substring(1);
+ for (int i = 1; i < components.length; i++) {
+ if (components[i].length() > 0)
+ components[i] = "" + Character.toUpperCase(components[i].charAt(0)) + components[i].substring(1);
+ }
StringBuilder builder = new StringBuilder();
for (String component : components)
builder.append(component);
@@ -710,7 +729,7 @@
String globalInternalsName = getInternals(info);
ArgInfo[] argInfos = fi.getArgs();
- List<Type> args = getCallableArgs(fi, false, false);
+ List<Type> args = getCallableArgs(fi, false, false, false);
String descriptor = Type.getMethodDescriptor(Type.VOID_TYPE, args.toArray(new Type[0]));
int nArgs = args.size();
@@ -754,7 +773,7 @@
String globalInternalsName = getInternals(info);
ArgInfo[] argInfos = fi.getArgs();
- List<Type> args = getCallableArgs(fi, false, false);
+ List<Type> args = getCallableArgs(fi, false, false, false);
BaseInfo parent = info.getParent();
String parentInternalType = getInternalNameMapped(parent);
String descriptor = Type.getMethodDescriptor(Type.VOID_TYPE, args.toArray(new Type[0]));
@@ -903,7 +922,7 @@
boolean isConstructor = (fi.getFlags() & FunctionInfoFlags.IS_CONSTRUCTOR) != 0;
if (!isConstructor)
continue;
- List<Type> args = getCallableArgs(fi, false, false);
+ List<Type> args = getCallableArgs(fi, false, false, false);
if (args == null) {
logger.warning("Skipping constructor with unhandled arg signature: " + fi.getSymbol());
continue;
@@ -982,29 +1001,36 @@
boolean throwsGError;
boolean isInterfaceMethod = false;
InterfaceInfo targetInterface = null;
+ boolean hasUserdata;
public CallableCompilationContext(Type returnType, ArgInfo[] args,
List<Type> argTypes, boolean throwsGError) {
this.returnType = returnType;
this.args = args;
this.argTypes = argTypes;
this.throwsGError = throwsGError;
+ if (argTypes.size() > 0) {
+ if (argTypes.get(argTypes.size()-1).equals(Type.VOID_TYPE)) {
+ this.hasUserdata = true;
+ argTypes.remove(argTypes.size()-1);
+ }
+ }
}
}
- private CallableCompilationContext tryCompileCallable(SignalInfo si) {
+ private CallableCompilationContext tryCompileCallable(CallableInfo si) {
Type returnType = getCallableReturn(si);
if (returnType == null) {
- logger.warning("Skipping signal with unhandled return signature: " + si.getName());
+ logger.warning("Skipping callable with unhandled return signature: " + si.getName());
return null;
}
ArgInfo[] argInfos = si.getArgs();
- List<Type> args = getCallableArgs(si, false, false);
+ List<Type> args = getCallableArgs(si, false, false, true);
if (args == null) {
- logger.warning("Skipping signal with unhandled arg signature: " + si.getName());
+ logger.warning("Skipping callable with unhandled arg signature: " + si.getName());
return null;
}
return new CallableCompilationContext(returnType, argInfos, args, false);
- }
+ }
private CallableCompilationContext tryCompileCallable(FunctionInfo fi, Set<String> seenSignatures) {
Type returnType = getCallableReturn(fi);
@@ -1014,9 +1040,13 @@
}
ArgInfo[] argInfos = fi.getArgs();
boolean throwsGError = argInfos.length > 0 &&
- argInfos[argInfos.length-1].getType().getTag().equals(TypeTag.ERROR);
+ argInfos[argInfos.length-1].getType().getTag().equals(TypeTag.ERROR);
+ if (throwsGError && returnType.equals(Type.VOID_TYPE)) {
+ logger.warning("Skipping function which returns Void and uses GError: " + fi.getSymbol());
+ return null;
+ }
List<Type> args = getCallableArgs(fi, (fi.getFlags() & FunctionInfoFlags.IS_METHOD) > 0,
- throwsGError);
+ throwsGError, true);
if (args == null) {
logger.warning("Skipping function with unhandled arg signature: " + fi.getSymbol());
return null;
@@ -1059,6 +1089,8 @@
int nInvokeArgs = nArgs;
if (includeThis)
nInvokeArgs += 1;
+ if (ctx.hasUserdata)
+ nInvokeArgs += 1;
int functionOffset = nInvokeArgs+1;
int arrayOffset = functionOffset+1;
int resultOffset = arrayOffset+1;
@@ -1100,9 +1132,15 @@
mv.visitVarInsn(ALOAD, i);
mv.visitInsn(AASTORE);
}
- if (ctx.throwsGError) {
+ if (ctx.hasUserdata) {
mv.visitInsn(DUP);
mv.visitIntInsn(BIPUSH, nInvokeArgs);
+ mv.visitInsn(ACONST_NULL);
+ mv.visitInsn(AASTORE);
+ }
+ if (ctx.throwsGError) {
+ mv.visitInsn(DUP);
+ mv.visitIntInsn(BIPUSH, nInvokeArgs + (ctx.hasUserdata ? 1 : 0));
mv.visitVarInsn(ALOAD, errorOffset);
mv.visitInsn(AASTORE);
}
@@ -1210,6 +1248,16 @@
continue;
writeCallable(ACC_PUBLIC, info, compilation, fi, ctx);
}
+
+ for (FieldInfo fi : info.getFields()) {
+ String name = ucaseToCamel(fi.getName());
+ Type type = toJava(fi);
+ if (type.equals(Type.VOID_TYPE)) // FIXME Temporary hack for GdkAtom
+ type = Type.getType(Pointer.class);
+ FieldVisitor fv = compilation.peer.writer.visitField(ACC_PUBLIC, name, type.getDescriptor(), null, null);
+ fv.visitEnd();
+ }
+
compilation.peer.close();
}
@@ -1234,7 +1282,26 @@
mv.visitEnd();
compilation.peer.close();
- }
+ }
+
+ private void compile(CallbackInfo info) {
+ InfoCompilation compilation = getCompilation(info);
+
+ String internalName = getInternalName(info);
+ compilation.peer.writer.visit(V1_6, ACC_PUBLIC + ACC_ABSTRACT + ACC_INTERFACE, internalName, null, "java/lang/Object",
+ new String[] { "com/sun/jna/Callback" });
+
+ CallableCompilationContext ctx = tryCompileCallable(info);
+
+ if (ctx != null) {
+ String descriptor = Type.getMethodDescriptor(ctx.returnType, ctx.argTypes.toArray(new Type[0]));
+ MethodVisitor mv = compilation.peer.writer.visitMethod(ACC_PUBLIC + ACC_ABSTRACT,
+ "callback", descriptor, null, null);
+ mv.visitEnd();
+ }
+
+ compilation.peer.close();
+ }
private boolean requireNamespaceOf(BaseInfo info) {
return requireNamespace(info.getNamespace());
@@ -1276,6 +1343,8 @@
compile((BoxedInfo) baseInfo);
} else if (baseInfo instanceof InterfaceInfo) {
compile((InterfaceInfo) baseInfo);
+ } else if (baseInfo instanceof CallbackInfo) {
+ compile((CallbackInfo) baseInfo);
} else {
logger.warning("unhandled info " + baseInfo.getName());
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]