use of lucee.transformer.bytecode.statement.tag.Attribute in project Lucee by lucee.
the class AbstrCFMLScriptTransformer method attributes.
private final Attribute[] attributes(Tag tag, TagLibTag tlt, ExprData data, EndCondition endCond, Expression defaultValue, Object oAllowExpression, String ignoreAttrReqFor, boolean allowTwiceAttr, char attributeSeparator, boolean allowColonAsNameValueSeparator) throws TemplateException {
ArrayList<Attribute> attrs = new ArrayList<Attribute>();
ArrayList<String> ids = new ArrayList<String>();
while (data.srcCode.isValidIndex()) {
data.srcCode.removeSpace();
// if no more attributes break
if (endCond.isEnd(data))
break;
Attribute attr = attribute(tlt, data, ids, defaultValue, oAllowExpression, allowTwiceAttr, allowColonAsNameValueSeparator);
attrs.add(attr);
// seperator
if (attributeSeparator > 0) {
data.srcCode.removeSpace();
data.srcCode.forwardIfCurrent(attributeSeparator);
}
}
// not defined attributes
if (tlt != null) {
boolean hasAttributeCollection = false;
Iterator<Attribute> iii = attrs.iterator();
while (iii.hasNext()) {
if ("attributecollection".equalsIgnoreCase(iii.next().getName())) {
hasAttributeCollection = true;
break;
}
}
int type = tlt.getAttributeType();
if (type == TagLibTag.ATTRIBUTE_TYPE_FIXED || type == TagLibTag.ATTRIBUTE_TYPE_MIXED) {
Map<String, TagLibTagAttr> hash = tlt.getAttributes();
Iterator<Entry<String, TagLibTagAttr>> it = hash.entrySet().iterator();
Entry<String, TagLibTagAttr> e;
while (it.hasNext()) {
e = it.next();
TagLibTagAttr att = e.getValue();
if (att.isRequired() && !contains(attrs, att) && att.getDefaultValue() == null && !att.getName().equals(ignoreAttrReqFor)) {
if (!hasAttributeCollection)
throw new TemplateException(data.srcCode, "attribute " + att.getName() + " is required for statement " + tlt.getName());
if (tag != null)
tag.addMissingAttribute(att);
}
}
}
}
return attrs.toArray(new Attribute[attrs.size()]);
}
use of lucee.transformer.bytecode.statement.tag.Attribute in project Lucee by lucee.
the class AbstrCFMLScriptTransformer method _propertyStatement.
private final Tag _propertyStatement(ExprData data, Body parent) throws TemplateException {
if (data.context != CTX_CFC || !data.srcCode.forwardIfCurrent("property "))
return null;
Position line = data.srcCode.getPosition();
TagLibTag tlt = CFMLTransformer.getTLT(data.srcCode, "property", data.config.getIdentification());
Tag property = new TagOther(data.factory, line, null);
addMetaData(data, property, IGNORE_LIST_PROPERTY);
boolean hasName = false, hasType = false;
int pos = data.srcCode.getPos();
String tmp = variableDec(data, true);
if (!StringUtil.isEmpty(tmp)) {
if (tmp.indexOf('.') != -1) {
property.addAttribute(new Attribute(false, "type", data.factory.createLitString(tmp), "string"));
hasType = true;
} else {
data.srcCode.setPos(pos);
}
} else
data.srcCode.setPos(pos);
// folgend wird tlt extra nicht uebergeben, sonst findet pruefung statt
Attribute[] attrs = attributes(property, tlt, data, SEMI, data.factory.NULL(), Boolean.FALSE, "name", true, NO_ATTR_SEP, false);
checkSemiColonLineFeed(data, true, true, false);
property.setTagLibTag(tlt);
property.setScriptBase(true);
Attribute attr;
// first fill all regular attribute -> name="value"
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;
} else if (attr.getName().equalsIgnoreCase("type")) {
hasType = true;
}
property.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) || !hasName)) {
first = attr.getNameOC();
} else // name
if (second == null && !hasName && !hasType) {
second = attr.getNameOC();
} else // attr with no value
{
attr = new Attribute(true, attr.getName(), data.factory.EMPTY(), "string");
property.addAttribute(attr);
}
}
}
if (first != null) {
hasName = true;
if (second != null) {
hasType = true;
property.addAttribute(new Attribute(false, "name", data.factory.createLitString(second), "string"));
property.addAttribute(new Attribute(false, "type", data.factory.createLitString(first), "string"));
} else {
property.addAttribute(new Attribute(false, "name", data.factory.createLitString(first), "string"));
}
}
if (!hasType) {
property.addAttribute(new Attribute(false, "type", data.factory.createLitString("any"), "string"));
}
if (!hasName)
throw new TemplateException(data.srcCode, "missing name declaration for property");
/*Tag property=new TagBase(line);
property.setTagLibTag(tlt);
property.addAttribute(new Attribute(false,"name",data.factory.createLitString(name),"string"));
property.addAttribute(new Attribute(false,"type",data.factory.createLitString(type),"string"));
*/
property.setEnd(data.srcCode.getPosition());
return property;
}
use of lucee.transformer.bytecode.statement.tag.Attribute in project Lucee by lucee.
the class AbstrCFMLScriptTransformer method getScriptFunctionArguments.
@Override
public ArrayList<Argument> getScriptFunctionArguments(ExprData data) throws TemplateException {
// arguments
LitBoolean passByRef;
Expression displayName;
Expression hint;
Map<String, Attribute> meta;
String _name;
ArrayList<Argument> result = new ArrayList<Argument>();
do {
comments(data);
// finish
if (data.srcCode.isCurrent(')'))
break;
// attribute
// name
// String idName=identifier(data,false,true);
boolean required = false;
String idName = variableDec(data, false);
// required
if ("required".equalsIgnoreCase(idName)) {
comments(data);
String idName2 = variableDec(data, false);
if (idName2 != null) {
idName = idName2;
required = true;
}
if (idName == null)
throw new TemplateException(data.srcCode, "invalid argument definition");
}
String typeName = "any";
if (idName == null)
throw new TemplateException(data.srcCode, "invalid argument definition");
comments(data);
if (!data.srcCode.isCurrent(')') && !data.srcCode.isCurrent('=') && !data.srcCode.isCurrent(':') && !data.srcCode.isCurrent(',')) {
typeName = idName.toLowerCase();
// MUST was upper case before, is this a problem?
idName = identifier(data, false);
} else if (idName.indexOf('.') != -1 || idName.indexOf('[') != -1) {
throw new TemplateException(data.srcCode, "invalid argument name [" + idName + "] definition");
}
if (idName == null)
throw new TemplateException(data.srcCode, "invalid argument definition");
comments(data);
Expression defaultValue;
if (data.srcCode.isCurrent('=') || data.srcCode.isCurrent(':')) {
data.srcCode.next();
comments(data);
defaultValue = expression(data);
} else
defaultValue = null;
// assign meta data defined in doc comment
passByRef = data.factory.TRUE();
displayName = data.factory.EMPTY();
hint = data.factory.EMPTY();
meta = null;
if (data.docComment != null) {
Map<String, Attribute> params = data.docComment.getParams();
Attribute[] attrs = params.values().toArray(new Attribute[params.size()]);
Attribute attr;
String name;
for (int i = 0; i < attrs.length; i++) {
attr = attrs[i];
name = attr.getName();
// hint
if (idName.equalsIgnoreCase(name) || name.equalsIgnoreCase(idName + ".hint")) {
hint = data.factory.toExprString(attr.getValue());
params.remove(name);
}
// meta
if (StringUtil.startsWithIgnoreCase(name, idName + ".")) {
if (name.length() > idName.length() + 1) {
if (meta == null)
meta = new HashMap<String, Attribute>();
_name = name.substring(idName.length() + 1);
meta.put(_name, new Attribute(attr.isDynamicType(), _name, attr.getValue(), attr.getType()));
}
params.remove(name);
}
}
}
// argument attributes
Attribute[] _attrs = attributes(null, null, data, COMMA_ENDBRACKED, data.factory.EMPTY(), Boolean.TRUE, null, false, NO_ATTR_SEP, true);
Attribute _attr;
if (!ArrayUtil.isEmpty(_attrs)) {
if (meta == null)
meta = new HashMap<String, Attribute>();
for (int i = 0; i < _attrs.length; i++) {
_attr = _attrs[i];
meta.put(_attr.getName(), _attr);
}
}
result.add(new Argument(data.factory.createLitString(idName), data.factory.createLitString(typeName), data.factory.createLitBoolean(required), defaultValue, passByRef, displayName, hint, meta));
comments(data);
} while (data.srcCode.forwardIfCurrent(','));
return result;
}
use of lucee.transformer.bytecode.statement.tag.Attribute in project Lucee by lucee.
the class AbstrCFMLScriptTransformer method addMetaData.
private final void addMetaData(ExprData data, Tag tag, String[] ignoreList) {
if (data.docComment == null)
return;
tag.addMetaData(data.docComment.getHintAsAttribute(data.factory));
Map<String, Attribute> params = data.docComment.getParams();
Iterator<Attribute> it = params.values().iterator();
Attribute attr;
outer: while (it.hasNext()) {
attr = it.next();
// ignore list
if (!ArrayUtil.isEmpty(ignoreList)) {
for (int i = 0; i < ignoreList.length; i++) {
if (ignoreList[i].equalsIgnoreCase(attr.getName()))
continue outer;
}
}
tag.addMetaData(attr);
}
data.docComment = null;
}
use of lucee.transformer.bytecode.statement.tag.Attribute in project Lucee by lucee.
the class AbstrCFMLScriptTransformer method attribute.
private final Attribute attribute(TagLibTag tlt, ExprData data, ArrayList<String> args, Expression defaultValue, Object oAllowExpression, boolean allowTwiceAttr, boolean allowColonSeparator) throws TemplateException {
StringBuffer sbType = new StringBuffer();
RefBoolean dynamic = new RefBooleanImpl(false);
// Name
String name = attributeName(data.srcCode, args, tlt, dynamic, sbType, allowTwiceAttr, !allowColonSeparator);
String nameLC = name == null ? null : name.toLowerCase();
boolean allowExpression = false;
if (oAllowExpression instanceof Boolean)
allowExpression = ((Boolean) oAllowExpression).booleanValue();
else if (oAllowExpression instanceof String)
allowExpression = ((String) oAllowExpression).equalsIgnoreCase(nameLC);
Expression value = null;
comments(data);
// value
boolean hasValue = data.srcCode.forwardIfCurrent('=') || (allowColonSeparator && data.srcCode.forwardIfCurrent(':'));
if (hasValue) {
comments(data);
value = attributeValue(data, allowExpression);
} else {
value = defaultValue;
}
comments(data);
// Type
TagLibTagAttr tlta = null;
if (tlt != null) {
tlta = tlt.getAttribute(nameLC, true);
if (tlta != null && tlta.getName() != null)
nameLC = tlta.getName();
}
return new Attribute(dynamic.toBooleanValue(), name, tlta != null ? CastOther.toExpression(value, tlta.getType()) : value, sbType.toString(), !hasValue);
}
Aggregations