diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfmentat/tag/CFMLStartTag.java b/cfml.parsing/src/main/java/cfml/parsing/cfmentat/tag/CFMLStartTag.java
index 7ab72e8..9c838f7 100644
--- a/cfml.parsing/src/main/java/cfml/parsing/cfmentat/tag/CFMLStartTag.java
+++ b/cfml.parsing/src/main/java/cfml/parsing/cfmentat/tag/CFMLStartTag.java
@@ -69,6 +69,8 @@ protected int getEnd(final Source source, final int pos) {
if (!isInQuotes && !isInApos) {
if (x > 2 && text.subSequence(x - 3, x).equals("---")) {
// do nothing, this is a comment
+ } else if (isArrowOperator(text, x)) {
+ // do nothing, this '>' is the tail of => or -> inside an expression
} else {
return x + 1;
}
@@ -95,6 +97,25 @@ protected int getEnd(final Source source, final int pos) {
return endStartTagEnd;
}
+ /**
+ * True when the '>' at pos is the second character of an arrow operator, as in
+ * <cfset f = (x) => x + 1>. Without this the tag ends inside the operator
+ * and the expression is silently truncated to f = (x) =.
+ *
+ * A '-' is only an arrow when it does not follow another '-', so the decrement in
+ * <cfset a = i--> still ends the tag.
+ */
+ private static boolean isArrowOperator(final ParseText text, final int pos) {
+ if (pos < 1) {
+ return false;
+ }
+ final char previous = text.charAt(pos - 1);
+ if (previous == '=') {
+ return true;
+ }
+ return previous == '-' && (pos < 2 || text.charAt(pos - 2) != '-');
+ }
+
protected ArrayList getAttributes(String inData) {
ArrayList attributes = new ArrayList();
Matcher matcher;
diff --git a/cfml.parsing/src/test/resources/tag/tests/parsing/cfset_lambda_44.cfm b/cfml.parsing/src/test/resources/tag/tests/parsing/cfset_lambda_44.cfm
new file mode 100644
index 0000000..786f3dd
--- /dev/null
+++ b/cfml.parsing/src/test/resources/tag/tests/parsing/cfset_lambda_44.cfm
@@ -0,0 +1,8 @@
+prefix
+ t.b()>
+ t.b()>
+ x + y>
+ target.toString() )>
+
+
+
diff --git a/cfml.parsing/src/test/resources/tag/tests/parsing/cfset_lambda_44.expected.txt b/cfml.parsing/src/test/resources/tag/tests/parsing/cfset_lambda_44.expected.txt
new file mode 100644
index 0000000..55c6c74
--- /dev/null
+++ b/cfml.parsing/src/test/resources/tag/tests/parsing/cfset_lambda_44.expected.txt
@@ -0,0 +1,279 @@
+START:cfoutput
+ =========TAG=================
+ prefix
+END:cfoutput
+START:cfset
+ =========TAG=================
+ t.b()>
+ TAG
+ ==========Tokens==============
+ IDENTIFIER
+ '=' <=>
+ IDENTIFIER
+ '=>' <=>>
+ IDENTIFIER
+ '.' <.>
+ IDENTIFIER
+ '(' <(>
+ ')' <)>
+ ===========Tree================
+ (expression
+ (assignmentExpression
+ (startExpression
+ (baseExpression (unaryExpression (memberExpression (identifier closure))))
+ )
+ =
+ (startExpression
+ (baseExpression
+ (lambdaDeclaration
+ (identifier t)
+ =>
+ (startExpression
+ (baseExpression
+ (unaryExpression
+ (memberExpression
+ (identifier t)
+ .
+ (qualifiedFunctionCall (identifier b) ( argumentList ))
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+
+ )
+ ===========Expression===============
+ closure = (t) => t.b()
+ ==================================
+END:cfset
+START:cfset
+ =========TAG=================
+ t.b()>
+ TAG
+ ==========Tokens==============
+ IDENTIFIER
+ '=' <=>
+ IDENTIFIER
+ '->' <->>
+ IDENTIFIER
+ '.' <.>
+ IDENTIFIER
+ '(' <(>
+ ')' <)>
+ ===========Tree================
+ (expression
+ (assignmentExpression
+ (startExpression
+ (baseExpression (unaryExpression (memberExpression (identifier lambda))))
+ )
+ =
+ (startExpression
+ (baseExpression
+ (lambdaDeclaration
+ (identifier t)
+ ->
+ (startExpression
+ (baseExpression
+ (unaryExpression
+ (memberExpression
+ (identifier t)
+ .
+ (qualifiedFunctionCall (identifier b) ( argumentList ))
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+
+ )
+ ===========Expression===============
+ lambda = (t) -> t.b()
+ ==================================
+END:cfset
+START:cfset
+ =========TAG=================
+ x + y>
+ TAG
+ ==========Tokens==============
+ IDENTIFIER
+ '=' <=>
+ '(' <(>
+ IDENTIFIER
+ ',' <,>
+ IDENTIFIER
+ ')' <)>
+ '=>' <=>>
+ IDENTIFIER
+ '+' <+>
+ IDENTIFIER
+ ===========Tree================
+ (expression
+ (assignmentExpression
+ (startExpression
+ (baseExpression
+ (unaryExpression (memberExpression (identifier parenthesised)))
+ )
+ )
+ =
+ (startExpression
+ (baseExpression
+ (lambdaDeclaration
+ (
+ (parameterList (parameter (identifier x)) , (parameter (identifier y)))
+ )
+ =>
+ (startExpression
+ (baseExpression
+ (baseExpression (unaryExpression (memberExpression (identifier x))))
+ +
+ (baseExpression (unaryExpression (memberExpression (identifier y))))
+ )
+ )
+ )
+ )
+ )
+ )
+
+ )
+ ===========Expression===============
+ parenthesised = (x, y) => x + y
+ ==================================
+END:cfset
+START:cfset
+ =========TAG=================
+ target.toString() )>
+ TAG
+ ==========Tokens==============
+ IDENTIFIER
+ '=' <=>
+ IDENTIFIER
+ '(' <(>
+ ')' <)>
+ '.' <.>
+ IDENTIFIER