Search in sources :

Example 1 with Argument

use of lucee.transformer.bytecode.statement.Argument in project Lucee by lucee.

the class AbstrCFMLScriptTransformer method getScriptFunctionArguments.

@Override
public ArrayList<Argument> getScriptFunctionArguments(ExprData data) throws TemplateException {
    // arguments
    LitBoolean passByRef;
    Expression displayName;
    Expression hint;
    Map<String, Attribute> meta;
    String _name;
    ArrayList<Argument> result = new ArrayList<Argument>();
    do {
        comments(data);
        // finish
        if (data.srcCode.isCurrent(')'))
            break;
        // attribute
        // name
        // String idName=identifier(data,false,true);
        boolean required = false;
        String idName = variableDec(data, false);
        // required
        if ("required".equalsIgnoreCase(idName)) {
            comments(data);
            String idName2 = variableDec(data, false);
            if (idName2 != null) {
                idName = idName2;
                required = true;
            }
            if (idName == null)
                throw new TemplateException(data.srcCode, "invalid argument definition");
        }
        String typeName = "any";
        if (idName == null)
            throw new TemplateException(data.srcCode, "invalid argument definition");
        comments(data);
        if (!data.srcCode.isCurrent(')') && !data.srcCode.isCurrent('=') && !data.srcCode.isCurrent(':') && !data.srcCode.isCurrent(',')) {
            typeName = idName.toLowerCase();
            // MUST was upper case before, is this a problem?
            idName = identifier(data, false);
        } else if (idName.indexOf('.') != -1 || idName.indexOf('[') != -1) {
            throw new TemplateException(data.srcCode, "invalid argument name [" + idName + "] definition");
        }
        if (idName == null)
            throw new TemplateException(data.srcCode, "invalid argument definition");
        comments(data);
        Expression defaultValue;
        if (data.srcCode.isCurrent('=') || data.srcCode.isCurrent(':')) {
            data.srcCode.next();
            comments(data);
            defaultValue = expression(data);
        } else
            defaultValue = null;
        // assign meta data defined in doc comment
        passByRef = data.factory.TRUE();
        displayName = data.factory.EMPTY();
        hint = data.factory.EMPTY();
        meta = null;
        if (data.docComment != null) {
            Map<String, Attribute> params = data.docComment.getParams();
            Attribute[] attrs = params.values().toArray(new Attribute[params.size()]);
            Attribute attr;
            String name;
            for (int i = 0; i < attrs.length; i++) {
                attr = attrs[i];
                name = attr.getName();
                // hint
                if (idName.equalsIgnoreCase(name) || name.equalsIgnoreCase(idName + ".hint")) {
                    hint = data.factory.toExprString(attr.getValue());
                    params.remove(name);
                }
                // meta
                if (StringUtil.startsWithIgnoreCase(name, idName + ".")) {
                    if (name.length() > idName.length() + 1) {
                        if (meta == null)
                            meta = new HashMap<String, Attribute>();
                        _name = name.substring(idName.length() + 1);
                        meta.put(_name, new Attribute(attr.isDynamicType(), _name, attr.getValue(), attr.getType()));
                    }
                    params.remove(name);
                }
            }
        }
        // argument attributes
        Attribute[] _attrs = attributes(null, null, data, COMMA_ENDBRACKED, data.factory.EMPTY(), Boolean.TRUE, null, false, NO_ATTR_SEP, true);
        Attribute _attr;
        if (!ArrayUtil.isEmpty(_attrs)) {
            if (meta == null)
                meta = new HashMap<String, Attribute>();
            for (int i = 0; i < _attrs.length; i++) {
                _attr = _attrs[i];
                meta.put(_attr.getName(), _attr);
            }
        }
        result.add(new Argument(data.factory.createLitString(idName), data.factory.createLitString(typeName), data.factory.createLitBoolean(required), defaultValue, passByRef, displayName, hint, meta));
        comments(data);
    } while (data.srcCode.forwardIfCurrent(','));
    return result;
}
Also used : Argument(lucee.transformer.bytecode.statement.Argument) Attribute(lucee.transformer.bytecode.statement.tag.Attribute) TemplateException(lucee.runtime.exp.TemplateException) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) LitBoolean(lucee.transformer.expression.literal.LitBoolean) FunctionAsExpression(lucee.transformer.bytecode.expression.FunctionAsExpression) Expression(lucee.transformer.expression.Expression)

Example 2 with Argument

use of lucee.transformer.bytecode.statement.Argument in project Lucee by lucee.

the class Function method createArguments.

