package st.gravel.support.compiler.ast;
/*
This file is automatically generated from typed smalltalk source. Do not edit by hand.
(C) AG5.com
*/
import java.math.BigInteger;
import st.gravel.support.jvm.NonLocalReturn;
import st.gravel.support.compiler.ast.MethodNode;
import st.gravel.support.compiler.jvm.BlockSendArgument;
import st.gravel.support.compiler.ast.SystemMapping;
import st.gravel.support.compiler.jvm.JVMNonPrimitiveType;
import st.gravel.support.compiler.ast.Reference;
import java.util.Map;
import st.gravel.support.compiler.ast.VariableDeclarationNode;
import java.util.List;
import java.util.ArrayList;
import st.gravel.support.compiler.ast.Expression;
import st.gravel.support.compiler.ast.SequenceNode;
import st.gravel.support.compiler.ast.SelfNode;
import st.gravel.support.compiler.ast.VariableNodeReplacer;
import st.gravel.support.compiler.ast.LiteralSendInliner;
import java.util.HashMap;
import st.gravel.support.compiler.ast.Node;
import st.gravel.support.compiler.ast.SystemMappingUpdater;
import st.gravel.support.compiler.ast.BoundVariableDeclarationNode;
import st.gravel.support.compiler.ast.UnaryMethodNode;
import st.gravel.support.compiler.ast.KeywordMethodNode;
import st.gravel.support.compiler.ast.BlockNode;
import st.gravel.support.compiler.jvm.JVMVariable;
import st.gravel.support.compiler.ast.VariableRenamer;
import st.gravel.support.compiler.ast.HolderDeclarationNode;
public class BlockInliner extends Object implements Cloneable {
public static BlockInliner_Factory factory = new BlockInliner_Factory();
BlockSendArgument[] _astConstants;
Map<String, String> _copiedArgRenames;
String[] _copiedArgumentNames;
MethodNode _methodNode;
Reference _receiverReference;
JVMNonPrimitiveType _selfType;
SystemMapping _systemMapping;
public static class BlockInliner_Factory extends st.gravel.support.jvm.SmalltalkFactory {
public BlockInliner basicNew() {
BlockInliner newInstance = new BlockInliner();
newInstance.initialize();
return newInstance;
}
public BlockInliner methodNode_astConstants_systemMapping_copiedArgumentNames_selfType_receiverReference_(final MethodNode _methodNode, final BlockSendArgument[] _astConstants, final SystemMapping _systemMapping, final String[] _copiedArgumentNames, final JVMNonPrimitiveType _selfType, final Reference _receiverReference) {
return this.basicNew().initializeMethodNode_astConstants_systemMapping_copiedArgumentNames_selfType_receiverReference_(_methodNode, _astConstants, _systemMapping, _copiedArgumentNames, _selfType, _receiverReference);
}
}
static public BlockInliner _methodNode_astConstants_systemMapping_copiedArgumentNames_selfType_receiverReference_(Object receiver, final MethodNode _methodNode, final BlockSendArgument[] _astConstants, final SystemMapping _systemMapping, final String[] _copiedArgumentNames, final JVMNonPrimitiveType _selfType, final Reference _receiverReference) {
return factory.methodNode_astConstants_systemMapping_copiedArgumentNames_selfType_receiverReference_(_methodNode, _astConstants, _systemMapping, _copiedArgumentNames, _selfType, _receiverReference);
}
public BlockSendArgument[] astConstants() {
return _astConstants;
}
public java.lang.invoke.MethodHandle build() {
return this.isOptimizable() ? this.buildOptimized() : this.buildNonOptimized();
}
public VariableDeclarationNode[] buildMethodNodeArguments_(final MethodNode _node) {
final List<VariableDeclarationNode>[] _arguments;
_arguments = new List[1];
_arguments[0] = new java.util.ArrayList();
st.gravel.support.jvm.ArrayExtensions.with_do_(_astConstants, _node.arguments(), new st.gravel.support.jvm.Block2<Object, BlockSendArgument, VariableDeclarationNode>() {
@Override
public Object value_value_(final BlockSendArgument _astConstant, final VariableDeclarationNode _arg) {
if (_astConstant == null) {
return _arguments[0].add(_arg);
}
return BlockInliner.this;
}
});
for (final String _each : _copiedArgumentNames) {
_arguments[0].add(BlockInliner.this.variableDeclarationNodeFor_(_each));
}
return _arguments[0].toArray(new VariableDeclarationNode[_arguments[0].size()]);
}
public java.lang.invoke.MethodHandle buildNonOptimized() {
final MethodNode _node;
final VariableDeclarationNode[] _arguments;
final List<Expression>[] _sendArgs;
_sendArgs = new List[1];
for (final String _each : _copiedArgumentNames) {
final String _newTempName;
_newTempName = BlockInliner.this.newTempName_for_(_each, _methodNode);
_copiedArgRenames.put(_each, _newTempName);
}
_arguments = this.buildMethodNodeArguments_(_methodNode);
_sendArgs[0] = new java.util.ArrayList();
st.gravel.support.jvm.ArrayExtensions.with_do_(_astConstants, _methodNode.arguments(), new st.gravel.support.jvm.Block2<Object, BlockSendArgument, VariableDeclarationNode>() {
@Override
public Object value_value_(final BlockSendArgument _astConstant, final VariableDeclarationNode _arg) {
if (_astConstant == null) {
return _sendArgs[0].add(_arg.asVariableNode());
} else {
return _sendArgs[0].add(BlockInliner.this.renamedBlockNodeFor_(_astConstant));
}
}
});
_node = this.newMethodNode_arguments_body_(_systemMapping.selectorConverter().selectorForNumArgs_(_arguments.length), _arguments, SequenceNode.factory.return_(SelfNode.factory.basicNew().send_withAll_(_methodNode.selector(), _sendArgs[0].toArray(new Expression[_sendArgs[0].size()]))));
this.log_text_("nonOptimized: ", _node.sourceString());
return this.compileMethodNode_allowBlockInlining_(this.link_(_node), false);
}
public java.lang.invoke.MethodHandle buildOptimized() {
final MethodNode[] _node;
MethodNode _inlined;
final VariableDeclarationNode[] _arguments;
final String _selector;
_node = new MethodNode[1];
this.log_text_("methodNode: ", _methodNode.sourceString());
_node[0] = this.link_(_methodNode);
this.log_text_("linked methodNode: ", _node[0].sourceString());
for (final String _each : _copiedArgumentNames) {
final String _newTempName;
_newTempName = BlockInliner.this.newTempName_for_(_each, _node[0]);
_copiedArgRenames.put(_each, _newTempName);
}
_arguments = this.buildMethodNodeArguments_(_node[0]);
_selector = _systemMapping.selectorConverter().selectorForNumArgs_(_arguments.length);
this.log_text_("selector: ", _selector);
_node[0] = this.newMethodNode_arguments_body_(_selector, _arguments, _node[0].body()).withNlrMarker_(_node[0].nlrMarker());
this.log_text_("node: ", _node[0].sourceString());
st.gravel.support.jvm.ArrayExtensions.with_do_(_astConstants, _methodNode.arguments(), new st.gravel.support.jvm.Block2<Object, BlockSendArgument, VariableDeclarationNode>() {
@Override
public Object value_value_(final BlockSendArgument _astConstant, final VariableDeclarationNode _arg) {
if (_astConstant != null) {
BlockInliner.this.log_text_("block " + _arg.name() + ": ", _astConstant.blockNode().sourceString());
return _node[0] = ((MethodNode) VariableNodeReplacer.factory.in_replace_with_(_node[0], _arg.name(), BlockInliner.this.renamedBlockNodeFor_(_astConstant)));
}
return BlockInliner.this;
}
});
_inlined = LiteralSendInliner.factory.inline_(_node[0]);
_inlined = this.link_(_inlined);
this.log_text_("inlined: ", _inlined.sourceString());
return this.compileMethodNode_(_inlined);
}
public java.lang.invoke.MethodHandle compileMethodNode_(final MethodNode _inlinedMethodNode) {
return this.compileMethodNode_allowBlockInlining_(_inlinedMethodNode, true);
}
public java.lang.invoke.MethodHandle compileMethodNode_allowBlockInlining_(final MethodNode _inlinedMethodNode, final boolean _allowBlockInlining) {
final Class _javaClass;
_javaClass = _systemMapping.compileInlinedMethod_selfType_allowBlockInlining_(_inlinedMethodNode, _selfType, _allowBlockInlining);
return _systemMapping.compilerTools().methodHandleAt_numArgs_in_identityClass_isStatic_(_systemMapping.selectorConverter().selectorAsFunctionName_(st.gravel.core.Symbol.value(_inlinedMethodNode.selector())), _inlinedMethodNode.numArgs(), _javaClass, _javaClass, true);
}
public BlockInliner copy() {
try {
BlockInliner _temp1 = (BlockInliner) this.clone();
_temp1.postCopy();
return _temp1;
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
public BlockInliner_Factory factory() {
return factory;
}
public BlockInliner initialize() {
_copiedArgRenames = new java.util.HashMap<String, String>();
return this;
}
public BlockInliner initializeMethodNode_astConstants_systemMapping_copiedArgumentNames_selfType_receiverReference_(final MethodNode _aMethodNode, final BlockSendArgument[] _anArray, final SystemMapping _anObject, final String[] _anObject1, final JVMNonPrimitiveType _anObject2, final Reference _anObject3) {
_methodNode = _aMethodNode;
_astConstants = _anArray;
_systemMapping = _anObject;
_copiedArgumentNames = _anObject1;
_selfType = _anObject2;
_receiverReference = _anObject3;
this.initialize();
return this;
}
public boolean isOptimizable() {
if (_methodNode.primitivePragma() != null) {
return false;
}
if (_methodNode.allNodesContains_(((st.gravel.support.jvm.Block1<Boolean, Node>) (new st.gravel.support.jvm.Block1<Boolean, Node>() {
@Override
public Boolean value_(final Node _node) {
return (boolean) _node.isSuperNode();
}
})))) {
return false;
}
return true;
}
public MethodNode link_(final MethodNode _aMethodNode) {
final SelfNode _owner;
final SystemMappingUpdater _updater;
final BoundVariableDeclarationNode[] _instVars;
_owner = SelfNode.factory.basicNew();
_updater = _systemMapping.newSystemMappingUpdater();
_instVars = _updater.allInstVarsForReference_(_receiverReference);
return ((MethodNode) _updater.localLink_instVars_ownerReference_owner_(_aMethodNode, _instVars, _receiverReference, _owner));
}
public BlockInliner log_text_(final String _label, final String _aString) {
return this;
}
public MethodNode methodNode() {
return _methodNode;
}
public MethodNode newMethodNode_arguments_body_(final String _selector, final VariableDeclarationNode[] _arguments, final SequenceNode _body) {
return _arguments.length == 0 ? UnaryMethodNode.factory.selector_body_(_selector, _body) : KeywordMethodNode.factory.selector_arguments_body_(_selector, _arguments, _body);
}
public String newTempName_for_(final String _argName, final Node _node) {
final LiteralSendInliner _lsi;
_lsi = LiteralSendInliner.factory.basicNew();
_lsi.initializeRoot_(_node);
return _lsi.newTempName_(_argName);
}
public BlockInliner postCopy() {
return this;
}
public BlockNode renamedBlockNodeFor_(final BlockSendArgument _astConstant) {
final BlockNode[] _blockNode;
_blockNode = new BlockNode[1];
_blockNode[0] = _astConstant.blockNode();
for (final JVMVariable _cv : _astConstant.copiedVariables()) {
_blockNode[0] = ((BlockNode) BlockInliner.this.renameVariable_from_to_(_blockNode[0], _cv.varName(), _copiedArgRenames.get(_cv.varName())));
}
this.log_text_("renamedBlockNode: ", _blockNode[0].sourceString());
return _blockNode[0];
}
public Node renameVariable_from_to_(final Node _node, final String _oldName, final String _newName) {
return VariableRenamer.factory.oldName_newName_(_oldName, _newName).visit_(_node);
}
public Node renameVariable_in_(final String _argName, final Node _node) {
return this.renameVariable_from_to_(_node, _argName, this.newTempName_for_(_argName, _node));
}
public VariableDeclarationNode variableDeclarationNodeFor_(final String _varName) {
for (final BlockSendArgument _astConstant : _astConstants) {
if (_astConstant != null) {
for (final JVMVariable _each : _astConstant.copiedVariables()) {
if (st.gravel.support.jvm.StringExtensions.equals_(_each.varName(), _varName)) {
return _each.type().isArrayType() ? HolderDeclarationNode.factory.name_(_copiedArgRenames.get(_each.varName())) : VariableDeclarationNode.factory.name_(_copiedArgRenames.get(_each.varName()));
}
}
}
}
throw new RuntimeException("cannot find varName: " + _varName);
}
}