You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Pascal Schumacher (JIRA)" <ji...@apache.org> on 2015/07/13 20:06:04 UTC

[jira] [Closed] (GROOVY-4315) Add an associated test (CLONE: OptimizerVisitor may run twice, corrupting constants)

     [ https://issues.apache.org/jira/browse/GROOVY-4315?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Pascal Schumacher closed GROOVY-4315.
-------------------------------------
    Resolution: Incomplete

Closing as incomplete, because nobody ever came up with a test.

> Add an associated test (CLONE: OptimizerVisitor may run twice, corrupting constants)
> ------------------------------------------------------------------------------------
>
>                 Key: GROOVY-4315
>                 URL: https://issues.apache.org/jira/browse/GROOVY-4315
>             Project: Groovy
>          Issue Type: Bug
>          Components: Compiler
>    Affects Versions: 1.7.3
>            Reporter: Peter Niederwieser
>            Priority: Critical
>
> The issue came up when Paul King showed me a Spock spec behaving in strange ways:
> TestSpock.groovy:
> {code}
> @Grab('org.spockframework:spock-core:0.4-groovy-1.7')
> class TestSpock extends spock.lang.Specification {
>   def convert = new Converter()
>   def 'important scenarios'() {
>     expect:
>     c == convert.toCelsius(f)
>     where:
>     c   | f   | scenario
>     0   | 32  | 'Freezing'
>     20  | 68  | 'Garden party conditions'
>     35  | 95  | 'Beach conditions'
>     100 | 212 | 'Boiling'
>   }
> }
> {code}
> Converter.groovy:
> {code}
> class Converter {
>   def toCelsius (fahrenheit) { (fahrenheit - 32) * 5 / 9 }
> }
> {code}
> If you run this with 'groovy TestSpock.groovy', you will notice that the values for 'c' and 'f' get mixed up. After debugging groovyc, I came to the following conclusion:
> Compilation of SpockTest advances until end of phase "semantic analysis", then CompilationUnit.dequeued() sets the phase back to "initialization". On the second pass, SourceUnitOperation's that have already run are skipped due to this check in CompilationUnit.applyToSourceUnits():
> {code}
> if ((source.phase < phase) || (source.phase == phase &&
> !source.phaseComplete)) ...
> {code}
> However, Compilation.applyToPrimaryClassNodes() has a slightly different check:
> {code}
> if (context == null || context.phase <= phase) ...
> {code}
> source.phaseComplete is not checked here, hence OptimizerVisitor (among others) runs a second time. This leads to wrong results, at least in the case where an AST transform has added additional constants. The TODO in OptimizerVisitor.setConstField() is on the spot.
> Adding the source.phaseComplete check to Compilation.applyToPrimaryClassNodes() seemed to solve the problem for Paul. I haven't investigated further if this is the correct approach.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)