You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Paul King (Jira)" <ji...@apache.org> on 2025/06/04 14:46:00 UTC
[jira] [Closed] (GROOVY-11563) CompileStatic does not detect type mismatch on "+="
[ 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)