001    package railo.transformer.bytecode.cast;
002    
003    import org.objectweb.asm.Type;
004    import org.objectweb.asm.commons.GeneratorAdapter;
005    import org.objectweb.asm.commons.Method;
006    
007    import railo.runtime.exp.TemplateException;
008    import railo.transformer.bytecode.BytecodeContext;
009    import railo.transformer.bytecode.BytecodeException;
010    import railo.transformer.bytecode.Literal;
011    import railo.transformer.bytecode.expression.ExprBoolean;
012    import railo.transformer.bytecode.expression.ExprDouble;
013    import railo.transformer.bytecode.expression.ExprString;
014    import railo.transformer.bytecode.expression.Expression;
015    import railo.transformer.bytecode.expression.ExpressionBase;
016    import railo.transformer.bytecode.literal.LitBoolean;
017    import railo.transformer.bytecode.util.Methods;
018    import railo.transformer.bytecode.util.Types;
019    
020    /**
021     * Cast to a Boolean
022     */
023    public final class CastBoolean extends ExpressionBase implements ExprBoolean {
024        
025        /**
026             * @see java.lang.Object#toString()
027             */
028            public String toString() {
029                    return "(boolean)"+expr;
030            }
031    
032            private Expression expr;
033    
034        /**
035         * constructor of the class
036         * @param expr
037         */
038        private CastBoolean(Expression expr) {
039            super(expr.getLine());
040            this.expr=expr;
041        }
042        
043        /**
044         * Create a String expression from a Expression
045         * @param expr
046         * @return String expression
047         * @throws TemplateException 
048         */
049        public static ExprBoolean toExprBoolean(Expression expr)  {
050            if(expr instanceof ExprBoolean) return (ExprBoolean) expr;
051            if(expr instanceof Literal) {
052                Boolean bool = ((Literal)expr).getBoolean(null);
053                if(bool!=null) return new LitBoolean(bool.booleanValue(),expr.getLine());
054                // TODO throw new TemplateException("can't cast value to a boolean value");
055            }
056            return new CastBoolean(expr);
057        }
058    
059        /**
060         * @see railo.transformer.bytecode.expression.Expression#writeOut(org.objectweb.asm.commons.GeneratorAdapter, int)
061         */
062        public Type _writeOut(BytecodeContext bc, int mode) throws BytecodeException {
063            GeneratorAdapter adapter = bc.getAdapter();
064            if(expr instanceof ExprDouble) {
065                expr.writeOut(bc,MODE_VALUE);
066                if(mode==MODE_VALUE)adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_BOOLEAN_VALUE_FROM_DOUBLE);
067                else adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_BOOLEAN_FROM_DOUBLE);
068            }
069            else if(expr instanceof ExprString) {
070                expr.writeOut(bc,MODE_REF);
071                if(mode==MODE_VALUE)adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_BOOLEAN_VALUE_FROM_STRING);
072                else adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_BOOLEAN_FROM_STRING);
073            }
074            else {
075                    Type rtn = expr.writeOut(bc,mode);
076                    
077                    if(mode==MODE_VALUE) {
078                            if(!Types.isPrimitiveType(rtn)) {
079                                    adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_BOOLEAN_VALUE);
080                            }
081                            else if(Types.BOOLEAN_VALUE.equals(rtn))        {}
082                            else if(Types.DOUBLE_VALUE.equals(rtn)) {
083                                    adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_BOOLEAN_VALUE_FROM_DOUBLE);
084                            }
085                            else {
086                                    adapter.invokeStatic(Types.CASTER,new Method("toRef",Types.toRefType(rtn),new Type[]{rtn}));
087                                    adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_BOOLEAN_VALUE);
088                            }
089                            //return Types.BOOLEAN_VALUE;
090                    }
091                    else {
092                            if(Types.BOOLEAN.equals(rtn))   {}
093                            else adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_BOOLEAN);
094                    }
095            }
096    
097            if(mode==MODE_VALUE)return Types.BOOLEAN_VALUE;
098            return Types.BOOLEAN;
099        }
100    
101        /* *
102         * @see railo.transformer.bytecode.expression.Expression#getType()
103         * /
104        public int getType() {
105            return Types._BOOLEAN;
106        }*/
107    }