You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2013/07/14 23:07:26 UTC

svn commit: r1503056 - in /tomcat/trunk: java/org/apache/el/ java/org/apache/el/parser/ test/org/apache/el/parser/

Author: markt
Date: Sun Jul 14 21:07:26 2013
New Revision: 1503056

URL: http://svn.apache.org/r1503056
Log:
Start to implement the lambda expression syntax. Very basic expressions work. I expect further changes to be required for more complex expressions.
Includes the initial unit tests for this syntax.

Added:
    tomcat/trunk/test/org/apache/el/parser/TestAstLambdaExpression.java   (with props)
Modified:
    tomcat/trunk/java/org/apache/el/Messages.properties
    tomcat/trunk/java/org/apache/el/parser/AstIdentifier.java
    tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java
    tomcat/trunk/java/org/apache/el/parser/AstLambdaExpressionOrInvocation.java

Modified: tomcat/trunk/java/org/apache/el/Messages.properties
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/el/Messages.properties?rev=1503056&r1=1503055&r2=1503056&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/el/Messages.properties (original)
+++ tomcat/trunk/java/org/apache/el/Messages.properties Sun Jul 14 21:07:26 2013
@@ -51,4 +51,7 @@ error.fnMapper.paramcount=Function ''{0}
 error.context.null=ELContext was null
 
 # Parser
-error.identifier.notjava=The identifier [{0}] is not a valid Java identifier as required by section 1.19 of the EL specification (Identifier ::= Java language identifier). This check can be disabled by setting the system property org.apache.el.parser.SKIP_IDENTIFIER_CHECK to true.
\ No newline at end of file
+error.identifier.notjava=The identifier [{0}] is not a valid Java identifier as required by section 1.19 of the EL specification (Identifier ::= Java language identifier). This check can be disabled by setting the system property org.apache.el.parser.SKIP_IDENTIFIER_CHECK to true.
+
+# AstLambdaExpression
+error.args.tooFew=Only [{0}] arguments were provided for a lambda expression that requires at least [{1}]

Modified: tomcat/trunk/java/org/apache/el/parser/AstIdentifier.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/el/parser/AstIdentifier.java?rev=1503056&r1=1503055&r2=1503056&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/el/parser/AstIdentifier.java (original)
+++ tomcat/trunk/java/org/apache/el/parser/AstIdentifier.java Sun Jul 14 21:07:26 2013
@@ -61,6 +61,12 @@ public final class AstIdentifier extends
 
     @Override
     public Object getValue(EvaluationContext ctx) throws ELException {
+        // Lambda parameters
+        if (ctx.isLambdaArgument(this.image)) {
+            return ctx.getLambdaArgument(this.image);
+        }
+
+        // Variable mapper
         VariableMapper varMapper = ctx.getVariableMapper();
         if (varMapper != null) {
             ValueExpression expr = varMapper.resolveVariable(this.image);
@@ -68,6 +74,8 @@ public final class AstIdentifier extends
                 return expr.getValue(ctx.getELContext());
             }
         }
