You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2022/11/10 23:49:28 UTC

[groovy] branch master updated: GROOVY-10820: STC: static methods for `Type.name()` except from `Class`

This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/master by this push:
     new 7bf356afad GROOVY-10820: STC: static methods for `Type.name()` except from `Class`
7bf356afad is described below

commit 7bf356afad7c3f4c28edc2395ad54a7e7e633b84
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Thu Nov 10 14:56:31 2022 -0600

    GROOVY-10820: STC: static methods for `Type.name()` except from `Class`
---
 .../transform/stc/StaticTypeCheckingVisitor.java   |  91 ++-
 src/spec/test/typing/TypeCheckingTest.groovy       |   3 +-
 src/test/groovy/bugs/Groovy7204Bug.groovy          |  23 +-
 src/test/groovy/bugs/Groovy7987.groovy             |  44 --
 src/test/groovy/bugs/Groovy8609Bug.groovy          | 171 +++--
 .../groovy/transform/stc/GenericsSTCTest.groovy    |  20 +-
 .../groovy/transform/stc/MethodCallsSTCTest.groovy | 129 ++--
 .../classgen/asm/sc/BugsStaticCompileTest.groovy   | 691 +++++++++++----------
 .../asm/sc/StaticCompilationTestSupport.groovy     |   2 +
 .../main/groovy/groovy/console/ui/Console.groovy   |  24 +-
 10 files changed, 571 insertions(+), 627 deletions(-)

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 e4eb401715..44e92b6ce5 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -274,7 +274,6 @@ import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.evalua
 import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.extractGenericsConnections;
 import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.extractGenericsParameterMapOfThis;
 import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.filterMethodsByVisibility;
-import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.findDGMMethodsByNameAndArguments;
 import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.findDGMMethodsForClassNode;
 import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.findSetters;
 import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.findTargetVariable;
@@ -1653,8 +1652,8 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
 
             // GROOVY-5568: the property may be defined by DGM
             for (ClassNode dgmReceiver : isPrimitiveType(receiverType) ? new ClassNode[]{receiverType, getWrapper(receiverType)} : new ClassNode[]{receiverType}) {
-                List<MethodNode> methods = findDGMMethodsByNameAndArguments(getSourceUnit().getClassLoader(), dgmReceiver, "get" + capName, ClassNode.EMPTY_ARRAY);
-                for (MethodNode method : findDGMMethodsByNameAndArguments(getSourceUnit().getClassLoader(), dgmReceiver, "is" + capName, ClassNode.EMPTY_ARRAY)) {
+                Set<MethodNode> methods = findDGMMethodsForClassNode(getSourceUnit().getClassLoader(), dgmReceiver, "get" + capName);
+                for (MethodNode method : findDGMMethodsForClassNode(getSourceUnit().getClassLoader(), dgmReceiver, "is" + capName)) {
                     if (isPrimitiveBoolean(method.getReturnType())) methods.add(method);
                 }
                 if (isUsingGenericsOrIsArrayUsingGenerics(dgmReceiver)) {
@@ -1833,10 +1832,10 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
         boolean isStatic;
         if (member instanceof FieldNode) {
             isStatic = ((FieldNode) member).isStatic();
-        } else if (member instanceof MethodNode) {
-            isStatic = ((MethodNode) member).isStatic();
-        } else {
+        } else if (member instanceof PropertyNode) {
             isStatic = ((PropertyNode) member).isStatic();
+        } else { // assume member instanceof MethodNode
+            isStatic = member instanceof ExtensionMethodNode ? ((ExtensionMethodNode) member).isStaticExtension() : ((MethodNode) member).isStatic();
         }
         return (isStatic ? member : null);
     }
@@ -3347,7 +3346,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                 if (dmd.getParent() == null) {
                     receivers.addAll(owners);
                 } else {
-                    //receivers.add(new Receiver<String>(CLOSURE_TYPE, path + "owner"));
+                  //receivers.add(new Receiver<String>(CLOSURE_TYPE, path + "owner"));
                     addReceivers(receivers, owners, dmd.getParent(), path + "owner.");
                 }
             }
@@ -3357,7 +3356,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
             if (dmd.getParent() == null) {
                 receivers.addAll(owners);
             } else {
-                //receivers.add(new Receiver<String>(CLOSURE_TYPE, path + "owner"));
+              //receivers.add(new Receiver<String>(CLOSURE_TYPE, path + "owner"));
                 addReceivers(receivers, owners, dmd.getParent(), path + "owner.");
             }
             if (strategy == Closure.OWNER_FIRST) {
@@ -3368,6 +3367,9 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
     }
 
     private static void addDelegateReceiver(final List<Receiver<String>> receivers, final ClassNode delegate, final String path) {
+        if (isClassClassNodeWrappingConcreteType(delegate)) { // add Type from Class<Type>
+            addDelegateReceiver(receivers, delegate.getGenericsTypes()[0].getType(), path);
+        }
         if (receivers.stream().map(Receiver::getType).noneMatch(delegate::equals)) {
             receivers.add(new Receiver<>(delegate, path));
         }
@@ -3498,38 +3500,20 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                 List<Receiver<String>> receivers = new ArrayList<>();
                 addReceivers(receivers, makeOwnerList(objectExpression), call.isImplicitThis());
 
+                MethodNode first = null;
                 List<MethodNode> mn = null;
                 Receiver<String> chosenReceiver = null;
                 for (Receiver<String> currentReceiver : receivers) {
-                    ClassNode receiverType = currentReceiver.getType();
-                    mn = findMethod(receiverType, name, args);
-
-                    // if receiver is "this" in a static context then only static methods are compatible
-                    // if not in a static context but the current receiver is a static class ensure that
-                    // all methods are either static or declared by the current receiver or a superclass
-                    if (!mn.isEmpty() && currentReceiver.getData() == null && (isThisObjectExpression || call.isImplicitThis())
-                            && (typeCheckingContext.isInStaticContext || (receiverType.getModifiers() & Opcodes.ACC_STATIC) != 0)) {
-                        // we create separate method lists just to be able to print out
-                        // a nice error message to the user
-                        // a method is accessible if it is static, or if we are not in a static context and it is
-                        // declared by the current receiver or a superclass
-                        List<MethodNode> accessibleMethods = new LinkedList<>();
-                        List<MethodNode> inaccessibleMethods = new LinkedList<>();
-                        for (final MethodNode node : mn) {
-                            if (node.isStatic() || (!typeCheckingContext.isInStaticContext
-                                    && implementsInterfaceOrIsSubclassOf(receiverType, node.getDeclaringClass()))) {
-                                accessibleMethods.add(node);
-                            } else {
-                                inaccessibleMethods.add(node);
-                            }
-                        }
-                        mn = accessibleMethods;
-                        if (accessibleMethods.isEmpty()) {
-                            MethodNode node = inaccessibleMethods.get(0); // choose an arbitrary method to display an error message
-                            addStaticTypeError("Non-static method " + prettyPrintTypeName(node.getDeclaringClass()) + "#" + node.getName() + " cannot be called from static context", call);
+                    mn = findMethod(currentReceiver.getType().getPlainNodeReference(), name, args);
+                    if (!mn.isEmpty()) {
+                        first = mn.get(0); // capture for error string
+                        // for "this" in a static context, only static methods are compatible
+                        if (currentReceiver.getData() == null && !isClassType(currentReceiver.getType())) {
+                            boolean staticThis = (isThisObjectExpression || call.isImplicitThis()) && typeCheckingContext.isInStaticContext;
+                            boolean staticThat = isClassClassNodeWrappingConcreteType(receiver); // GROOVY-10819, GROOVY-10820
+                            mn = allowStaticAccessToMember(mn, staticThis || staticThat);
                         }
                     }
-
                     if (!mn.isEmpty()) {
                         chosenReceiver = currentReceiver;
                         break;
@@ -3538,19 +3522,17 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                 if (mn.isEmpty() && isThisObjectExpression && call.isImplicitThis() && typeCheckingContext.getEnclosingClosure() != null) {
                     mn = CLOSURE_TYPE.getDeclaredMethods(name);
                     if (!mn.isEmpty()) {
-                        chosenReceiver = Receiver.make(CLOSURE_TYPE);
                         objectExpression.removeNodeMetaData(INFERRED_TYPE);
                     }
                 }
                 if (mn.isEmpty()) {
                     mn = extension.handleMissingMethod(receiver, name, argumentList, args, call);
+                    if (mn.isEmpty() && first != null) mn.add(first); // non-static method error?
                 }
                 if (mn.isEmpty()) {
                     addNoMatchingMethodError(receiver, name, args, call);
                 } else {
-                    if (areCategoryMethodCalls(mn, name, args)) {
-                        addCategoryMethodCallError(call);
-                    }
+                    if (areCategoryMethodCalls(mn, name, args)) addCategoryMethodCallError(call);
 
                     {
                         ClassNode obj = chosenReceiver != null ? chosenReceiver.getType() : null;
@@ -3569,8 +3551,11 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                     if (mn.size() == 1) {
                         MethodNode targetMethodCandidate = mn.get(0);
                         ClassNode declaringClass = targetMethodCandidate.getDeclaringClass();
-                        if (!targetMethodCandidate.isStatic() && !isClassType(declaringClass)
-                                && objectExpression instanceof ClassExpression && call.getNodeMetaData(DYNAMIC_RESOLUTION) == null) {
+                        if (chosenReceiver == null) {
+                            chosenReceiver = Receiver.make(declaringClass.getPlainNodeReference());
+                        }
+                        if (!targetMethodCandidate.isStatic() && !isClassType(declaringClass) && isClassType(receiver)
+                                && chosenReceiver.getData() == null && call.getNodeMetaData(DYNAMIC_RESOLUTION) == null) {
                             addStaticTypeError("Non-static method " + prettyPrintTypeName(declaringClass) + "#" + targetMethodCandidate.getName() + " cannot be called from static context", call);
                         } else if (targetMethodCandidate.isAbstract() && isSuperExpression(objectExpression)) { // GROOVY-10341
                             String target = toMethodParametersString(targetMethodCandidate.getName(), extractTypesFromParameters(targetMethodCandidate.getParameters()));
@@ -3580,9 +3565,6 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                                 addStaticTypeError("Abstract method " + target + " cannot be called directly", call);
                             }
                         }
-                        if (chosenReceiver == null) {
-                            chosenReceiver = Receiver.make(declaringClass);
-                        }
                         // note second pass here to differentiate from extension that sets type
                         boolean mergeType = (call.getNodeMetaData(INFERRED_TYPE) != null);
                         storeTargetMethod(call, targetMethodCandidate);
@@ -5004,11 +4986,12 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                     methods.add(callMethod);
                 }
             }
-            if (!receiver.isStaticClass() && receiver.getOuterClass() != null
-                    && typeCheckingContext.getEnclosingClassNodes().contains(receiver)) {
-                ClassNode outer = receiver.getOuterClass();
-                do { methods.addAll(findMethodsWithGenerated(outer, name));
-                } while (!outer.isStaticClass() && (outer = outer.getOuterClass()) != null);
+            if (typeCheckingContext.getEnclosingClassNodes().contains(receiver)) {
+                boolean staticOnly = Modifier.isStatic(receiver.getModifiers());
+                for (ClassNode outer = receiver; (outer = outer.getOuterClass()) != null;
+                        staticOnly = staticOnly || Modifier.isStatic(outer.getModifiers())) {
+                    methods.addAll(allowStaticAccessToMember(findMethodsWithGenerated(outer, name), staticOnly));
+                }
             }
             if (methods.isEmpty()) {
                 addArrayMethods(methods, receiver, name, args);
@@ -5072,7 +5055,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
             }
         }
 
-        if (isClassClassNodeWrappingConcreteType(receiver)) { // GROOVY-6802, GROOVY-6803
+        if (isClassClassNodeWrappingConcreteType(receiver)) { // GROOVY-6802, GROOVY-6803, GROOVY-9415
             List<MethodNode> result = findMethod(receiver.getGenericsTypes()[0].getType(), name, args);
             if (!result.isEmpty()) return result;
         }
@@ -5935,11 +5918,9 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
         }
     }
 
-    protected void addNoMatchingMethodError(ClassNode receiver, final String name, final ClassNode[] args, final Expression call) {
-        if (isClassClassNodeWrappingConcreteType(receiver)) {
-            receiver = receiver.getGenericsTypes()[0].getType();
-        }
-        addStaticTypeError("Cannot find matching method " + prettyPrintTypeName(receiver) + "#" + toMethodParametersString(name, args) + ". Please check if the declared type is correct and if the method exists.", call);
+    protected void addNoMatchingMethodError(final ClassNode receiver, final String name, final ClassNode[] args, final Expression call) {
+        ClassNode type = isClassClassNodeWrappingConcreteType(receiver) ? receiver.getGenericsTypes()[0].getType() : receiver;
+        addStaticTypeError("Cannot find matching method " + prettyPrintTypeName(type) + "#" + toMethodParametersString(name, args) + ". Please check if the declared type is correct and if the method exists.", call);
     }
 
     protected void addAmbiguousErrorMessage(final List<MethodNode> foundMethods, final String name, final ClassNode[] args, final Expression expr) {
diff --git a/src/spec/test/typing/TypeCheckingTest.groovy b/src/spec/test/typing/TypeCheckingTest.groovy
index 75d85b92ee..84c18ac9ef 100644
--- a/src/spec/test/typing/TypeCheckingTest.groovy
+++ b/src/spec/test/typing/TypeCheckingTest.groovy
@@ -700,7 +700,8 @@ import static org.codehaus.groovy.ast.tools.WideningCategories.lowestUpperBound
             }
             // end::flowtyping_typeconstraints_failure[]
             flowTypingWithExplicitType()
-        ''', '[Static type checking] - Cannot find matching method java.util.ArrayList#add(int)'
+        ''',
+        'Cannot call java.util.ArrayList#add(java.lang.String) with arguments [int]'
 
         assertScript '''
             // tag::flowtyping_typeconstraints_fixed[]
diff --git a/src/test/groovy/bugs/Groovy7204Bug.groovy b/src/test/groovy/bugs/Groovy7204Bug.groovy
index 59254ff8b1..749dbc5ddb 100644
--- a/src/test/groovy/bugs/Groovy7204Bug.groovy
+++ b/src/test/groovy/bugs/Groovy7204Bug.groovy
@@ -18,6 +18,7 @@
  */
 package groovy.bugs
 
+import groovy.test.NotYetImplemented
 import org.junit.Test
 
 import static groovy.test.GroovyAssert.assertScript
@@ -57,13 +58,11 @@ final class Groovy7204Bug {
             class MyRepositoryImpl implements MyRepository {
                 @Override
                 public void delete(String arg) {
-                    System.out.println('String')
                     assert true
                 }
 
                 @Override
                 public void delete(Long arg) {
-                    System.out.println('Long')
                     assert false: 'wrong method invoked'
                 }
             }
@@ -99,13 +98,11 @@ final class Groovy7204Bug {
             class MyRepositoryImpl extends MyRepository {
                 @Override
                 public void delete(String arg) {
-                    System.out.println('String')
                     assert true
                 }
 
                 @Override
                 public void delete(Long arg) {
-                    System.out.println('Long')
                     assert false: 'wrong method invoked'
                 }
             }
@@ -145,13 +142,11 @@ final class Groovy7204Bug {
             class MyRepositoryImpl implements MyRepository {
                 @Override
                 public void delete(String arg) {
-                    System.out.println('String')
                     assert true
                 }
 
                 @Override
                 public void delete(Long arg) {
-                    System.out.println('Long')
                     assert false: 'wrong method invoked'
                 }
             }
@@ -191,13 +186,11 @@ final class Groovy7204Bug {
             class MyRepositoryImpl extends MyRepository {
                 @Override
                 public void delete(String arg) {
-                    System.out.println('String')
                     assert true
                 }
 
                 @Override
                 public void delete(Long arg) {
-                    System.out.println('Long')
                     assert false: 'wrong method invoked'
                 }
             }
@@ -237,13 +230,11 @@ final class Groovy7204Bug {
             class MyRepositoryImpl extends MyRepository {
                 @Override
                 public void delete(String arg) {
-                    System.out.println('String')
                     assert true
                 }
 
                 @Override
                 public void delete(Long arg) {
-                    System.out.println('Long')
                     assert false: 'wrong method invoked'
                 }
             }
@@ -281,13 +272,11 @@ final class Groovy7204Bug {
             class MyRepositoryImpl implements MyRepository {
                 @Override
                 public void delete(String arg) {
-                    System.out.println('String')
                     assert true
                 }
 
                 @Override
                 public void delete(Long arg) {
-                    System.out.println('Long')
                     assert false: 'wrong method invoked'
                 }
             }
@@ -323,13 +312,11 @@ final class Groovy7204Bug {
             class MyRepositoryImpl extends MyRepository {
                 @Override
                 public void delete(String arg) {
-                    System.out.println('String')
                     assert true
                 }
 
                 @Override
                 public void delete(Long arg) {
-                    System.out.println('Long')
                     assert false: 'wrong method invoked'
                 }
             }
@@ -369,13 +356,11 @@ final class Groovy7204Bug {
             class MyRepositoryImpl implements MyRepository {
                 @Override
                 public void delete(String arg) {
-                    System.out.println('String')
                     assert true
                 }
 
                 @Override
                 public void delete(Long arg) {
-                    System.out.println('Long')
                     assert false: 'wrong method invoked'
                 }
             }
@@ -415,13 +400,11 @@ final class Groovy7204Bug {
             class MyRepositoryImpl extends MyRepository {
                 @Override
                 public void delete(String arg) {
-                    System.out.println('String')
                     assert true
                 }
 
                 @Override
                 public void delete(Long arg) {
-                    System.out.println('Long')
                     assert false: 'wrong method invoked'
                 }
             }
@@ -461,20 +444,18 @@ final class Groovy7204Bug {
             class MyRepositoryImpl extends MyRepository {
                 @Override
                 public void delete(String arg) {
-                    System.out.println('String')
                     assert true
                 }
 
                 @Override
                 public void delete(Long arg) {
-                    System.out.println('Long')
                     assert false: 'wrong method invoked'
                 }
             }
         '''
     }
 
-    @Test
+    @NotYetImplemented @Test
     void testCompileStatic6() {
         assertScript shell, '''
             @CompileStatic
diff --git a/src/test/groovy/bugs/Groovy7987.groovy b/src/test/groovy/bugs/Groovy7987.groovy
deleted file mode 100644
index 7f15e085b4..0000000000
--- a/src/test/groovy/bugs/Groovy7987.groovy
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package groovy.bugs
-
-import org.junit.Test
-
-import static groovy.test.GroovyAssert.shouldFail
-
-final class Groovy7987 {
-
-    @Test
-    void testNonStaticMethodViaStaticReceiver() {
-        def err = shouldFail '''
-            class Foo {
-                def bar() {
-                }
-            }
-
-            @groovy.transform.TypeChecked
-            void test() {
-                Foo.bar()
-            }
-
-            test()
-        '''
-        assert err =~ 'Non-static method Foo#bar cannot be called from static context'
-    }
-}
diff --git a/src/test/groovy/bugs/Groovy8609Bug.groovy b/src/test/groovy/bugs/Groovy8609Bug.groovy
index 08720909fe..28bb9232eb 100644
--- a/src/test/groovy/bugs/Groovy8609Bug.groovy
+++ b/src/test/groovy/bugs/Groovy8609Bug.groovy
@@ -26,121 +26,118 @@ final class Groovy8609Bug extends GroovyTestCase {
 
     void testUpperBoundWithGenerics() {
         assertScript '''
-        @groovy.transform.CompileStatic
-        public class A<T extends List<E>, E extends Map<String, Integer>> {
-            E getFirstRecord(T recordList) {
-                return recordList.get(0)
+            @groovy.transform.CompileStatic
+            public class A<T extends List<E>, E extends Map<String, Integer>> {
+                E getFirstRecord(T recordList) {
+                    return recordList.get(0)
+                }
+
+                static void main(args) {
+                    def list = new ArrayList<HashMap<String, Integer>>()
+                    def record = new HashMap<String, Integer>()
+                    list.add(record)
+                    def a = new A<ArrayList<HashMap<String, Integer>>, HashMap<String, Integer>>()
+                    assert record.is(a.getFirstRecord(list))
+                }
             }
-
-            static void main(args) {
-                def list = new ArrayList<HashMap<String, Integer>>()
-                def record = new HashMap<String, Integer>()
-                list.add(record)
-                def a = new A<ArrayList<HashMap<String, Integer>>, HashMap<String, Integer>>()
-                assert record.is(a.getFirstRecord(list))
-            }
-        }
         '''
     }
 
     void testUpperBoundWithoutGenerics() {
         assertScript '''
-        @groovy.transform.CompileStatic
-        public class A<T extends List<E>, E extends Map> {
-            E getFirstRecord(T recordList) {
-                return recordList.get(0);
-            }
-
-            static void main(args) {
-                def list = new ArrayList<HashMap<String, Integer>>()
-                def record = new HashMap<String, Integer>()
-                list.add(record)
-                def a = new A<ArrayList<HashMap<String, Integer>>, HashMap<String, Integer>>()
-                assert record.is(a.getFirstRecord(list))
+            @groovy.transform.CompileStatic
+            public class A<T extends List<E>, E extends Map> {
+                E getFirstRecord(T recordList) {
+                    return recordList.get(0);
+                }
+
+                static void main(args) {
+                    def list = new ArrayList<HashMap<String, Integer>>()
+                    def record = new HashMap<String, Integer>()
+                    list.add(record)
+                    def a = new A<ArrayList<HashMap<String, Integer>>, HashMap<String, Integer>>()
+                    assert record.is(a.getFirstRecord(list))
+                }
             }
-        }
         '''
     }
 
     void testNoUpperBound() {
         assertScript '''
-        @groovy.transform.CompileStatic
-        public class A<T extends List<E>, E> {
-            E getFirstRecord(T recordList) {
-                return recordList.get(0);
+            @groovy.transform.CompileStatic
+            public class A<T extends List<E>, E> {
+                E getFirstRecord(T recordList) {
+                    return recordList.get(0);
+                }
+
+                static void main(args) {
+                    def list = new ArrayList<HashMap<String, Integer>>()
+                    def record = new HashMap<String, Integer>()
+                    list.add(record)
+                    def a = new A<ArrayList<HashMap<String, Integer>>, HashMap<String, Integer>>()
+                    assert record.is(a.getFirstRecord(list))
+                }
             }
-
-            static void main(args) {
-                def list = new ArrayList<HashMap<String, Integer>>()
-                def record = new HashMap<String, Integer>()
-                list.add(record)
-                def a = new A<ArrayList<HashMap<String, Integer>>, HashMap<String, Integer>>()
-                assert record.is(a.getFirstRecord(list))
-            }
-        }
         '''
     }
 
     void testUpperBoundWithGenericsThroughWrongType() {
-        def errMsg = shouldFail '''
-        @groovy.transform.CompileStatic
-        public class A<T extends List<E>, E extends Map<String, Integer>> {
-            E getFirstRecord(T recordList) {
-                return recordList.get(0)
-            }
-
-            static void main(args) {
-                def list = new ArrayList<TreeMap<String, Integer>>()
-                def record = new TreeMap<String, Integer>()
-                list.add(record)
-                def a = new A<ArrayList<HashMap<String, Integer>>, HashMap<String, Integer>>()
-                assert record.is(a.getFirstRecord(list))
+        def err = shouldFail '''
+            @groovy.transform.CompileStatic
+            public class A<T extends List<E>, E extends Map<String, Integer>> {
+                E getFirstRecord(T recordList) {
+                    return recordList.get(0)
+                }
+
+                static void main(args) {
+                    def list = new ArrayList<TreeMap<String, Integer>>()
+                    def record = new TreeMap<String, Integer>()
+                    list.add(record)
+                    def a = new A<ArrayList<HashMap<String, Integer>>, HashMap<String, Integer>>()
+                    assert record.is(a.getFirstRecord(list))
+                }
             }
-        }
         '''
-
-        assert errMsg.contains('[Static type checking] - Cannot find matching method A#getFirstRecord(java.util.ArrayList<java.util.TreeMap<java.lang.String, java.lang.Integer>>)')
+        assert err.contains('Cannot call A#getFirstRecord(java.util.ArrayList<java.util.HashMap<java.lang.String, java.lang.Integer>>) with arguments [java.util.ArrayList<java.util.TreeMap<java.lang.String, java.lang.Integer>>]')
     }
 
     void testUpperBoundWithGenericsThroughWrongType2() {
-        def errMsg = shouldFail '''
-        @groovy.transform.CompileStatic
-        public class A<T extends List<E>, E extends Map<String, Integer>> {
-            E getFirstRecord(T recordList) {
-                return recordList.get(0)
-            }
-
-            static void main(args) {
-                def list = new ArrayList<HashMap<String, Long>>()
-                def record = new HashMap<String, Long>()
-                list.add(record)
-                def a = new A<ArrayList<HashMap<String, Integer>>, HashMap<String, Integer>>()
-                assert record.is(a.getFirstRecord(list))
+        def err = shouldFail '''
+            @groovy.transform.CompileStatic
+            public class A<T extends List<E>, E extends Map<String, Integer>> {
+                E getFirstRecord(T recordList) {
+                    return recordList.get(0)
+                }
+
+                static void main(args) {
+                    def list = new ArrayList<HashMap<String, Long>>()
+                    def record = new HashMap<String, Long>()
+                    list.add(record)
+                    def a = new A<ArrayList<HashMap<String, Integer>>, HashMap<String, Integer>>()
+                    assert record.is(a.getFirstRecord(list))
+                }
             }
-        }
         '''
-
-        assert errMsg.contains('[Static type checking] - Cannot find matching method A#getFirstRecord(java.util.ArrayList<java.util.HashMap<java.lang.String, java.lang.Long>>)')
+        assert err.contains('Cannot call A#getFirstRecord(java.util.ArrayList<java.util.HashMap<java.lang.String, java.lang.Integer>>) with arguments [java.util.ArrayList<java.util.HashMap<java.lang.String, java.lang.Long>>]')
     }
 
     void testUpperBoundWithGenericsThroughWrongType3() {
-        def errMsg = shouldFail '''
-        @groovy.transform.CompileStatic
-        public class A<T extends List<E>, E extends Map<String, Integer>> {
-            E getFirstRecord(T recordList) {
-                return recordList.get(0)
+        def err = shouldFail '''
+            @groovy.transform.CompileStatic
+            public class A<T extends List<E>, E extends Map<String, Integer>> {
+                E getFirstRecord(T recordList) {
+                    return recordList.get(0)
+                }
+
+                static void main(args) {
+                    def list = new ArrayList<HashMap<StringBuffer, Integer>>()
+                    def record = new HashMap<StringBuffer, Integer>()
+                    list.add(record)
+                    def a = new A<ArrayList<HashMap<String, Integer>>, HashMap<String, Integer>>()
+                    assert record.is(a.getFirstRecord(list))
+                }
             }
-
-            static void main(args) {
-                def list = new ArrayList<HashMap<StringBuffer, Integer>>()
-                def record = new HashMap<StringBuffer, Integer>()
-                list.add(record)
-                def a = new A<ArrayList<HashMap<String, Integer>>, HashMap<String, Integer>>()
-                assert record.is(a.getFirstRecord(list))
-            }
-        }
         '''
-
-        assert errMsg.contains('[Static type checking] - Cannot find matching method A#getFirstRecord(java.util.ArrayList<java.util.HashMap<java.lang.StringBuffer, java.lang.Integer>>)')
+        assert err.contains('Cannot call A#getFirstRecord(java.util.ArrayList<java.util.HashMap<java.lang.String, java.lang.Integer>>) with arguments [java.util.ArrayList<java.util.HashMap<java.lang.StringBuffer, java.lang.Integer>>]')
     }
 }
diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
index 3f1a294afc..36fdd1d997 100644
--- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
@@ -58,7 +58,7 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
             List<String> list = []
             list.add(1)
         ''',
-        'Cannot find matching method java.util.ArrayList#add(int)'
+        'Cannot call java.util.ArrayList#add(java.lang.String) with arguments [int]'
     }
 
     void testAddOnList2() {
@@ -134,7 +134,7 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
             List<Integer> list = new LinkedList<>()
             list.add 'Hello'
         ''',
-        'Cannot find matching method java.util.LinkedList#add(java.lang.String). Please check if the declared type is correct and if the method exists.'
+        'Cannot call java.util.LinkedList#add(java.lang.Integer) with arguments [java.lang.String]'
     }
 
     void testAddOnListWithDiamondAndWrongTypeUsingLeftShift() {
@@ -241,7 +241,7 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
             Number number = Optional.of(42).orElse(Double.NaN)
             assert number.intValue() == 42
         ''',
-        'Cannot find matching method java.util.Optional#orElse(double).'
+        'Cannot call java.util.Optional#orElse(java.lang.Integer) with arguments [double]'
     }
 
     void testReturnTypeInferenceWithMethodGenerics5() {
@@ -257,7 +257,7 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
             Number number = Optional.ofNullable((Integer) null).orElse(42d)
             assert number.intValue() == 42
         ''',
-        'Cannot find matching method java.util.Optional#orElse(double).'
+        'Cannot call java.util.Optional#orElse(java.lang.Integer) with arguments [double]'
     }
 
     void testReturnTypeInferenceWithMethodGenerics7() {
@@ -2061,7 +2061,7 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
             def map = new HashMap<String, Integer>()
             map.put('hello', new Object())
         ''',
-        'Cannot find matching method java.util.HashMap#put(java.lang.String, java.lang.Object). Please check if the declared type is correct and if the method exists.'
+        'Cannot call java.util.HashMap#put(java.lang.String, java.lang.Integer) with arguments [java.lang.String, java.lang.Object]'
     }
 
     void testPutAtWithWrongValueType() {
@@ -2093,7 +2093,7 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
                 }
             }
         ''',
-        'Cannot find matching method java.util.Map#put(java.lang.String, java.util.LinkedHashMap<java.lang.String, java.util.List<ConfigAttribute>>)',
+        'Cannot call java.util.Map#put(java.lang.String, java.util.Map<java.lang.String, java.util.List<java.lang.String>>) with arguments [java.lang.String, java.util.LinkedHashMap<java.lang.String, java.util.List<ConfigAttribute>>]',
         'Cannot assign java.util.LinkedHashMap<java.lang.String, java.util.List<ConfigAttribute>> to: java.util.Map<java.lang.String, java.util.List<java.lang.String>>'
 
         assertScript '''
@@ -2870,7 +2870,7 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
             Map<Date, Date> map = new HashMap<>()
             map.put(123, new Date())
         ''',
-        'Cannot find matching method java.util.HashMap#put(int, java.util.Date). Please check if the declared type is correct and if the method exists.'
+        'Cannot call java.util.HashMap#put(java.util.Date, java.util.Date) with arguments [int, java.util.Date]'
     }
     void testInferDiamondForAssignmentWithDatesAndIllegalKeyUsingSquareBracket() {
         shouldFailWithMessages '''
@@ -2910,7 +2910,7 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
             Map<Date, Date> map = new HashMap<>()
             map.put(new Date(), 'foo')
         ''',
-        'Cannot find matching method java.util.HashMap#put(java.util.Date, java.lang.String). Please check if the declared type is correct and if the method exists.'
+        'Cannot call java.util.HashMap#put(java.util.Date, java.util.Date) with arguments [java.util.Date, java.lang.String]'
     }
     void testInferDiamondForAssignmentWithDatesAndIllegalValueUsingSquareBracket() {
         shouldFailWithMessages '''
@@ -3301,8 +3301,8 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
             test(new Holder<Object>())
         ''',
         'Cannot call TypedProperty#eq(java.lang.String) with arguments [groovy.lang.GString]',
-        'Cannot find matching method TypedProperty#eq(int)', // chooseBestMethod removes "eq"
-        'Cannot find matching method TypedProperty#eq(java.lang.String)'
+        'Cannot call TypedProperty#eq(java.lang.String) with arguments [int]',
+        'Cannot call TypedProperty#eq(java.lang.Number) with arguments [java.lang.String]'
     }
 
     // GROOVY-5748
diff --git a/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy b/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy
index c4629e97bc..c594abeaea 100644
--- a/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy
@@ -56,7 +56,8 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
         shouldFailWithMessages '''
             A a = new A()
             assert a.foo(1,1)==2
-        ''', 'Cannot find matching method'
+        ''',
+        'Cannot find matching method'
     }
 
     void testMethodCallOnInstanceWithVarArgs() {
@@ -84,7 +85,8 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
     void testMissingStaticMethod() {
         shouldFailWithMessages '''
             A.missing 'echo'
-        ''', 'Cannot find matching method'
+        ''',
+        'Cannot find matching method'
     }
 
     void testStaticMethodWithVarArgs() {
@@ -206,7 +208,8 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
             B c = new B<Integer>()
             String[] args = ['a','b','c']
             assert c.identity(args) == args
-        ''', 'Cannot call groovy.transform.stc.MethodCallsSTCTest$MyMethodCallTestClass2#identity(java.lang.Integer[]) with arguments [java.lang.String[]]'
+        ''',
+        'Cannot call groovy.transform.stc.MethodCallsSTCTest$MyMethodCallTestClass2#identity(java.lang.Integer[]) with arguments [java.lang.String[]]'
     }
 
     // GROOVY-8909
@@ -222,7 +225,8 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
             void m(Set<Integer> set) {
             }
             m([1,2,3,3])
-        ''', 'm(java.util.List<java.lang.Integer>). Please check if the declared type is correct and if the method exists.'
+        ''',
+        'm(java.util.List<java.lang.Integer>). Please check if the declared type is correct and if the method exists.'
     }
 
     // GROOVY-7106, GROOVY-7274, GROOVY-9844
@@ -384,7 +388,8 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
             class Peer {
                 def foo() { new Main() }
             }
-        ''', '[Static type checking] - Cannot find matching method Main#<init>()'
+        ''',
+        'Cannot find matching method Main#<init>()'
     }
 
     // GROOVY-8509
@@ -512,7 +517,8 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
                     bar(null, new Date())
                 }
             }
-        ''', 'Reference to method is ambiguous'
+        ''',
+        'Reference to method is ambiguous'
     }
 
     // GROOVY-5175
@@ -572,7 +578,8 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
                 'Boolean'
             }
             ['foo',123,true].each { foo(it) }
-        ''', 'Cannot find matching method'
+        ''',
+        'Cannot find matching method'
     }
 
     void testShouldNotFailThanksToInstanceOfChecks() {
@@ -660,7 +667,8 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
                     foo(it)
                 }
             }
-        ''', 'Reference to method is ambiguous'
+        ''',
+        'Reference to method is ambiguous'
     }
 
     void testShouldFailWithMultiplePossibleMethods2() {
@@ -679,7 +687,8 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
                     foo(argument)
                 }
             }
