Sergei Egorov / @bsideup
Baruch Sadogursky / @jbaruch
/* Before */
def persons = Person.findAll {
name =~ /Serg/
}
/* After */
def persons = Person.executeQuery '''
FROM Person WHERE name LIKE '%Serg%'
'''
@Macro
def findAll(def context, Expression exp, ClosureExpression cl) {
return callX(
exp,
"executeQuery",
constX("FROM ${exp.name} " +
cl.code.statements.collect {
if(it instanceof BinaryExpression
&& it.operation.type == REGEX_COMPARISON_OPERATOR)
"$it.leftExpression LIKE '%$it.rightExpression.text%'"
}.filter{ it != null }.join(" AND ")
)
)
}
def hello = assertNulls foo.bar.messages.hello.toUpperCase()
println hello
Will print
Assertion failed:
assert foo?.bar?.messages?.hello?.toUpperCase() != null
| | | | | |
| | null null null false
| [hello:World!]
[bar:[hello:World!]]
@Macro def assertNulls(def context, Expression self, Expression exp){
makeNullSafe(exp)
def cl = closureX(params(), block(
new AssertStatement(notNullX(exp)),
returnS(exp)
))
return callX(cl, "call", args())
}
def makeNullSafe(Expression exp) {
if (exp instanceof PropertyExpression
|| exp instanceof MethodCallExpression) {
exp.safe = true
makeNullSafe(exp.objectExpression)
}
}
def hello = {
assert foo?.bar?.messages?.hello?.toUpperCase() != null
return foo.bar.messages.hello.toUpperCase()
}()
println hello
def returnStatement = new ReturnStatement(
new ConstructorCallExpression(
ClassHelper.make(SomeCoolClass),
new ArgumentListExpression(
new ConstantExpression("someValue")
)
)
)
def returnStatement = macro {
return new SomeCoolClass("someValue")
}
def returnStatement = new ReturnStatement(
new ConstructorCallExpression(
ClassHelper.make(SomeCoolClass),
new ArgumentListExpression(
new ConstantExpression("someValue")
)
)
)
def returnStatement = macro {
return new SomeCoolClass("someValue")
}
def returnStatement = macro {
return new SomeCoolClass("someValue")
}
def returnStatement = MacroBuilder.INSTANCE.macro(
'''return new SomeCoolClass("someValue")''',
[:],
ReturnStatement
)
Where:
public enum MacroBuilder {
public <T> T macro(
String source,
Map<MacroSubstitutionKey, Closure<Expression>> context,
Class<T> resultClass
)
}