Paul King created GROOVY-12479:
----------------------------------

             Summary: SC: receiver expression is not evaluated when it is used 
to access a static field or call a static method
                 Key: GROOVY-12479
                 URL: https://issues.apache.org/jira/browse/GROOVY-12479
             Project: Groovy
          Issue Type: Bug
            Reporter: Paul King


Under {{@CompileStatic}}, when a static field or static method is reached 
through a receiver expression rather than a class name, the receiver expression 
is never evaluated. Any side effects it has are silently lost. Dynamic Groovy 
and {{@TypeChecked}} evaluate it, as Java does (JLS 15.11.1, 15.12.4.1: for a 
static member the receiver expression is evaluated and the result discarded).

{code:groovy}
class K { static final String CONST = 'c'; static String stat() { 's' } }
class Probe {
    static List log = []
    static Class<Integer> pickClass() { log << 'pickClass'; Integer }
    static K pickInstance() { log << 'pickInstance'; new K() }
}

@groovy.transform.CompileStatic
class CS {
    static a() { Probe.pickClass().MAX_VALUE }   // static field via 
Class-typed expression
    static b() { Probe.pickInstance().CONST }    // static field via 
instance-typed expression
    static c() { Probe.pickInstance().stat() }   // static method via 
instance-typed expression
    static d() { Probe.pickClass().valueOf(1) }  // static method via 
Class-typed expression
}

Probe.log.clear(); CS.a(); assert Probe.log == ['pickClass']      // fails: []
Probe.log.clear(); CS.b(); assert Probe.log == ['pickInstance']   // fails: []
Probe.log.clear(); CS.c(); assert Probe.log == ['pickInstance']   // fails: []
Probe.log.clear(); CS.d(); assert Probe.log == ['pickClass']      // fails: []
{code}

The values are correct in every case; only the evaluation of the receiver is 
missing.

||Case||@CompileStatic||@TypeChecked||dynamic||
|{{pickClass().MAX_VALUE}}|not evaluated|evaluated|evaluated|
|{{pickInstance().CONST}}|not evaluated|evaluated|evaluated|
|{{pickInstance().stat()}}|not evaluated|-|-|
|{{pickClass().valueOf(1)}}|not evaluated|-|-|

Same behaviour in 4.0.32, 5.1.2, 6.0.0 and master.

*Expected:* the receiver expression is evaluated once, its value discarded, and 
the static member accessed, so the static-compiled result matches dynamic 
Groovy and Java.

*Workaround:* evaluate the expression separately (e.g. {{def c = pickClass(); 
c.MAX_VALUE}}), or access the member through the class name.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to