Created
August 25, 2015 15:32
-
-
Save k33g/9fdf20797fbd7bcbba6f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module frankenstein | |
import javassist.ClassPool | |
import javassist.CtField | |
import javassist.CtNewMethod | |
import gololang.Adapters | |
struct dynamicClass = { | |
className, | |
fields, | |
methods, | |
_ctClass | |
} | |
augment dynamicClass { | |
function field = |this, fieldName, fieldType| { | |
this: fields(): put(fieldName, fieldType) | |
return this | |
} | |
function method = |this, methodName, closure| { | |
this: methods(): put(methodName, closure) | |
return this | |
} | |
function toClass = |this| { | |
let resolveCtClass = |clazz| { | |
let pool = ClassPool.getDefault() | |
return pool: get(clazz: getName()) | |
} | |
this: fields(): each(|fieldName, fieldType| { | |
let field = CtField(resolveCtClass(clazz= fieldType), fieldName, this: _ctClass()) | |
field: setModifiers(javassist.Modifier.PUBLIC()) | |
this: _ctClass(): addField(field) | |
}) | |
this: methods(): each(|methodName, closure| { | |
let method = javassist.CtNewMethod.make( | |
"public Object "+ methodName +"() { return null ; }" | |
, this: _ctClass() | |
) | |
this: _ctClass(): addMethod(method) | |
}) | |
let klass = this: _ctClass(): toClass() | |
let klassDef = Adapter(): extends(this: className()) | |
this: methods(): each(|methodName, closure| { | |
klassDef: implements(methodName, |this| { | |
return closure(this) | |
}) | |
}) | |
return klassDef | |
} | |
} | |
function DynamicClass = |className| { | |
let pool = ClassPool.getDefault() | |
let ctClass = pool: makeClass(className) | |
let dynaKlass = dynamicClass(className, map[], map[], ctClass) | |
return dynaKlass | |
} | |
function main = |args| { | |
let Human = DynamicClass("org.k33g.Human") | |
: field("name", String.class) | |
: field("age", Integer.class) | |
: method("hello", |self| { | |
println("Hello " + self: name()) | |
}) | |
: method("yo", |self| { | |
println("yo " + self: name() + ", your age: " + self: age()) | |
}) | |
: toClass() | |
let bob = Human: newInstance() | |
bob: name("Bob Morane"): age(42) | |
bob: hello() | |
bob: yo() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment