Skip to content

Commit

Permalink
Don't blindly add SimpleFieldAccess as interface to carpented classes
Browse files Browse the repository at this point in the history
This fix really only applies to the testing case where, to test the
carpenter as it integrates with the deserialzer we need classes not
found on the class path. To do this they can be created by a second
class carpenter

However, the original carpenter *always* added SimpleFieldAccess as an
interface to the class it would be creating. Under normal circumstances
that's fine as that interface wouldn't be in the list of interfaces
given to the carpenter for the class it's being asked to created.
However, if as described above the carpenter schema was synthesised from
a class that was carpented it will.

If this happens we get an error as understandably you can't have a
duplicate interface.

Fix is to simply check weather the list of interfaces the schema
describes and only add SimpleFieldAccess if it isn't on it
  • Loading branch information
Katelyn Baker committed Jul 27, 2017
1 parent c721316 commit 337ccd4
Showing 1 changed file with 9 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,12 @@ class ClassCarpenter {
private fun generateClass(classSchema: Schema): Class<*> {
return generate(classSchema) { cw, schema ->
val superName = schema.superclass?.jvmName ?: "java/lang/Object"
val interfaces = arrayOf(SimpleFieldAccess::class.java.name.jvm) + schema.interfaces.map { it.name.jvm }
var interfaces = schema.interfaces.map { it.name.jvm }.toMutableList()

if (SimpleFieldAccess::class.java !in schema.interfaces) interfaces.add(SimpleFieldAccess::class.java.name.jvm)

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.toTypedArray())

generateFields(schema)
generateConstructor(schema)
Expand Down Expand Up @@ -304,6 +306,11 @@ class ClassCarpenter {
+ "with 'get': ${itf.name}.${it.name}")
}

// if we're trying to carpent a class that prior to serialisation / deserialisation
// was made by a carpenter then we can ignore this (it will implement a plain get
// method from SimpleFieldAccess)
if (fieldNameFromItf.isEmpty() && SimpleFieldAccess::class.java in schema.interfaces) return@forEach

if ((schema is ClassSchema) and (fieldNameFromItf !in allFields))
throw InterfaceMismatchException(
"Interface ${itf.name} requires a field named $fieldNameFromItf but that "
Expand Down

0 comments on commit 337ccd4

Please sign in to comment.