Skip to content

Instantly share code, notes, and snippets.

@eugene-kamenev
Last active December 14, 2015 08:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save eugene-kamenev/4049c670e30cf279fea5 to your computer and use it in GitHub Desktop.
Save eugene-kamenev/4049c670e30cf279fea5 to your computer and use it in GitHub Desktop.
We used AstBuilder.buildFromString to parse groovy code and tell AndroidStudio to add code completion & checking for SwissKnife lib
package gdsl
import org.codehaus.groovy.ast.builder.AstBuilder
import org.codehaus.groovy.ast.expr.BinaryExpression
import org.codehaus.groovy.ast.expr.ClosureExpression
import org.codehaus.groovy.ast.expr.MethodCallExpression
import org.codehaus.groovy.ast.stmt.BlockStatement
import org.codehaus.groovy.ast.stmt.ExpressionStatement
import org.codehaus.groovy.ast.stmt.ReturnStatement
import org.codehaus.groovy.control.CompilePhase
contributor(context(scope: annotatedScope(ctype: "com.android.ast.restable.RestableEntity"))) {
try {
classType?.fields?.each {
method name: it.name, type: 'void', params: ['map': Map.name]
if (it.name == 'toJSON') {
def statement = new AstBuilder().buildFromString(it.text)[0] as BlockStatement
statement.statements.each {
def returnStatement = it as ReturnStatement
def methods = getMethodNames(returnStatement.expression) as List<String>
methods.each {
method name: it, type: Map.name, params: ['closure': Closure.name]
method name: it, type: Map.name
}
}
}
if (it.name == 'fromJSON') {
def statement = new AstBuilder().buildFromString(CompilePhase.CONVERSION, false, it.text)[0] as BlockStatement
statement.statements.each {
def expressionStatement = it as ExpressionStatement
def methods = getMethodNames(expressionStatement.expression) as List<String>
methods.each {
method isStatic: true, name: it, type: classType.name, params: ['closure': Closure.name]
method isStatic: true, name: it, type: classType.name, params: ['map': Map.name]
}
}
}
if (it.name == 'restMethods') {
def statement = new AstBuilder().buildFromString(CompilePhase.CONVERSION, false, it.text)[0] as BlockStatement
statement.statements.each {
def expressionStatement = it as ExpressionStatement
def methods = getMethodNames(expressionStatement.expression) as List<String>
methods.each {
method(isStatic: true, name: it, type: 'java.lang.Object', params: ['map': Map.name, 'closure': Closure.name])
}
}
}
}
} catch (emAll) {
}
}
private List getMethodNames(BinaryExpression expression) {
def methodNames = []
def closure = expression.rightExpression as ClosureExpression
def closureStatement = closure.code as BlockStatement
closureStatement.statements.each {
if (it instanceof ExpressionStatement) {
def expr = it as ExpressionStatement
def methodCall = expr.expression as MethodCallExpression
methodNames << methodCall.methodAsString
} else if (it instanceof ReturnStatement) {
if (it.expression instanceof MethodCallExpression) {
methodNames << it.expression.methodAsString
}
}
}
return methodNames
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment