body = bodyNode.accept(this);
} finally {
parentSourceSection = null;
}
} else {
body = new ObjectLiteralNode(context, sourceSection, context.getCoreLibrary().getNilObject());
}
final LoadArgumentsTranslator loadArgumentsTranslator = new LoadArgumentsTranslator(currentNode, context, source, isBlock, this);
final RubyNode loadArguments = argsNode.accept(loadArgumentsTranslator);
final RubyNode prelude;
if (isBlock) {
boolean shouldSwitch = true;
if (argsNode.getPreCount() == 0 && argsNode.getOptionalArgsCount() == 0 && argsNode.getPostCount() == 0 && argsNode.getRestArgNode() == null) {
shouldSwitch = false;
}
if (argsNode.getPreCount() + argsNode.getPostCount() == 1 && argsNode.getOptionalArgsCount() == 0 && argsNode.getRestArgNode() == null) {
shouldSwitch = false;
}
if (argsNode.getPreCount() == 0 && argsNode.getRestArgNode() != null) {
shouldSwitch = false;
}
RubyNode preludeBuilder;
if (shouldSwitch) {
final RubyNode readArrayNode = new ReadPreArgumentNode(context, sourceSection, 0, MissingArgumentBehaviour.RUNTIME_ERROR);
final RubyNode castArrayNode = ArrayCastNodeFactory.create(context, sourceSection, readArrayNode);
final FrameSlot arraySlot = environment.declareVar(environment.allocateLocalTemp("destructure"));
final RubyNode writeArrayNode = WriteLocalVariableNodeFactory.create(context, sourceSection, arraySlot, castArrayNode);
final LoadArgumentsTranslator destructureArgumentsTranslator = new LoadArgumentsTranslator(currentNode, context, source, isBlock, this);
destructureArgumentsTranslator.pushArraySlot(arraySlot);
final RubyNode newDestructureArguments = argsNode.accept(destructureArgumentsTranslator);
preludeBuilder = new IfNode(context, sourceSection,
BooleanCastNodeFactory.create(context, sourceSection,
new AndNode(context, sourceSection,
new BehaveAsBlockNode(context, sourceSection, true),
new ShouldDestructureNode(context, sourceSection, arity,
new RespondToNode(context, sourceSection, readArrayNode, "to_ary")))),
SequenceNode.sequence(context, sourceSection, writeArrayNode, newDestructureArguments),
loadArguments);
} else {
preludeBuilder = loadArguments;
}
prelude = SequenceNode.sequence(context, sourceSection,
new IfNode(context, sourceSection,
BooleanCastNodeFactory.create(context, sourceSection,
new BehaveAsBlockNode(context, sourceSection, true)),
new ObjectLiteralNode(context, sourceSection, context.getCoreLibrary().getNilObject()),
new CheckArityNode(context, sourceSection, arityForCheck)), preludeBuilder);
} else {
prelude = SequenceNode.sequence(context, sourceSection,
new CheckArityNode(context, sourceSection, arityForCheck),
loadArguments);