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 }