package som.interpreter;

import som.interpreter.nodes.ContextualNode;
import som.interpreter.nodes.ExpressionNode;
import som.interpreter.nodes.SOMNode;

import com.oracle.truffle.api.frame.FrameSlot;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.NodeUtil;
import com.oracle.truffle.api.nodes.NodeVisitor;


public final class Inliner implements NodeVisitor {

  public static ExpressionNode doInline(
      final ExpressionNode body,
      final LexicalContext inlinedContext) {
    ExpressionNode inlinedBody = NodeUtil.cloneNode(body);
    inlinedBody.accept(new Inliner(inlinedContext));
    return inlinedBody;
  }

  private final LexicalContext inlinedContext;

  private Inliner(final LexicalContext inlinedContext) {
    this.inlinedContext = inlinedContext;
  }

  public LexicalContext getLexicalContext() {
    return inlinedContext;
  }

  @Override
  public boolean visit(final Node node) {
    prepareBodyNode(node);
    assert !(node instanceof Method);
    return true;
  }

  public FrameSlot getLocalFrameSlot(final Object slotId) {
    return inlinedContext.getFrameDescriptor().findFrameSlot(slotId);
  }

  public FrameSlot getFrameSlot(final ContextualNode node, final Object slotId) {
    return getFrameSlot(slotId, node.getContextLevel());
  }

  public FrameSlot getFrameSlot(final Object slotId, int level) {
    LexicalContext ctx = inlinedContext;
    while (level > 0) {
      ctx = ctx.getOuterContext();
      level--;
    }
    return ctx.getFrameDescriptor().findFrameSlot(slotId);
  }

  private void prepareBodyNode(final Node node) {
    ((SOMNode) node).replaceWithIndependentCopyForInlining(this);
  }
}

@@ -1594,24 +1594,61 @@
 ode node) %7B%0A
+    if (node instanceof SOMNode) %7B%0A  
     ((SOMNod
@@ -1701,14 +1701,20 @@
 (this);%0A
+    %7D%0A
   %7D%0A%7D%0A

Fix Inliner to work only on SOMNodes