-        ''', 'Reference to method is ambiguous'
+        ''',
+        'Reference to method is ambiguous'
     }
 
     // GROOVY-5703
@@ -781,7 +790,8 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
                 it = new Date()
                 foo(it)
             }
-        ''', 'foo(java.util.Date)'
+        ''',
+        'foo(java.util.Date)'
     }
 
     void testShouldNotFailEvenIfVariableIsReassigned() {
@@ -832,7 +842,8 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
                 return val.toUpperCase()
             }
             assert m(123) == 'HELLO'
-        ''', '#m(int)'
+        ''',
+        '#m(int)'
     }
 
     void testOneDefaultParamAndOneWithout() {
@@ -851,7 +862,8 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
                 return val.toUpperCase() + append
             }
             m('test', new Object())
-        ''', 'm(java.lang.String, java.lang.Object)'
+        ''',
+        'm(java.lang.String, java.lang.Object)'
     }
 
     void testMultipleDefaultArgs() {
@@ -880,7 +892,8 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
                 return first.toUpperCase() + ' ' + second + ' ' + third.toUpperCase()
             }
             m('f',123,'s', 'too many args')
-        ''', '#m(java.lang.String, int, java.lang.String, java.lang.String)'
+        ''',
+        '#m(java.lang.String, int, java.lang.String, java.lang.String)'
     }
 
     void testMultipleDefaultArgsWithMixedTypesAndWrongType() {
@@ -889,7 +902,8 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
                 return first.toUpperCase() + ' ' + second + ' ' + third.toUpperCase()
             }
             m('hello') // no value set for "second"
