Allow access to Java inner classes using lua field syntax.

This commit is contained in:
James Roseborough
2015-03-14 17:53:55 +00:00
parent 6bde11639c
commit 8c8c98fb00
6 changed files with 44 additions and 2 deletions

View File

@@ -972,6 +972,7 @@ Files are no longer hosted at LuaForge.
<li>Make LuaC compile state explicit and improve factoring.</li>
<li>Add sample build.gradle file for Android example.</li>
<li>collectgarbage() now behaves same as collectgarbage("collect") (fixes issue #41).</li>
<li>Allow access to Java inner classes using lua field syntax (fixes issue #40).</li>
</ul></td></tr>
</table></td></tr></table>

View File

@@ -54,6 +54,7 @@ class JavaClass extends JavaInstance implements CoerceJavaToLua.Coercion {
Map fields;
Map methods;
Map innerclasses;
static JavaClass forClass(Class c) {
JavaClass j = (JavaClass) classes.get(c);
@@ -78,7 +79,7 @@ class JavaClass extends JavaInstance implements CoerceJavaToLua.Coercion {
for ( int i=0; i<f.length; i++ ) {
Field fi = f[i];
if ( Modifier.isPublic(fi.getModifiers()) ) {
m.put( LuaValue.valueOf(fi.getName()), fi );
m.put(LuaValue.valueOf(fi.getName()), fi);
try {
if (!fi.isAccessible())
fi.setAccessible(true);
@@ -131,6 +132,21 @@ class JavaClass extends JavaInstance implements CoerceJavaToLua.Coercion {
return (LuaValue) methods.get(key);
}
Class getInnerClass(LuaValue key) {
if ( innerclasses == null ) {
Map m = new HashMap();
Class[] c = ((Class)m_instance).getClasses();
for ( int i=0; i<c.length; i++ ) {
Class ci = c[i];
String name = ci.getName();
String stub = name.substring(Math.max(name.lastIndexOf('$'), name.lastIndexOf('.'))+1);
m.put(LuaValue.valueOf(stub), ci);
}
innerclasses = m;
}
return (Class) innerclasses.get(key);
}
public LuaValue getConstructor() {
return getMethod(NEW);
}

View File

@@ -59,6 +59,9 @@ class JavaInstance extends LuaUserdata {
LuaValue m = jclass.getMethod(key);
if ( m != null )
return m;
Class c = jclass.getInnerClass(key);
if ( c != null )
return JavaClass.forClass(c);
return super.get(key);
}

View File

@@ -53,10 +53,16 @@ public class LuajavaAccessibleMembersTest extends TestCase {
"return a.public_field;"));
}
public void testAccessFromPrivateClassPublicConcstructor() {
public void testAccessFromPrivateClassPublicConstructor() {
assertEquals("privateImpl-constructor", invokeScript(
"b = luajava.newInstance('"+TestClass.class.getName()+"');" +
"c = b:get_PrivateImplClass();" +
"return luajava.new(c);"));
}
public void testAccessPublicEnum() {
assertEquals("class org.luaj.vm2.lib.jse.TestClass$SomeEnum", invokeScript(
"b = luajava.newInstance('"+TestClass.class.getName()+"');" +
"return b.SomeEnum"));
}
}

View File

@@ -49,6 +49,9 @@ public class LuajavaClassMembersTest extends TestCase {
public String pick(String s) { return "class-c-pick(string:"+s+")"; }
public String pick(int i) { return "class-c-pick(int:"+i+")"; }
public static class D {
public static String name() { return "name-of-D"; }
}
}
static LuaValue ZERO = LuaValue.ZERO;
@@ -223,4 +226,13 @@ public class LuajavaClassMembersTest extends TestCase {
assertEquals( "static-pick(int:1,string:abc)", p.call(SOMEB,ONE,ABC).tojstring() );
assertEquals( "static-pick(int:1,string:abc)", p.invoke(LuaValue.varargsOf(new LuaValue[] {SOMEB,ONE,ABC,ONE})).arg1().tojstring() );
}
public void testGetInnerClass() {
C c = new C();
JavaInstance ic = new JavaInstance(c);
LuaValue d = ic.get("D");
assertFalse(d.isnil());
assertSame(d, JavaClass.forClass(C.D.class));
LuaValue e = ic.get("E");
assertTrue(e.isnil());
}
}

View File

@@ -15,4 +15,8 @@ public class TestClass {
}
public TestInterface create_PrivateImpl(String f) { return new PrivateImpl(f); }
public Class get_PrivateImplClass() { return PrivateImpl.class; }
public enum SomeEnum {
ValueOne,
ValueTwo,
}
}