You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@groovy.apache.org by Jonny <jo...@apache.org> on 2025/06/16 22:18:33 UTC

Static Type Checker Changes for Closure Parameters in 4.0.19 onward

Cross-posting to the mailing list from Slack
<https://groovy-community.slack.com/archives/C2NEFCM55/p1750110654202509>.

I'm trying to debug an issue with the static type checker and closure
method parameters. It seems like in Groovy 4.0.19, something changed that
has broken type checking for statements like:

cfValues['SpecialKey']*.name.collect {it.toUpperCase()}

Some context: cfValues is a binding variable that I provide custom type
information for via a ClassCodeExpressionTransformer.

In this case, the static type checker seems to know that
cfValues['SpecialKey'] returns a value of the expected type which, in turn,
has a name property that is a String. Statements like:

cfValues['SpecialKey']*.name*.toUpperCase()

compile just fine. But from Groovy 4.0.19 onward, the static type checker
only seems to think that the it Closure parameter is an Object, not a
String. I've been poring over the diff, the changelog
<https://groovy-lang.org/changelogs/changelog-4.0.19.html>, and stepping
through the debugger to figure out what changed, but I haven't been able to
fathom it out. Does this ring a bell for anyone?

Thanks for any pointers.

Best,

Jonny Carter

Re: Static Type Checker Changes for Closure Parameters in 4.0.19 onward

Posted by Jonny <jo...@apache.org>.
Well, `cfValues` is a bit upstream of the closure parameter. The
expressions getting checked are more like:

cfValues['MultiGroupPicker']*.name.collect {it.toUpperCase()}.contains("AAA")

So `it` is the closure parameter. Through my ClassCodeExpressionTransformer,
Groovy knows the type of cfValues['MultiGroupPicker'], and so can infer
that the `name` property is a string. It was actually handling expressions
like

cfValues['MultiGroupPicker']*.name*.toUpperCase().contains("AAA")

just fine, which makes sense given that the bug was only happening in the
parameter processing branch of the getType method.

I did a local build off the 4.0 line with that cherry-picked commit (thanks
for back-porting, btw!), and it resolved the problem with no ill side
effects. Reckon we'll just need the next 4.x release and we'll be right as
rain. :)

On Thu, Jul 3, 2025 at 11:12 AM Milles, Eric (TR Technology) <
eric.milles@thomsonreuters.com> wrote:

> So in your code, is "cfValues" a closure parameter that is supposed to be
> helped by ClosureParams metadata?
>
> This should resolve the problem:
> https://github.com/apache/groovy/commit/e0a02a28738736334ba3b14de5bfa34895710aff
>
>
> ------------------------------
> *From:* Jonathan Carter <jo...@gmail.com>
> *Sent:* Wednesday, July 2, 2025 8:39 PM
> *To:* dev@groovy.apache.org <de...@groovy.apache.org>
> *Cc:* Milles, Eric (TR Technology) <er...@thomsonreuters.com>
> *Subject:* [EXT] Re: Static Type Checker Changes for Closure Parameters
> in 4.0.19 onward
>
> *External Email:* Use caution with links and attachments.
>
> Been debugging on this a bit. I've not yet been able to get a script that
> reproduces the problem outside of my application. However, I think I've
> tracked down the source of the problem and I'm *pretty* sure it's a bug?
>
>
> org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor#getTemporaryTypesForExpression changed
> in 4.0.19 so that it would always return an empty list. However, that
> disrupts the logic of
> org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor#getType,
> which has checks like:
>
> if (type == null && temporaryTypesForExpression == null) {
>
> ...which will basically never evaluate to true, meaning that
>
> getTypeFromClosureArguments(parameter);
>
> doesn't get hit.
>
> Sorry for the stream of consciousness. I'll try and get a repro script & a
> bug report together.
>
> On Tue, Jun 17, 2025 at 8:28 AM Milles, Eric (TR Technology) via dev <
> dev@groovy.apache.org> wrote:
>
> Could you provide a small script that demonstrates the issue?
>
> For your example, what is the type returned by "cfValues['SpecialKey']"?
> Is it a list, map or some user-defined type?  What is the expected type of
> "cfValues['SpecialKey']*.name" if you assigned it to a temporary variable?
>
> Determining the aggregate type when applying the * operator has had some
> fixes to it.  If you supply special metadata to help type on of the
> subexpressions, can you say what keys you are using or are you using a
> type-checker extension?
>
>
> ------------------------------
> *From:* Jonny <jo...@apache.org>
> *Sent:* Monday, June 16, 2025 5:18 PM
> *To:* dev@groovy.apache.org <de...@groovy.apache.org>
> *Subject:* [EXT] Static Type Checker Changes for Closure Parameters in
> 4.0.19 onward
>
> *External Email:* Use caution with links and attachments.
>
> Cross-posting to the mailing list from Slack
> <https://urldefense.com/v3/__https://groovy-community.slack.com/archives/C2NEFCM55/p1750110654202509__;!!GFN0sa3rsbfR8OLyAw!YZyV0o3N2Xf4XCeQ_ksNawkcRNlQN2eVfW0Z6J8my3GZOuFXbV_v5_Bp1S1rbqvW8x3WewID0n1WMO6C9zhl6V9g$>
> .
>
> I'm trying to debug an issue with the static type checker and closure
> method parameters. It seems like in Groovy 4.0.19, something changed that
> has broken type checking for statements like:
>
> cfValues['SpecialKey']*.name.collect {it.toUpperCase()}
>
> Some context: cfValues is a binding variable that I provide custom type
> information for via a ClassCodeExpressionTransformer.
>
> In this case, the static type checker seems to know that
> cfValues['SpecialKey'] returns a value of the expected type which, in turn,
> has a name property that is a String. Statements like:
>
> cfValues['SpecialKey']*.name*.toUpperCase()
>
> compile just fine. But from Groovy 4.0.19 onward, the static type checker
> only seems to think that the it Closure parameter is an Object, not a
> String. I've been poring over the diff, the changelog
> <https://urldefense.com/v3/__https://groovy-lang.org/changelogs/changelog-4.0.19.html__;!!GFN0sa3rsbfR8OLyAw!YZyV0o3N2Xf4XCeQ_ksNawkcRNlQN2eVfW0Z6J8my3GZOuFXbV_v5_Bp1S1rbqvW8x3WewID0n1WMO6C9xN9UByT$>,
> and stepping through the debugger to figure out what changed, but I haven't
> been able to fathom it out. Does this ring a bell for anyone?
>
> Thanks for any pointers.
>
> Best,
>
> Jonny Carter
>
>

Re: Static Type Checker Changes for Closure Parameters in 4.0.19 onward

Posted by "Milles, Eric (TR Technology) via dev" <de...@groovy.apache.org>.
So in your code, is "cfValues" a closure parameter that is supposed to be helped by ClosureParams metadata?

This should resolve the problem: https://github.com/apache/groovy/commit/e0a02a28738736334ba3b14de5bfa34895710aff


________________________________
From: Jonathan Carter <jo...@gmail.com>
Sent: Wednesday, July 2, 2025 8:39 PM
To: dev@groovy.apache.org <de...@groovy.apache.org>
Cc: Milles, Eric (TR Technology) <er...@thomsonreuters.com>
Subject: [EXT] Re: Static Type Checker Changes for Closure Parameters in 4.0.19 onward

External Email: Use caution with links and attachments.

Been debugging on this a bit. I've not yet been able to get a script that reproduces the problem outside of my application. However, I think I've tracked down the source of the problem and I'm pretty sure it's a bug?

org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor#getTemporaryTypesForExpression changed in 4.0.19 so that it would always return an empty list. However, that disrupts the logic of org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor#getType, which has checks like:

if (type == null && temporaryTypesForExpression == null) {

...which will basically never evaluate to true, meaning that

getTypeFromClosureArguments(parameter);

doesn't get hit.

Sorry for the stream of consciousness. I'll try and get a repro script & a bug report together.

On Tue, Jun 17, 2025 at 8:28 AM Milles, Eric (TR Technology) via dev <de...@groovy.apache.org>> wrote:
Could you provide a small script that demonstrates the issue?

For your example, what is the type returned by "cfValues['SpecialKey']"?  Is it a list, map or some user-defined type?  What is the expected type of "cfValues['SpecialKey']*.name" if you assigned it to a temporary variable?

Determining the aggregate type when applying the * operator has had some fixes to it.  If you supply special metadata to help type on of the subexpressions, can you say what keys you are using or are you using a type-checker extension?


________________________________
From: Jonny <jo...@apache.org>>
Sent: Monday, June 16, 2025 5:18 PM
To: dev@groovy.apache.org<ma...@groovy.apache.org> <de...@groovy.apache.org>>
Subject: [EXT] Static Type Checker Changes for Closure Parameters in 4.0.19 onward

External Email: Use caution with links and attachments.

Cross-posting to the mailing list from Slack<https://urldefense.com/v3/__https://groovy-community.slack.com/archives/C2NEFCM55/p1750110654202509__;!!GFN0sa3rsbfR8OLyAw!YZyV0o3N2Xf4XCeQ_ksNawkcRNlQN2eVfW0Z6J8my3GZOuFXbV_v5_Bp1S1rbqvW8x3WewID0n1WMO6C9zhl6V9g$>.

I'm trying to debug an issue with the static type checker and closure method parameters. It seems like in Groovy 4.0.19, something changed that has broken type checking for statements like:

cfValues['SpecialKey']*.name.collect {it.toUpperCase()}

Some context: cfValues is a binding variable that I provide custom type information for via a ClassCodeExpressionTransformer.

In this case, the static type checker seems to know that cfValues['SpecialKey'] returns a value of the expected type which, in turn, has a name property that is a String. Statements like:

cfValues['SpecialKey']*.name*.toUpperCase()

compile just fine. But from Groovy 4.0.19 onward, the static type checker only seems to think that the it Closure parameter is an Object, not a String. I've been poring over the diff, the changelog<https://urldefense.com/v3/__https://groovy-lang.org/changelogs/changelog-4.0.19.html__;!!GFN0sa3rsbfR8OLyAw!YZyV0o3N2Xf4XCeQ_ksNawkcRNlQN2eVfW0Z6J8my3GZOuFXbV_v5_Bp1S1rbqvW8x3WewID0n1WMO6C9xN9UByT$>, and stepping through the debugger to figure out what changed, but I haven't been able to fathom it out. Does this ring a bell for anyone?

Thanks for any pointers.

Best,

Jonny Carter

Re: Static Type Checker Changes for Closure Parameters in 4.0.19 onward

Posted by Jonathan Carter <jo...@gmail.com>.
Been debugging on this a bit. I've not yet been able to get a script that
reproduces the problem outside of my application. However, I think I've
tracked down the source of the problem and I'm *pretty* sure it's a bug?

org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor#getTemporaryTypesForExpression
changed in 4.0.19 so that it would always return an empty list. However,
that disrupts the logic of
org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor#getType, which
has checks like:

if (type == null && temporaryTypesForExpression == null) {

...which will basically never evaluate to true, meaning that

getTypeFromClosureArguments(parameter);

doesn't get hit.

Sorry for the stream of consciousness. I'll try and get a repro script & a
bug report together.

On Tue, Jun 17, 2025 at 8:28 AM Milles, Eric (TR Technology) via dev <
dev@groovy.apache.org> wrote:

> Could you provide a small script that demonstrates the issue?
>
> For your example, what is the type returned by "cfValues['SpecialKey']"?
> Is it a list, map or some user-defined type?  What is the expected type of
> "cfValues['SpecialKey']*.name" if you assigned it to a temporary variable?
>
> Determining the aggregate type when applying the * operator has had some
> fixes to it.  If you supply special metadata to help type on of the
> subexpressions, can you say what keys you are using or are you using a
> type-checker extension?
>
>
> ------------------------------
> *From:* Jonny <jo...@apache.org>
> *Sent:* Monday, June 16, 2025 5:18 PM
> *To:* dev@groovy.apache.org <de...@groovy.apache.org>
> *Subject:* [EXT] Static Type Checker Changes for Closure Parameters in
> 4.0.19 onward
>
> *External Email:* Use caution with links and attachments.
>
> Cross-posting to the mailing list from Slack
> <https://urldefense.com/v3/__https://groovy-community.slack.com/archives/C2NEFCM55/p1750110654202509__;!!GFN0sa3rsbfR8OLyAw!YZyV0o3N2Xf4XCeQ_ksNawkcRNlQN2eVfW0Z6J8my3GZOuFXbV_v5_Bp1S1rbqvW8x3WewID0n1WMO6C9zhl6V9g$>
> .
>
> I'm trying to debug an issue with the static type checker and closure
> method parameters. It seems like in Groovy 4.0.19, something changed that
> has broken type checking for statements like:
>
> cfValues['SpecialKey']*.name.collect {it.toUpperCase()}
>
> Some context: cfValues is a binding variable that I provide custom type
> information for via a ClassCodeExpressionTransformer.
>
> In this case, the static type checker seems to know that
> cfValues['SpecialKey'] returns a value of the expected type which, in turn,
> has a name property that is a String. Statements like:
>
> cfValues['SpecialKey']*.name*.toUpperCase()
>
> compile just fine. But from Groovy 4.0.19 onward, the static type checker
> only seems to think that the it Closure parameter is an Object, not a
> String. I've been poring over the diff, the changelog
> <https://urldefense.com/v3/__https://groovy-lang.org/changelogs/changelog-4.0.19.html__;!!GFN0sa3rsbfR8OLyAw!YZyV0o3N2Xf4XCeQ_ksNawkcRNlQN2eVfW0Z6J8my3GZOuFXbV_v5_Bp1S1rbqvW8x3WewID0n1WMO6C9xN9UByT$>,
> and stepping through the debugger to figure out what changed, but I haven't
> been able to fathom it out. Does this ring a bell for anyone?
>
> Thanks for any pointers.
>
> Best,
>
> Jonny Carter
>

Re: Static Type Checker Changes for Closure Parameters in 4.0.19 onward

Posted by "Milles, Eric (TR Technology) via dev" <de...@groovy.apache.org>.
Could you provide a small script that demonstrates the issue?

For your example, what is the type returned by "cfValues['SpecialKey']"?  Is it a list, map or some user-defined type?  What is the expected type of "cfValues['SpecialKey']*.name" if you assigned it to a temporary variable?

Determining the aggregate type when applying the * operator has had some fixes to it.  If you supply special metadata to help type on of the subexpressions, can you say what keys you are using or are you using a type-checker extension?


________________________________
From: Jonny <jo...@apache.org>
Sent: Monday, June 16, 2025 5:18 PM
To: dev@groovy.apache.org <de...@groovy.apache.org>
Subject: [EXT] Static Type Checker Changes for Closure Parameters in 4.0.19 onward

External Email: Use caution with links and attachments.

Cross-posting to the mailing list from Slack<https://urldefense.com/v3/__https://groovy-community.slack.com/archives/C2NEFCM55/p1750110654202509__;!!GFN0sa3rsbfR8OLyAw!YZyV0o3N2Xf4XCeQ_ksNawkcRNlQN2eVfW0Z6J8my3GZOuFXbV_v5_Bp1S1rbqvW8x3WewID0n1WMO6C9zhl6V9g$>.

I'm trying to debug an issue with the static type checker and closure method parameters. It seems like in Groovy 4.0.19, something changed that has broken type checking for statements like:

cfValues['SpecialKey']*.name.collect {it.toUpperCase()}

Some context: cfValues is a binding variable that I provide custom type information for via a ClassCodeExpressionTransformer.

In this case, the static type checker seems to know that cfValues['SpecialKey'] returns a value of the expected type which, in turn, has a name property that is a String. Statements like:

cfValues['SpecialKey']*.name*.toUpperCase()

compile just fine. But from Groovy 4.0.19 onward, the static type checker only seems to think that the it Closure parameter is an Object, not a String. I've been poring over the diff, the changelog<https://urldefense.com/v3/__https://groovy-lang.org/changelogs/changelog-4.0.19.html__;!!GFN0sa3rsbfR8OLyAw!YZyV0o3N2Xf4XCeQ_ksNawkcRNlQN2eVfW0Z6J8my3GZOuFXbV_v5_Bp1S1rbqvW8x3WewID0n1WMO6C9xN9UByT$>, and stepping through the debugger to figure out what changed, but I haven't been able to fathom it out. Does this ring a bell for anyone?

Thanks for any pointers.

Best,

Jonny Carter