private final void createArguments(BytecodeContext bc) throws TransformerException {
    GeneratorAdapter ga = bc.getAdapter();
    ga.push(arguments.size());
    ga.newArray(FUNCTION_ARGUMENT);
    Argument arg;
    for (int i = 0; i < arguments.size(); i++) {
        arg = arguments.get(i);
        boolean canHaveKey = Factory.canRegisterKey(arg.getName());
        // CHECK if default values
        // type
        ExprString _strType = arg.getType();
        short _type = CFTypes.TYPE_UNKNOW;
        if (_strType instanceof LitString) {
            _type = CFTypes.toShortStrict(((LitString) _strType).getString(), CFTypes.TYPE_UNKNOW);
        }
        boolean useType = !canHaveKey || _type != CFTypes.TYPE_ANY;
        // boolean useStrType=useType && (_type==CFTypes.TYPE_UNDEFINED || _type==CFTypes.TYPE_UNKNOW || CFTypes.toString(_type, null)==null);
        // required
        ExprBoolean _req = arg.getRequired();
        boolean useReq = !canHaveKey || toBoolean(_req, null) != Boolean.FALSE;
        // default-type
        Expression _def = arg.getDefaultValueType(bc.getFactory());
        boolean useDef = !canHaveKey || toInt(_def, -1) != FunctionArgument.DEFAULT_TYPE_NULL;
        // pass by reference
        ExprBoolean _pass = arg.isPassByReference();
        boolean usePass = !canHaveKey || toBoolean(_pass, null) != Boolean.TRUE;
        // display-hint
        ExprString _dsp = arg.getDisplayName();
        boolean useDsp = !canHaveKey || !isLiteralEmptyString(_dsp);
        // hint
        ExprString _hint = arg.getHint();
        boolean useHint = !canHaveKey || !isLiteralEmptyString(_hint);
        // meta
        Map _meta = arg.getMetaData();
        boolean useMeta = !canHaveKey || (_meta != null && !_meta.isEmpty());
        int functionIndex = 7;
        if (!useMeta) {
            functionIndex--;
            if (!useHint) {
                functionIndex--;
                if (!useDsp) {
                    functionIndex--;
                    if (!usePass) {
                        functionIndex--;
                        if (!useDef) {
                            functionIndex--;
                            if (!useReq) {
                                functionIndex--;
                                if (!useType) {
                                    functionIndex--;
                                }
                            }
                        }
                    }
                }
            }
        }
        // write out arguments
        ga.dup();
        ga.push(i);
        // new FunctionArgument(...)
        ga.newInstance(canHaveKey && functionIndex < INIT_FAI_KEY_LIGHT.length ? FUNCTION_ARGUMENT_LIGHT : FUNCTION_ARGUMENT_IMPL);
        ga.dup();
        // name
        bc.getFactory().registerKey(bc, arg.getName(), false);
        // type
        if (functionIndex >= INIT_FAI_KEY.length - 7) {
            _strType.writeOut(bc, Expression.MODE_REF);
            bc.getAdapter().push(_type);
        }
        // required
        if (functionIndex >= INIT_FAI_KEY.length - 6)
            _req.writeOut(bc, Expression.MODE_VALUE);
        // default value
        if (functionIndex >= INIT_FAI_KEY.length - 5)
            _def.writeOut(bc, Expression.MODE_VALUE);
        // pass by reference
        if (functionIndex >= INIT_FAI_KEY.length - 4)
            _pass.writeOut(bc, Expression.MODE_VALUE);
        // display-name
        if (functionIndex >= INIT_FAI_KEY.length - 3)
            _dsp.writeOut(bc, Expression.MODE_REF);
        // hint
        if (functionIndex >= INIT_FAI_KEY.length - 2)
            _hint.writeOut(bc, Expression.MODE_REF);
        // meta
        if (functionIndex == INIT_FAI_KEY.length - 1)
            Page.createMetaDataStruct(bc, _meta, null);
        if (functionIndex < INIT_FAI_KEY_LIGHT.length)
            ga.invokeConstructor(FUNCTION_ARGUMENT_LIGHT, INIT_FAI_KEY[functionIndex]);
        else
            ga.invokeConstructor(FUNCTION_ARGUMENT_IMPL, INIT_FAI_KEY[functionIndex]);
        ga.visitInsn(Opcodes.AASTORE);
    }
}
Also used : LitString(lucee.transformer.expression.literal.LitString) Argument(lucee.transformer.bytecode.statement.Argument) FunctionArgument(lucee.runtime.type.FunctionArgument) ExprString(lucee.transformer.expression.ExprString) Expression(lucee.transformer.expression.Expression) ExprBoolean(lucee.transformer.expression.ExprBoolean) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) HashMap(java.util.HashMap) Map(java.util.Map)

