001 package railo.transformer.bytecode.expression.var; 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.type.FunctionValueImpl; 008 import railo.transformer.bytecode.BytecodeContext; 009 import railo.transformer.bytecode.BytecodeException; 010 import railo.transformer.bytecode.cast.CastString; 011 import railo.transformer.bytecode.expression.Expression; 012 import railo.transformer.bytecode.literal.LitString; 013 import railo.transformer.bytecode.util.Types; 014 import railo.transformer.bytecode.visitor.ArrayVisitor; 015 016 public final class NamedArgument extends Argument { 017 018 019 020 private static final Type TYPE_FUNCTION_VALUE=Type.getType(FunctionValueImpl.class); 021 // railo.runtime.type.FunctionValue newInstance (String,Object) 022 /* 023 private final static Method NEW_INSTANCE = new Method("newInstance", 024 Types.FUNCTION_VALUE, 025 new Type[]{Types.STRING,Types.OBJECT}); 026 027 private final static Method NEW_INSTANCE_ARR = new Method("newInstance", 028 Types.FUNCTION_VALUE, 029 new Type[]{Types.STRING_ARRAY,Types.OBJECT}); 030 */ 031 private static final int VALUE=0; 032 private static final int ARRAY=1; 033 private static final int KEY=0; 034 private static final int STRING=1; 035 036 private final static Method[][] NEW_INSTANCE = new Method[][]{ 037 new Method[]{ 038 new Method("newInstance",Types.FUNCTION_VALUE,new Type[]{Types.COLLECTION_KEY,Types.OBJECT}), 039 new Method("newInstance",Types.FUNCTION_VALUE,new Type[]{Types.COLLECTION_KEY_ARRAY,Types.OBJECT}) 040 }, 041 new Method[]{ 042 new Method("newInstance",Types.FUNCTION_VALUE,new Type[]{Types.STRING,Types.OBJECT}), 043 new Method("newInstance",Types.FUNCTION_VALUE,new Type[]{Types.STRING_ARRAY,Types.OBJECT}) 044 } 045 }; 046 047 048 private Expression name; 049 050 public NamedArgument(Expression name, Expression value, String type) { 051 super(value,type); 052 this.name=name; 053 } 054 055 /** 056 * 057 * @see railo.transformer.bytecode.expression.var.Argument#_writeOut(org.objectweb.asm.commons.GeneratorAdapter, int) 058 */ 059 public Type _writeOut(BytecodeContext bc, int mode) throws BytecodeException { 060 061 int form=VALUE; 062 int type=STRING; 063 if(name instanceof Variable) { 064 GeneratorAdapter adapter = bc.getAdapter(); 065 String[] arr = VariableString.variableToStringArray((Variable) name); 066 if(arr.length>1){ 067 form=ARRAY; 068 ArrayVisitor av=new ArrayVisitor(); 069 av.visitBegin(adapter,Types.STRING,arr.length); 070 for(int y=0;y<arr.length;y++){ 071 av.visitBeginItem(adapter, y); 072 adapter.push(arr[y]); 073 av.visitEndItem(bc); 074 } 075 av.visitEnd(); 076 } 077 else { 078 //VariableString.toExprString(name).writeOut(bc, MODE_REF); 079 name=LitString.toExprString(VariableString.variableToString((Variable) name)); 080 type=Variable.registerKey(bc, VariableString.toExprString(name))?KEY:STRING; 081 } 082 } 083 else { 084 //CastString.toExprString(name).writeOut(bc, MODE_REF); 085 type=Variable.registerKey(bc, CastString.toExprString(name))?KEY:STRING; 086 087 } 088 //name.writeOut(bc, MODE_REF); 089 super._writeOut(bc, MODE_REF); 090 //bc.getAdapter().push(variableString); 091 bc.getAdapter().invokeStatic(TYPE_FUNCTION_VALUE,NEW_INSTANCE[type][form]); 092 return Types.FUNCTION_VALUE; 093 } 094 095 096 /** 097 * @see railo.transformer.bytecode.expression.var.Argument#writeOutValue(railo.transformer.bytecode.BytecodeContext, int) 098 */ 099 public Type writeOutValue(BytecodeContext bc, int mode) 100 throws BytecodeException { 101 // TODO Auto-generated method stub 102 return super.writeOutValue(bc, mode); 103 } 104 105 106 /** 107 * @return the name 108 */ 109 public Expression getName() { 110 return name; 111 } 112 }