@@ -142,17 +142,17 @@ private void maybeRecord(Class<?> clazz, Supplier<String> message) {
142
142
delegate .setProperty (lhs , name , value );
143
143
if (SystemProperties .getBoolean (LoggingInvoker .class .getName () + ".fieldSetWarning" , true )) {
144
144
if (value != null && !CLOSURE_METAPROPS .contains (name )) {
145
- var owner = findOwner (lhs );
146
- if (owner instanceof CpsScript ) {
145
+ var receiver = findReceiver (lhs );
146
+ if (receiver instanceof CpsScript ) {
147
147
try {
148
- owner .getClass ().getDeclaredField (name );
148
+ receiver .getClass ().getDeclaredField (name );
149
149
// OK, @Field, ignore
150
150
} catch (NoSuchFieldException x ) {
151
151
var g = CpsThreadGroup .current ();
152
152
if (g != null ) {
153
153
var e = g .getExecution ();
154
154
if (e != null ) {
155
- e .getOwner ().getListener ().getLogger ().println (Messages .LoggingInvoker_field_set (owner .getClass ().getSimpleName (), name , value .getClass ().getSimpleName ()));
155
+ e .getOwner ().getListener ().getLogger ().println (Messages .LoggingInvoker_field_set (receiver .getClass ().getSimpleName (), name , value .getClass ().getSimpleName ()));
156
156
}
157
157
}
158
158
}
@@ -161,8 +161,28 @@ private void maybeRecord(Class<?> clazz, Supplier<String> message) {
161
161
}
162
162
}
163
163
164
- private Object findOwner (Object o ) {
165
- return o instanceof Closure <?> c ? findOwner (c .getOwner ()) : o ;
164
+ private Object findReceiver (Object o ) {
165
+ if (o instanceof Closure <?> c ) {
166
+ // c.f. https://github.com/apache/groovy/blob/41b990d0a20e442f29247f0e04cbed900f3dcad4/src/main/groovy/lang/Closure.java#L344
167
+ return switch (c .getResolveStrategy ()) {
168
+ case Closure .DELEGATE_ONLY -> findReceiver (c .getDelegate ());
169
+ case Closure .OWNER_ONLY -> findReceiver (c .getOwner ());
170
+ case Closure .TO_SELF -> c ;
171
+ case Closure .DELEGATE_FIRST -> {
172
+ var delegate = c .getDelegate ();
173
+ if (delegate == null ) {
174
+ yield findReceiver (c .getOwner ());
175
+ }
176
+ // TODO: Groovy will actually try the delegate first and then the owner if needed, but it is
177
+ // difficult for us to know what will happen in advance.
178
+ yield findReceiver (delegate );
179
+ }
180
+ default ->
181
+ // TODO: Groovy will actually try the owner first and then the delegate if needed.
182
+ findReceiver (c .getOwner ());
183
+ };
184
+ }
185
+ return o ;
166
186
}
167
187
168
188
@ Override public Object getAttribute (Object lhs , String name ) throws Throwable {
0 commit comments