Example 3 with Argument

use of lucee.transformer.bytecode.statement.Argument in project Lucee by lucee.

the class SourceLastModifiedClassAdapter method writeOutFunctionDefaultValueInnerInner.

private void writeOutFunctionDefaultValueInnerInner(BytecodeContext bc, Function function) throws TransformerException {
    GeneratorAdapter adapter = bc.getAdapter();
    List<Argument> args = function.getArguments();
    if (args.size() == 0) {
        adapter.loadArg(DEFAULT_VALUE);
        adapter.returnValue();
        return;
    }
    Iterator<Argument> it = args.iterator();
    Argument arg;
    ConditionVisitor cv = new ConditionVisitor();
    DecisionIntVisitor div;
    cv.visitBefore();
    int count = 0;
    while (it.hasNext()) {
        arg = it.next();
        cv.visitWhenBeforeExpr();
        div = new DecisionIntVisitor();
        div.visitBegin();
        adapter.loadArg(2);
        div.visitEQ();
        adapter.push(count++);
        div.visitEnd(bc);
        cv.visitWhenAfterExprBeforeBody(bc);
        Expression defaultValue = arg.getDefaultValue();
        if (defaultValue != null) {
            /*if(defaultValue instanceof Null) {
						adapter.invokeStatic(NULL, GET_INSTANCE);
					}
					else*/
            defaultValue.writeOut(bc, Expression.MODE_REF);
        } else
            adapter.loadArg(DEFAULT_VALUE);
        // adapter.visitInsn(Opcodes.ACONST_NULL);
        adapter.returnValue();
        cv.visitWhenAfterBody(bc);
    }
    cv.visitOtherviseBeforeBody();
    // adapter.visitInsn(ACONST_NULL);
    // adapter.returnValue();
    cv.visitOtherviseAfterBody();
    cv.visitAfter(bc);
}
Also used : ConditionVisitor(lucee.transformer.bytecode.visitor.ConditionVisitor) Argument(lucee.transformer.bytecode.statement.Argument) Expression(lucee.transformer.expression.Expression) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) DecisionIntVisitor(lucee.transformer.bytecode.visitor.DecisionIntVisitor)

Example 4 with Argument

use of lucee.transformer.bytecode.statement.Argument in project Lucee by lucee.

the class AbstrCFMLScriptTransformer method lambdaPart.

@Override
protected final Function lambdaPart(ExprData data, String id, int access, int modifier, String rtnType, Position line, ArrayList<Argument> args) throws TemplateException {
    Body body = new FunctionBody(data.factory);
    Function func = new Lambda(data.root, id, access, modifier, rtnType, body, line, null);
    // new FunctionImpl(data.page,id,access,rtnType,body,line,null);
    comments(data);
    // add arguments
    for (Argument arg : args) {
        func.addArgument(arg.getName(), arg.getType(), arg.getRequired(), arg.getDefaultValue(), arg.isPassByReference(), arg.getDisplayName(), arg.getHint(), arg.getMetaData());
    }
    comments(data);
    // body
    boolean oldInsideFunction = data.insideFunction;
    data.insideFunction = true;
    try {
        if (data.srcCode.isCurrent('{')) {
            statement(data, body, CTX_FUNCTION);
        } else {
            if (data.srcCode.forwardIfCurrent("return ")) {
                comments(data);
            }
            // ex block
            short prior = data.context;
            data.context = CTX_FUNCTION;
            comments(data);
            Expression expr = expression(data);
            // checkSemiColonLineFeed( data, true ,true );
            Return rtn = new Return(expr, line, data.srcCode.getPosition());
            body.addStatement(rtn);
            data.docComment = null;
            data.context = prior;
        }
    } finally {
        data.insideFunction = oldInsideFunction;
    }
    /*try {
		// ex block
		statement(data,body,CTX_FUNCTION);
		}
		finally{
			data.insideFunction=oldInsideFunction;
		}*/
    func.setEnd(data.srcCode.getPosition());
    comments(data);
    return func;
}
Also used : Function(lucee.transformer.bytecode.statement.udf.Function) CFFunction(lucee.runtime.functions.system.CFFunction) FunctionLibFunction(lucee.transformer.library.function.FunctionLibFunction) Return(lucee.transformer.bytecode.statement.Return) Argument(lucee.transformer.bytecode.statement.Argument) FunctionAsExpression(lucee.transformer.bytecode.expression.FunctionAsExpression) Expression(lucee.transformer.expression.Expression) FunctionBody(lucee.transformer.bytecode.FunctionBody) Body(lucee.transformer.bytecode.Body) ScriptBody(lucee.transformer.bytecode.ScriptBody) FunctionBody(lucee.transformer.bytecode.FunctionBody) Lambda(lucee.transformer.bytecode.statement.udf.Lambda)

