Mattias Reichel created GROOVY-11794:
----------------------------------------

             Summary: STC - Cannot find matching method
                 Key: GROOVY-11794
                 URL: https://issues.apache.org/jira/browse/GROOVY-11794
             Project: Groovy
          Issue Type: Bug
          Components: Static compilation
    Affects Versions: 5.0.0
         Environment: Linux, Java 17
            Reporter: Mattias Reichel


This code fails to compile statically with Groovy 5 but does so successfully 
with Groovy 4.

{color:#b20000} {color}

 

 
{code:java}
[Static type checking] - Cannot find matching method java.lang.Object#get(). 
Please check if the declared type is correct and if the method exists.
 at line: 54, column: 57
[Static type checking] - Cannot find matching method 
java.lang.Object#get(java.lang.String). Please check if the declared type is 
correct and if the method exists.
 at line: 54, column: 25
{code}
 

 
{code:java}
import groovy.transform.CompileStatic
import org.codehaus.groovy.runtime.InvokerHelper
@CompileStatic
class ClosureDecorators {
    /**
     * Wraps a closure so that during its execution, System.getProperty(key)
     * returns a custom value instead of what is actually in the system 
properties.
     */
    static Closure withSystemProperty(Closure target, String key, Object value) 
{
        Closure wrapped = { Object... args ->
            SysPropScope.withProperty(key, value.toString()) {
                InvokerHelper.invokeClosure(target, args)
            }
        }
        // keep original closure semantics
        wrapped.rehydrate(target.delegate, target.owner, target.thisObject).tap 
{
            resolveStrategy = target.resolveStrategy
        }
    }
    @CompileStatic
    private static class SysPropScope {
        static final ThreadLocal<Map<String,String>> 
OVERRIDDEN_SYSTEM_PROPERTIES =
                ThreadLocal.withInitial() { [:] as Map<String,String> }
        @Lazy // Thread-safe wrapping of system properties
        private static Properties propertiesWrappedOnFirstAccess = {
            new InterceptingProperties().tap {
                putAll(System.getProperties())
                System.setProperties(it)
            }
        }()
        static Object withProperty(String key, String value, Closure body) {
            propertiesWrappedOnFirstAccess // Access property to trigger 
property wrapping
            def map = OVERRIDDEN_SYSTEM_PROPERTIES.get()
            def prev = map.put(key, value)
            try {
                return body.call()
            } finally {
                if (prev == null) map.remove(key) else map[key] = prev
                if (map.isEmpty()) OVERRIDDEN_SYSTEM_PROPERTIES.remove()
            }
        }
        @CompileStatic
        private static class InterceptingProperties extends Properties {
            @Override
            String getProperty(String key) {
                def v = OVERRIDDEN_SYSTEM_PROPERTIES.get().get(key)
                v != null ? v : super.getProperty(key)
            }
        }
    }
}
def c1 = {
    System.getProperty('java.version')
}
def c2 = ClosureDecorators.withSystemProperty(c1, 'java.version', 'hello')
println c1()
println c2()
{code}
Adding a cast to line 54 does resolve the problem:
{code:java}
def v = ((ThreadLocal<Map<String,String>>) 
OVERRIDDEN_SYSTEM_PROPERTIES).get().get(key){code}
 

 



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to