[ 
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)

Reply via email to