IntelliJ reformat of the code

This commit is contained in:
Katelyn Baker 2017-06-23 09:02:00 +01:00
parent b356220da1
commit 28b7610e47
2 changed files with 63 additions and 62 deletions

View File

@ -76,27 +76,27 @@ class ClassCarpenter {
val descriptors = fields.map { it.key to Type.getDescriptor(it.value) }.toMap() val descriptors = fields.map { it.key to Type.getDescriptor(it.value) }.toMap()
fun fieldsIncludingSuperclasses(): Map<String, Class<out Any?>> = (superclass?.fieldsIncludingSuperclasses() ?: emptyMap()) + LinkedHashMap(fields) fun fieldsIncludingSuperclasses(): Map<String, Class<out Any?>> = (superclass?.fieldsIncludingSuperclasses() ?: emptyMap()) + LinkedHashMap(fields)
fun descriptorsIncludingSuperclasses(): Map<String, String> = (superclass?.descriptorsIncludingSuperclasses() ?: emptyMap()) + LinkedHashMap(descriptors) fun descriptorsIncludingSuperclasses(): Map<String, String> = (superclass?.descriptorsIncludingSuperclasses() ?: emptyMap()) + LinkedHashMap(descriptors)
val jvmName : String val jvmName: String
get() = name.replace (".", "/") get() = name.replace(".", "/")
} }
private val String.jvm: String get() = replace(".", "/") private val String.jvm: String get() = replace(".", "/")
class ClassSchema( class ClassSchema(
name: String, name: String,
fields: Map<String, Class<out Any?>>, fields: Map<String, Class<out Any?>>,
superclass: Schema? = null, superclass: Schema? = null,
interfaces: List<Class<*>> = emptyList() interfaces: List<Class<*>> = emptyList()
) : Schema (name, fields, superclass, interfaces) ) : Schema(name, fields, superclass, interfaces)
class InterfaceSchema( class InterfaceSchema(
name: String, name: String,
fields: Map<String, Class<out Any?>>, fields: Map<String, Class<out Any?>>,
superclass: Schema? = null, superclass: Schema? = null,
interfaces: List<Class<*>> = emptyList() interfaces: List<Class<*>> = emptyList()
) : Schema (name, fields, superclass, interfaces) ) : Schema(name, fields, superclass, interfaces)
class DuplicateName : RuntimeException("An attempt was made to register two classes with the same name within the same ClassCarpenter namespace.") class DuplicateName : RuntimeException("An attempt was made to register two classes with the same name within the same ClassCarpenter namespace.")
class InterfaceMismatch(msg: String) : RuntimeException(msg) class InterfaceMismatch(msg: String) : RuntimeException(msg)
@ -104,6 +104,7 @@ class ClassCarpenter {
private class CarpenterClassLoader : ClassLoader(Thread.currentThread().contextClassLoader) { private class CarpenterClassLoader : ClassLoader(Thread.currentThread().contextClassLoader) {
fun load(name: String, bytes: ByteArray) = defineClass(name, bytes, 0, bytes.size) fun load(name: String, bytes: ByteArray) = defineClass(name, bytes, 0, bytes.size)
} }
private val classloader = CarpenterClassLoader() private val classloader = CarpenterClassLoader()
private val _loaded = HashMap<String, Class<*>>() private val _loaded = HashMap<String, Class<*>>()
@ -132,18 +133,18 @@ class ClassCarpenter {
hierarchy.reversed().forEach { hierarchy.reversed().forEach {
when (it) { when (it) {
is InterfaceSchema -> generateInterface(it) is InterfaceSchema -> generateInterface(it)
is ClassSchema -> generateClass(it) is ClassSchema -> generateClass(it)
} }
} }
return _loaded[schema.name]!! return _loaded[schema.name]!!
} }
private fun generateInterface (schema: Schema): Class<*> { private fun generateInterface(schema: Schema): Class<*> {
return generate (schema) { cw, schema -> return generate(schema) { cw, schema ->
val interfaces = schema.interfaces.map { it.name.jvm }.toTypedArray() val interfaces = schema.interfaces.map { it.name.jvm }.toTypedArray()
with (cw) { with(cw) {
visit(V1_8, ACC_PUBLIC + ACC_ABSTRACT + ACC_INTERFACE, schema.jvmName, null, "java/lang/Object", interfaces) visit(V1_8, ACC_PUBLIC + ACC_ABSTRACT + ACC_INTERFACE, schema.jvmName, null, "java/lang/Object", interfaces)
generateAbstractGetters(schema) generateAbstractGetters(schema)
@ -153,12 +154,12 @@ class ClassCarpenter {
} }
} }
private fun generateClass (schema: Schema): Class<*> { private fun generateClass(schema: Schema): Class<*> {
return generate (schema) { cw, schema -> return generate(schema) { cw, schema ->
val superName = schema.superclass?.jvmName ?: "java/lang/Object" val superName = schema.superclass?.jvmName ?: "java/lang/Object"
val interfaces = arrayOf(SimpleFieldAccess::class.java.name.jvm) + schema.interfaces.map { it.name.jvm } val interfaces = arrayOf(SimpleFieldAccess::class.java.name.jvm) + schema.interfaces.map { it.name.jvm }
with (cw) { with(cw) {
visit(V1_8, ACC_PUBLIC + ACC_SUPER, schema.jvmName, null, superName, interfaces) visit(V1_8, ACC_PUBLIC + ACC_SUPER, schema.jvmName, null, superName, interfaces)
generateFields(schema) generateFields(schema)
@ -173,11 +174,11 @@ class ClassCarpenter {
} }
} }
private fun generate(schema: Schema, generator : (ClassWriter, Schema) -> Unit): Class<*> { private fun generate(schema: Schema, generator: (ClassWriter, Schema) -> Unit): Class<*> {
// Lazy: we could compute max locals/max stack ourselves, it'd be faster. // Lazy: we could compute max locals/max stack ourselves, it'd be faster.
val cw = ClassWriter (ClassWriter.COMPUTE_FRAMES or ClassWriter.COMPUTE_MAXS) val cw = ClassWriter(ClassWriter.COMPUTE_FRAMES or ClassWriter.COMPUTE_MAXS)
generator (cw, schema) generator(cw, schema)
val clazz = classloader.load(schema.name, cw.toByteArray()) val clazz = classloader.load(schema.name, cw.toByteArray())
_loaded[schema.name] = clazz _loaded[schema.name] = clazz
@ -252,8 +253,8 @@ class ClassCarpenter {
private fun ClassWriter.generateAbstractGetters(schema: Schema) { private fun ClassWriter.generateAbstractGetters(schema: Schema) {
for ((name, _) in schema.fields) { for ((name, _) in schema.fields) {
val descriptor = schema.descriptors[name] val descriptor = schema.descriptors[name]
val opcodes = ACC_ABSTRACT + ACC_PUBLIC val opcodes = ACC_ABSTRACT + ACC_PUBLIC
with (visitMethod(opcodes, "get" + name.capitalize(), "()" + descriptor, null, null)) { with(visitMethod(opcodes, "get" + name.capitalize(), "()" + descriptor, null, null)) {
// abstract method doesn't have any implementation so just end // abstract method doesn't have any implementation so just end
visitEnd() visitEnd()
} }

View File

@ -143,9 +143,9 @@ class ClassCarpenterTest {
assertEquals(iface.declaredMethods[0].name, "getA") assertEquals(iface.declaredMethods[0].name, "getA")
val schema2 = ClassCarpenter.ClassSchema("gen.Derived", mapOf("a" to Int::class.java), interfaces = listOf(iface)) val schema2 = ClassCarpenter.ClassSchema("gen.Derived", mapOf("a" to Int::class.java), interfaces = listOf(iface))
val clazz = cc.build(schema2) val clazz = cc.build(schema2)
val testA = 42 val testA = 42
val i = clazz.constructors[0].newInstance(testA) as SimpleFieldAccess val i = clazz.constructors[0].newInstance(testA) as SimpleFieldAccess
assertEquals(testA, i["a"]) assertEquals(testA, i["a"])
} }
@ -156,20 +156,20 @@ class ClassCarpenterTest {
val iFace2 = ClassCarpenter.InterfaceSchema("gen.Interface2", mapOf("c" to Int::class.java, "d" to String::class.java)) val iFace2 = ClassCarpenter.InterfaceSchema("gen.Interface2", mapOf("c" to Int::class.java, "d" to String::class.java))
val class1 = ClassCarpenter.ClassSchema( val class1 = ClassCarpenter.ClassSchema(
"gen.Derived", "gen.Derived",
mapOf( mapOf(
"a" to Int::class.java, "a" to Int::class.java,
"b" to String::class.java, "b" to String::class.java,
"c" to Int::class.java, "c" to Int::class.java,
"d" to String::class.java), "d" to String::class.java),
interfaces = listOf(cc.build(iFace1), cc.build(iFace2))) interfaces = listOf(cc.build(iFace1), cc.build(iFace2)))
val clazz = cc.build(class1) val clazz = cc.build(class1)
val testA = 42 val testA = 42
val testB = "don't touch me, I'm scared" val testB = "don't touch me, I'm scared"
val testC = 0xDEAD val testC = 0xDEAD
val testD = "wibble" val testD = "wibble"
val i = clazz.constructors[0].newInstance(testA, testB, testC, testD) as SimpleFieldAccess val i = clazz.constructors[0].newInstance(testA, testB, testC, testD) as SimpleFieldAccess
assertEquals(testA, i["a"]) assertEquals(testA, i["a"])
assertEquals(testB, i["b"]) assertEquals(testB, i["b"])
@ -180,33 +180,33 @@ class ClassCarpenterTest {
@Test @Test
fun `interface implementing interface`() { fun `interface implementing interface`() {
val iFace1 = ClassCarpenter.InterfaceSchema( val iFace1 = ClassCarpenter.InterfaceSchema(
"gen.Interface1", "gen.Interface1",
mapOf( mapOf(
"a" to Int::class.java, "a" to Int::class.java,
"b" to String::class.java)) "b" to String::class.java))
val iFace2 = ClassCarpenter.InterfaceSchema( val iFace2 = ClassCarpenter.InterfaceSchema(
"gen.Interface2", "gen.Interface2",
mapOf( mapOf(
"c" to Int::class.java, "c" to Int::class.java,
"d" to String::class.java), "d" to String::class.java),
interfaces = listOf(cc.build(iFace1))) interfaces = listOf(cc.build(iFace1)))
val class1 = ClassCarpenter.ClassSchema( val class1 = ClassCarpenter.ClassSchema(
"gen.Derived", "gen.Derived",
mapOf( mapOf(
"a" to Int::class.java, "a" to Int::class.java,
"b" to String::class.java, "b" to String::class.java,
"c" to Int::class.java, "c" to Int::class.java,
"d" to String::class.java), "d" to String::class.java),
interfaces = listOf(cc.build(iFace2))) interfaces = listOf(cc.build(iFace2)))
val clazz = cc.build(class1) val clazz = cc.build(class1)
val testA = 99 val testA = 99
val testB = "green is not a creative colour" val testB = "green is not a creative colour"
val testC = 7 val testC = 7
val testD = "I like jam" val testD = "I like jam"
val i = clazz.constructors[0].newInstance(testA, testB, testC, testD) as SimpleFieldAccess val i = clazz.constructors[0].newInstance(testA, testB, testC, testD) as SimpleFieldAccess
assertEquals(testA, i["a"]) assertEquals(testA, i["a"])
assertEquals(testB, i["b"]) assertEquals(testB, i["b"])