001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.transformer.bytecode.statement.tag;
020
021import lucee.transformer.bytecode.BytecodeContext;
022import lucee.transformer.bytecode.BytecodeException;
023import lucee.transformer.bytecode.Position;
024import lucee.transformer.bytecode.cast.CastInt;
025import lucee.transformer.bytecode.expression.Expression;
026import lucee.transformer.bytecode.util.Types;
027import lucee.transformer.cfml.evaluator.impl.Argument;
028
029import org.objectweb.asm.Opcodes;
030import org.objectweb.asm.Type;
031import org.objectweb.asm.commons.GeneratorAdapter;
032import org.objectweb.asm.commons.Method;
033
034public final class TagParam extends TagBaseNoFinal {
035
036        // void param(String type, String name, Object defaultValue)
037        private static final Method PARAM_TYPE_NAME_DEFAULTVALUE = new Method(
038                        "param",
039                        Types.VOID,
040                        new Type[]{Types.STRING,Types.STRING,Types.OBJECT}
041        );
042        private static final Method PARAM_TYPE_NAME_DEFAULTVALUE_REGEX = new Method(
043                        "param",
044                        Types.VOID,
045                        new Type[]{Types.STRING,Types.STRING,Types.OBJECT,Types.STRING}
046        );
047        private static final Method PARAM_TYPE_NAME_DEFAULTVALUE_MIN_MAX = new Method(
048                        "param",
049                        Types.VOID,
050                        new Type[]{Types.STRING,Types.STRING,Types.OBJECT,Types.DOUBLE_VALUE,Types.DOUBLE_VALUE}
051        );
052        private static final Method PARAM_TYPE_NAME_DEFAULTVALUE_MAXLENGTH = new Method(
053                        "param",
054                        Types.VOID,
055                        new Type[]{Types.STRING,Types.STRING,Types.OBJECT,Types.INT_VALUE}
056        );
057        
058        public TagParam(Position start,Position end) {
059                super(start,end);
060        }
061
062        /**
063         *
064         * @see lucee.transformer.bytecode.statement.tag.TagBase#_writeOut(org.objectweb.asm.commons.GeneratorAdapter)
065         */
066        public void _writeOut(BytecodeContext bc) throws BytecodeException {
067                GeneratorAdapter adapter = bc.getAdapter();
068                //PageContextImpl pc=null;
069                //pc.param("", "", "");
070                
071                Argument.checkDefaultValue(this);
072                
073                // pc
074                adapter.loadArg(0);
075                
076                // type
077                Attribute attrType = getAttribute("type");
078                if(attrType!=null) {
079                        attrType.getValue().writeOut(bc, Expression.MODE_REF);
080                }
081                else adapter.push("any");
082                
083                // name
084                getAttribute("name").getValue().writeOut(bc, Expression.MODE_REF);
085                
086                // default
087                Attribute attrDefault = getAttribute("default");
088                if(attrDefault!=null) {
089                        attrDefault.getValue().writeOut(bc, Expression.MODE_REF);
090                }
091                else adapter.visitInsn(Opcodes.ACONST_NULL);
092                
093                Attribute attrMin = getAttribute("min");
094                Attribute attrMax = getAttribute("max");
095                Attribute attrPattern = getAttribute("pattern");
096                Attribute maxLength = getAttribute("maxLength");
097
098                if(attrMin!=null || attrMax!=null) {
099                        // min
100                        if(attrMin!=null)attrMin.getValue().writeOut(bc, Expression.MODE_VALUE);
101                        else {
102                                adapter.visitLdcInsn(new Double("NaN"));
103                        }
104                        // max
105                        if(attrMax!=null)attrMax.getValue().writeOut(bc, Expression.MODE_VALUE);
106                        else {
107                                adapter.visitLdcInsn(new Double("NaN"));
108                        }
109                        adapter.invokeVirtual(Types.PAGE_CONTEXT, PARAM_TYPE_NAME_DEFAULTVALUE_MIN_MAX);
110                }
111                else if(attrPattern!=null) {
112                        attrPattern.getValue().writeOut(bc, Expression.MODE_REF);
113                        adapter.invokeVirtual(Types.PAGE_CONTEXT, PARAM_TYPE_NAME_DEFAULTVALUE_REGEX);
114                }
115                else if(maxLength!=null) {
116                        CastInt.toExprInt(maxLength.getValue()).writeOut(bc, Expression.MODE_VALUE);
117                        adapter.invokeVirtual(Types.PAGE_CONTEXT, PARAM_TYPE_NAME_DEFAULTVALUE_MAXLENGTH);
118                }
119                else adapter.invokeVirtual(Types.PAGE_CONTEXT, PARAM_TYPE_NAME_DEFAULTVALUE);
120
121        }
122
123}