use of lucee.transformer.bytecode.expression.var.UDF in project Lucee by lucee.
the class AbstrCFMLExprTransformer method getFunctionMember.
/**
* Liest die Argumente eines Funktonsaufruf ein und prueft ob die Funktion
* innerhalb der FLD (Function Library Descriptor) definiert ist.
* Falls sie existiert wird die Funktion gegen diese geprueft und ein build-in-function CFXD Element generiert,
* ansonsten ein normales funcion-call Element.
* <br />
* EBNF:<br />
* <code>[impOp{"," impOp}];</code>
* @param name Identifier der Funktion als Zeichenkette
* @param checkLibrary Soll geprueft werden ob die Funktion innerhalb der Library existiert.
* @return CFXD Element
* @throws TemplateException
*/
private FunctionMember getFunctionMember(ExprData data, final ExprString name, boolean checkLibrary) throws TemplateException {
// get Function Library
checkLibrary = checkLibrary && data.flibs != null;
FunctionLibFunction flf = null;
if (checkLibrary) {
if (!(name instanceof Literal))
// should never happen!
throw new TemplateException(data.srcCode, "syntax error");
for (int i = 0; i < data.flibs.length; i++) {
flf = data.flibs[i].getFunction(((Literal) name).getString());
if (flf != null)
break;
}
if (flf == null) {
checkLibrary = false;
}
}
FunctionMember fm = null;
while (true) {
int pos = data.srcCode.getPos();
// Element Function
if (checkLibrary) {
BIF bif = new BIF(data.factory, data.settings, flf);
// TODO data.ep.add(flf, bif, data.srcCode);
bif.setArgType(flf.getArgType());
try {
bif.setClassDefinition(flf.getFunctionClassDefinition());
} catch (Throwable t) {
ExceptionUtil.rethrowIfNecessary(t);
throw new PageRuntimeException(t);
}
bif.setReturnType(flf.getReturnTypeAsString());
fm = bif;
if (flf.getArgType() == FunctionLibFunction.ARG_DYNAMIC && flf.hasDefaultValues()) {
ArrayList<FunctionLibFunctionArg> args = flf.getArg();
Iterator<FunctionLibFunctionArg> it = args.iterator();
FunctionLibFunctionArg arg;
while (it.hasNext()) {
arg = it.next();
if (arg.getDefaultValue() != null)
bif.addArgument(new NamedArgument(data.factory.createLitString(arg.getName()), data.factory.createLitString(arg.getDefaultValue()), arg.getTypeAsString(), false));
}
}
} else {
fm = new UDF(name);
}
int count = getFunctionMemberAttrs(data, name, checkLibrary, fm, flf);
if (checkLibrary) {
// pre
if (flf.hasTteClass()) {
FunctionLibFunction tmp = flf.getEvaluator().pre((BIF) fm, flf);
if (tmp != null && tmp != flf) {
flf = tmp;
data.srcCode.setPos(pos);
continue;
}
}
// check max attributes
{
boolean isDynamic = flf.getArgType() == FunctionLibFunction.ARG_DYNAMIC;
int max = flf.getArgMax();
// Dynamic
if (isDynamic) {
if (max != -1 && max < fm.getArguments().length)
throw new TemplateException(data.srcCode, "too many Attributes (" + max + ":" + fm.getArguments().length + ") in function [ " + ASMUtil.display(name) + " ]");
} else // Fix
{
if (flf.getArg().size() < fm.getArguments().length) {
TemplateException te = new TemplateException(data.srcCode, "too many Attributes (" + flf.getArg().size() + ":" + fm.getArguments().length + ") in function call [" + ASMUtil.display(name) + "]");
UDFUtil.addFunctionDoc(te, flf);
throw te;
}
}
}
// check min attributes
if (flf.getArgMin() > count) {
TemplateException te = new TemplateException(data.srcCode, "too few attributes in function [" + ASMUtil.display(name) + "]");
if (flf.getArgType() == FunctionLibFunction.ARG_FIX)
UDFUtil.addFunctionDoc(te, flf);
throw te;
}
// evaluator
if (flf.hasTteClass()) {
flf.getEvaluator().execute((BIF) fm, flf);
}
}
comments(data);
if (checkLibrary)
data.ep.add(flf, (BIF) fm, data.srcCode);
break;
}
return fm;
}
use of lucee.transformer.bytecode.expression.var.UDF in project Lucee by lucee.
the class ExpressionInvoker method _writeOut.
@Override
public Type _writeOut(BytecodeContext bc, int mode) throws TransformerException {
GeneratorAdapter adapter = bc.getAdapter();
Type rtn = Types.OBJECT;
int count = members.size();
for (int i = 0; i < count; i++) {
adapter.loadArg(0);
}
expr.writeOut(bc, Expression.MODE_REF);
for (int i = 0; i < count; i++) {
Member member = members.get(i);
// Data Member
if (member instanceof DataMember) {
((DataMember) member).getName().writeOut(bc, MODE_REF);
adapter.invokeVirtual(Types.PAGE_CONTEXT, ((i + 1) == count) ? GET : GET_COLLECTION);
rtn = Types.OBJECT;
} else // UDF
if (member instanceof UDF) {
UDF udf = (UDF) member;
udf.getName().writeOut(bc, MODE_REF);
ExpressionUtil.writeOutExpressionArray(bc, Types.OBJECT, udf.getArguments());
adapter.invokeVirtual(Types.PAGE_CONTEXT, udf.hasNamedArgs() ? GET_FUNCTION_WITH_NAMED_ARGS : GET_FUNCTION);
rtn = Types.OBJECT;
}
}
return rtn;
}
use of lucee.transformer.bytecode.expression.var.UDF in project Lucee by lucee.
the class Query method translateChildren.
private void translateChildren(Iterator it) {
Statement stat;
while (it.hasNext()) {
stat = (Statement) it.next();
if (stat instanceof PrintOut) {
PrintOut printOut = ((PrintOut) stat);
Expression e = printOut.getExpr();
if (!(e instanceof Literal)) {
Expression expr = removeCastString(e);
if (expr instanceof Variable) {
// do not preserve BIF PreserveSingleQuotes return value
Member member = ((Variable) expr).getFirstMember();
if (member instanceof BIF) {
BIF bif = (BIF) member;
if (bif.getClassDefinition().getClassName().equals(PreserveSingleQuotes.class.getName())) {
printOut.setExpr(bif.getArguments()[0].getValue());
continue;
} else if (bif.getClassDefinition().getClassName().equals(ListQualify.class.getName())) {
Argument[] args = bif.getArguments();
List<Argument> arr = new ArrayList<Argument>();
// first get existing arguments
arr.add(args[0]);
arr.add(args[1]);
if (args.length >= 3)
arr.add(args[2]);
else
arr.add(new Argument(expr.getFactory().createLitString(","), "string"));
if (args.length >= 4)
arr.add(args[3]);
else
arr.add(new Argument(expr.getFactory().createLitString("all"), "string"));
if (args.length >= 5)
arr.add(args[4]);
else
arr.add(new Argument(expr.getFactory().createLitBoolean(false), "boolean"));
// PSQ-BIF DO NOT REMOVE THIS COMMENT
arr.add(new Argument(expr.getFactory().createLitBoolean(true), "boolean"));
bif.setArguments(arr.toArray(new Argument[arr.size()]));
continue;
} else if (bif.getClassDefinition().getClassName().equals(QuotedValueList.class.getName()) || bif.getClassDefinition().getClassName().equals(ValueList.class.getName())) {
// printOut.setPreserveSingleQuote(false);
continue;
}
}
// do not preserve UDF return value
member = ((Variable) expr).getLastMember();
if (member instanceof UDF)
continue;
}
printOut.setCheckPSQ(true);
if (e != expr)
printOut.setExpr(expr);
}
} else if (stat instanceof Tag) {
Body b = ((Tag) stat).getBody();
if (b != null)
translateChildren(b.getStatements().iterator());
} else if (stat instanceof Body) {
translateChildren(((Body) stat).getStatements().iterator());
}
}
}
Aggregations