use of lucee.transformer.TransformerException in project Lucee by lucee.
the class Function method addAttribute.
public final void addAttribute(Attribute attr) throws TemplateException {
String name = attr.getName().toLowerCase();
// name
if ("name".equals(name)) {
throw new TransformerException("name cannot be defined twice", getStart());
} else if ("returntype".equals(name)) {
this.returnType = toLitString(name, attr.getValue());
} else if ("access".equals(name)) {
LitString ls = toLitString(name, attr.getValue());
String strAccess = ls.getString();
int acc = ComponentUtil.toIntAccess(strAccess, -1);
if (acc == -1)
throw new TransformerException("invalid access type [" + strAccess + "], access types are remote, public, package, private", getStart());
access = acc;
} else if ("output".equals(name))
this.output = toLitBoolean(name, attr.getValue());
else if ("bufferoutput".equals(name))
this.bufferOutput = toLitBoolean(name, attr.getValue());
else if ("displayname".equals(name))
this.displayName = toLitString(name, attr.getValue());
else if ("hint".equals(name))
this.hint = toLitString(name, attr.getValue());
else if ("description".equals(name))
this.description = toLitString(name, attr.getValue());
else if ("returnformat".equals(name))
this.returnFormat = toLitString(name, attr.getValue());
else if ("securejson".equals(name))
this.secureJson = toLitBoolean(name, attr.getValue());
else if ("verifyclient".equals(name))
this.verifyClient = toLitBoolean(name, attr.getValue());
else if ("localmode".equals(name)) {
Expression v = attr.getValue();
if (v != null) {
String str = ASMUtil.toString(v, null);
if (!StringUtil.isEmpty(str)) {
int mode = AppListenerUtil.toLocalMode(str, -1);
if (mode != -1)
this.localMode = v.getFactory().createLitInteger(mode);
else
throw new TransformerException("Attribute localMode of the Tag Function, must be a literal value (modern, classic, true or false)", getStart());
}
}
} else if ("cachedwithin".equals(name)) {
try {
// ASMUtil.timeSpanToLong(attr.getValue());
this.cachedWithin = ASMUtil.cachedWithinValue(attr.getValue());
} catch (EvaluatorException e) {
throw new TemplateException(e.getMessage());
}
} else if ("modifier".equals(name)) {
Expression val = attr.getValue();
if (val instanceof Literal) {
Literal l = (Literal) val;
String str = StringUtil.emptyIfNull(l.getString()).trim();
if ("abstract".equalsIgnoreCase(str))
modifier = Component.MODIFIER_ABSTRACT;
else if ("final".equalsIgnoreCase(str))
modifier = Component.MODIFIER_FINAL;
}
} else {
// needed for testing
toLitString(name, attr.getValue());
if (metadata == null)
metadata = new HashMap<String, Attribute>();
metadata.put(attr.getName(), attr);
}
}
use of lucee.transformer.TransformerException in project Lucee by lucee.
the class ASMUtil method leadFlow.
public static void leadFlow(BytecodeContext bc, Statement stat, int flowType, String label) throws TransformerException {
List<FlowControlFinal> finallyLabels = new ArrayList<FlowControlFinal>();
FlowControl fc;
String name;
if (FlowControl.BREAK == flowType) {
fc = ASMUtil.getAncestorBreakFCStatement(stat, finallyLabels, label);
name = "break";
} else if (FlowControl.CONTINUE == flowType) {
fc = ASMUtil.getAncestorContinueFCStatement(stat, finallyLabels, label);
name = "continue";
} else {
fc = ASMUtil.getAncestorRetryFCStatement(stat, finallyLabels, label);
name = "retry";
}
if (fc == null)
throw new TransformerException(name + " must be inside a loop (for,while,do-while,<cfloop>,<cfwhile> ...)", stat.getStart());
GeneratorAdapter adapter = bc.getAdapter();
Label end;
if (FlowControl.BREAK == flowType)
end = ((FlowControlBreak) fc).getBreakLabel();
else if (FlowControl.CONTINUE == flowType)
end = ((FlowControlContinue) fc).getContinueLabel();
else
end = ((FlowControlRetry) fc).getRetryLabel();
// first jump to all final labels
FlowControlFinal[] arr = finallyLabels.toArray(new FlowControlFinal[finallyLabels.size()]);
if (arr.length > 0) {
FlowControlFinal fcf;
for (int i = 0; i < arr.length; i++) {
fcf = arr[i];
// first
if (i == 0) {
adapter.visitJumpInsn(Opcodes.GOTO, fcf.getFinalEntryLabel());
}
// last
if (arr.length == i + 1)
fcf.setAfterFinalGOTOLabel(end);
else
fcf.setAfterFinalGOTOLabel(arr[i + 1].getFinalEntryLabel());
}
} else
bc.getAdapter().visitJumpInsn(Opcodes.GOTO, end);
}
use of lucee.transformer.TransformerException in project Lucee by lucee.
the class Assign method _writeOut.
@Override
public Type _writeOut(BytecodeContext bc, int mode) throws TransformerException {
GeneratorAdapter adapter = bc.getAdapter();
int count = variable.getCount();
// count 0
if (count == 0) {
if (variable.ignoredFirstMember() && variable.getScope() == Scope.SCOPE_VAR) {
// print.dumpStack();
return Types.VOID;
}
return _writeOutEmpty(bc);
}
boolean doOnlyScope = variable.getScope() == Scope.SCOPE_LOCAL;
Type rtn = Types.OBJECT;
// boolean last;
for (int i = doOnlyScope ? 0 : 1; i < count; i++) {
adapter.loadArg(0);
}
rtn = _writeOutFirst(bc, (variable.getMembers().get(0)), mode, count == 1, doOnlyScope);
// pc.get(
for (int i = doOnlyScope ? 0 : 1; i < count; i++) {
Member member = (variable.getMembers().get(i));
boolean last = (i + 1) == count;
// Data Member
if (member instanceof DataMember) {
// ((DataMember)member).getName().writeOut(bc, MODE_REF);
getFactory().registerKey(bc, ((DataMember) member).getName(), false);
if (last)
writeValue(bc);
adapter.invokeVirtual(Types.PAGE_CONTEXT, last ? SET_KEY : TOUCH_KEY);
rtn = Types.OBJECT;
} else // UDF
if (member instanceof UDF) {
if (last)
throw new TransformerException("can't assign value to a user defined function", getStart());
UDF udf = (UDF) member;
getFactory().registerKey(bc, udf.getName(), false);
ExpressionUtil.writeOutExpressionArray(bc, Types.OBJECT, udf.getArguments());
adapter.invokeVirtual(Types.PAGE_CONTEXT, udf.hasNamedArgs() ? GET_FUNCTION_WITH_NAMED_ARGS_KEY : GET_FUNCTION_KEY);
rtn = Types.OBJECT;
}
}
return rtn;
}
use of lucee.transformer.TransformerException in project Lucee by lucee.
the class Call method namedArgs.
private boolean namedArgs() throws TransformerException {
if (args.isEmpty())
return false;
Iterator<Argument> it = args.iterator();
boolean named = it.next() instanceof NamedArgument;
while (it.hasNext()) {
if (named != (it.next() instanceof NamedArgument))
throw new TransformerException("You cannot mix named and unnamed arguments in function calls", getEnd());
}
return named;
}
use of lucee.transformer.TransformerException in project Lucee by lucee.
the class VT method _writeOutFirstBIF.
static Type _writeOutFirstBIF(BytecodeContext bc, BIF bif, int mode, boolean last, Position line) throws TransformerException {
double start = SystemUtil.millis();
GeneratorAdapter adapter = bc.getAdapter();
adapter.loadArg(0);
// class
ClassDefinition bifCD = bif.getClassDefinition();
Class clazz = null;
try {
clazz = bifCD.getClazz();
} catch (Exception e) {
SystemOut.printDate(e);
}
Type rtnType = Types.toType(bif.getReturnType());
if (rtnType == Types.VOID)
rtnType = Types.STRING;
// arguments
Argument[] args = bif.getArguments();
Type[] argTypes;
// MUST setting this to false need to work !!!
boolean core = bif.getFlf().isCore();
if (bif.getArgType() == FunctionLibFunction.ARG_FIX && !bifCD.isBundle() && core) {
if (isNamed(bif.getFlf().getName(), args)) {
NamedArgument[] nargs = toNamedArguments(args);
String[] names = new String[nargs.length];
// get all names
for (int i = 0; i < nargs.length; i++) {
names[i] = getName(nargs[i].getName());
}
ArrayList<FunctionLibFunctionArg> list = bif.getFlf().getArg();
Iterator<FunctionLibFunctionArg> it = list.iterator();
argTypes = new Type[list.size() + 1];
argTypes[0] = Types.PAGE_CONTEXT;
FunctionLibFunctionArg flfa;
int index = 0;
VT vt;
while (it.hasNext()) {
flfa = it.next();
vt = getMatchingValueAndType(bc.getFactory(), flfa, nargs, names, line);
if (vt.index != -1)
names[vt.index] = null;
argTypes[++index] = Types.toType(vt.type);
if (vt.value == null)
ASMConstants.NULL(bc.getAdapter());
else
vt.value.writeOut(bc, Types.isPrimitiveType(argTypes[index]) ? MODE_VALUE : MODE_REF);
}
for (int y = 0; y < names.length; y++) {
if (names[y] != null) {
TransformerException bce = new TransformerException("argument [" + names[y] + "] is not allowed for function [" + bif.getFlf().getName() + "]", args[y].getStart());
UDFUtil.addFunctionDoc(bce, bif.getFlf());
throw bce;
}
}
} else {
argTypes = new Type[args.length + 1];
argTypes[0] = Types.PAGE_CONTEXT;
for (int y = 0; y < args.length; y++) {
argTypes[y + 1] = Types.toType(args[y].getStringType());
args[y].writeOutValue(bc, Types.isPrimitiveType(argTypes[y + 1]) ? MODE_VALUE : MODE_REF);
}
// if no method exists for the exact match of arguments, call the method with all arguments (when exists)
if (methodExists(clazz, "call", argTypes, rtnType) == Boolean.FALSE) {
ArrayList<FunctionLibFunctionArg> _args = bif.getFlf().getArg();
Type[] tmp = new Type[_args.size() + 1];
// fill the existing
for (int i = 0; i < argTypes.length; i++) {
tmp[i] = argTypes[i];
}
// get the rest with default values
FunctionLibFunctionArg flfa;
VT def;
for (int i = argTypes.length; i < tmp.length; i++) {
flfa = _args.get(i - 1);
tmp[i] = Types.toType(flfa.getTypeAsString());
def = getDefaultValue(bc.getFactory(), flfa);
if (def.value != null)
def.value.writeOut(bc, Types.isPrimitiveType(tmp[i]) ? MODE_VALUE : MODE_REF);
else
ASMConstants.NULL(bc.getAdapter());
}
argTypes = tmp;
}
}
} else // Arg Type DYN or bundle based
{
// /////////////////////////////////////////////////////////////
if (bif.getArgType() == FunctionLibFunction.ARG_FIX) {
if (isNamed(bif.getFlf().getName(), args)) {
NamedArgument[] nargs = toNamedArguments(args);
String[] names = getNames(nargs);
ArrayList<FunctionLibFunctionArg> list = bif.getFlf().getArg();
Iterator<FunctionLibFunctionArg> it = list.iterator();
LinkedList<Argument> tmpArgs = new LinkedList<Argument>();
LinkedList<Boolean> nulls = new LinkedList<Boolean>();
FunctionLibFunctionArg flfa;
VT vt;
while (it.hasNext()) {
flfa = it.next();
vt = getMatchingValueAndType(bc.getFactory(), flfa, nargs, names, line);
if (vt.index != -1)
names[vt.index] = null;
if (vt.value == null)
// has to by any otherwise a caster is set
tmpArgs.add(new Argument(bif.getFactory().createNull(), "any"));
else
tmpArgs.add(new Argument(vt.value, vt.type));
nulls.add(vt.value == null);
}
for (int y = 0; y < names.length; y++) {
if (names[y] != null) {
TransformerException bce = new TransformerException("argument [" + names[y] + "] is not allowed for function [" + bif.getFlf().getName() + "]", args[y].getStart());
UDFUtil.addFunctionDoc(bce, bif.getFlf());
throw bce;
}
}
// remove null at the end
Boolean tmp;
while ((tmp = nulls.pollLast()) != null) {
if (!tmp.booleanValue())
break;
tmpArgs.pollLast();
}
args = tmpArgs.toArray(new Argument[tmpArgs.size()]);
}
}
// /////////////////////////////////////////////////////////////
argTypes = new Type[2];
argTypes[0] = Types.PAGE_CONTEXT;
argTypes[1] = Types.OBJECT_ARRAY;
ExpressionUtil.writeOutExpressionArray(bc, Types.OBJECT, args);
}
// core
if (core && !bifCD.isBundle()) {
adapter.invokeStatic(Type.getType(clazz), new Method("call", rtnType, argTypes));
} else // external
{
// className
if (bifCD.getClassName() != null)
adapter.push(bifCD.getClassName());
else
ASMConstants.NULL(adapter);
if (// bundle name
bifCD.getName() != null)
// bundle name
adapter.push(bifCD.getName());
else
ASMConstants.NULL(adapter);
if (// bundle version
bifCD.getVersionAsString() != null)
// bundle version
adapter.push(bifCD.getVersionAsString());
else
ASMConstants.NULL(adapter);
adapter.invokeStatic(Types.FUNCTION_HANDLER_POOL, INVOKE);
rtnType = Types.OBJECT;
}
if (mode == MODE_REF || !last) {
if (Types.isPrimitiveType(rtnType)) {
adapter.invokeStatic(Types.CASTER, new Method("toRef", Types.toRefType(rtnType), new Type[] { rtnType }));
rtnType = Types.toRefType(rtnType);
}
}
return rtnType;
}
Aggregations