bmuschko / gradle-clover-plugin

Gradle plugin for generating a code coverage report using Clover
Apache License 2.0
74 stars 49 forks source link

@CompileStatic and safe navigation operator fails cloverGenerateReport task #127

Closed zpalazov closed 5 years ago

zpalazov commented 5 years ago

When a combination of @CompileStatic annotation and safe navigation operator is used in a class cloverGenerateReport task fails during clover-setup it can not compile it. The same code is successfully compiled with the compileTestGroovy task

[groovyc] Compiling 2 source files to /home/zahari/workspace/laboratory/open-clover-compilestatic-issue/build/classes/groovy/main [clover-setup] Creating new database at '/home/zahari/workspace/laboratory/open-clover-compilestatic-issue/build/.clover/clover.db-test'. [groovyc] org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: [groovyc] /home/zahari/workspace/laboratory/open-clover-compilestatic-issue/src/main/groovy/open/clover/compilestatic/issue/PersonService.groovy: 10: [Static type checking] - Cannot find matching method java.lang.Object#toLowerCase(). Please check if the declared type is correct and if the method exists. [groovyc] @ line 10, column 22. [groovyc] String ext = FilenameUtils.getExtension(person?.file)?.toLowerCase() [groovyc] ^ [groovyc] [groovyc] 1 error `

Example project https://github.com/zpalazov/example-open-clover

Alex-Vol-SV commented 5 years ago

This issue is with Clover library. I cannot fix this, it fails because of @CompileStatic. Remove that and it works.

zpalazov commented 5 years ago

Thanks for the answer, I have a question about the compilation part in the plugin , why is needed for Openclover to compile again the Groovy src files with ANT task, do we have the option to use the classes already compiled with the Gradle task From what I see in the source if the Groovy plugin is applied to a Gradle project it always compiles again the Groovy sources ?

Nice project thanks for doing this !

Alex-Vol-SV commented 5 years ago

The OpenClover generates instrumented classes. You have to build them twice if you want to have a usable, not instrumented JAR file at the end. There is no way around this. The Gradle tasks generate non-instrumented code.

sbglasius commented 5 years ago

If #128 gets accepted it is possible to work around this issue with a groovyc compiler configuration like this:

withConfig(configuration) {
    inline(phase: 'CONVERSION') { source, context, classNode ->
        source.ast.unit.classes.each { clazz ->
            println "Fixing $clazz.name"
            clazz.annotations.removeAll { annotation -> annotation.classNode.name in ['CompileStatic', 'TypeChecked'] }
        }
    }
}

removing the CompileStatic and TypeChecked in the test phase when running with OpenClover

Alex-Vol-SV commented 5 years ago

I would love to add this feature. I am not familiar with the groovyc compiler configuration. Where would this code be called from?

Alex-Vol-SV commented 5 years ago

So, to complete this I will add the above groovyc compiler configuration code snippet in the documentation.

zpalazov commented 5 years ago

I've just tested it with 2.2.2-SNAPSHOT and works correctly, big thanks Soren and Alex !

Alex-Vol-SV commented 5 years ago

Thank you @zpalazov for the additional verification. I plan to create a release for the 2.2.2 version by the end of the month. I want to run some validation on my own projects although I am quite comfortable with the results so far.

zpalazov commented 5 years ago

@Alex-Vol-SV if I can help with testing of some scenario let me know.

Alex-Vol-SV commented 5 years ago

Unit test and functional test coverage in this plugin is very comprehensive. I usually just spot check against some live projects at work where we utilize the plugin so I know real world projects are not going to have adverse side-effects from any changes. Feel free to use the SNAPSHOT build as you see fit. The changes from the previous version are identified in the release notes, I am going based on that to do the testing myself.