-        ''', '#m(java.lang.String)'
+        ''',
+        '#m(java.lang.String)'
     }
 
     void testShouldNotFailWithAmbiguousMethodSelection() {
@@ -915,7 +929,8 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
         shouldFailWithMessages '''
             float square(float x) { x*x }
             assert square(2.0d) == 4.0d
-        ''', '#square(double)'
+        ''',
+        '#square(double)'
     }
 
     void testShouldNotBeAbleToCallMethodUsingLongWithFloatOrDouble() {
@@ -923,31 +938,34 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
             float square(long x) { x*x }
             assert square(2.0d) == 4.0d
             assert square(2.0f) == 4.0d
-        ''', '#square(double)', '#square(float)'
+        ''',
+        '#square(double)', '#square(float)'
     }
 
-    void testShouldNotAllowMethodCallFromStaticContext() {
+    void testShouldNotAllowMethodCallFromStaticInitializer() {
         shouldFailWithMessages '''
             class A {
                 void instanceMethod() {}
-                static void staticMethod() {
-                    instanceMethod() // calling instance method from static context
+                static {
+                    instanceMethod()
                 }
             }
-            A.staticMethod()
-        ''', 'Non-static method A#instanceMethod cannot be called from static context'
+            new A()
+        ''',
+        'Non-static method A#instanceMethod cannot be called from static context'
     }
 
-    void testShouldNotAllowMethodCallFromStaticConstructor() {
+    void testShouldNotAllowMethodCallFromStaticMethod() {
         shouldFailWithMessages '''
             class A {
                 void instanceMethod() {}
-                static {
-                    instanceMethod() // calling instance method from static context
+                static void staticMethod() {
+                    instanceMethod()
                 }
             }
-            new A()
-        ''', 'Non-static method A#instanceMethod cannot be called from static context'
+            A.staticMethod()
+        ''',
+        'Non-static method A#instanceMethod cannot be called from static context'
     }
 
     void testShouldNotAllowMethodCallFromStaticField() {
@@ -957,7 +975,8 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
                 static FOO = instanceMethod()
             }
             new A()
-        ''', 'Non-static method A#instanceMethod cannot be called from static context'
+        ''',
+        'Non-static method A#instanceMethod cannot be called from static context'
     }
 
     // GROOVY-5495
@@ -1672,11 +1691,13 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
     void testMoreExplicitErrorMessageOnStaticMethodNotFound() {
         shouldFailWithMessages '''
             Double.isFiniteMissing(2.0d)
-        ''', 'Cannot find matching method java.lang.Double#isFiniteMissing(double)'
+        ''',
+        'Cannot find matching method java.lang.Double#isFiniteMissing(double)'
 
         shouldFailWithMessages '''
             String.doSomething()
-        ''', 'Cannot find matching method java.lang.String#doSomething()'
+        ''',
+        'Cannot find matching method java.lang.String#doSomething()'
     }
 
     // GROOVY-6776
@@ -1687,7 +1708,8 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
                 foo null
             }
             bar()
-        ''', '#foo(int) with arguments [<unknown parameter type>]'
+        ''',
+        '#foo(int) with arguments [<unknown parameter type>]'
     }
 
     // GROOVY-6751
@@ -1709,49 +1731,58 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
+    // GROOVY-7987
+    void testNonStaticMethodViaStaticReceiver() {
+        shouldFailWithMessages '''
+            class Foo {
+                def m() {}
+            }
+            Foo.m()
+        ''',
+        'Non-static method Foo#m cannot be called from static context'
+    }
+
     // GROOVY-7813
     void testNonStaticOuterMethodCannotBeCalledFromStaticClass() {
         shouldFailWithMessages '''
             class Foo {
-                def bar() { 2 }
-
-                static class Baz {
-                    def doBar() { bar() }
+                def m() {}
+                static class Bar {
+                    void test() { m() }
                 }
             }
-            null
-        ''', 'Non-static method Foo#bar cannot be called from static context'
+        ''',
+        'Cannot find matching method Foo$Bar#m()'
     }
 
     void testStaticOuterMethodCanBeCalledFromStaticClass() {
         assertScript '''
             class Foo {
-                static def bar() { 2 }
-
-                static class Baz {
-                    def doBar() {
-                        bar()
+                static def sm() { 2 }
+                static class Bar {
+                    void test() {
+                        assert sm() == 2
                     }
                 }
             }
-            assert new Foo.Baz().doBar() == 2
+            new Foo.Bar().test()
         '''
     }
 
     void testInheritedMethodCanBeCalledFromStaticClass() {
         assertScript '''
-            class Bar {
-                def bar() { 1 }
+            class Foo {
+                def m() { 1 }
             }
 
-            class Foo {
-                static class Baz extends Bar {
-                    def doBar() {
-                        bar()
+            class Bar {
+                static class Baz extends Foo {
+                    void test() {
+                        assert m() == 1
                     }
                 }
             }
-            assert new Foo.Baz().doBar() == 1
+            new Bar.Baz().test()
         '''
     }
 
diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/BugsStaticCompileTest.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/BugsStaticCompileTest.groovy
index b608b6879c..1c26771c7f 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/BugsStaticCompileTest.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/BugsStaticCompileTest.groovy
@@ -49,8 +49,7 @@ final class BugsStaticCompileTest extends BugsSTCTest implements StaticCompilati
 
     // GROOVY-5512
     void testCreateRangeInInnerClass() {
-        def shell = new GroovyShell()
-        shell.evaluate '''
+        new GroovyShell().evaluate '''
             class Outer {
                 static class Inner {
                     @groovy.transform.CompileStatic
@@ -67,54 +66,46 @@ final class BugsStaticCompileTest extends BugsSTCTest implements StaticCompilati
 
     // GROOVY-5526
     void testAssertEqualsShouldNotThrowVerifyError() {
-        assertScript '''
-            import static org.junit.Assert.*;
-            import groovy.transform.CompileStatic;
-
+        assertScript '''import static org.junit.Assert.*
             class CompilerBugs {
-
-              public static void main(String[] args) {
-                int expected = 0
-                assertEquals(expected, args.length)
-              }
-
+                public static void main(String[] args) {
+                    int expected = 0
+                    assertEquals(expected, args.length)
+                }
             }
         '''
     }
 
     // GROOVY-5529
     void testStaticCompilationOfClosureWhenSingleMethodAnnotated() {
-        new GroovyShell().evaluate '''import groovy.transform.ASTTest
-        import static org.codehaus.groovy.control.CompilePhase.*
-
-        interface Row {
-            int getKey()
-        }
-
-        class RowImpl implements Row {
-            int getKey() { 1 }
-        }
+        new GroovyShell().evaluate '''
+            interface Row {
+                int getKey()
+            }
 
-        @groovy.transform.CompileStatic
-        def test() {
-            def rows = [new RowImpl(), new RowImpl(), new RowImpl()]
+            class RowImpl implements Row {
+                int getKey() { 1 }
+            }
 
-            rows.each { Row row ->
-                println row.key
+            @groovy.transform.CompileStatic
+            def test() {
+                def rows = [new RowImpl(), new RowImpl(), new RowImpl()]
+                rows.each { Row row ->
+                    println row.key
+                }
             }
-        }
 
-        test()
+            test()
         '''
     }
 
     // GROOVY-5536
     void testShouldNotThrowVerifyErrorWithNullDereferenceInIf() {
         assertScript '''
-                boolean getDescriptorForPlugin(File pluginDir) {
-                    if (pluginDir?.exists()) { true } else { false }
-                }
-                assert getDescriptorForPlugin(null) == false
+            boolean getDescriptorForPlugin(File pluginDir) {
+                if (pluginDir?.exists()) { true } else { false }
+            }
+            assert getDescriptorForPlugin(null) == false
         '''
     }
 
@@ -138,7 +129,8 @@ final class BugsStaticCompileTest extends BugsSTCTest implements StaticCompilati
 
     // GROOVY-
     void testPowerShouldNotThrowVerifyError() {
-        assertScript '''int squarePlusOne(int num) {
+        assertScript '''
+            int squarePlusOne(int num) {
                 num ** num + 1
             }
             assert squarePlusOne(2) == 5
@@ -148,17 +140,17 @@ final class BugsStaticCompileTest extends BugsSTCTest implements StaticCompilati
     // GROOVY-5570
     void testShouldNotThrowVerifyErrorRegisterContainsWrongType() {
         assertScript '''
-                void foo() {
+            void foo() {
                 boolean idx = false
                 def cl = { idx }
-                }
-            '''
+            }
+        '''
         assertScript '''
-                void foo() {
+            void foo() {
                 int idx = 0
                 def cl = { idx }
-                }
-            '''
+            }
+        '''
     }
 
     // GROOVY-5572
@@ -212,7 +204,6 @@ final class BugsStaticCompileTest extends BugsSTCTest implements StaticCompilati
                 }
             }
 
-            @groovy.transform.CompileStatic
             class Main {
                 void test() {
                     @ASTTest(phase=INSTRUCTION_SELECTION, value={
@@ -228,104 +219,104 @@ final class BugsStaticCompileTest extends BugsSTCTest implements StaticCompilati
 
     void testCompileStaticTwiceShouldNotBeAProblem() {
         new GroovyShell().evaluate '''import groovy.transform.CompileStatic
-        @CompileStatic
-        class Tool {
-            @CompileStatic // annotated too, even if class is already annotated
-            String relativePath(File relbase, File file) {
-                def pathParts = []
-                def currentFile = file
-                while (currentFile != null && currentFile != relbase) {
-                    pathParts += currentFile.name
-                    currentFile = currentFile.parentFile
+            @CompileStatic
+            class Tool {
+                @CompileStatic // annotated too, even if class is already annotated
+                String relativePath(File relbase, File file) {
+                    def pathParts = []
+                    def currentFile = file
+                    while (currentFile != null && currentFile != relbase) {
+                        pathParts += currentFile.name
+                        currentFile = currentFile.parentFile
+                    }
+                    pathParts.reverse().join('/')
                 }
-                pathParts.reverse().join('/')
             }
-        }
-        File a = new File('foo')
-        File b = new File(new File(a, 'bar'), 'baz')
-        assert new Tool().relativePath(a,b) == 'bar/baz'
+            File a = new File('foo')
+            File b = new File(new File(a, 'bar'), 'baz')
+            assert new Tool().relativePath(a,b) == 'bar/baz'
         '''
     }
 
     void testCompileStaticTwiceShouldNotBeAProblemUsingCustomizer() {
-        assertScript '''import groovy.transform.CompileStatic
-        @CompileStatic
-        class Tool {
-            @CompileStatic // annotated too, even if class is already annotated
-            String relativePath(File relbase, File file) {
-                def pathParts = []
-                def currentFile = file
-                while (currentFile != null && currentFile != relbase) {
-                    pathParts += currentFile.name
-                    currentFile = currentFile.parentFile
+        assertScript '''
+            @CompileStatic
+            class Tool {
+                @CompileStatic // annotated too, even if class is already annotated
+                String relativePath(File relbase, File file) {
+                    def pathParts = []
+                    def currentFile = file
+                    while (currentFile != null && currentFile != relbase) {
+                        pathParts += currentFile.name
+                        currentFile = currentFile.parentFile
+                    }
+                    pathParts.reverse().join('/')
                 }
-                pathParts.reverse().join('/')
             }
-        }
-        File a = new File('foo')
-        File b = new File(new File(a, 'bar'), 'baz')
-        assert new Tool().relativePath(a,b) == 'bar/baz'
+            File a = new File('foo')
+            File b = new File(new File(a, 'bar'), 'baz')
+            assert new Tool().relativePath(a,b) == 'bar/baz'
         '''
     }
 
     // GROOVY-5613
     void testNullSafeAssignment() {
         assertScript '''
-        class A {
-            int x = -1
-        }
-        A a = new A()
-        @ASTTest(phase=INSTRUCTION_SELECTION, value={
-            assert node.getNodeMetaData(INFERRED_TYPE) == Integer_TYPE
-        })
-        def x = a?.x
+            class A {
+                int x = -1
+            }
+            A a = new A()
+            @ASTTest(phase=INSTRUCTION_SELECTION, value={
+                assert node.getNodeMetaData(INFERRED_TYPE) == Integer_TYPE
+            })
+            def x = a?.x
         '''
     }
 
     void testNullSafeAssignmentWithLong() {
         assertScript '''
-        class A {
-            long x = -1
-        }
-        A a = new A()
-        @ASTTest(phase=INSTRUCTION_SELECTION, value={
-            assert node.getNodeMetaData(INFERRED_TYPE) == Long_TYPE
-        })
-        def x = a?.x
+            class A {
+                long x = -1
+            }
+            A a = new A()
+            @ASTTest(phase=INSTRUCTION_SELECTION, value={
+                assert node.getNodeMetaData(INFERRED_TYPE) == Long_TYPE
+            })
+            def x = a?.x
         '''
     }
 
     void testNullSafeAssignmentWithChar() {
         assertScript '''
-        class A {
-            char x = 'a'
-        }
-        A a = new A()
-        @ASTTest(phase=INSTRUCTION_SELECTION, value={
-            assert node.getNodeMetaData(INFERRED_TYPE) == Character_TYPE
-        })
-        def x = a?.x
-        assert x == 'a'
+            class A {
+                char x = 'a'
+            }
+            A a = new A()
+            @ASTTest(phase=INSTRUCTION_SELECTION, value={
+                assert node.getNodeMetaData(INFERRED_TYPE) == Character_TYPE
+            })
+            def x = a?.x
+            assert x == 'a'
         '''
     }
 
     void testCallStaticallyImportedMethodWithNullSafeArgument() {
         assertScript '''import static java.lang.Math.abs
-        class A {
-            int x = -1
-        }
-        def a = new A()
-        def x = a?.x
-        assert abs(a?.x) == 1
+            class A {
+                int x = -1
+            }
+            def a = new A()
+            def x = a?.x
+            assert abs(a?.x) == 1
         '''
     }
 
     void testClosureAsInterfaceArgument() {
         assertScript '''
-                Closure c = { Integer x, Integer y -> x <=> y }
-                def list = [ 3,1,5,2,4 ]
-                assert ((Collection)list).sort(c) == [1,2,3,4,5]
-            '''
+            Closure c = { Integer x, Integer y -> x <=> y }
+            def list = [ 3,1,5,2,4 ]
+            assert ((Collection)list).sort(c) == [1,2,3,4,5]
+        '''
     }
 
     void testInferredTypeForInteger() {
@@ -351,35 +342,35 @@ final class BugsStaticCompileTest extends BugsSTCTest implements StaticCompilati
 
     void testPostfixIncInteger() {
         assertScript '''
-                Integer x = 0
-                x++
-                x++
-                assert x == 2
-                assert x++ == 2
-                assert x == 3
-            '''
+            Integer x = 0
+            x++
+            x++
+            assert x == 2
+            assert x++ == 2
+            assert x == 3
+        '''
     }
 
     void testPostfixDecInt() {
         assertScript '''
-                int x = 0
-                x--
-                x--
-                assert x == -2
-                assert x-- == -2
-                assert x == -3
-            '''
+            int x = 0
+            x--
+            x--
+            assert x == -2
+            assert x-- == -2
+            assert x == -3
+        '''
     }
 
     void testPostfixDecInteger() {
         assertScript '''
-                Integer x = 0
-                x--
-                x--
-                assert x == -2
-                assert x-- == -2
-                assert x == -3
-            '''
+            Integer x = 0
+            x--
+            x--
+            assert x == -2
+            assert x-- == -2
+            assert x == -3
+        '''
     }
 
     void testPrefixIncPrimitiveInteger() {
@@ -395,42 +386,42 @@ final class BugsStaticCompileTest extends BugsSTCTest implements StaticCompilati
 
     void testPrefixIncInteger() {
         assertScript '''
-                Integer x = 0
-                ++x
-                ++x
-                assert x == 2
-                assert ++x == 3
-                assert x == 3
-            '''
+            Integer x = 0
+            ++x
+            ++x
+            assert x == 2
+            assert ++x == 3
+            assert x == 3
+        '''
     }
 
     void testPrefixDecInt() {
         assertScript '''
-                int x = 0
-                --x
-                --x
-                assert --x == -3
-                assert x == -3
-            '''
+            int x = 0
+            --x
+            --x
+            assert --x == -3
+            assert x == -3
+        '''
     }
 
     void testPrefixDecInteger() {
         assertScript '''
-                Integer x = 0
-                --x
-                --x
-                assert --x == -3
-                assert x == -3
-            '''
+            Integer x = 0
+            --x
+            --x
+            assert --x == -3
+            assert x == -3
+        '''
     }
 
     void testShouldSkipSpreadOperator() {
-        new GroovyShell().evaluate '''import groovy.transform.TypeCheckingMode
-            import groovy.transform.CompileStatic
+        new GroovyShell().evaluate '''import groovy.transform.CompileStatic
+            import static groovy.transform.TypeCheckingMode.SKIP
 
             @CompileStatic // top level must be @CS
             class Foo {
-                @CompileStatic(TypeCheckingMode.SKIP)
+                @CompileStatic(SKIP)
                 static void foo(fun, args) {
                     new Runnable() { // create an anonymous class which should *not* be visited
                         void run() {
@@ -445,16 +436,14 @@ final class BugsStaticCompileTest extends BugsSTCTest implements StaticCompilati
 
     // GROOVY-5672
     void testTypeCheckedPlusCompileStatic() {
-        new GroovyShell().evaluate '''import groovy.transform.CompileStatic
-        import groovy.transform.TypeChecked
-
-        @TypeChecked
-        @CompileStatic
-        class SampleClass {
-            def a = "some string"
-            def b = a.toString()
-        }
-        new SampleClass()
+        new GroovyShell().evaluate '''import groovy.transform.*
+            @TypeChecked
+            @CompileStatic
+            class SampleClass {
+                def a = "some string"
+                def b = a.toString()
+            }
+            new SampleClass()
         '''
     }
 
@@ -479,79 +468,86 @@ final class BugsStaticCompileTest extends BugsSTCTest implements StaticCompilati
 
     void testIncrementOperatorOnInt() {
         assertScript '''
-                int incInt(int n) {
-                    def result = n
-                    ++result
-                    result++
-                    return result
-                }
-                assert  incInt(5) == 7'''
+            int incInt(int n) {
+                def result = n
+                ++result
+                result++
+                return result
+            }
+            assert  incInt(5) == 7
+        '''
     }
 
     void testIncrementOperatorOnShort() {
         assertScript '''
-                short incInt(short n) {
-                    def result = n
-                    ++result
-                    result++
-                    return result
-                }
-                assert  incInt((short)5) == 7'''
+            short incInt(short n) {
+                def result = n
+                ++result
+                result++
+                return result
+            }
+            assert  incInt((short)5) == 7
+        '''
     }
 
     void testIncrementOperatorOnByte() {
         assertScript '''
-                byte incInt(byte n) {
-                    def result = n
-                    ++result
-                    result++
-                    return result
-                }
-                assert  incInt((byte)5) == 7'''
+            byte incInt(byte n) {
+                def result = n
+                ++result
+                result++
+                return result
+            }
+            assert  incInt((byte)5) == 7
+        '''
     }
 
     void testIncrementOperatorOnLong() {
         assertScript '''
-                long incInt(long n) {
-                    def result = n
-                    ++result
-                    result++
-                    return result
-                }
-                assert  incInt(5) == 7'''
+            long incInt(long n) {
+                def result = n
+                ++result
+                result++
+                return result
+            }
+            assert  incInt(5) == 7
+        '''
     }
 
     void testIncrementOperatorOnFloat() {
         assertScript '''
-                float incInt(float n) {
-                    def result = n
-                    ++result
-                    result++
-                    return result
-                }
-                assert  incInt(5) == 7'''
+            float incInt(float n) {
+                def result = n
+                ++result
+                result++
+                return result
+            }
+            assert  incInt(5) == 7
+        '''
     }
 
     void testIncrementOperatorOnDouble() {
         assertScript '''
-                double incInt(double n) {
-                    def result = n
-                    ++result
-                    result++
-                    return result
-                }
-                assert  incInt(5) == 7'''
+            double incInt(double n) {
+                def result = n
+                ++result
+                result++
+                return result
+            }
+            assert  incInt(5) == 7
+        '''
     }
 
     void testIncrementOperatorOnChar() {
         assertScript '''
-                char incInt(char n) {
-                    def result = n
-                    ++result
-                    result++
-                    return result
-                }
-                assert  incInt((char)'a') == (char)('c')'''
+            char incInt(char n) {
+                def result = n
+                ++result
+                result++
+                return result
+            }
+            assert  incInt((char)'a') == (char)('c')
+        '''
     }
 
     void testIncrementField() {
@@ -570,13 +566,13 @@ final class BugsStaticCompileTest extends BugsSTCTest implements StaticCompilati
     // GROOVY-5789
     void testLoopWithIncrement() {
         assertScript '''
-        int execute() {
-            // using a list, so that if the loop is endless, the test eventually fails with OOM
-            List<Integer> list = new LinkedList<Integer>()
-            for (def i = 0; i < 4; ++i) { println i; list << i }
-            list.size()
-        }
-        assert execute() == 4
+            int execute() {
+                // using a list, so that if the loop is endless, the test eventually fails with OOM
+                List<Integer> list = new LinkedList<Integer>()
+                for (def i = 0; i < 4; ++i) { println i; list << i }
+                list.size()
+            }
+            assert execute() == 4
         '''
     }
 
@@ -588,7 +584,7 @@ final class BugsStaticCompileTest extends BugsSTCTest implements StaticCompilati
             }
             assert m(1) == true
             assert m(4) == false
-            '''
+        '''
     }
 
     // GROOVY-5814
@@ -650,16 +646,16 @@ final class BugsStaticCompileTest extends BugsSTCTest implements StaticCompilati
     // GROOVY-5804
     void testNegateSharedBooleanInClosure() {
         assertScript '''
-                boolean x = false
-                def cl = {
-                    if (!x) {
-                        assert true
-                    } else {
-                        assert false
-                    }
+            boolean x = false
+            def cl = {
+                if (!x) {
+                    assert true
+                } else {
+                    assert false
                 }
-                cl()
-            '''
+            }
+            cl()
+        '''
     }
 
     void testCallClosureInInnerClass() {
@@ -711,13 +707,12 @@ final class BugsStaticCompileTest extends BugsSTCTest implements StaticCompilati
     }
 
     void testSuperMethodCallInSkippedSection() {
-        assertScript '''import groovy.transform.CompileStatic
-import groovy.transform.TypeCheckingMode
+        assertScript '''
             class Top {
                 public int foo() { 123 }
             }
             class Bottom extends Top {
-                @CompileStatic(TypeCheckingMode.SKIP)
+                @CompileStatic(SKIP)
                 public int bar() {
                     foo()
                 }
@@ -732,7 +727,8 @@ import groovy.transform.TypeCheckingMode
             def foo(Object o) {
                 o[0]
             }
-        ''', 'Cannot find matching method java.lang.Object#getAt(int)'
+        ''',
+        'Cannot find matching method java.lang.Object#getAt(int)'
     }
 
     void testStaticCompileWithPattern() {
@@ -745,25 +741,26 @@ import groovy.transform.TypeCheckingMode
             def value = fieldMatcher[0]
             // should not pass
             def str = value[0]
-        ''', 'Cannot find matching method java.lang.Object#getAt(int)'
+        ''',
+        'Cannot find matching method java.lang.Object#getAt(int)'
     }
 
     void testChainedNullSafePropertyOnMap() {
         assertScript '''
-        Map<String, Map<String,Map<String,Integer>>> m=[:]
-        // this is ok
-        assert m?.a == null
-        assert m?.a?.b == null
-        assert m?.a?.b?.c == null
-        assert m?.a?.b?.c?.intValue() == null
+            Map<String, Map<String,Map<String,Integer>>> m = [:]
+            // this is ok
+            assert m?.a == null
+            assert m?.a?.b == null
+            assert m?.a?.b?.c == null
+            assert m?.a?.b?.c?.intValue() == null
         '''
     }
 
     void testNullSafePropertyOnList() {
         assertScript '''
-        List<Class> classes = null
-        // this is ok
-        assert classes?.name == null
+            List<Class> classes = null
+            // this is ok
+            assert classes?.name == null
         '''
     }
 
@@ -784,21 +781,21 @@ import groovy.transform.TypeCheckingMode
     // GROOVY-6101
     void testShouldNotGenerateInvalidClassWithNullSafeInvocationOnMethodReturningPrimitiveType() {
         assertScript '''
-        class Piece {
-            int x() { 333 }
-        }
+            class Piece {
+                int x() { 333 }
+            }
 
-        void foo() {
-            Piece[] pieces = [new Piece(), null] as Piece[]
-            int sum = 0
-            for (int i=0;i<pieces.length;i++) {
-                if (pieces[i]?.x()) {
-                    sum += pieces[i].x()
+            void foo() {
+                Piece[] pieces = [new Piece(), null] as Piece[]
+                int sum = 0
+                for (int i=0;i<pieces.length;i++) {
+                    if (pieces[i]?.x()) {
+                        sum += pieces[i].x()
+                    }
                 }
+                assert sum == 333
             }
-            assert sum == 333
-        }
-        foo()
+            foo()
         '''
     }
 
@@ -841,7 +838,6 @@ import groovy.transform.TypeCheckingMode
 
             def b = new Groovy5921()
             b.doSomething()
-
         '''
     }
 
@@ -857,7 +853,6 @@ import groovy.transform.TypeCheckingMode
 
             def b = new Groovy5921()
             b.doSomething()
-
         '''
     }
 
@@ -873,7 +868,6 @@ import groovy.transform.TypeCheckingMode
 
             def b = new Groovy5921()
             b.doSomething()
-
         '''
     }
 
@@ -889,7 +883,6 @@ import groovy.transform.TypeCheckingMode
 
             def b = new Groovy5921()
             b.doSomething()
-
         '''
     }
 
@@ -931,24 +924,20 @@ import groovy.transform.TypeCheckingMode
 
     // GROOVY-6095
     void testServletError() {
-        assertScript '''
+        new GroovyShell().evaluate '''
             @Grab('javax.servlet:javax.servlet-api:3.0.1')
-            import groovy.transform.CompileStatic
-
             import javax.servlet.ServletContext
             import javax.servlet.ServletRegistration
 
             /**
              * author: Richard Vowles - http://gplus.to/RichardVowles
              */
-            @CompileStatic
+            @groovy.transform.CompileStatic
             class ServletExample {
-
               public void myMethod(ServletContext ctx) {
                 ctx.getServletRegistrations().each { String name, ServletRegistration sr ->
                   println name
                 }
-
               }
             }
             new ServletExample()
@@ -958,67 +947,67 @@ import groovy.transform.TypeCheckingMode
     // GROOVY-6137
     void testIsCaseShouldBeNullSafe() {
         assertScript '''
-        def isCaseNullCS(a, b) {
-            a in b
-        }
-        assert isCaseNullCS(1, null) == false
-        assert isCaseNullCS(null, 1) == false
-        assert isCaseNullCS(1,1) == true
-        assert isCaseNullCS(1,2) == false
-        assert isCaseNullCS(2,1) == false
+            def isCaseNullCS(a, b) {
+                a in b
+            }
+            assert isCaseNullCS(1, null) == false
+            assert isCaseNullCS(null, 1) == false
+            assert isCaseNullCS(1,1) == true
+            assert isCaseNullCS(1,2) == false
+            assert isCaseNullCS(2,1) == false
         '''
     }
 
     // GROOVY-6242
     void testGetAtBigInt() {
         assertScript '''
-class Sequence {
-    public Sequence() {}
-    static BigInteger getAt(final int index) { 1G }
-    static BigInteger getAt(final BigInteger index) { getAt(index as int) }
-}
-
-class Iterator implements java.util.Iterator {
-    private BigInteger currentIndex = 0G
-    private final Sequence sequence
-    Iterator(final Sequence s) { sequence = s }
-    boolean hasNext() { return true }
-    @ASTTest(phase=INSTRUCTION_SELECTION,value={
-        def expr = node.code.statements[0].expression
-        def indexType = expr.rightExpression.getNodeMetaData(INFERRED_TYPE)
-        assert indexType == make(BigInteger)
-    })
-    BigInteger next() { sequence[currentIndex++] }
-    void remove() { throw new UnsupportedOperationException() }
-}
+            class Sequence {
+                public Sequence() {}
+                static BigInteger getAt(final int index) { 1G }
+                static BigInteger getAt(final BigInteger index) { getAt(index as int) }
+            }
+
+            class Iterator implements java.util.Iterator {
+                private BigInteger currentIndex = 0G
+                private final Sequence sequence
+                Iterator(final Sequence s) { sequence = s }
+                boolean hasNext() { return true }
+                @ASTTest(phase=INSTRUCTION_SELECTION,value={
+                    def expr = node.code.statements[0].expression
+                    def indexType = expr.rightExpression.getNodeMetaData(INFERRED_TYPE)
+                    assert indexType == make(BigInteger)
+                })
+                BigInteger next() { sequence[currentIndex++] }
+                void remove() { throw new UnsupportedOperationException() }
+            }
 
-def it = new Iterator(new Sequence())
-assert it.next() == 1G
-'''
+            def it = new Iterator(new Sequence())
+            assert it.next() == 1G
+        '''
     }
 
     // GROOVY-6243
     void testSwapUsingMultipleAssignment() {
         assertScript '''
-        def swap(result,next) {
-            print "($result,$next) -> "
-            (result, next) =  [next, result]
-            println "($result,$next)"
-            [result, next]
-        }
+            def swap(result,next) {
+                print "($result,$next) -> "
+                (result, next) =  [next, result]
+                println "($result,$next)"
+                [result, next]
+            }
 
-        assert swap(0,1) == [1,0]
-        assert swap('a','b') == ['b','a']
-        assert swap('a', 1) == [1, 'a']
-        def o1 = new Object()
-        def o2 = new Date()
-        assert swap(o1,o2) == [o2, o1]
+            assert swap(0,1) == [1,0]
+            assert swap('a','b') == ['b','a']
+            assert swap('a', 1) == [1, 'a']
+            def o1 = new Object()
+            def o2 = new Date()
+            assert swap(o1,o2) == [o2, o1]
         '''
     }
 
     // GROOVY-5882
     void testMod() {
-        assertScript """
+        assertScript '''
             int foo(Map<Integer, Object> markers, int i) {
                 int res = 0
                 for (e in markers.entrySet()) {
@@ -1027,9 +1016,9 @@ assert it.next() == 1G
                 return res
             }
             assert foo([(1):null,(2):null,(3):null],2)==2
-        """
+        '''
 
-        assertScript """
+        assertScript '''
             int foo(Map<Integer, Object> markers, int i) {
                 int res = 0
                 for (e in markers.entrySet()) {
@@ -1039,8 +1028,8 @@ assert it.next() == 1G
                 return res
             }
             assert foo([(1):null,(2):null,(3):null],2)==2
-        """
-        assertScript """
+        '''
+        assertScript '''
             int foo(Map<Integer, Object> markers, int i) {
                 int res = 0
                 for (e in markers.entrySet()) {
@@ -1049,7 +1038,7 @@ assert it.next() == 1G
                 return res
             }
             assert foo([(1):null,(2):null,(3):null],2)==2
-        """
+        '''
     }
 
     void testSuperCallShouldBeDirect() {
@@ -1088,7 +1077,7 @@ assert it.next() == 1G
               println seq.next?.longValue()
             }
             assert seq.next == 5
-'''
+        '''
     }
 
     void testNullSafeOperatorShouldNotCallMethodTwiceWithPrimitive() {
@@ -1108,7 +1097,7 @@ assert it.next() == 1G
               println seq.next?.longValue()
             }
             assert seq.next == 5
-'''
+        '''
     }
 
     void testNullSafeOperatorShouldNotCallMethodTwice1Arg() {
@@ -1128,7 +1117,7 @@ assert it.next() == 1G
               println seq.getNext(2)?.longValue()
             }
             assert seq.getNext(2) == 10
-'''
+        '''
     }
 
     void testNullSafeOperatorShouldNotCallMethodTwiceWithPrimitive1Arg() {
@@ -1148,7 +1137,7 @@ assert it.next() == 1G
               println seq.getNext(2)?.longValue()
             }
             assert seq.getNext(2) == 10
-'''
+        '''
     }
 
     void testShouldAllowSubscriptOperatorOnSet() {
@@ -1180,21 +1169,20 @@ assert it.next() == 1G
     // GROOVY-6552
     void testShouldNotThrowClassCastException() {
         assertScript '''import java.util.concurrent.Callable
-
-    String text(Class clazz) {
-        new Callable<String>() {
-            String call() throws Exception {
+            String text(Class clazz) {
                 new Callable<String>() {
                     String call() throws Exception {
-                        clazz.getName()
+                        new Callable<String>() {
+                            String call() throws Exception {
+                                clazz.getName()
+                            }
+                        }.call()
                     }
                 }.call()
             }
-        }.call()
-    }
 
-    assert text(String) == 'java.lang.String'
-    '''
+            assert text(String) == 'java.lang.String'
+        '''
     }
 
     // GROOVY-6851
@@ -1212,19 +1200,19 @@ assert it.next() == 1G
                 }
             }
             new GrailsHomeWorkspaceReader()
-            '''
+        '''
     }
 
     // GROOVY-6342
     void testShouldNotThrowNPEIfElvisOperatorIsUsedInsideTernary() {
-        assertScript '''class Inner {
-    int somestuff
-}
-Inner inner = null
-int someInt = inner?.somestuff ?: 0
-println someInt
-
-'''
+        assertScript '''
+            class Inner {
+                int somestuff
+            }
+            Inner inner = null
+            int someInt = inner?.somestuff ?: 0
+            println someInt
+        '''
     }
 
     void testAccessOuterClassMethodFromInnerClassConstructor() {
@@ -1355,7 +1343,7 @@ println someInt
             class Foo {
                 long rankOrderingOrId
                 void setRankOrderingOrId(long rankOrderingOrId) {
-                    this.rankOrderingOrId = rankOrderingOrId < 0 ? -1 : rankOrderingOrId
+                    this.rankOrderingOrId = rankOrderingOrId < 0 ? -1L : rankOrderingOrId
                 }
             }
             def f = new Foo()
@@ -1381,26 +1369,26 @@ println someInt
     void testShouldNotThrowIncompatibleClassChangeError() {
         try {
             assertScript '''import org.codehaus.groovy.classgen.asm.sc.Groovy6924Support
-            class Test {
-                static void foo() {
-                    Groovy6924Support bean = new Groovy6924Support()
-                    bean.with {
-                        foo = 'foo'
-                        bar = 'bar'
+                class Test {
+                    static void foo() {
+                        Groovy6924Support bean = new Groovy6924Support()
+                        bean.with {
+                            foo = 'foo'
+                            bar = 'bar'
+                        }
+                        String val = "$bean.foo and $bean.bar"
+                        assert val == 'foo and bar'
                     }
-                    String val = "$bean.foo and $bean.bar"
-                    assert val == 'foo and bar'
                 }
-            }
-            Test.foo()
-        '''
+                Test.foo()
+            '''
         } finally {
             assert astTrees['Test$_foo_closure1'][1].contains('INVOKEVIRTUAL org/codehaus/groovy/classgen/asm/sc/Groovy6924Support.setFoo (Ljava/lang/String;)V')
         }
     }
 
     // GROOVY-7381
-    void testNonVoidSetterCalls(){
+    void testNonVoidSetterCalls() {
         assertScript '''
             class Foo {
                 int num
@@ -1523,4 +1511,21 @@ println someInt
             test()
         '''
     }
+
+    // GROOVY-10819, GROOVY-10820
+    void testClassVersusObjectMethods() {
+        assertScript '''
+            assert String.metaClass != Class.metaClass
+            assert String.metaClass != Class.getMetaClass()
+            assert String.getMetaClass() != Class.getMetaClass()
+        '''
+        assertScript '''
+            @ASTTest(phase=INSTRUCTION_SELECTION, value={
+                def source = node.rightExpression // "String.getMetaClass()"
+                def target = source.getNodeMetaData(DIRECT_METHOD_CALL_TARGET)
+                assert target.declaringClass == CLASS_Type // not OBJECT_TYPE!
+            })
+            def smc = String.getMetaClass()
+        '''
+    }
 }
diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompilationTestSupport.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompilationTestSupport.groovy
index 0f9a644822..7b67973346 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompilationTestSupport.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompilationTestSupport.groovy
@@ -56,10 +56,12 @@ trait StaticCompilationTestSupport {
                 new ImportCustomizer().tap {
                     addImports(
                             'groovy.transform.ASTTest',
+                            'groovy.transform.CompileStatic',
                             'groovy.transform.stc.ClosureParams',
                             'org.codehaus.groovy.ast.ClassHelper',
                             'org.codehaus.groovy.transform.stc.StaticTypesMarker')
                     addStaticStars(
+                            'groovy.transform.TypeCheckingMode',
                             'org.codehaus.groovy.ast.ClassHelper',
                             'org.codehaus.groovy.control.CompilePhase',
                             'org.codehaus.groovy.transform.stc.StaticTypesMarker')
diff --git a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/Console.groovy b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/Console.groovy
index bc1b9a66f9..c78aac38e0 100644
--- a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/Console.groovy
+++ b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/Console.groovy
@@ -1426,26 +1426,16 @@ class Console implements CaretListener, HyperlinkListener, ComponentListener, Fo
 
     @CompileStatic
     private static Optional<String> findPrimaryClassName(String javaSrc) {
-        List<TypeDeclaration<?>> result = new LinkedList<>()
-        CompilationUnit compilationUnit = StaticJavaParser.parse(javaSrc)
-
+        CompilationUnit compilationUnit= StaticJavaParser.parse(javaSrc)
         for (TypeDeclaration<?> td : compilationUnit.getTypes()) {
-            if (!(td.isTopLevelType() && td.isClassOrInterfaceDeclaration() && td.getModifiers().contains(Modifier.publicModifier()))) continue
-
-            if (td.fullyQualifiedName.isPresent()) {
-                result << td
-            }
-        }
-
-        String className = null
-        if (!result.isEmpty()) {
-            Optional<String> optionalClassName = result.get(0).getFullyQualifiedName()
-            if (optionalClassName.isPresent()) {
-                className = optionalClassName.get()
+            if (td.isPublic()
+                    && td.isTopLevelType()
+                    && td.isClassOrInterfaceDeclaration()
+                    && td.getFullyQualifiedName().isPresent()) {
+                return td.getFullyQualifiedName();
             }
         }
-
-        return Optional.ofNullable(className)
+        return Optional.empty()
     }
 
     void compileAsJava(EventObject evt = null) {