package org.overture.codegen.visitor;
import java.util.Stack;
import org.overture.ast.analysis.AnalysisException;
import org.overture.ast.node.INode;
import org.overture.ast.types.AUnknownType;
import org.overture.ast.types.PType;
import org.overture.codegen.ir.IRInfo;
import org.overture.codegen.ir.STypeIR;
import org.overture.codegen.ir.types.AObjectTypeIR;
public class IRVisitorRecursiveTypeHandler extends IRVisitor<STypeIR>
{
private Stack<PType> typeStack;
public IRVisitorRecursiveTypeHandler(
AbstractVisitorIR<IRInfo, STypeIR> visitor)
{
super(visitor);
this.typeStack = new Stack<PType>();
}
@Override
public STypeIR defaultINode(INode node, IRInfo question)
throws AnalysisException
{
if (node instanceof PType)
{
if (contains((PType) node, question))
{
return new AObjectTypeIR();
}
typeStack.push((PType) node);
STypeIR result = super.defaultINode(node, question);
typeStack.pop();
return result;
}
return super.defaultINode(node, question);
}
private boolean contains(PType type, IRInfo question)
{
for (PType e : typeStack)
{
// Everything equals the unknown type according to the type equality
// checker so we give unknown types special treatment
if (type instanceof AUnknownType)
{
if (e instanceof AUnknownType)
{
return true;
} else
{
return false;
}
} else if (e instanceof AUnknownType)
{
if (type instanceof AUnknownType)
{
return true;
} else
{
return false;
}
}
// Now that we are sure that none of them are unknown types we use
// the type equality checker
else if (question.getTcFactory().createPTypeAssistant().equals(type, e)
&& question.getTcFactory().createPTypeAssistant().equals(e, type))
{
return true;
}
}
return false;
}
}