James Daugherty created GROOVY-12551:
----------------------------------------

             Summary: SC: a named argument of a constructor call gets no line 
number when the constructed class is already compiled
                 Key: GROOVY-12551
                 URL: https://issues.apache.org/jira/browse/GROOVY-12551
             Project: Groovy
          Issue Type: Bug
          Components: Static compilation
    Affects Versions: 5.1.3
            Reporter: James Daugherty


With static compilation, a constructor call with named arguments, {{new 
Ctx(name: name)}}, is expanded into a constructor call and one assignment per 
argument. The assignment gets a line number entry only when {{Ctx}} is compiled 
together with the caller. When {{Ctx}} is already compiled, the entry is 
missing, so the same source compiles to a different class file depending on 
what else is compiled, and a debugger cannot stop on that line. Groovy 4.0.33 
writes the entry in both cases.

{code:groovy}
class Ctx {
    String name
}

@groovy.transform.CompileStatic
class Svc {
    static Object use(int i, Ctx ctx) { ctx }

    Object make(String name) {
        use(
                1,
                new Ctx(name: name) // no line number entry when Ctx is already 
compiled
        )
    }
}
{code}

Reproduced with 5.1.3 and master. A reproducer with a groovyc script and an 
incremental Gradle build: 
https://github.com/jdaugherty/groovy-named-argument-line-numbers

*Cause*

{{ConstructorCallTransformer}} builds {{tmp.name = name}} for each named 
argument, transforms it, and only then sets the position of the map entry on 
the result. When {{Ctx}} is compiled, static type checking knows its setter, so 
{{BinaryExpressionTransformer}} rewrites the assignment into a setter call 
built from the untransformed expression, which has no position yet, and no line 
number is written. When {{Ctx}} is in the compilation unit, the assignment 
stays a binary expression, which writes the line of the position set afterwards.

*Proposed fix*

Write the line of the map entry before generating the code for its assignment, 
whatever expression the transformer returns.

Found while making incremental builds of a Grails application produce the same 
classes as a full build; see also GROOVY-12550 and GROOVY-12544.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to