// TODO: don't require pop
if (!expr) context.consumeCurrentValue();
}
public void compileDefs(Node node, BodyCompiler context, boolean expr) {
final DefsNode defsNode = (DefsNode) node;
final ArgsNode argsNode = defsNode.getArgsNode();
CompilerCallback receiver = new CompilerCallback() {
public void call(BodyCompiler context) {
compile(defsNode.getReceiverNode(), context, true);
}
};
CompilerCallback body = new CompilerCallback() {
public void call(BodyCompiler context) {
if (defsNode.getBodyNode() != null) {
if (defsNode.getBodyNode() instanceof RescueNode) {
// if root of method is rescue, compile as light rescue
compileRescueInternal(defsNode.getBodyNode(), context, true);
} else {
compile(defsNode.getBodyNode(), context, true);
}
} else {
context.loadNil();
}
}
};
CompilerCallback args = new CompilerCallback() {
public void call(BodyCompiler context) {
compileArgs(argsNode, context, true);
}
};
// inspect body and args
ASTInspector inspector = new ASTInspector();
inspector.inspect(defsNode.getArgsNode());
// if body is a rescue node, inspect its pieces separately to avoid it disabling all optz
// TODO: this is gross.
if (defsNode.getBodyNode() instanceof RescueNode) {
RescueNode rescueNode = (RescueNode)defsNode.getBodyNode();
inspector.inspect(rescueNode.getBodyNode());
inspector.inspect(rescueNode.getElseNode());
inspector.inspect(rescueNode.getRescueNode());
} else {
inspector.inspect(defsNode.getBodyNode());
}
context.defineNewMethod(
defsNode.getName(), defsNode.getArgsNode().getArity().getValue(),
defsNode.getScope(), body, args, receiver, inspector, false,
defsNode.getPosition().getFile(), defsNode.getPosition().getStartLine(),
RuntimeHelpers.encodeParameterList(argsNode));
// TODO: don't require pop
if (!expr) context.consumeCurrentValue();
}