use of org.apache.drill.exec.compile.sig.CodeGeneratorMethod in project drill by apache.
the class ClassGenerator method flushCode.
/**
* Creates methods from the signature {@code sig} with body from the appropriate {@code blocks}.
*/
void flushCode() {
JVar innerClassField = null;
if (innerClassGenerator != null) {
blocks = oldBlocks;
innerClassField = clazz.field(JMod.NONE, model.ref(innerClassGenerator.clazz.name()), "innerClassField");
innerClassGenerator.flushCode();
}
int i = 0;
for (CodeGeneratorMethod method : sig) {
JMethod outer = clazz.method(JMod.PUBLIC, model._ref(method.getReturnType()), method.getMethodName());
for (CodeGeneratorArgument arg : method) {
outer.param(arg.getType(), arg.getName());
}
for (Class<?> c : method.getThrowsIterable()) {
outer._throws(model.ref(c));
}
outer._throws(SchemaChangeException.class);
int methodIndex = 0;
int exprsInMethod = 0;
boolean isVoidMethod = method.getReturnType() == void.class;
for (SizedJBlock sb : blocks[i++]) {
JBlock b = sb.getBlock();
if (!b.isEmpty()) {
if (optionManager != null && exprsInMethod > optionManager.getOption(ExecConstants.CODE_GEN_EXP_IN_METHOD_SIZE_VALIDATOR)) {
JMethod inner = clazz.method(JMod.PRIVATE, model._ref(method.getReturnType()), method.getMethodName() + methodIndex);
JInvocation methodCall = JExpr.invoke(inner);
for (CodeGeneratorArgument arg : method) {
inner.param(arg.getType(), arg.getName());
methodCall.arg(JExpr.direct(arg.getName()));
}
for (Class<?> c : method.getThrowsIterable()) {
inner._throws(model.ref(c));
}
inner._throws(SchemaChangeException.class);
if (isVoidMethod) {
outer.body().add(methodCall);
} else {
outer.body()._return(methodCall);
}
outer = inner;
exprsInMethod = 0;
++methodIndex;
}
outer.body().add(b);
exprsInMethod += sb.getCount();
}
}
if (innerClassField != null) {
// creates inner class instance and initializes innerClassField
if (method.getMethodName().equals("__DRILL_INIT__")) {
JInvocation rhs = JExpr._new(innerClassGenerator.clazz);
JBlock block = new JBlock().assign(innerClassField, rhs);
outer.body().add(block);
}
List<JType> argTypes = new ArrayList<>();
for (CodeGeneratorArgument arg : method) {
argTypes.add(model._ref(arg.getType()));
}
JMethod inner = innerClassGenerator.clazz.getMethod(method.getMethodName(), argTypes.toArray(new JType[0]));
if (inner != null) {
// removes empty method from the inner class
if (inner.body().isEmpty()) {
innerClassGenerator.clazz.methods().remove(inner);
continue;
}
JInvocation methodCall = innerClassField.invoke(inner);
for (CodeGeneratorArgument arg : method) {
methodCall.arg(JExpr.direct(arg.getName()));
}
if (isVoidMethod) {
outer.body().add(methodCall);
} else {
outer.body()._return(methodCall);
}
}
}
}
for (ClassGenerator<T> child : innerClasses.values()) {
child.flushCode();
}
}
Aggregations