[ https://issues.apache.org/jira/browse/GROOVY-11591?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17939477#comment-17939477 ]
Jochen Theodorou commented on GROOVY-11591: ------------------------------------------- I think the correct way would be a single evaluation of the receiver. This means that we would have to implement for x?.y(z): {code:Groovy} tmp = x tmp? tmp.y(z) : null {code} That would mean for dynamic Groovy to have the callsite code changed and do safe navigation before the call and the safe call is removed as case for invokedynamic. And it would mean the static variant should change as well, since it exhibits the same "problem". And since it is only arguably a bug, I think this should be 5.0 only. > safe call evaluates arguments > ------------------------------ > > Key: GROOVY-11591 > URL: https://issues.apache.org/jira/browse/GROOVY-11591 > Project: Groovy > Issue Type: Bug > Components: class generator > Reporter: OC > Assignee: Eric Milles > Priority: Minor > Fix For: 5.0.0-alpha-13 > > > A safe method call first evaluates method's arguments, and only then trashes > the call. It would seem to me much better if the arguments were not evaluated > in this case (precisely same way as if we used the java-like “if (obj) > obj.whatever...” approach instead of the safe call). > Based on Jochen insight, what probably happens is > * push arguments on stack > * push receiver on stack > * write jmp if null > * write method call > * jmp to after call > * marker for null case > * remove elements from stack > * push null > * marker for after call > Testable e.g., by > {code:java} > 1040 ocs /tmp> <q.groovy > class qq { > def foo(String s) { > println "foo called!" > s > } > def bar(String s) { > println "bar: $s" > } > } > null?.bar(new qq().foo('Oops!')) > 1041 ocs /tmp> /usr/local/groovy-4.0.25/bin/groovy q > foo called! > 1042 ocs /tmp> {code} -- This message was sent by Atlassian Jira (v8.20.10#820010)