Example 5 with Argument

use of lucee.transformer.bytecode.statement.Argument in project Lucee by lucee.

the class AbstrCFMLScriptTransformer method closurePart.

@Override
protected final Function closurePart(ExprData data, String id, int access, int modifier, String rtnType, Position line, boolean closure) throws TemplateException {
    Body body = new FunctionBody(data.factory);
    Function func = closure ? new Closure(data.root, id, access, modifier, rtnType, body, line, null) : new FunctionImpl(data.root, id, access, modifier, rtnType, body, line, null);
    comments(data);
    if (!data.srcCode.forwardIfCurrent('('))
        throw new TemplateException(data.srcCode, "invalid syntax in function head, missing begin [(]");
    // arguments
    ArrayList<Argument> args = getScriptFunctionArguments(data);
    for (Argument arg : args) {
        func.addArgument(arg.getName(), arg.getType(), arg.getRequired(), arg.getDefaultValue(), arg.isPassByReference(), arg.getDisplayName(), arg.getHint(), arg.getMetaData());
    }
    // end )
    comments(data);
    if (!data.srcCode.forwardIfCurrent(')'))
        throw new TemplateException(data.srcCode, "invalid syntax in function head, missing ending [)]");
    // doc comment
    if (data.docComment != null) {
        func.setHint(data.factory, data.docComment.getHint());
        // params
        /*Map<String, Attribute> params = data.docComment.getParams();
			Iterator<Attribute> it = params.values().iterator();
			Attribute attr;
			String name;
			while(it.hasNext()){
				attr=it.next();
				name=attr.getName();
			}*/
        func.setMetaData(data.docComment.getParams());
        data.docComment = null;
    }
    comments(data);
    // attributes
    Attribute[] attrs = attributes(null, null, data, SEMI_BLOCK, data.factory.EMPTY(), Boolean.TRUE, null, false, NO_ATTR_SEP, true);
    for (int i = 0; i < attrs.length; i++) {
        func.addAttribute(attrs[i]);
    }
    // body
    boolean oldInsideFunction = data.insideFunction;
    data.insideFunction = true;
    try {
        // ex block
        statement(data, body, CTX_FUNCTION);
    } finally {
        data.insideFunction = oldInsideFunction;
    }
    func.setEnd(data.srcCode.getPosition());
    if (closure)
        comments(data);
    return func;
}
Also used : Function(lucee.transformer.bytecode.statement.udf.Function) CFFunction(lucee.runtime.functions.system.CFFunction) FunctionLibFunction(lucee.transformer.library.function.FunctionLibFunction) Closure(lucee.transformer.bytecode.statement.udf.Closure) Argument(lucee.transformer.bytecode.statement.Argument) TemplateException(lucee.runtime.exp.TemplateException) Attribute(lucee.transformer.bytecode.statement.tag.Attribute) FunctionBody(lucee.transformer.bytecode.FunctionBody) FunctionImpl(lucee.transformer.bytecode.statement.udf.FunctionImpl) Body(lucee.transformer.bytecode.Body) ScriptBody(lucee.transformer.bytecode.ScriptBody) FunctionBody(lucee.transformer.bytecode.FunctionBody)

Aggregations

Argument (lucee.transformer.bytecode.statement.Argument)5 Expression (lucee.transformer.expression.Expression)4 HashMap (java.util.HashMap)2 TemplateException (lucee.runtime.exp.TemplateException)2 CFFunction (lucee.runtime.functions.system.CFFunction)2 Body (lucee.transformer.bytecode.Body)2 FunctionBody (lucee.transformer.bytecode.FunctionBody)2 ScriptBody (lucee.transformer.bytecode.ScriptBody)2 FunctionAsExpression (lucee.transformer.bytecode.expression.FunctionAsExpression)2 Attribute (lucee.transformer.bytecode.statement.tag.Attribute)2 Function (lucee.transformer.bytecode.statement.udf.Function)2 FunctionLibFunction (lucee.transformer.library.function.FunctionLibFunction)2 GeneratorAdapter (org.objectweb.asm.commons.GeneratorAdapter)2 ArrayList (java.util.ArrayList)1 Map (java.util.Map)1 FunctionArgument (lucee.runtime.type.FunctionArgument)1 Return (lucee.transformer.bytecode.statement.Return)1 Closure (lucee.transformer.bytecode.statement.udf.Closure)1 FunctionImpl (lucee.transformer.bytecode.statement.udf.FunctionImpl)1 Lambda (lucee.transformer.bytecode.statement.udf.Lambda)1