use of lucee.transformer.library.function.FunctionLibFunction in project Lucee by lucee.
the class ConfigImpl method createFunction.
public void createFunction(FunctionLib fl, String filename) {
// filename.substring(0,filename.length()-(getCFMLExtensions().length()+1));
String name = toName(filename);
FunctionLibFunction flf = new FunctionLibFunction(fl, true);
flf.setArgType(FunctionLibFunction.ARG_DYNAMIC);
flf.setFunctionClass("lucee.runtime.functions.system.CFFunction", null, null);
flf.setName(name);
flf.setReturn("object");
FunctionLibFunctionArg arg = new FunctionLibFunctionArg(flf);
arg.setName("__filename");
arg.setRequired(true);
arg.setType("string");
arg.setHidden(true);
arg.setDefaultValue(filename);
flf.setArg(arg);
arg = new FunctionLibFunctionArg(flf);
arg.setName("__name");
arg.setRequired(true);
arg.setHidden(true);
arg.setType("string");
arg.setDefaultValue(name);
flf.setArg(arg);
arg = new FunctionLibFunctionArg(flf);
arg.setName("__isweb");
arg.setRequired(true);
arg.setHidden(true);
arg.setType("boolean");
arg.setDefaultValue(this instanceof ConfigWeb ? "true" : "false");
flf.setArg(arg);
fl.setFunction(flf);
}
use of lucee.transformer.library.function.FunctionLibFunction in project Lucee by lucee.
the class Function method checkFunctionName.
public static void checkFunctionName(String name, FunctionLib[] flibs, PageSource ps) throws EvaluatorException {
FunctionLibFunction flf;
for (int i = 0; i < flibs.length; i++) {
flf = flibs[i].getFunction(name);
if (flf != null && flf.getFunctionClassDefinition().getClazz(null) != CFFunction.class) {
String path = null;
if (ps != null) {
path = ps.getDisplayPath();
path = path.replace('\\', '/');
}
if (// TODO make better
path == null || path.indexOf("/library/function/") == -1)
throw new EvaluatorException("The name [" + name + "] is already used by a built in Function");
}
}
}
use of lucee.transformer.library.function.FunctionLibFunction in project Lucee by lucee.
the class MemberUtil method getMembers.
public static Map<Collection.Key, FunctionLibFunction> getMembers(PageContext pc, short type) {
Map<Short, Map<Key, FunctionLibFunction>> matches = pc.getCurrentTemplateDialect() == CFMLEngine.DIALECT_LUCEE ? matchesLucee : matchesCFML;
Map<Key, FunctionLibFunction> match = matches.get(type);
if (match != null)
return match;
FunctionLib[] flds = ((ConfigWebImpl) pc.getConfig()).getFLDs(pc.getCurrentTemplateDialect());
Iterator<FunctionLibFunction> it;
FunctionLibFunction f;
match = new HashMap<Collection.Key, FunctionLibFunction>();
String[] names;
for (int i = 0; i < flds.length; i++) {
it = flds[i].getFunctions().values().iterator();
while (it.hasNext()) {
f = it.next();
names = f.getMemberNames();
if (!ArrayUtil.isEmpty(names) && f.getMemberType() == type && f.getArgType() == FunctionLibFunction.ARG_FIX) {
for (int y = 0; y < names.length; y++) match.put(KeyImpl.getInstance(names[y]), f);
}
}
}
matches.put(type, match);
return match;
}
use of lucee.transformer.library.function.FunctionLibFunction in project Lucee by lucee.
the class MemberUtil method call.
public static Object call(PageContext pc, Object coll, Collection.Key methodName, Object[] args, short[] types, String[] strTypes) throws PageException {
// look for members
short type;
String strType;
Map<Key, FunctionLibFunction> members = null;
for (int i = 0; i < types.length; i++) {
type = types[i];
strType = strTypes[i];
members = getMembers(pc, type);
FunctionLibFunction member = members.get(methodName);
if (member != null) {
List<FunctionLibFunctionArg> _args = member.getArg();
if (args.length < _args.size()) {
ArrayList<Ref> refs = new ArrayList<Ref>();
int pos = member.getMemberPosition();
FunctionLibFunctionArg flfa;
Iterator<FunctionLibFunctionArg> it = _args.iterator();
int glbIndex = 0, argIndex = -1;
while (it.hasNext()) {
glbIndex++;
flfa = it.next();
if (glbIndex == pos) {
refs.add(new Casting(strType, type, coll));
} else if (args.length > ++argIndex) {
// careful, argIndex is only incremented when condition above is false
refs.add(new Casting(flfa.getTypeAsString(), flfa.getType(), args[argIndex]));
}
}
return new BIFCall(coll, member, refs.toArray(new Ref[refs.size()])).getValue(pc);
}
}
}
// do reflection
if (pc.getConfig().getSecurityManager().getAccess(lucee.runtime.security.SecurityManager.TYPE_DIRECT_JAVA_ACCESS) == lucee.runtime.security.SecurityManager.VALUE_YES) {
if (!(coll instanceof Undefined)) {
Object res = callMethod(coll, methodName, args);
if (res != DEFAULT)
return res;
}
}
// merge
if (types.length > 1) {
Map<Key, FunctionLibFunction> tmp;
members = null;
for (int i = 0; i < types.length; i++) {
tmp = getMembers(pc, types[i]);
if (members == null)
members = tmp;
else {
Iterator<Entry<Key, FunctionLibFunction>> it = tmp.entrySet().iterator();
Entry<Key, FunctionLibFunction> e;
while (it.hasNext()) {
e = it.next();
members.put(e.getKey(), e.getValue());
}
}
}
}
Set<Key> set = members.keySet();
String msg = ExceptionUtil.similarKeyMessage(set.toArray(new Key[set.size()]), methodName.getString(), "function", "functions", "Object", true);
throw new ExpressionException(msg);
// throw new ExpressionException("No matching function member ["+methodName+"] found, available function members are ["+
// lucee.runtime.type.util.ListUtil.sort(CollectionUtil.getKeyList(members.keySet().iterator(), ","),"textnocase","asc",",")+"]");
}
use of lucee.transformer.library.function.FunctionLibFunction 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;
}
Aggregations