+
+        // EL Resolvers
         ctx.setPropertyResolved(false);
         Object result = ctx.getELResolver().getValue(ctx, null, this.image);
         if (!ctx.isPropertyResolved()) {

Modified: tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java?rev=1503056&r1=1503055&r2=1503056&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java (original)
+++ tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java Sun Jul 14 21:07:26 2013
@@ -17,10 +17,53 @@
 /* Generated By:JJTree: Do not edit this line. AstLambdaExpression.java Version 4.3 */
 package org.apache.el.parser;
 
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.el.ELException;
+
+import org.apache.el.lang.EvaluationContext;
+import org.apache.el.util.MessageFactory;
+
 public class AstLambdaExpression extends SimpleNode {
 
     public AstLambdaExpression(int id) {
         super(id);
     }
+
+    @SuppressWarnings("null") // paramValues[i] can't be null due to checks
+    @Override
+    public Object invoke(EvaluationContext ctx, Class<?>[] paramTypes,
+            Object[] paramValues) throws ELException {
+
+        // Two children - the formal parameters and the expression
+        AstLambdaParameters formalParameters =
+                (AstLambdaParameters) children[0];
+
+        int paramCount = formalParameters.children.length;
+        int argCount = 0;
+        if (paramValues != null) {
+            argCount = paramValues.length;
+        }
+        if (paramCount > argCount) {
+            throw new ELException(MessageFactory.get("error.args.tooFew",
+                    Integer.valueOf(argCount), Integer.valueOf(paramCount)));
+        }
+
+        // Build the argument map
+        Map<String,Object> lambdaArgumnents = new HashMap<>();
+        for (int i = 0; i < formalParameters.children.length; i++) {
+            lambdaArgumnents.put(formalParameters.children[i].getImage(),
+                    paramValues[i]);
+        }
+
+        ctx.enterLambdaScope(lambdaArgumnents);
+
+        try {
+            return children[1].getValue(ctx);
+        } finally {
+            ctx.exitLambdaScope();
+        }
+    }
 }
 /* JavaCC - OriginalChecksum=071159eff10c8e15ec612c765ae4480a (do not edit this line) */

Modified: tomcat/trunk/java/org/apache/el/parser/AstLambdaExpressionOrInvocation.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/el/parser/AstLambdaExpressionOrInvocation.java?rev=1503056&r1=1503055&r2=1503056&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/el/parser/AstLambdaExpressionOrInvocation.java (original)
+++ tomcat/trunk/java/org/apache/el/parser/AstLambdaExpressionOrInvocation.java Sun Jul 14 21:07:26 2013
@@ -17,10 +17,33 @@
 /* Generated By:JJTree: Do not edit this line. AstLambdaExpressionOrInvocation.java Version 4.3 */
 package org.apache.el.parser;
 
-public
-class AstLambdaExpressionOrInvocation extends SimpleNode {
-  public AstLambdaExpressionOrInvocation(int id) {
-    super(id);
-  }
+import javax.el.ELException;
+
+import org.apache.el.lang.EvaluationContext;
+
+public class AstLambdaExpressionOrInvocation extends SimpleNode {
+
+    public AstLambdaExpressionOrInvocation(int id) {
+        super(id);
+    }
+
+
+    @Override
+    public Object getValue(EvaluationContext ctx) throws ELException {
+
+        if (children.length == 2) {
+            AstLambdaExpression lambdaExpression =
+                    (AstLambdaExpression) children[0];
+
+
+            Object[] args =
+                    ((AstMethodParameters) children[1]).getParameters(ctx);
+
+            return lambdaExpression.invoke(ctx, null, args);
+        }
+
+        // TODO Auto-generated method stub
+        return super.getValue(ctx);
+    }
 }
 /* JavaCC - OriginalChecksum=6b3dd15b31540457a41bd55974037ed9 (do not edit this line) */

Added: tomcat/trunk/test/org/apache/el/parser/TestAstLambdaExpression.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/el/parser/TestAstLambdaExpression.java?rev=1503056&view=auto
==============================================================================
--- tomcat/trunk/test/org/apache/el/parser/TestAstLambdaExpression.java (added)
+++ tomcat/trunk/test/org/apache/el/parser/TestAstLambdaExpression.java Sun Jul 14 21:07:26 2013
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.el.parser;
+
+import javax.el.ELProcessor;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestAstLambdaExpression {
+
+    @Test
+    public void testSpec01() {
+        ELProcessor processor = new ELProcessor();
+        Object result = processor.getValue("(x->x+1)(1)", Integer.class);
+        Assert.assertEquals(Integer.valueOf(2), result);
+    }
+}

Propchange: tomcat/trunk/test/org/apache/el/parser/TestAstLambdaExpression.java
------------------------------------------------------------------------------
    svn:eol-style = native



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: svn commit: r1503056 - in /tomcat/trunk: java/org/apache/el/ java/org/apache/el/parser/ test/org/apache/el/parser/

Posted by Mark Thomas <ma...@apache.org>.
On 16/07/2013 16:02, Mark Thomas wrote:
> On 16/07/2013 15:39, Violeta Georgieva wrote:
>> 2013/7/16 Mark Thomas wrote:
>>>
> 
> <snip/>
> 
>>> Do you have an example of a valid expression that needs multiple method
>>> arguments? I'll try and come up with one. If I can't I'll change the
>>> grammar and re-generate.
>>
>> What about
>> (x->y->x+y)(a)(b)
>>
>> in the spec it is said that
>>
>> "x->y->x+y is parsed as x->(y->x+y)"
> 
> I dug into the change history of the grammar used in the spec. The
> example you quote above is indeed the style of invocation that triggered
> a change from '?' to '*'.
> 
> Modifying your example a little, consider this:
> (x->y->x-y)(1)(2)

This isn't even parsed correctly currently. The result is two nested
lambda expressions both with a single parameter x.

I suspect that the spec grammar forces what I have called
LambdaExpressionOrInvocation to parse as LambdaExpression is the key
difference here.

I have found the references in the spec that make clear that the
(args)(args) syntax is expected but nothing that defines the ordering -
I'll have to look at the RI. (Once I get the parsing fixed).

Mark


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: svn commit: r1503056 - in /tomcat/trunk: java/org/apache/el/ java/org/apache/el/parser/ test/org/apache/el/parser/

Posted by Mark Thomas <ma...@apache.org>.
On 16/07/2013 15:39, Violeta Georgieva wrote:
> 2013/7/16 Mark Thomas wrote:
>>

<snip/>

>> Do you have an example of a valid expression that needs multiple method
>> arguments? I'll try and come up with one. If I can't I'll change the
>> grammar and re-generate.
> 
> What about
> (x->y->x+y)(a)(b)
> 
> in the spec it is said that
> 
> "x->y->x+y is parsed as x->(y->x+y)"

I dug into the change history of the grammar used in the spec. The
example you quote above is indeed the style of invocation that triggered
a change from '?' to '*'.

Modifying your example a little, consider this:
(x->y->x-y)(1)(2)

Is the result +1 or -1? I don't recall anything in the spec that defines
which it is. I need to re-read the spec and I hope I've missed
something. Failing that, I'll have to dig through the reference
implementation to figure out what the intended behaviour is.

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: svn commit: r1503056 - in /tomcat/trunk: java/org/apache/el/ java/org/apache/el/parser/ test/org/apache/el/parser/

Posted by Violeta Georgieva <mi...@gmail.com>.
2013/7/16 Mark Thomas wrote:
>
> On 16/07/2013 09:02, Violeta Georgieva wrote:
> > 2013/7/15 <ma...@apache.org>
>
> <snip/>
>
> >> +public class AstLambdaExpressionOrInvocation extends SimpleNode {
> >> +
> >> +    public AstLambdaExpressionOrInvocation(int id) {
> >> +        super(id);
> >> +    }
> >> +
> >> +
> >> +    @Override
> >> +    public Object getValue(EvaluationContext ctx) throws ELException {
> >> +
> >> +        if (children.length == 2) {
> >
> > Why you are limiting the children to 2.
>
> I was working on the basis that one LambdaExpression should have one set
> of method parameters.
>
> > We have MethodArguments -> zero or more:
>
> That is what the specification indicates and where I would have got the
> choice of '*' rather than '? 'from but as I think about it I wonder if
> that is right. It doesn't look right. My instinct is that it should be
'?'.
>
> Note that the use of * might be an artefact of how they decided to
> implement the spec. Note also that the grammar is not definitive - it is
> only meant to be a guide.
>
> Do you have an example of a valid expression that needs multiple method
> arguments? I'll try and come up with one. If I can't I'll change the
> grammar and re-generate.

What about
(x->y->x+y)(a)(b)

in the spec it is said that

"x->y->x+y is parsed as x->(y->x+y)"

Re: svn commit: r1503056 - in /tomcat/trunk: java/org/apache/el/ java/org/apache/el/parser/ test/org/apache/el/parser/

Posted by Mark Thomas <ma...@apache.org>.
On 16/07/2013 09:02, Violeta Georgieva wrote:
> 2013/7/15 <ma...@apache.org>

<snip/>

>> +public class AstLambdaExpressionOrInvocation extends SimpleNode {
>> +
>> +    public AstLambdaExpressionOrInvocation(int id) {
>> +        super(id);
>> +    }
>> +
>> +
>> +    @Override
>> +    public Object getValue(EvaluationContext ctx) throws ELException {
>> +
>> +        if (children.length == 2) {
> 
> Why you are limiting the children to 2.

I was working on the basis that one LambdaExpression should have one set
of method parameters.

> We have MethodArguments -> zero or more:

That is what the specification indicates and where I would have got the
choice of '*' rather than '? 'from but as I think about it I wonder if
that is right. It doesn't look right. My instinct is that it should be '?'.

Note that the use of * might be an artefact of how they decided to
implement the spec. Note also that the grammar is not definitive - it is
only meant to be a guide.

Do you have an example of a valid expression that needs multiple method
arguments? I'll try and come up with one. If I can't I'll change the
grammar and re-generate.

Mark

> void LambdaExpressionOrCall() #LambdaExpression : {}
> {
> <LPAREN>
> LambdaParameters() <ARROW>
> (LOOKAHEAD(3) LambdaExpression() | Choice() )
> <RPAREN>
> (MethodArguments())*
> }




---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: svn commit: r1503056 - in /tomcat/trunk: java/org/apache/el/ java/org/apache/el/parser/ test/org/apache/el/parser/

Posted by Violeta Georgieva <mi...@gmail.com>.
2013/7/15 <ma...@apache.org>
>
> Author: markt
> Date: Sun Jul 14 21:07:26 2013
> New Revision: 1503056
>
> URL: http://svn.apache.org/r1503056
> Log:
> Start to implement the lambda expression syntax. Very basic expressions
work. I expect further changes to be required for more complex expressions.
> Includes the initial unit tests for this syntax.
>
> Modified:
tomcat/trunk/java/org/apache/el/parser/AstLambdaExpressionOrInvocation.java
> URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/el/parser/AstLambdaExpressionOrInvocation.java?rev=1503056&r1=1503055&r2=1503056&view=diff
>
==============================================================================
> ---
tomcat/trunk/java/org/apache/el/parser/AstLambdaExpressionOrInvocation.java
(original)
> +++
tomcat/trunk/java/org/apache/el/parser/AstLambdaExpressionOrInvocation.java
Sun Jul 14 21:07:26 2013
> @@ -17,10 +17,33 @@
>  /* Generated By:JJTree: Do not edit this line.
AstLambdaExpressionOrInvocation.java Version 4.3 */
>  package org.apache.el.parser;
>
> -public
> -class AstLambdaExpressionOrInvocation extends SimpleNode {
> -  public AstLambdaExpressionOrInvocation(int id) {
> -    super(id);
> -  }
> +import javax.el.ELException;
> +
> +import org.apache.el.lang.EvaluationContext;
> +
> +public class AstLambdaExpressionOrInvocation extends SimpleNode {
> +
> +    public AstLambdaExpressionOrInvocation(int id) {
> +        super(id);
> +    }
> +
> +
> +    @Override
> +    public Object getValue(EvaluationContext ctx) throws ELException {
> +
> +        if (children.length == 2) {

Why you are limiting the children to 2.
We have MethodArguments -> zero or more:

void LambdaExpressionOrCall() #LambdaExpression : {}
{
<LPAREN>
LambdaParameters() <ARROW>
(LOOKAHEAD(3) LambdaExpression() | Choice() )
<RPAREN>
(MethodArguments())*
}

> +            AstLambdaExpression lambdaExpression =
> +                    (AstLambdaExpression) children[0];
> +
> +
> +            Object[] args =
> +                    ((AstMethodParameters)
children[1]).getParameters(ctx);
> +
> +            return lambdaExpression.invoke(ctx, null, args);
> +        }
> +
> +        // TODO Auto-generated method stub
> +        return super.getValue(ctx);
> +    }
>  }
>  /* JavaCC - OriginalChecksum=6b3dd15b31540457a41bd55974037ed9 (do not
edit this line) */

Re: svn commit: r1503056 - in /tomcat/trunk: java/org/apache/el/ java/org/apache/el/parser/ test/org/apache/el/parser/

Posted by Mark Thomas <ma...@apache.org>.
On 14/07/2013 23:01, Konstantin Kolinko wrote:
> 2013/7/15  <ma...@apache.org>:
>> Author: markt
>> Date: Sun Jul 14 21:07:26 2013
>> New Revision: 1503056
>>
>> URL: http://svn.apache.org/r1503056

>> +# AstLambdaExpression
>> +error.args.tooFew=Only [{0}] arguments were provided for a lambda expression that requires at least [{1}]
> 
> Maybe rename the message key to "error.lambda.args.tooFew", to be more
> specific (as the message text mentions lambda expressions)?
> 
> [...]
> 
>> Modified: tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java
>> URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java?rev=1503056&r1=1503055&r2=1503056&view=diff
>> ==============================================================================
>> --- tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java (original)
>> +++ tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java Sun Jul 14 21:07:26 2013
> [...]
>> +
>> +        // Build the argument map
>> +        Map<String,Object> lambdaArgumnents = new HashMap<>();
> 
> A typo in local variable name above.


Fixed. Thanks.

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: svn commit: r1503056 - in /tomcat/trunk: java/org/apache/el/ java/org/apache/el/parser/ test/org/apache/el/parser/

Posted by Konstantin Kolinko <kn...@gmail.com>.
2013/7/15  <ma...@apache.org>:
> Author: markt
> Date: Sun Jul 14 21:07:26 2013
> New Revision: 1503056
>
> URL: http://svn.apache.org/r1503056
> Log:
> Start to implement the lambda expression syntax. Very basic expressions work. I expect further changes to be required for more complex expressions.
> Includes the initial unit tests for this syntax.
>
> Added:
>     tomcat/trunk/test/org/apache/el/parser/TestAstLambdaExpression.java   (with props)
> Modified:
>     tomcat/trunk/java/org/apache/el/Messages.properties
>     tomcat/trunk/java/org/apache/el/parser/AstIdentifier.java
>     tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java
>     tomcat/trunk/java/org/apache/el/parser/AstLambdaExpressionOrInvocation.java
>

> \ No newline at end of file
> +error.identifier.notjava=The identifier [{0}] is not a valid Java identifier as required by section 1.19 of the EL specification (Identifier ::= Java language identifier). This check can be disabled by setting the system property org.apache.el.parser.SKIP_IDENTIFIER_CHECK to true.
> +
> +# AstLambdaExpression
> +error.args.tooFew=Only [{0}] arguments were provided for a lambda expression that requires at least [{1}]

Maybe rename the message key to "error.lambda.args.tooFew", to be more
specific (as the message text mentions lambda expressions)?

[...]

> Modified: tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java
> URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java?rev=1503056&r1=1503055&r2=1503056&view=diff
> ==============================================================================
> --- tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java (original)
> +++ tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java Sun Jul 14 21:07:26 2013
[...]
> +
> +        // Build the argument map
> +        Map<String,Object> lambdaArgumnents = new HashMap<>();

A typo in local variable name above.

> +        for (int i = 0; i < formalParameters.children.length; i++) {
> +            lambdaArgumnents.put(formalParameters.children[i].getImage(),
> +                    paramValues[i]);
> +        }
> +
> +        ctx.enterLambdaScope(lambdaArgumnents);
> +

Best regards,
Konstantin Kolinko

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org