package org.overture.codegen.trans;
import java.util.LinkedList;
import org.overture.codegen.ir.SStmIR;
import org.overture.codegen.ir.analysis.DepthFirstAnalysisAdaptor;
import org.overture.codegen.ir.statements.ABlockStmIR;
public class BlockCleanupTrans extends DepthFirstAnalysisAdaptor
{
@Override
public void caseABlockStmIR(ABlockStmIR node)
throws org.overture.codegen.ir.analysis.AnalysisException
{
for (SStmIR s : new LinkedList<>(node.getStatements()))
{
s.apply(this);
}
if (node.parent() instanceof ABlockStmIR && isEmpty(node))
{
/**
* Only remove empty blocks from blocks, otherwise we can get into a situation where we destroy the tree.
* For example, 'if exp then () else ()'
*/
node.parent().removeChild(node);
return;
}
if (singleBlockWrapsBlock(node))
{
SStmIR enclosedStm = node.getStatements().get(0);
if (node.parent() != null)
{
node.parent().replaceChild(node, enclosedStm);
}
}
}
private boolean singleBlockWrapsBlock(ABlockStmIR node)
{
return node.getLocalDefs().isEmpty() && node.getStatements().size() == 1
&& node.getStatements().get(0) instanceof ABlockStmIR;
}
public boolean isEmpty(SStmIR target)
{
if (!(target instanceof ABlockStmIR))
{
return false;
}
ABlockStmIR block = (ABlockStmIR) target;
if (!block.getLocalDefs().isEmpty())
{
return false;
}
if (block.getStatements().isEmpty())
{
return true;
} else
{
for (SStmIR s : block.getStatements())
{
if (!isEmpty(s))
{
return false;
}
}
return true;
}
}
}