package railo.transformer.bytecode.statement.tag;
import java.util.Iterator;
import java.util.List;
import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.GeneratorAdapter;
import railo.transformer.bytecode.Body;
import railo.transformer.bytecode.BytecodeContext;
import railo.transformer.bytecode.BytecodeException;
import railo.transformer.bytecode.Position;
import railo.transformer.bytecode.Statement;
import railo.transformer.bytecode.cast.CastBoolean;
import railo.transformer.bytecode.expression.ExprBoolean;
import railo.transformer.bytecode.expression.Expression;
import railo.transformer.bytecode.util.ExpressionUtil;
public final class TagIf extends TagBaseNoFinal {
public TagIf(Position start,Position end) {
super(start,end);
}
public void _writeOut(BytecodeContext bc) throws BytecodeException {
GeneratorAdapter adapter = bc.getAdapter();
Label end = new Label();
Body ifBody=getBody();
List stats = ifBody.getStatements();
Iterator it = stats.iterator();
Tag t;
Label endIf=writeOutElseIfStart(bc, this);
boolean hasElse=false;
while(it.hasNext()) {
Statement stat = ((Statement)it.next());
if(!hasElse && stat instanceof Tag) {
t=(Tag) stat;
if(t.getTagLibTag().getTagClassName().equals("railo.runtime.tag.ElseIf")) {
writeOutElseIfEnd(adapter, endIf, end);
endIf=writeOutElseIfStart(bc,t);
continue;
}
else if(t.getTagLibTag().getTagClassName().equals("railo.runtime.tag.Else")) {
ExpressionUtil.visitLine(bc, t.getStart());
hasElse=true;
writeOutElseIfEnd(adapter, endIf, end);
//endIf=writeOutElseIfStart(adapter,t);
continue;
}
}
stat.writeOut(bc);
}
if(!hasElse)writeOutElseIfEnd(adapter, endIf, end);
adapter.visitLabel(end);
}
private static Label writeOutElseIfStart(BytecodeContext bc, Tag tag) throws BytecodeException {
GeneratorAdapter adapter = bc.getAdapter();
ExprBoolean cont = CastBoolean.toExprBoolean(tag.getAttribute("condition").getValue());
Label endIf = new Label();
ExpressionUtil.visitLine(bc, tag.getStart());
cont.writeOut(bc,Expression.MODE_VALUE);
adapter.ifZCmp(Opcodes.IFEQ, endIf);
return endIf;
}
private static void writeOutElseIfEnd(GeneratorAdapter adapter, Label endIf, Label end) {
adapter.visitJumpInsn(Opcodes.GOTO, end);
adapter.visitLabel(endIf);
}
}