GROOVY-11372: STC: write property via extension method
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index f7a546c..2fbc6b9 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -137,6 +137,7 @@
 import java.util.Optional;
 import java.util.Set;
 import java.util.StringJoiner;
+import java.util.TreeSet;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.function.BiPredicate;
 import java.util.function.Consumer;
@@ -1602,7 +1603,26 @@
                 return true;
             }
 
-            LinkedList<ClassNode> queue = new LinkedList<>();
+            // in case of a lookup on java.lang.Class, look for instance methods on Class
+            // as well; in case of static property access Class<Type> and Type are listed
+            boolean staticOnly = isClassClassNodeWrappingConcreteType(receiverType) ? false
+                                   : (receiver.getData() == null ? staticOnlyAccess : false);
+
+            List<MethodNode> setters = findSetters(wrapTypeIfNecessary(receiverType), setterName, /*voidOnly:*/false);
+            setters = allowStaticAccessToMember(setters, staticOnly);
+            // GROOVY-11319:
+            setters.removeIf(setter -> !hasAccessToMember(typeCheckingContext.getEnclosingClassNode(), setter.getDeclaringClass(), setter.getModifiers()));
+            // GROOVY-11372:
+            var loader = getSourceUnit().getClassLoader();
+            var dgmSet = (TreeSet<MethodNode>) findDGMMethodsForClassNode(loader,            receiverType,  setterName);
+            if (isPrimitiveType(receiverType)) findDGMMethodsForClassNode(loader, getWrapper(receiverType), setterName, dgmSet);
+            for (MethodNode method : dgmSet) {
+                if ((!staticOnly || method.isStatic()) && method.getParameters().length == 1) {
+                    setters.add(method);
+                }
+            }
+
+            var queue = new LinkedList<ClassNode>();
             queue.add(receiverType);
             if (isPrimitiveType(receiverType)) {
                 queue.add(getWrapper(receiverType));
@@ -1618,11 +1638,6 @@
                     Collections.addAll(queue, current.getInterfaces());
                 }
 
-                boolean staticOnly = (receiver.getData() == null ? staticOnlyAccess : false);
-                // in case of a lookup on java.lang.Class, look for instance methods on Class
-                // as well; in case of static property access Class<Type> and Type are listed
-                if (isClassClassNodeWrappingConcreteType(current)) staticOnly = false;
-
                 field = allowStaticAccessToMember(field, staticOnly);
 
                 // skip property/accessor checks for "x.@field"
@@ -1652,10 +1667,6 @@
                             && (!getter.isPublic() || (propertyName.matches("empty|class|metaClass") && !List.of(getTypeCheckingAnnotations()).contains(COMPILESTATIC_CLASSNODE)))))) {
                     getter = null;
                 }
-                List<MethodNode> setters = findSetters(current, setterName, /*voidOnly:*/false);
-                setters = allowStaticAccessToMember(setters, staticOnly);
-                // GROOVY-11319:
-                setters.removeIf(setter -> !hasAccessToMember(typeCheckingContext.getEnclosingClassNode(), setter.getDeclaringClass(), setter.getModifiers()));
 
                 if (readMode && getter != null && visitor != null) visitor.visitMethod(getter);
 
@@ -1709,9 +1720,10 @@
             }
 
             // GROOVY-5568, GROOVY-9115, GROOVY-9123: the property may be defined by an extension
+            if (readMode) // GROOVY-11372
             for (ClassNode dgmReceiver : isPrimitiveType(receiverType) ? new ClassNode[]{receiverType, getWrapper(receiverType)} : new ClassNode[]{receiverType}) {
-                Set<MethodNode> methods = findDGMMethodsForClassNode(getSourceUnit().getClassLoader(), dgmReceiver, getterName);
-                for (MethodNode method : findDGMMethodsForClassNode(getSourceUnit().getClassLoader(), dgmReceiver, isserName)) {
+                Set<MethodNode> methods = findDGMMethodsForClassNode(loader, dgmReceiver, getterName);
+                for (MethodNode method : findDGMMethodsForClassNode(loader, dgmReceiver, isserName)) {
                     if (isPrimitiveBoolean(method.getReturnType())) methods.add(method);
                 }
                 if (staticOnlyAccess && receiver.getData() == null && !isClassType(receiver.getType())) {
@@ -1732,7 +1744,7 @@
                         }
                         ClassNode returnType = inferReturnTypeGenerics(dgmReceiver, getter, ArgumentListExpression.EMPTY_ARGUMENTS);
                         storeInferredTypeForPropertyExpression(pexp, returnType);
-                        if (readMode) storeTargetMethod(pexp, getter);
+                        storeTargetMethod(pexp, getter);
                         return true;
                     }
                 }
diff --git a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
index 142ca9c..0b92a41 100644
--- a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
+++ b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
@@ -478,7 +478,7 @@
     }
 
     // GROOVY-5232
-    void testSetterForProperty() {
+    void testSetterForProperty1() {
         assertScript '''
             class Person {
                 String name
@@ -493,6 +493,16 @@
         '''
     }
 
+    // GROOVY-11372
+    void testSetterForProperty2() {
+        assertScript '''
+            def baos = new ByteArrayOutputStream()
+            assert baos.size() == 0
+            baos.bytes= new byte[1]
+            assert baos.size() == 1
+        '''
+    }
+
     // GROOVY-5443
     void testFieldInitShouldPass() {
         assertScript '''
diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
index 506db21..5ff4102 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
@@ -908,9 +908,9 @@
 
         assertScript '''
             def map = [:]
-            map.metaClass = null // TODO: GROOVY-6549 made this "put" (SC only)!
+            map.metaClass = null
             assert map.metaClass != null
-            assert map.containsKey('metaClass')
+            assert !map.containsKey('metaClass')
         '''
     }