Skip to content

Instantly share code, notes, and snippets.

@jimwhite
Last active August 29, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jimwhite/5fd26ae225e793463a75 to your computer and use it in GitHub Desktop.
Save jimwhite/5fd26ae225e793463a75 to your computer and use it in GitHub Desktop.
Synthetic class in Groovy using compiler API.
// Fixed synthetic class snippet originally from <anonimista@outlook.com>.
import groovyjarjarasm.asm.Opcodes
import org.codehaus.groovy.ast.*
import org.codehaus.groovy.ast.expr.*
import org.codehaus.groovy.control.*
import org.codehaus.groovy.tools.GroovyClass
CompilationUnit compilationUnit = new CompilationUnit()
def className = 'Position'
// This gets an NPE...
//ClassNode classNode = ClassHelper.make(className)
//classNode.superClass = ClassHelper.OBJECT_TYPE
//classNode.modifiers = Opcodes.ACC_PUBLIC
ClassNode classNode = new ClassNode(className, Opcodes.ACC_PUBLIC, ClassHelper.OBJECT_TYPE)
FieldNode xFieldNode = new FieldNode(
'x', FieldNode.ACC_PUBLIC,
ClassHelper.Integer_TYPE, classNode,
new ConstantExpression(0))
FieldNode yFieldNode = new FieldNode(
'y', FieldNode.ACC_PUBLIC,
ClassHelper.Integer_TYPE, classNode,
new ConstantExpression(0))
classNode.addField(xFieldNode)
classNode.addField(yFieldNode)
compilationUnit.addClassNode(classNode)
compilationUnit.compile(Phases.CLASS_GENERATION)
def classes = compilationUnit.getClasses()
println classes
// Really should load all the classes and find the one we want by name.
// This approach based on the implementation of o.c.g.transform.stc.StaticTypeCheckingSupport.evaluateExpression(...).
Class aClass = compilationUnit.getClassLoader().defineClass(className, classes.head().getBytes())
println aClass
def instance = aClass.newInstance()
instance.x = 1
instance.y = -4
// We've got a POJO rather than POGO because we've bypassed the compiler logic that adds the Groovy magic.
// That'll be true even if we use ClassHelper.GROOVY_OBJECT_SUPPORT_TYPE for the ClassNode.
// So synthesizing a POGO would take more investigation.
println instance
println instance.getProperties()
println ([x:instance.x, y:instance.y])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment