001    package railo.transformer.bytecode.op;
002    
003    import org.objectweb.asm.Type;
004    import org.objectweb.asm.commons.Method;
005    
006    import railo.transformer.bytecode.BytecodeContext;
007    import railo.transformer.bytecode.BytecodeException;
008    import railo.transformer.bytecode.Literal;
009    import railo.transformer.bytecode.cast.CastString;
010    import railo.transformer.bytecode.expression.ExprString;
011    import railo.transformer.bytecode.expression.Expression;
012    import railo.transformer.bytecode.expression.ExpressionBase;
013    import railo.transformer.bytecode.literal.LitString;
014    import railo.transformer.bytecode.util.Types;
015    
016    public final class OpString extends ExpressionBase implements ExprString {
017        
018        private ExprString right;
019        private ExprString left;
020    
021        // String concat (String)
022        private final static Method METHOD_CONCAT = new Method("concat",
023                            Types.STRING,
024                            new Type[]{Types.STRING});
025        
026        private OpString(Expression left, Expression right) {
027            super(left.getLine());
028            this.left=CastString.toExprString(left);
029            this.right=CastString.toExprString(right);   
030        }
031        
032        /**
033         * Create a String expression from a Expression
034         * @param left 
035         * @param right 
036         * 
037         * @return String expression
038         */
039        public static ExprString toExprString(Expression left, Expression right) {
040            return toExprString(left, right, true);
041        }
042        
043        public static ExprString toExprString(Expression left, Expression right, boolean concatStatic) {
044            if(concatStatic && left instanceof Literal && right instanceof Literal) {
045                String l = ((Literal)left).getString();
046                    String r = ((Literal)right).getString();
047                    if((l.length()+r.length())<=LitString.MAX_SIZE)return new LitString(l.concat(r),left.getLine());
048            }
049            return new OpString(left,right);
050        }
051        
052        
053        /**
054         *
055         * @see railo.transformer.bytecode.expression.ExpressionBase#_writeOut(org.objectweb.asm.commons.GeneratorAdapter, int)
056         */
057        public Type _writeOut(BytecodeContext bc, int mode) throws BytecodeException {
058            left.writeOut(bc,MODE_REF);
059            right.writeOut(bc,MODE_REF);
060            bc.getAdapter().invokeVirtual(Types.STRING,METHOD_CONCAT);
061            return Types.STRING;
062        }
063    
064        /* *
065         * @see railo.transformer.bytecode.expression.Expression#getType()
066         * /
067        public int getType() {
068            return Types._STRING;
069        }*/
070    
071    }