001    package railo.transformer.bytecode.statement.tag;
002    
003    import java.util.Iterator;
004    import java.util.List;
005    
006    import org.objectweb.asm.Label;
007    import org.objectweb.asm.Opcodes;
008    import org.objectweb.asm.commons.GeneratorAdapter;
009    
010    import railo.transformer.bytecode.Body;
011    import railo.transformer.bytecode.BytecodeContext;
012    import railo.transformer.bytecode.BytecodeException;
013    import railo.transformer.bytecode.Position;
014    import railo.transformer.bytecode.Statement;
015    import railo.transformer.bytecode.cast.CastBoolean;
016    import railo.transformer.bytecode.expression.ExprBoolean;
017    import railo.transformer.bytecode.expression.Expression;
018    import railo.transformer.bytecode.util.ExpressionUtil;
019    
020    public final class TagIf extends TagBaseNoFinal {
021    
022            
023            public TagIf(Position start,Position end) {
024                    super(start,end);
025            }
026    
027            public void _writeOut(BytecodeContext bc) throws BytecodeException {
028                    GeneratorAdapter adapter = bc.getAdapter();
029                    Label end = new Label();
030                    Body ifBody=getBody();
031                    
032                    List stats = ifBody.getStatements();
033                    Iterator it = stats.iterator();
034                    Tag t;
035                    Label endIf=writeOutElseIfStart(bc, this);
036                    boolean hasElse=false;
037                    while(it.hasNext()) {
038                            Statement stat = ((Statement)it.next());
039                            if(!hasElse && stat instanceof Tag) {
040                                    t=(Tag) stat;
041                                    if(t.getTagLibTag().getTagClassName().equals("railo.runtime.tag.ElseIf")) {
042                                            writeOutElseIfEnd(adapter, endIf, end);
043                                            endIf=writeOutElseIfStart(bc,t);
044                                            continue;
045                                    }
046                                    else if(t.getTagLibTag().getTagClassName().equals("railo.runtime.tag.Else")) {
047                                            ExpressionUtil.visitLine(bc, t.getStart());
048                                    hasElse=true;
049                                            writeOutElseIfEnd(adapter, endIf, end);
050                                            //endIf=writeOutElseIfStart(adapter,t);
051                                            continue;
052                                    }
053                            }
054                            stat.writeOut(bc);
055                    }
056                    if(!hasElse)writeOutElseIfEnd(adapter, endIf, end);
057                    
058                    adapter.visitLabel(end);
059            }
060    
061            private static Label writeOutElseIfStart(BytecodeContext bc, Tag tag) throws BytecodeException {
062                    GeneratorAdapter adapter = bc.getAdapter();
063    
064                    ExprBoolean cont = CastBoolean.toExprBoolean(tag.getAttribute("condition").getValue());
065                    
066                    Label endIf = new Label();
067            
068                    ExpressionUtil.visitLine(bc, tag.getStart());
069            cont.writeOut(bc,Expression.MODE_VALUE);
070            adapter.ifZCmp(Opcodes.IFEQ, endIf);
071            return endIf;
072            }
073            private static void writeOutElseIfEnd(GeneratorAdapter adapter, Label endIf, Label end) {
074    
075            adapter.visitJumpInsn(Opcodes.GOTO, end);
076            adapter.visitLabel(endIf);
077            }
078    }