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    }