use of lucee.runtime.type.FunctionValue in project Lucee by lucee.
the class CFFunction method call.
// private static Map udfs=new ReferenceMap();
public static Object call(PageContext pc, Object[] objArr) throws PageException {
if (objArr.length < 3)
throw new ExpressionException("invalid call of a CFML Based built in function");
// translate arguments
String filename = Caster.toString((((FunctionValue) objArr[0]).getValue()));
Collection.Key name = KeyImpl.toKey((((FunctionValue) objArr[1]).getValue()));
boolean isweb = Caster.toBooleanValue((((FunctionValue) objArr[2]).getValue()));
UDF udf = loadUDF(pc, filename, name, isweb);
Struct meta = udf.getMetaData(pc);
boolean callerScopes = (meta == null) ? false : Caster.toBooleanValue(meta.get("callerScopes", Boolean.FALSE), false);
boolean caller = meta == null ? false : Caster.toBooleanValue(meta.get(KeyConstants._caller, Boolean.FALSE), false);
Struct namedArguments = null, cs = null;
if (callerScopes) {
cs = new StructImpl();
if (pc.undefinedScope().getCheckArguments()) {
cs.set(KeyConstants._local, pc.localScope().duplicate(false));
cs.set(KeyConstants._arguments, pc.argumentsScope().duplicate(false));
}
}
Object[] arguments = null;
if (objArr.length <= 3)
arguments = ArrayUtil.OBJECT_EMPTY;
else if (objArr[3] instanceof FunctionValue) {
FunctionValue fv;
namedArguments = new StructImpl(Struct.TYPE_LINKED);
if (callerScopes)
namedArguments.setEL(KeyConstants._caller, cs);
else if (caller)
namedArguments.setEL(KeyConstants._caller, Duplicator.duplicate(pc.undefinedScope(), false));
for (int i = 3; i < objArr.length; i++) {
fv = toFunctionValue(name, objArr[i]);
namedArguments.set(fv.getName(), fv.getValue());
}
} else {
int offset = (caller || callerScopes ? 2 : 3);
arguments = new Object[objArr.length - offset];
if (callerScopes)
arguments[0] = cs;
else if (caller)
arguments[0] = Duplicator.duplicate(pc.undefinedScope(), false);
for (int i = 3; i < objArr.length; i++) {
arguments[i - offset] = toObject(name, objArr[i]);
}
}
// execute UDF
if (namedArguments == null) {
return ((UDFImpl) udf).call(pc, name, arguments, false);
}
return ((UDFImpl) udf).callWithNamedValues(pc, name, namedArguments, false);
}
use of lucee.runtime.type.FunctionValue in project Lucee by lucee.
the class VT method isNamed.
private boolean isNamed(PageContext pc, Ref[] refArgs) throws PageException {
if (ArrayUtil.isEmpty(refArgs))
return false;
Casting cast;
int count = 0;
for (int i = 0; i < refArgs.length; i++) {
if (refArgs[i] instanceof Casting) {
cast = (Casting) refArgs[i];
if (cast.getRef() instanceof LFunctionValue && ((LFunctionValue) cast.getRef()).getValue(pc) instanceof FunctionValue) {
count++;
}
}
}
if (count != 0 && count != refArgs.length) {
ExpressionException ee = new InterpreterException("invalid argument for function " + flf.getName() + ", you can not mix named and unnamed arguments");
UDFUtil.addFunctionDoc(ee, flf);
throw ee;
}
return count != 0;
}
use of lucee.runtime.type.FunctionValue in project Lucee by lucee.
the class VT method getValue.
@Override
public Object getValue(PageContext pc) throws PageException {
Object[] arguments = null;
if (isDynamic()) {
arguments = RefUtil.getValue(pc, refArgs);
if (flf.hasDefaultValues()) {
List<Object> tmp = new ArrayList<Object>();
ArrayList<FunctionLibFunctionArg> args = flf.getArg();
Iterator<FunctionLibFunctionArg> it = args.iterator();
FunctionLibFunctionArg arg;
while (it.hasNext()) {
arg = it.next();
if (arg.getDefaultValue() != null)
tmp.add(new FunctionValueImpl(arg.getName(), arg.getDefaultValue()));
}
for (int i = 0; i < arguments.length; i++) {
tmp.add(arguments[i]);
}
arguments = tmp.toArray();
}
arguments = new Object[] { arguments };
} else {
if (isNamed(pc, refArgs)) {
FunctionValue[] fvalues = getFunctionValues(pc, refArgs);
String[] names = getNames(fvalues);
ArrayList<FunctionLibFunctionArg> list = flf.getArg();
Iterator<FunctionLibFunctionArg> it = list.iterator();
arguments = new Object[list.size()];
FunctionLibFunctionArg flfa;
int index = 0;
VT vt;
while (it.hasNext()) {
flfa = it.next();
vt = getMatchingValueAndType(flfa, fvalues, names);
if (vt.index != -1)
names[vt.index] = null;
arguments[index++] = new Casting(vt.type, CFTypes.toShort(vt.type, false, CFTypes.TYPE_UNKNOW), vt.value).getValue(pc);
}
for (int y = 0; y < names.length; y++) {
if (names[y] != null) {
ExpressionException ee = new InterpreterException("argument [" + names[y] + "] is not allowed for function [" + flf.getName() + "]");
UDFUtil.addFunctionDoc(ee, flf);
throw ee;
}
}
} else {
arguments = RefUtil.getValue(pc, refArgs);
}
}
BIF bif = flf.getBIF();
if (flf.getMemberChaining() && obj != null) {
bif.invoke(pc, arguments);
return obj;
}
if (!isDynamic() && flf.getArgMin() > arguments.length) {
throw new FunctionException(pc, flf.getName(), flf.getArgMin(), flf.getArgMax(), arguments.length);
}
return Caster.castTo(pc, flf.getReturnTypeAsString(), bif.invoke(pc, arguments), false);
}
use of lucee.runtime.type.FunctionValue in project Lucee by lucee.
the class Struct_ method _call.
protected static Struct _call(Object[] objArr, String expMessage, int type) throws PageException {
StructImpl sct = type < 0 ? new StructImpl() : new StructImpl(type);
FunctionValueImpl fv;
for (int i = 0; i < objArr.length; i++) {
if (objArr[i] instanceof FunctionValue) {
fv = ((FunctionValueImpl) objArr[i]);
if (fv.getNames() == null) {
sct.set(fv.getNameAsKey(), fv.getValue());
} else {
String[] arr = fv.getNames();
Struct s = sct;
for (int y = 0; y < arr.length - 1; y++) {
s = touch(s, arr[y]);
}
s.set(KeyImpl.init(arr[arr.length - 1]), fv.getValue());
}
} else {
throw new ExpressionException(expMessage);
}
}
return sct;
}
use of lucee.runtime.type.FunctionValue in project Lucee by lucee.
the class Caster method toFunctionValues.
public static Object[] toFunctionValues(Struct args) {
// TODO nicht sehr optimal
Iterator<Entry<Key, Object>> it = args.entryIterator();
Entry<Key, Object> e;
List<FunctionValue> fvalues = new ArrayList<FunctionValue>();
while (it.hasNext()) {
e = it.next();
fvalues.add(new FunctionValueImpl(e.getKey().getString(), e.getValue()));
}
return fvalues.toArray(new FunctionValue[fvalues.size()]);
}
Aggregations