I think it is worth reviewing some of these edge cases but we want to keep the overall conceptual
model describing the parser behavior (i.e. parser rules) as simple as possible.

Here is my understanding of the rules for the classic parser. Java supports a fluent api style such as:

String lowerCity = person

Java knows when to stop because of the trailing semicolon. Groovy doesn't require the trailing
semicolon so has the following additional rules. If the tokens at the end of a line don't make up
a complete expression, looking onto the next line is done. This accounts for various opening and
closing delimiters but also when using '.'. This allows expressions like:

assert person.
    toLowerCase() == 'berlin'


def foobar1 = 'foo' +
assert foobar1.size() == 7

def baz =
println baz

As a follow-on rule, even if a line ends with valid tokens but the subsequent line doesn't start with
valid tokens (in particular starts with a '.') we try to join. This allows for:

assert person
    .size() == 6

But doesn't allow for:

def foobar2 = 'foo'
    + 'bar2'

which compiles but gives a runtime error:
MissingMethodException: No signature of method: java.lang.String.positive()

Since + here is the unary plus operator which while seldom used in that fashion is a valid operator.

Strangely, the foobar2 example parses and runs successfully on Groovy 3 setting
foobar2 to 'foo'. I'll have to check if that is a bug or "feature".

Groovy 2.5 similarly doesn't allow:

println 'foo'.with
{ s -> s.size() }

It compiles but fails to find the 'with' property on the 'foo' String. So these are two
fully valid expressions one after the other.

Groovy 3 does allow this last case. That's a breaking change. I'll need to double
check if that is something we have discussed previously and add it to the 3.0 breaking
changes if so.

Neither Groovy 2.5 nor 3 supports an anonymous inner class creation with the
curly brace on the subsequent line:

def bar = new Object()
{ String toString() { 'bar' } } // Method def not expected here
println bar.toString()

Anyway, given the above rules, my first inclination would be to retain
at least the GROOVY-8642 syntax and possibly GROOVY-8650.
I agree the use of those rules within an import is ugly but I see it
as consistent application of those rules.

But having said that, if we can describe an alternative set of rules
that are just as simple, we can have a slightly refined way of describing
the parser behavior for Groovy 3.0. I'd prefer not though to have
a very piece-meal set of rules where every construct needs to be
described separately.

Cheers, Paul.

On Tue, Jul 3, 2018 at 12:44 PM Daniel.Sun <sunlan@apache.org> wrote:
Hi all,

     The following code is supported in the older parser, but I propose to
stop supporting the ugly code style in the new Parrot parser. Any thoughts?

1) import statement ( https://issues.apache.org/jira/browse/GROOVY-8642 )
import java.

2) prefix operator ( https://issues.apache.org/jira/browse/GROOVY-8650 )
def c = --


Daniel Sun
Apache Groovy committer
Blog: http://blog.sunlan.me
Twitter: @daniel_sun

Sent from: http://groovy.329449.n5.nabble.com/Groovy-Users-f329450.html