[ https://issues.apache.org/jira/browse/GROOVY-11563?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Paul King closed GROOVY-11563. ------------------------------ > CompileStatic does not detect type mismatch on "+=" > --------------------------------------------------- > > Key: GROOVY-11563 > URL: https://issues.apache.org/jira/browse/GROOVY-11563 > Project: Groovy > Issue Type: Bug > Components: Static compilation, Static Type Checker > Affects Versions: 4.0.25 > Reporter: Martin Häusler > Assignee: Eric Milles > Priority: Major > Fix For: 5.0.0-beta-1 > > > Hello, > I'm using Groovy 4.0.25 on OpenJDK 21. I'm using static compilation. It seems > like the static typechecker is unable to find type issues related to the "+=" > operator. I have a full self-contained JUnit test for you below. > In the test class, there are two test methods that check the output of the > type checker. > Please note that "<number> += <string>" compiles without problems (and it > really should report an issue here), but "<number> = <number> + <string>" > produces the expected compilation issue. > > {code:java} > import groovy.lang.GroovyClassLoader; > import groovy.transform.CompileStatic; > import org.codehaus.groovy.control.CompilationFailedException; > import org.codehaus.groovy.control.CompilationUnit; > import org.codehaus.groovy.control.CompilerConfiguration; > import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer; > import org.codehaus.groovy.control.messages.Message; > import org.codehaus.groovy.control.messages.WarningMessage; > import org.junit.jupiter.api.Test; > import java.util.List; > import java.util.UUID; > import static org.junit.jupiter.api.Assertions.fail; > public class GroovyCompilerStandaloneExampleTest { > @Test > public void testWithPlusEquals() throws Exception { > try { > compileGroovy( > "Number x = 0\n" + > "x += \"hello\"" > ); > fail("No compile error!"); > } catch (CompilationFailedException e) { > // success! > } > } > @Test > public void testWithAssignment() throws Exception { > try { > compileGroovy( > "Number x = 0\n" + > "x = x + \"hello\"" > ); > fail("No compile error!"); > } catch (CompilationFailedException e) { > // success! > } > } > private Class<?> compileGroovy(String source) throws Exception { > ClassLoader classLoader = > Thread.currentThread().getContextClassLoader(); > CompilerConfiguration compilerConfig = createCompilerConfig(); > try (GroovyClassLoader gcl = new GroovyClassLoader(classLoader, > compilerConfig)) { > List<? extends Class<?>> classes = > compileInternal(compilerConfig, gcl, source); > return classes.getFirst(); > } > } > private CompilerConfiguration createCompilerConfig() { > CompilerConfiguration config = new CompilerConfiguration(); > config.setWarningLevel(WarningMessage.PARANOIA); > config.addCompilationCustomizers( > new ASTTransformationCustomizer(CompileStatic.class) > ); > return config; > } > private List<? extends Class<?>> compileInternal( > CompilerConfiguration config, > GroovyClassLoader gcl, > String sourceCode > ) throws Exception { > CompilationUnit compilationUnit = new CompilationUnit(config, null, > gcl); > compilationUnit.addSource("script-" + UUID.randomUUID().toString(), > sourceCode); > compilationUnit.compile(); > List<? extends Message> errors = > compilationUnit.getErrorCollector().getErrors(); > if (errors != null && !errors.isEmpty()) { > fail("Groovy compilation has failed with " + errors.size() + " > errors:\n" + > String.join("\n - ", errors.toString())); > } > return compilationUnit.getClasses().stream().map(groovyClass -> { > gcl.defineClass(groovyClass.getName(), groovyClass.getBytes()); > try { > return gcl.loadClass(groovyClass.getName()); > } catch (ClassNotFoundException e) { > throw new RuntimeException(e); > } > }).toList(); > } > } {code} -- This message was sent by Atlassian Jira (v8.20.10#820010)