001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.transformer.bytecode.statement; 020 021import java.util.ArrayList; 022import java.util.Iterator; 023 024import lucee.transformer.bytecode.Body; 025import lucee.transformer.bytecode.BytecodeContext; 026import lucee.transformer.bytecode.BytecodeException; 027import lucee.transformer.bytecode.Position; 028import lucee.transformer.bytecode.Statement; 029import lucee.transformer.bytecode.expression.ExprBoolean; 030import lucee.transformer.bytecode.expression.Expression; 031import lucee.transformer.bytecode.literal.LitBoolean; 032import lucee.transformer.bytecode.util.ExpressionUtil; 033import lucee.transformer.bytecode.visitor.ConditionVisitor; 034 035public final class Condition extends StatementBaseNoFinal implements HasBodies { 036 037 private ArrayList<Pair> ifs=new ArrayList<Pair>(); 038 private Pair _else; 039 040 /** 041 * Constructor of the class 042 * @param condition 043 * @param body 044 * @param line 045 */ 046 public Condition(Position start,Position end) { 047 super(start,end); 048 } 049 050 /** 051 * Constructor of the class 052 * @param condition 053 * @param body 054 * @param line 055 */ 056 public Condition(ExprBoolean condition, Statement body, Position start,Position end) { 057 super(start,end); 058 addElseIf(condition,body,start,end); 059 060 body.setParent(this); 061 } 062 063 public Condition(boolean b, Statement body, Position start,Position end) { 064 this(LitBoolean.toExprBoolean(b),body,start,end); 065 } 066 067 /** 068 * adds a else statement 069 * @param condition 070 * @param body 071 */ 072 public Pair addElseIf(ExprBoolean condition, Statement body, Position start,Position end) { 073 Pair pair; 074 ifs.add(pair=new Pair(condition,body,start,end)); 075 body.setParent(this); 076 return pair; 077 } 078 079 /** 080 * sets the else Block of the condition 081 * @param body 082 */ 083 public Pair setElse(Statement body, Position start,Position end) { 084 _else=new Pair(null,body,start,end); 085 body.setParent(this); 086 return _else; 087 } 088 089 public final class Pair { 090 private ExprBoolean condition; 091 private Statement body; 092 private Position start; 093 public Position end; 094 095 public Pair(ExprBoolean condition, Statement body, Position start,Position end) { 096 this.condition=condition; 097 this.body=body; 098 this.start=start; 099 this.end=end; 100 } 101 } 102 103 104 105 public void _writeOut(BytecodeContext bc) throws BytecodeException { 106 Iterator<Pair> it = ifs.iterator(); 107 Pair pair; 108 ConditionVisitor cv=new ConditionVisitor(); 109 cv.visitBefore(); 110 // ifs 111 while(it.hasNext()) { 112 pair=it.next(); 113 ExpressionUtil.visitLine(bc, pair.start); 114 cv.visitWhenBeforeExpr(); 115 pair. condition.writeOut(bc,Expression.MODE_VALUE); 116 cv.visitWhenAfterExprBeforeBody(bc); 117 pair.body.writeOut(bc); 118 cv.visitWhenAfterBody(bc); 119 if(pair.end!=null)ExpressionUtil.visitLine(bc, pair.end); 120 } 121 // else 122 if(_else!=null && _else.body!=null) { 123 cv.visitOtherviseBeforeBody(); 124 _else.body.writeOut(bc); 125 cv.visitOtherviseAfterBody(); 126 } 127 128 cv.visitAfter(bc); 129 } 130 131 /** 132 * @see lucee.transformer.bytecode.statement.HasBodies#getBodies() 133 */ 134 public Body[] getBodies() { 135 int len=ifs.size(),count=0; 136 if(_else!=null)len++; 137 Body[] bodies=new Body[len]; 138 Pair p; 139 Iterator<Pair> it = ifs.iterator(); 140 while(it.hasNext()) { 141 p=it.next(); 142 bodies[count++]=(Body) p.body; 143 } 144 if(_else!=null)bodies[count++]=(Body) _else.body; 145 146 return bodies; 147 } 148}