[
https://issues.apache.org/jira/browse/GROOVY-12441?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18133810#comment-18133810
]
ASF GitHub Bot commented on GROOVY-12441:
-----------------------------------------
testlens-app[bot] commented on PR #3068:
URL: https://github.com/apache/groovy/pull/3068#issuecomment-6479151626
## ✅ All tests passed ✅
🏷️ Commit: d8cbb64b2d3acb8c0576955d02be270ecf51454b
▶️ Tests: 124040 executed
⚪️ Checks: 32/32 completed
---
_Learn more about TestLens at
[testlens.app/docs](https://testlens.app/docs/features/pr-comment/)._
> STC gets confused when THIS_EXPRESSION is used
> ----------------------------------------------
>
> Key: GROOVY-12441
> URL: https://issues.apache.org/jira/browse/GROOVY-12441
> Project: Groovy
> Issue Type: Bug
> Affects Versions: 2.5.23, 3.0.25, 4.0.33, 5.1.3, 6.0.0
> Reporter: Björn Kautler
> Assignee: Daniel Sun
> Priority: Major
>
> If you use {{VariableExpression.THIS_EXPRESSION}} the STC and thus
> static-compile gets confused.
> I assume this is a bug, if it is expected, sorry for the noise.
> We use this at some places in the Spock transform.
> While trying to make Spock specs compatible with STC and SC, it was observed
> that STC stores type information at the current node and using
> {{VariableExpression.THIS_EXPRESSION}} then causes conflicting casts when
> used inside and outside a closure.
> As a work-around we can instead use {{{}new VariableExpression("this"){}}},
> but I guess this actually is a bug, thus this report.
> As an example.
> {code:java}
> class ASpec extends Specification {
> def "mock init closure"() {
> given:
> List<String> list = Mock(List) {
> size() >> 3
> }
> when:
> int size = list.size()
> then:
> size == 3
> }
> }
> {code}
> compiles in semantic analysis to
> {code:java}
> import spock.lang.*
> @org.spockframework.runtime.model.SpecMetadata(filename = 'script.groovy',
> line = 1)
> public class ASpec extends spock.lang.Specification {
> @org.spockframework.runtime.model.FeatureMetadata(name = 'mock init
> closure', ordinal = 0, line = 2, blocks =
> [@org.spockframework.runtime.model.BlockMetadata(kind =
> org.spockframework.runtime.model.BlockKind.SETUP, texts = []),
> @org.spockframework.runtime.model.BlockMetadata(kind =
> org.spockframework.runtime.model.BlockKind.WHEN, texts = []),
> @org.spockframework.runtime.model.BlockMetadata(kind =
> org.spockframework.runtime.model.BlockKind.THEN, texts = [])], parameterNames
> = [])
> public void $spock_feature_0_0() {
> org.spockframework.runtime.ValueRecorder $spock_valueRecorder = new
> org.spockframework.runtime.ValueRecorder()
> org.spockframework.runtime.ErrorCollector $spock_errorCollector =
> org.spockframework.runtime.ErrorRethrower.INSTANCE
> org.spockframework.runtime.SpockRuntime.callBlockEntered(this, 0)
> java.util.List<String> list =
> org.spockframework.runtime.SpecInternals.MockImpl(this, 'list',
> java.util.List, java.util.List, { ->
>
> this.getSpecificationContext().getMockController().addInteraction(new
> org.spockframework.mock.runtime.InteractionBuilder(5, 7, 'size() >>
> 3').addEqualTarget(it).addEqualMethodName('size').setArgListKind(true,
> false).addConstantResponse(3).build())
> })
> org.spockframework.runtime.SpockRuntime.callBlockExited(this, 0)
> org.spockframework.runtime.SpockRuntime.callBlockEntered(this, 1)
> java.lang.Integer size = list.size()
> org.spockframework.runtime.SpockRuntime.callBlockExited(this, 1)
> org.spockframework.runtime.SpockRuntime.callBlockEntered(this, 2)
> try {
>
> org.spockframework.runtime.SpockRuntime.verifyCondition($spock_errorCollector,
> $spock_valueRecorder.reset(), 'size == 3', 12, 5, null,
> $spock_valueRecorder.record($spock_valueRecorder.startRecordingValue(2),
> $spock_valueRecorder.record($spock_valueRecorder.startRecordingValue(0),
> size) ==
> $spock_valueRecorder.record($spock_valueRecorder.startRecordingValue(1), 3)))
> }
> catch (java.lang.Throwable $spock_condition_throwable) {
>
> org.spockframework.runtime.SpockRuntime.conditionFailedWithException($spock_errorCollector,
> $spock_valueRecorder, 'size == 3', 12, 5, null, $spock_condition_throwable)}
> finally {
> }
> org.spockframework.runtime.SpockRuntime.callBlockExited(this, 2)
> this.getSpecificationContext().getMockController().leaveScope()
> }
> }
> {code}
> The important part here is the two {{getSpecificationContext()}} calls, one
> inside the mock init closure, one as last line in the feature method, both
> added by the Spock transform.
> If those use {{VariableExpression.THIS_EXPRESSION}} then at runtime you get
> {{{}java.lang.ClassCastException: apackage.ASpec cannot be cast to
> apackage.ASpec$__spock_feature_0_0_closure1{}}}.
> If you use {{new VariableExpression("this")}} instead, it works as intended.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)