java-gobject-introspection r19 - in trunk/src/org/gnome/gir: compiler gobject
- From: walters svn gnome org
- To: svn-commits-list gnome org
- Subject: java-gobject-introspection r19 - in trunk/src/org/gnome/gir: compiler gobject
- Date: Wed, 3 Sep 2008 01:55:46 +0000 (UTC)
Author: walters
Date: Wed Sep 3 01:55:46 2008
New Revision: 19
URL: http://svn.gnome.org/viewvc/java-gobject-introspection?rev=19&view=rev
Log:
Handle return interfaces with no known native proxy by creating Stub
Modified:
trunk/src/org/gnome/gir/compiler/CodeFactory.java
trunk/src/org/gnome/gir/compiler/Test.java
trunk/src/org/gnome/gir/gobject/GObject.java
trunk/src/org/gnome/gir/gobject/GTypeMapper.java
trunk/src/org/gnome/gir/gobject/NativeObject.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 Wed Sep 3 01:55:46 2008
@@ -884,9 +884,27 @@
sigCompilation.writer.visitEnd();
}
+
+ private void writeHandleInitializer(ClassCompilation compilation, String parentInternalName) {
+ MethodVisitor mv = compilation.writer.visitMethod(ACC_PROTECTED, "<init>", "(Lorg/gnome/gir/gobject/Handle$Initializer;)V", null, null);
+ mv.visitCode();
+ Label l0 = new Label();
+ mv.visitLabel(l0);
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitVarInsn(ALOAD, 1);
+ mv.visitMethodInsn(INVOKESPECIAL, parentInternalName, "<init>", "(Lorg/gnome/gir/gobject/Handle$Initializer;)V");
+ Label l1 = new Label();
+ mv.visitLabel(l1);
+ mv.visitInsn(RETURN);
+ Label l2 = new Label();
+ mv.visitLabel(l2);
+ mv.visitLocalVariable("this", "L" + compilation.internalName + ";", null, l0, l2, 0);
+ mv.visitLocalVariable("init", "Lorg/gnome/gir/gobject/Handle$Initializer;", null, l0, l2, 1);
+ mv.visitMaxs(2, 2);
+ mv.visitEnd();
+ }
private void compile(ObjectInfo info) {
- Label l0, l1, l2;
StubClassCompilation compilation = getCompilation(info);
if (info.getNamespace().equals("GObject") && info.getName().equals("Object"))
@@ -921,22 +939,7 @@
writeGetGType(info, compilation);
- MethodVisitor mv = compilation.writer.visitMethod(ACC_PROTECTED, "<init>", "(Lorg/gnome/gir/gobject/Handle$Initializer;)V", null, null);
- mv.visitCode();
- l0 = new Label();
- mv.visitLabel(l0);
- mv.visitVarInsn(ALOAD, 0);
- mv.visitVarInsn(ALOAD, 1);
- mv.visitMethodInsn(INVOKESPECIAL, parentInternalName, "<init>", "(Lorg/gnome/gir/gobject/Handle$Initializer;)V");
- l1 = new Label();
- mv.visitLabel(l1);
- mv.visitInsn(RETURN);
- l2 = new Label();
- mv.visitLabel(l2);
- mv.visitLocalVariable("this", "L" + internalName + ";", null, l0, l2, 0);
- mv.visitLocalVariable("init", "Lorg/gnome/gir/gobject/Handle$Initializer;", null, l0, l2, 1);
- mv.visitMaxs(2, 2);
- mv.visitEnd();
+ writeHandleInitializer(compilation, parentInternalName);
compileDefaultConstructor(info, compilation);
@@ -985,7 +988,7 @@
CallableCompilationContext ctx = tryCompileCallable(fi, sigs);
if (ctx == null)
continue;
- writeCallable(ACC_PUBLIC, info, compilation, fi, ctx);
+ writeCallable(ACC_PUBLIC, compilation, fi, ctx);
}
for (InterfaceInfo iface : giInterfaces) {
for (FunctionInfo fi: iface.getMethods()) {
@@ -994,7 +997,7 @@
continue;
ctx.isInterfaceMethod = true;
ctx.targetInterface = iface;
- writeCallable(ACC_PUBLIC, info, compilation, fi, ctx);
+ writeCallable(ACC_PUBLIC, compilation, fi, ctx);
}
}
compilation.close();
@@ -1005,7 +1008,8 @@
String internalName = getInternalName(info);
- compilation.writer.visit(V1_6, ACC_PUBLIC + ACC_ABSTRACT + ACC_INTERFACE, internalName, null, "java/lang/Object", null);
+ compilation.writer.visit(V1_6, ACC_PUBLIC + ACC_ABSTRACT + ACC_INTERFACE, internalName, null, "java/lang/Object",
+ new String[] { "org/gnome/gir/gobject/GObject$GObjectProxy" });
Set<String> sigs = new HashSet<String>();
for (FunctionInfo fi : info.getMethods()) {
CallableCompilationContext ctx = tryCompileCallable(fi, sigs);
@@ -1017,6 +1021,22 @@
mv.visitEnd();
}
+ InnerClassCompilation anonProxy = compilation.newInner("AnonStub");
+ compilation.writer.visitInnerClass(anonProxy.internalName,
+ compilation.internalName, "AnonStub", ACC_PUBLIC + ACC_FINAL + ACC_STATIC);
+ anonProxy.writer.visit(V1_6, ACC_PUBLIC + ACC_SUPER + ACC_FINAL, anonProxy.internalName, null, "org/gnome/gir/gobject/GObject",
+ new String[] { compilation.internalName });
+ writeHandleInitializer(anonProxy, "org/gnome/gir/gobject/GObject");
+ sigs = new HashSet<String>();
+ for (FunctionInfo fi: info.getMethods()) {
+ CallableCompilationContext ctx = tryCompileCallable(fi, sigs);
+ if (ctx == null)
+ continue;
+ ctx.isInterfaceMethod = false;
+ ctx.targetInterface = info;
+ writeCallable(ACC_PUBLIC, anonProxy, fi, ctx);
+ }
+
compilation.close();
}
@@ -1086,8 +1106,7 @@
return new CallableCompilationContext(returnType, argInfos, args, throwsGError);
}
- private void writeCallable(int accessFlags,
- RegisteredTypeInfo parent, ClassCompilation compilation, FunctionInfo fi,
+ private void writeCallable(int accessFlags, ClassCompilation compilation, FunctionInfo fi,
CallableCompilationContext ctx) {
String descriptor = Type.getMethodDescriptor(ctx.returnType, ctx.argTypes.toArray(new Type[0]));
String name = ucaseToCamel(fi.getName());
@@ -1216,6 +1235,7 @@
mv.visitLocalVariable("result", "L" + ctx.returnType.getInternalName() + ";", null, l2, l4, resultOffset);
}
mv.visitMaxs(8, errorOffset+1);
+ mv.visitEnd();
}
private void writeGetGType(RegisteredTypeInfo rti, ClassCompilation compilation) {
@@ -1243,7 +1263,7 @@
CallableCompilationContext ctx = tryCompileCallable(fi, globalSigs);
if (ctx == null)
return;
- writeCallable(ACC_PUBLIC + ACC_STATIC + ACC_FINAL, null, compilation, fi, ctx);
+ writeCallable(ACC_PUBLIC + ACC_STATIC + ACC_FINAL, compilation, fi, ctx);
}
private void compile(StructInfo info) {
@@ -1284,7 +1304,7 @@
CallableCompilationContext ctx = tryCompileCallable(fi, sigs);
if (ctx == null)
continue;
- writeCallable(ACC_PUBLIC, info, compilation, fi, ctx);
+ writeCallable(ACC_PUBLIC, compilation, fi, ctx);
}
for (FieldInfo fi : info.getFields()) {
Modified: trunk/src/org/gnome/gir/compiler/Test.java
==============================================================================
--- trunk/src/org/gnome/gir/compiler/Test.java (original)
+++ trunk/src/org/gnome/gir/compiler/Test.java Wed Sep 3 01:55:46 2008
@@ -36,11 +36,11 @@
PointerByReference error = new PointerByReference(null);
Function target = Internals.library.getFunction("glib_baz");
Object[] args = new Object[] { x, z };
- Test result = (Test) target.invoke(Integer.class, args, Internals.invocationOptions);
+ Pointer result = (Pointer) target.invoke(Pointer.class, args, Internals.invocationOptions);
if (result == null) {
throw new GErrorException(new GErrorStruct(error.getValue()));
}
- return result;
+ return (Test) objectFor(result, Test.class);
}
public static Test newWithFoo(String blah) {
Modified: trunk/src/org/gnome/gir/gobject/GObject.java
==============================================================================
--- trunk/src/org/gnome/gir/gobject/GObject.java (original)
+++ trunk/src/org/gnome/gir/gobject/GObject.java Wed Sep 3 01:55:46 2008
@@ -72,6 +72,13 @@
private Map<String, Map<Closure, ClosureProxy>> signalClosures;
private final IntPtr objectID = new IntPtr(System.identityHashCode(this));
+
+ /**
+ * A tagging interface used in the code generator - if a method returns an interface,
+ * we have it extend this interface so we know it's a GObject.
+ * @author walters
+ */
+ public static interface GObjectProxy {};
public GObject(Initializer init) {
super(init.needRef ? initializer(init.ptr, false, init.ownsHandle) : init);
@@ -521,6 +528,7 @@
if (nativeParam == null) {
continue;
}
+
if (NativeObject.class.isAssignableFrom(paramType)) {
javaParam = NativeObject.objectFor((Pointer) nativeParam,
paramType, 1, true);
Modified: trunk/src/org/gnome/gir/gobject/GTypeMapper.java
==============================================================================
--- trunk/src/org/gnome/gir/gobject/GTypeMapper.java (original)
+++ trunk/src/org/gnome/gir/gobject/GTypeMapper.java Wed Sep 3 01:55:46 2008
@@ -274,7 +274,9 @@
@SuppressWarnings("unchecked")
public FromNativeConverter getFromNativeConverter(Class type) {
if (Enum.class.isAssignableFrom(type)) {
- return enumConverter;
+ return enumConverter;
+ } else if (GObject.GObjectProxy.class.isAssignableFrom(type)) {
+ return nativeObjectConverter;
} else if (NativeObject.class.isAssignableFrom(type)) {
return nativeObjectConverter;
} else if (Boolean.class == type || boolean.class == type) {
@@ -293,6 +295,8 @@
public ToNativeConverter getToNativeConverter(Class type) {
if (NativeObject.class.isAssignableFrom(type)) {
return nativeObjectConverter;
+ } else if (GObject.GObjectProxy.class.isAssignableFrom(type)) {
+ return nativeObjectConverter;
} else if (NativeValue.class.isAssignableFrom(type)) {
return nativeValueArgumentConverter;
} else if (Enum.class.isAssignableFrom(type)) {
Modified: trunk/src/org/gnome/gir/gobject/NativeObject.java
==============================================================================
--- trunk/src/org/gnome/gir/gobject/NativeObject.java (original)
+++ trunk/src/org/gnome/gir/gobject/NativeObject.java Wed Sep 3 01:55:46 2008
@@ -168,7 +168,17 @@
return objectFor(ptr, cls, needRef ? 1 : 0, ownsHandle);
}
- public static <T extends NativeObject> T objectFor(Pointer ptr, Class<T> cls, int refAdjust, boolean ownsHandle) {
+ private static Class<?> getStubClassFor(Class<?> proxyClass) {
+ Class<?>[] declared = proxyClass.getDeclaredClasses();
+ for (Class<?> c: declared) {
+ if (c.getName().endsWith("$AnonStub"))
+ return c;
+ }
+ throw new RuntimeException("Couldn't find Stub for interface: " + proxyClass);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T extends NativeObject> T objectFor(Pointer ptr, Class<T> cls, int refAdjust, boolean ownsHandle) {
// Ignore null pointers
if (ptr == null) {
return null;
@@ -184,15 +194,21 @@
}
return cls.cast(obj);
}
-
- //
- // If it is a GObject or MiniObject, read the g_class field to find
- // the most exact class match
- //
- // || MiniObject.class.isAssignableFrom(cls)
- if (GObject.class.isAssignableFrom(cls)) {
+
+
+ /* Special-case GObject.GObjectProxy here - these are interface values
+ * for which we don't know of a current concrete class.
+ */
+ if (GObject.GObjectProxy.class.isAssignableFrom(cls)) {
+ cls = (Class<T>) getStubClassFor(cls);
+ /* For GObject, read the g_class field to find
+ * the most exact class match
+ */
+ } else if (GObject.class.isAssignableFrom(cls)) {
cls = classFor(ptr, cls);
}
+ /* Ok, something else, let's try to find an Initializer constructor
+ */
try {
Constructor<T> constructor = cls.getDeclaredConstructor(Initializer.class);
constructor.setAccessible(true);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]