use of lucee.transformer.bytecode.statement.tag.Attribute in project Lucee by lucee.
the class Output method evaluate.
@Override
public void evaluate(Tag tag, TagLibTag libTag, FunctionLib[] flibs) throws EvaluatorException {
TagOutput output = (TagOutput) tag;
// check if inside a query tag
TagOutput parent = output;
// encodeFor
Attribute encodeFor = tag.getAttribute("encodefor");
if (encodeFor != null) {
Expression encodeForValue = CastString.toExprString(encodeFor.getValue());
if (encodeForValue instanceof Literal) {
Literal l = (Literal) encodeForValue;
short df = (short) -1;
short encType = ESAPIEncode.toEncodeType(l.getString(), df);
if (encType != df)
encodeForValue = encodeForValue.getFactory().createLitInteger(encType);
}
addEncodeToChildren(tag.getBody().getStatements().iterator(), encodeForValue, getEncodeForFunction(flibs));
}
// query
boolean hasParentWithGroup = false;
boolean hasParentWithQuery = false;
boolean hasQuery = tag.containsAttribute("query");
while ((parent = getParentTagOutput(parent)) != null) {
if (!hasParentWithQuery)
hasParentWithQuery = parent.hasQuery();
if (!hasParentWithGroup)
hasParentWithGroup = parent.hasGroup();
if (hasParentWithQuery && hasParentWithGroup)
break;
}
if (hasQuery && hasParentWithQuery)
throw new EvaluatorException("Nesting of tags cfoutput with attribute query is not allowed");
if (hasQuery)
output.setType(TagOutput.TYPE_QUERY);
else if (tag.containsAttribute("group") && hasParentWithQuery)
output.setType(TagOutput.TYPE_GROUP);
else if (hasParentWithQuery) {
if (hasParentWithGroup)
output.setType(TagOutput.TYPE_INNER_GROUP);
else
output.setType(TagOutput.TYPE_INNER_QUERY);
} else
output.setType(TagOutput.TYPE_NORMAL);
// attribute maxrows and endrow not allowd at the same time
if (tag.containsAttribute("maxrows") && tag.containsAttribute("endrow"))
throw new EvaluatorException("Wrong Context, you cannot use attribute maxrows and endrow at the same time.");
}
use of lucee.transformer.bytecode.statement.tag.Attribute 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.bytecode.statement.tag.Attribute in project Lucee by lucee.
the class SourceLastModifiedClassAdapter method writeOutNewInterface.
private void writeOutNewInterface(ConstrBytecodeContext constr, List<LitString> keys, ClassWriter cw, Tag interf, String name) throws TransformerException {
GeneratorAdapter adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, NEW_INTERFACE_IMPL_INSTANCE, null, new Type[] { Types.PAGE_EXCEPTION }, cw);
BytecodeContext bc = new BytecodeContext(null, constr, this, keys, cw, name, adapter, NEW_INTERFACE_IMPL_INSTANCE, writeLog(), suppressWSbeforeArg, output, returnValue);
Label methodBegin = new Label();
Label methodEnd = new Label();
adapter.visitLocalVariable("this", "L" + name + ";", null, methodBegin, methodEnd, 0);
ExpressionUtil.visitLine(bc, interf.getStart());
adapter.visitLabel(methodBegin);
// ExpressionUtil.visitLine(adapter, interf.getStartLine());
int comp = adapter.newLocal(Types.INTERFACE_IMPL);
adapter.newInstance(Types.INTERFACE_IMPL);
adapter.dup();
// PageContext
adapter.visitVarInsn(Opcodes.ALOAD, 1);
// Interface Page
adapter.visitVarInsn(Opcodes.ALOAD, 0);
adapter.checkCast(Types.INTERFACE_PAGE_IMPL);
// extened
Attribute attr = interf.removeAttribute("extends");
if (attr != null)
ExpressionUtil.writeOutSilent(attr.getValue(), bc, Expression.MODE_REF);
else
adapter.push("");
// hint
attr = interf.removeAttribute("hint");
if (attr != null)
ExpressionUtil.writeOutSilent(attr.getValue(), bc, Expression.MODE_REF);
else
adapter.push("");
// dspName
attr = interf.removeAttribute("displayname");
if (attr == null)
attr = interf.getAttribute("display");
if (attr != null)
ExpressionUtil.writeOutSilent(attr.getValue(), bc, Expression.MODE_REF);
else
adapter.push("");
// callpath
adapter.visitVarInsn(Opcodes.ALOAD, 2);
// relpath
adapter.visitVarInsn(Opcodes.ILOAD, 3);
// interface udfs
// adapter.visitVarInsn(Opcodes.ALOAD, 3);
createMetaDataStruct(bc, interf.getAttributes(), interf.getMetaData());
adapter.invokeConstructor(Types.INTERFACE_IMPL, CONSTR_INTERFACE_IMPL8);
adapter.storeLocal(comp);
// initInterface(pc,c);
adapter.visitVarInsn(Opcodes.ALOAD, 0);
// adapter.loadArg(0);
adapter.loadLocal(comp);
adapter.invokeVirtual(Types.INTERFACE_PAGE_IMPL, INIT_INTERFACE);
adapter.visitLabel(methodEnd);
// return interface;
adapter.loadLocal(comp);
adapter.returnValue();
// ExpressionUtil.visitLine(adapter, interf.getEndLine());
adapter.endMethod();
}
use of lucee.transformer.bytecode.statement.tag.Attribute in project Lucee by lucee.
the class CFMLTransformer method attributes.
/**
* Liest die Attribute eines Tags ein, dies Abhaengig von der Definition innerhalb der Tag-Lib.
* Hierbei unterscheiden wir vier verschiedene Arten von Attributen:<br>
* <ul>
* <li>FIX: Definierte Attribute Fix, fuer jedes Attribut ist definiert ob es required ist oder nicht (gleich wie JSP). </li>
* <li>DYNAMIC: Die Attribute des Tag sind frei, keine Namen sind vorgegeben.
* Es kann aber definiert sein wieviele Attribute maximal und minimal verwendetet werden duerfen.</li>
* <li>FULLDYNAMIC: Gleich wie DYNAMIC, jedoch kann der Name des Attribut auch ein dynamischer Wert sein (wie bei cfset).</li>
* <li>NONAME: Ein Tag welches nur ein Attribut besitzt ohne Name, sondern einfach nur mit einem Attribut Wert</li>
* </ul>
* <br />
* EBNF:<br />
* <code>({spaces attribute} "/>" | {spaces attribute} ">") | attribute-value;(* Welcher Teil der "oder" Bedingung ausgefuehrt wird, ist abhaengig von der Tag Attribute Definition in der Tag Lib. *)</code>
* @param tag
* @param parent
* @throws TemplateException
*/
public static void attributes(TagData data, TagLibTag tag, Tag parent) throws TemplateException {
int type = tag.getAttributeType();
int start = data.srcCode.getPos();
// Tag with attribute names
if (type != TagLibTag.ATTRIBUTE_TYPE_NONAME) {
try {
int min = tag.getMin();
int max = tag.getMax();
int count = 0;
ArrayList<String> args = new ArrayList<String>();
RefBoolean allowDefaultValue = new RefBooleanImpl(tag.getDefaultAttribute() != null);
while (data.srcCode.isValidIndex()) {
data.srcCode.removeSpace();
// if no more attributes break
if (data.srcCode.isCurrent('/') || data.srcCode.isCurrent('>'))
break;
parent.addAttribute(attribute(data, tag, args, allowDefaultValue));
count++;
}
// set default values
if (tag.hasDefaultValue()) {
Map<String, TagLibTagAttr> hash = tag.getAttributes();
Iterator<Entry<String, TagLibTagAttr>> it = hash.entrySet().iterator();
Entry<String, TagLibTagAttr> e;
TagLibTagAttr att;
while (it.hasNext()) {
e = it.next();
att = e.getValue();
if (!parent.containsAttribute(att.getName()) && att.hasDefaultValue()) {
Attribute attr = new Attribute(tag.getAttributeType() == TagLibTag.ATTRIBUTE_TYPE_DYNAMIC, att.getName(), CastOther.toExpression(data.factory.createLitString(Caster.toString(att.getDefaultValue(), null)), att.getType()), att.getType());
attr.setDefaultAttribute(true);
parent.addAttribute(attr);
}
}
}
boolean hasAttributeCollection = args.contains("attributecollection");
// to less attributes
if (!hasAttributeCollection && min > count)
throw createTemplateException(data.srcCode, "the tag " + tag.getFullName() + " must have at least " + min + " attributes", tag);
// too much attributes
if (!hasAttributeCollection && max > 0 && max < count)
throw createTemplateException(data.srcCode, "the tag " + tag.getFullName() + " can have a maximum of " + max + " attributes", tag);
// not defined attributes
if (type == TagLibTag.ATTRIBUTE_TYPE_FIXED || type == TagLibTag.ATTRIBUTE_TYPE_MIXED) {
// Map<String, TagLibTagAttr> hash = tag.getAttributes();
Iterator<TagLibTagAttr> it = tag.getAttributes().values().iterator();
while (it.hasNext()) {
TagLibTagAttr att = it.next();
if (att.isRequired() && !contains(args, att) && att.getDefaultValue() == null) {
if (!hasAttributeCollection)
throw createTemplateException(data.srcCode, "attribute " + att.getName() + " is required for tag " + tag.getFullName(), tag);
parent.addMissingAttribute(att);
}
}
}
} catch (TemplateException te) {
data.srcCode.setPos(start);
// if the tag supports a non name attribute try this
TagLibTagAttr sa = tag.getSingleAttr();
if (sa != null)
attrNoName(parent, tag, data, sa);
else
throw te;
}
} else // tag without attributes name
{
attrNoName(parent, tag, data, null);
}
}
use of lucee.transformer.bytecode.statement.tag.Attribute in project Lucee by lucee.
the class AbstrCFMLScriptTransformer method _paramStatement.
private Tag _paramStatement(ExprData data, Body parent) throws TemplateException {
if (!data.srcCode.forwardIfCurrent("param "))
return null;
Position line = data.srcCode.getPosition();
TagLibTag tlt = CFMLTransformer.getTLT(data.srcCode, "param", data.config.getIdentification());
TagParam param = new TagParam(data.factory, line, null);
// type
boolean hasType = false;
boolean hasName = false;
int pos = data.srcCode.getPos();
// first 2 arguments can be type/name directly
String tmp = variableDec(data, true);
do {
if (!StringUtil.isEmpty(tmp)) {
TagLibTagAttr attr = tlt.getAttribute(tmp.toLowerCase(), true);
// name is not a defined attribute
if (attr == null) {
comments(data);
// it could be a name followed by default value
if (data.srcCode.forwardIfCurrent('=')) {
comments(data);
Expression v = attributeValue(data, true);
param.addAttribute(new Attribute(false, "name", data.factory.createLitString(tmp), "string"));
param.addAttribute(new Attribute(false, "default", v, "string"));
hasName = true;
// if we had a value this was already name
break;
}
// can be type or name
int pos2 = data.srcCode.getPos();
// first could be type, followed by name
comments(data);
String tmp2 = variableDec(data, true);
if (!StringUtil.isEmpty(tmp2)) {
attr = tlt.getAttribute(tmp2.toLowerCase(), true);
if (attr == null) {
param.addAttribute(new Attribute(false, "name", data.factory.createLitString(tmp2), "string"));
param.addAttribute(new Attribute(false, "type", data.factory.createLitString(tmp), "string"));
if (data.srcCode.forwardIfCurrent('=')) {
Expression v = attributeValue(data, true);
param.addAttribute(new Attribute(false, "default", v, "string"));
}
hasName = true;
hasType = true;
break;
}
}
param.addAttribute(new Attribute(false, "name", data.factory.createLitString(tmp), "string"));
data.srcCode.setPos(pos2);
hasName = true;
} else
data.srcCode.setPos(pos);
} else
data.srcCode.setPos(pos);
} while (false);
// folgend wird tlt extra nicht uebergeben, sonst findet pruefung statt
Attribute[] attrs = attributes(param, tlt, data, SEMI, data.factory.NULL(), Boolean.TRUE, "name", true, ',', false);
checkSemiColonLineFeed(data, true, true, true);
param.setTagLibTag(tlt);
param.setScriptBase(true);
Attribute attr;
// first fill all regular attribute -> name="value"
boolean hasDynamic = false;
for (int i = attrs.length - 1; i >= 0; i--) {
attr = attrs[i];
if (!attr.getValue().equals(data.factory.NULL())) {
if (attr.getName().equalsIgnoreCase("name")) {
hasName = true;
param.addAttribute(attr);
} else if (attr.getName().equalsIgnoreCase("type")) {
hasType = true;
param.addAttribute(attr);
} else if (attr.isDynamicType()) {
hasName = true;
if (hasDynamic)
throw attrNotSupported(data.srcCode, tlt, attr.getName());
hasDynamic = true;
param.addAttribute(new Attribute(false, "name", data.factory.createLitString(attr.getName()), "string"));
param.addAttribute(new Attribute(false, "default", attr.getValue(), "any"));
} else
param.addAttribute(attr);
}
}
// now fill name named attributes -> attr1 attr2
String first = null, second = null;
for (int i = 0; i < attrs.length; i++) {
attr = attrs[i];
if (attr.getValue().equals(data.factory.NULL())) {
// type
if (first == null && (!hasName || !hasType)) {
first = attr.getName();
} else // name
if (second == null && !hasName && !hasType) {
second = attr.getName();
} else // attr with no value
{
attr = new Attribute(true, attr.getName(), data.factory.EMPTY(), "string");
param.addAttribute(attr);
}
}
}
if (first != null) {
if (second != null) {
hasName = true;
hasType = true;
if (hasDynamic)
throw attrNotSupported(data.srcCode, tlt, first);
hasDynamic = true;
param.addAttribute(new Attribute(false, "name", data.factory.createLitString(second), "string"));
param.addAttribute(new Attribute(false, "type", data.factory.createLitString(first), "string"));
} else {
param.addAttribute(new Attribute(false, hasName ? "type" : "name", data.factory.createLitString(first), "string"));
hasName = true;
}
}
if (!hasName)
throw new TemplateException(data.srcCode, "missing name declaration for param");
param.setEnd(data.srcCode.getPosition());
return param;
}
Aggregations