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/09/27 23:38:14 UTC

[groovy] branch master updated: GROOVY-10771: STC: add `import org.codehaus.groovy.ast.*` for extensions

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 3ff60dd069 GROOVY-10771: STC: add `import org.codehaus.groovy.ast.*` for extensions
3ff60dd069 is described below

commit 3ff60dd069e136b162da80c9ebd90c16c427422d
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Sep 27 18:22:43 2022 -0500

    GROOVY-10771: STC: add `import org.codehaus.groovy.ast.*` for extensions
---
 .../stc/GroovyTypeCheckingExtensionSupport.java    |  72 +++++------
 src/spec/doc/_type-checking-extensions.adoc        |  39 +++---
 src/spec/test-resources/unresolvedattribute.groovy |   6 +-
 src/spec/test-resources/unresolvedproperty.groovy  |   8 +-
 src/spec/test-resources/unresolvedvariable.groovy  |   6 +-
 .../transform/stc/FinishTestExtension.groovy       |   2 +-
 .../groovy/transform/stc/SetupTestExtension.groovy |   2 +-
 .../stc/TypeCheckingExtensionsTest.groovy          | 138 ++++++++++++---------
 8 files changed, 150 insertions(+), 123 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/transform/stc/GroovyTypeCheckingExtensionSupport.java b/src/main/java/org/codehaus/groovy/transform/stc/GroovyTypeCheckingExtensionSupport.java
index 0852cf33da..5a72984917 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/GroovyTypeCheckingExtensionSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/GroovyTypeCheckingExtensionSupport.java
@@ -63,37 +63,32 @@ import java.util.Map;
 public class GroovyTypeCheckingExtensionSupport extends AbstractTypeCheckingExtension {
 
     // method name to DSL name
-    private static final Map<String, String> METHOD_ALIASES = Collections.unmodifiableMap(
-            new HashMap<String, String>() {
-                private static final long serialVersionUID = 8938707932245818749L;
-
-                {
-                put("onMethodSelection", "onMethodSelection");
-                put("afterMethodCall", "afterMethodCall");
-                put("beforeMethodCall", "beforeMethodCall");
-                put("unresolvedVariable", "handleUnresolvedVariableExpression");
-                put("unresolvedProperty", "handleUnresolvedProperty");
-                put("unresolvedAttribute", "handleUnresolvedAttribute");
-                put("ambiguousMethods", "handleAmbiguousMethods");
-                put("methodNotFound", "handleMissingMethod");
-                put("afterVisitMethod", "afterVisitMethod");
-                put("beforeVisitMethod", "beforeVisitMethod");
-                put("afterVisitClass", "afterVisitClass");
-                put("beforeVisitClass", "beforeVisitClass");
-                put("incompatibleAssignment", "handleIncompatibleAssignment");
-                put("incompatibleReturnType", "handleIncompatibleReturnType");
-                put("setup","setup");
-                put("finish", "finish");
-            }}
+    private static final Map<String, String> METHOD_ALIASES = org.apache.groovy.util.Maps.of(
+            "onMethodSelection",      "onMethodSelection",
+            "afterMethodCall",        "afterMethodCall",
+            "beforeMethodCall",       "beforeMethodCall",
+            "unresolvedVariable",     "handleUnresolvedVariableExpression",
+            "unresolvedProperty",     "handleUnresolvedProperty",
+            "unresolvedAttribute",    "handleUnresolvedAttribute",
+            "ambiguousMethods",       "handleAmbiguousMethods",
+            "methodNotFound",         "handleMissingMethod",
+            "afterVisitMethod",       "afterVisitMethod",
+            "beforeVisitMethod",      "beforeVisitMethod",
+            "afterVisitClass",        "afterVisitClass",
+            "beforeVisitClass",       "beforeVisitClass",
+            "incompatibleAssignment", "handleIncompatibleAssignment",
+            "incompatibleReturnType", "handleIncompatibleReturnType",
+            "setup",                  "setup",
+            "finish",                 "finish"
     );
 
-    // the following fields are closures executed in event-based methods
-    private final Map<String, List<Closure>> eventHandlers = new HashMap<String, List<Closure>>();
-
     private final String scriptPath;
 
     private final CompilationUnit compilationUnit;
 
+    /** Closures executed in event-based methods. */
+    private final Map<String, List<Closure>> eventHandlers = new HashMap<>();
+
     /**
      * Builds a type checking extension relying on a Groovy script (type checking DSL).
      *
@@ -115,13 +110,17 @@ public class GroovyTypeCheckingExtensionSupport extends AbstractTypeCheckingExte
 
     @Override
     public void setup() {
-        CompilerConfiguration config = new CompilerConfiguration();
-        config.setScriptBaseClass("org.codehaus.groovy.transform.stc.GroovyTypeCheckingExtensionSupport.TypeCheckingDSL");
         ImportCustomizer ic = new ImportCustomizer();
-        ic.addStarImports("org.codehaus.groovy.ast.expr");
-        ic.addStaticStars("org.codehaus.groovy.ast.ClassHelper");
-        ic.addStaticStars("org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport");
-        config.addCompilationCustomizers(ic);
+        ic.addStarImports(
+                "org.codehaus.groovy.ast",
+                "org.codehaus.groovy.ast.expr");
+        ic.addStaticStars(
+                "org.codehaus.groovy.ast.ClassHelper",
+                "org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport");
+
+        CompilerConfiguration config = new CompilerConfiguration().addCompilationCustomizers(ic);
+        config.setScriptBaseClass("org.codehaus.groovy.transform.stc.GroovyTypeCheckingExtensionSupport.TypeCheckingDSL");
+
         final GroovyClassLoader transformLoader = compilationUnit!=null?compilationUnit.getTransformLoader():typeCheckingVisitor.getSourceUnit().getClassLoader();
 
         // since Groovy 2.2, it is possible to use FQCN for type checking extension scripts
@@ -152,7 +151,7 @@ public class GroovyTypeCheckingExtensionSupport extends AbstractTypeCheckingExte
         } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
             addLoadingError(config);
         }
-        if (script==null) {
+        if (script == null) {
             ClassLoader cl = typeCheckingVisitor.getSourceUnit().getClassLoader();
             // cast to prevent incorrect @since 1.7 warning
             InputStream is = ((ClassLoader)transformLoader).getResourceAsStream(scriptPath);
@@ -182,7 +181,7 @@ public class GroovyTypeCheckingExtensionSupport extends AbstractTypeCheckingExte
                 throw new GroovyBugError("Unsupported encoding found in compiler configuration", e);
             }
         }
-        if (script!=null) {
+        if (script != null) {
             script.extension = this;
             script.run();
             List<Closure> list = eventHandlers.get("setup");
@@ -427,14 +426,15 @@ public class GroovyTypeCheckingExtensionSupport extends AbstractTypeCheckingExte
             if (name.startsWith("is") && name.endsWith("Expression") && args instanceof Object[] && ((Object[]) args).length == 1) {
                 String type = name.substring(2);
                 Object target = ((Object[]) args)[0];
-                if (target==null) return false;
+                if (target == null) return Boolean.FALSE;
                 try {
-                    Class typeClass = Class.forName("org.codehaus.groovy.ast.expr."+type);
+                    Class<?> typeClass = Class.forName("org.codehaus.groovy.ast.expr." + type);
                     return typeClass.isAssignableFrom(target.getClass());
                 } catch (ClassNotFoundException e) {
-                    return false;
+                    return Boolean.FALSE;
                 }
             }
+
             if (args instanceof Object[] && ((Object[]) args).length == 1 && ((Object[]) args)[0] instanceof Closure) {
                 Object[] argsArray = (Object[]) args;
                 String methodName = METHOD_ALIASES.get(name);
diff --git a/src/spec/doc/_type-checking-extensions.adoc b/src/spec/doc/_type-checking-extensions.adoc
index 16d7eeb5ac..fa0b668424 100644
--- a/src/spec/doc/_type-checking-extensions.adoc
+++ b/src/spec/doc/_type-checking-extensions.adoc
@@ -25,13 +25,12 @@
 
 === Towards a smarter type checker
 
-Despite being a dynamic language, Groovy can be used with a static type
-checker at compile time, enabled using the <<s...@TypeChecked>>
-annotation. In this mode, the compiler becomes
-more verbose and throws errors for, example, typos, non-existent
-methods,… This comes with a few limitations though, most of them coming
-from the fact that Groovy remains inherently a dynamic language. For
-example, you wouldn’t be able to use type checking on code that uses the markup builder:
+Despite being a dynamic language, Groovy can be used with a <<static-type-checking,static type checker>>
+at compile time, enabled using the `@TypeChecked` annotation. In this mode, the
+compiler becomes more verbose and throws errors for, example, typos, non-existent
+methods, etc. This comes with a few limitations though, most of them coming from
+the fact that Groovy remains inherently a dynamic language. For example, you
+wouldn’t be able to use type checking on code that uses the markup builder:
 
 [source,groovy]
 ----
@@ -246,7 +245,7 @@ Can be used to perform additional checks after the type checker has finished its
 | Called when the type checker finds an
   unresolved variable
 | *Arguments*
-| VariableExpression var
+| VariableExpression vexp
 | *Usage*
 |
 [source,groovy]
@@ -286,7 +285,7 @@ Allows the developer to handle "dynamic" properties
 | Called when the type checker cannot
   find an attribute on the receiver
 | *Arguments*
-| AttributeExpression aex
+| AttributeExpression aexp
 | *Usage*
 |
 [source,groovy]
@@ -564,19 +563,16 @@ make things easier.
 [[Typecheckingextensions-Supportclasses]]
 ==== Support classes
 
-The DSL relies on a support class
-called gapi:org.codehaus.groovy.transform.stc.GroovyTypeCheckingExtensionSupport[] .
-This class itself
-extends gapi:org.codehaus.groovy.transform.stc.TypeCheckingExtension[] . Those
-two classes define a number of _helper_ methods that will make working
+The DSL relies on a support class called gapi:org.codehaus.groovy.transform.stc.GroovyTypeCheckingExtensionSupport[] .
+This class itself extends gapi:org.codehaus.groovy.transform.stc.TypeCheckingExtension[] .
+Those two classes define a number of _helper_ methods that will make working
 with the AST easier, especially regarding type checking. One interesting
 thing to know is that you *have access to the type checker*. This means
 that you can programmatically call methods of the type checker,
 including those that allow you to *throw compilation errors*.
 
-The extension script delegates to
-the gapi:org.codehaus.groovy.transform.stc.GroovyTypeCheckingExtensionSupport[] class, meaning that you have
-direct access to the following variables:
+The extension script delegates to the gapi:org.codehaus.groovy.transform.stc.GroovyTypeCheckingExtensionSupport[] class,
+meaning that you have direct access to the following variables:
 
 * _context_: the type checker context, of type gapi:org.codehaus.groovy.transform.stc.TypeCheckingContext[]
 * _typeCheckingVisitor_: the type checker itself, a gapi:org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor[] instance
@@ -589,6 +585,12 @@ enclosing method calls, binary expressions, closures, … This information
 is in particular important if you have to know _where_ you are when an
 error occurs and that you want to handle it.
 
+In addition to facilities provided by `GroovyTypeCheckingExtensionSupport` and `StaticTypeCheckingVisitor`,
+a type-checking DSL script imports static members from gapi:org.codehaus.groovy.ast.ClassHelper[] and
+gapi:org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport[] granting access to common types via
+`OBJECT_TYPE`, `STRING_TYPE`, `THROWABLE_TYPE`, etc. and checks like `missesGenericsTypes(ClassNode)`,
+`isClassClassNodeWrappingConcreteType(ClassNode)` and so on.
+
 [[Typecheckingextensions-Classnodes]]
 ==== Class nodes
 
@@ -677,8 +679,7 @@ if (node instanceof BinaryExpression) {
 }
 ---------------------------------------
 
-which requires you to import the `BinaryExpression` class, you can just
-write:
+you can just write:
 
 [source,groovy]
 -------------------------------
diff --git a/src/spec/test-resources/unresolvedattribute.groovy b/src/spec/test-resources/unresolvedattribute.groovy
index 1b361fbbd1..c2e55024da 100644
--- a/src/spec/test-resources/unresolvedattribute.groovy
+++ b/src/spec/test-resources/unresolvedattribute.groovy
@@ -17,9 +17,9 @@
  *  under the License.
  */
 // tag::event[]
-unresolvedAttribute { aex ->
-    if (getType(aex.objectExpression)==classNodeFor(String)) {
-        storeType(aex,classNodeFor(String))
+unresolvedAttribute { AttributeExpression aexp ->
+    if (getType(aexp.objectExpression) == STRING_TYPE) {
+        storeType(aexp, STRING_TYPE)
         handled = true
     }
 }
diff --git a/src/spec/test-resources/unresolvedproperty.groovy b/src/spec/test-resources/unresolvedproperty.groovy
index 386cdae3a4..cb0514571c 100644
--- a/src/spec/test-resources/unresolvedproperty.groovy
+++ b/src/spec/test-resources/unresolvedproperty.groovy
@@ -19,10 +19,10 @@
 
 
 // tag::event[]
-unresolvedProperty { pexp ->
-    if ('longueur'==pexp.propertyAsString &&
-        getType(pexp.objectExpression)==classNodeFor(String)) {
-        storeType(pexp,classNodeFor(int))
+unresolvedProperty { PropertyExpression pexp ->
+    if (pexp.propertyAsString == 'longueur' &&
+            getType(pexp.objectExpression) == STRING_TYPE) {
+        storeType(pexp, int_TYPE)
         handled = true
     }
 }
diff --git a/src/spec/test-resources/unresolvedvariable.groovy b/src/spec/test-resources/unresolvedvariable.groovy
index b8e112bb5b..2c3734578c 100644
--- a/src/spec/test-resources/unresolvedvariable.groovy
+++ b/src/spec/test-resources/unresolvedvariable.groovy
@@ -17,9 +17,9 @@
  *  under the License.
  */
 // tag::event[]
-unresolvedVariable { var ->
-    if ('people' == var.name) {
-        storeType(var, classNodeFor(List))
+unresolvedVariable { VariableExpression vexp ->
+    if (vexp.name == 'people') {
+        storeType(vexp, LIST_TYPE)
         handled = true
     }
 }
diff --git a/src/test-resources/groovy/transform/stc/FinishTestExtension.groovy b/src/test-resources/groovy/transform/stc/FinishTestExtension.groovy
index 118a574e64..24437b888b 100644
--- a/src/test-resources/groovy/transform/stc/FinishTestExtension.groovy
+++ b/src/test-resources/groovy/transform/stc/FinishTestExtension.groovy
@@ -18,6 +18,6 @@
  */
 // Dummy extension that just puts the "finish" node metadata on the 'A' class node
 finish {
-    def cn = context.source.AST.classes.find { it.name == 'A' }
+    ClassNode cn = context.source.AST.classes.find { it.name == 'A' }
     cn.putNodeMetaData('finish', true)
 }
diff --git a/src/test-resources/groovy/transform/stc/SetupTestExtension.groovy b/src/test-resources/groovy/transform/stc/SetupTestExtension.groovy
index cd0cac034f..1deba6b868 100644
--- a/src/test-resources/groovy/transform/stc/SetupTestExtension.groovy
+++ b/src/test-resources/groovy/transform/stc/SetupTestExtension.groovy
@@ -18,6 +18,6 @@
  */
 // Dummy extension that just puts the "setup" node metadata on the 'A' class node
 setup {
-    def cn = context.source.AST.classes.find { it.name == 'A' }
+    ClassNode cn = context.source.AST.classes.find { it.name == 'A' }
     cn.putNodeMetaData('setup', true)
 }
diff --git a/src/test/groovy/transform/stc/TypeCheckingExtensionsTest.groovy b/src/test/groovy/transform/stc/TypeCheckingExtensionsTest.groovy
index af5ddceac9..8c7b1ab204 100644
--- a/src/test/groovy/transform/stc/TypeCheckingExtensionsTest.groovy
+++ b/src/test/groovy/transform/stc/TypeCheckingExtensionsTest.groovy
@@ -86,7 +86,8 @@ class TypeCheckingExtensionsTest extends StaticTypeCheckingTestCase {
         extension = 'groovy/transform/stc/NewMethodAndIsGeneratedTestExtension.groovy'
         shouldFailWithMessages '''
             'foo'
-        ''', 'Extension was executed properly'
+        ''',
+        'Extension was executed properly'
     }
 
     void testUndefinedVariable() {
@@ -103,8 +104,9 @@ class TypeCheckingExtensionsTest extends StaticTypeCheckingTestCase {
     void testUndefinedVariableNoHandle() {
         extension = 'groovy/transform/stc/UndefinedVariableNoHandleTestExtension.groovy'
         shouldFailWithMessages '''
-                foo.toUpperCase() // normal type checker would fail here
-            ''', 'The variable [foo] is undeclared'
+            foo.toUpperCase() // normal type checker would fail here
+        ''',
+        'The variable [foo] is undeclared'
     }
 
     void testMissingMethod() {
@@ -112,7 +114,9 @@ class TypeCheckingExtensionsTest extends StaticTypeCheckingTestCase {
         shouldFailWithMessages '''
             String msg = 'foo'
             msg.TOUPPERCASE()
-        ''', 'Cannot find matching method'
+        ''',
+        'Cannot find matching method'
+
         extension = 'groovy/transform/stc/MissingMethod1TestExtension.groovy'
         try {
             assertScript '''
@@ -130,7 +134,9 @@ class TypeCheckingExtensionsTest extends StaticTypeCheckingTestCase {
             String msg = 'foo'
             msg.SIZE()
             msg.CONCAT('bar')
-        ''', 'Cannot find matching method java.lang.String#SIZE()', 'Cannot find matching method java.lang.String#CONCAT(java.lang.String)'
+        ''',
+        'Cannot find matching method java.lang.String#SIZE()', 'Cannot find matching method java.lang.String#CONCAT(java.lang.String)'
+
         extension = 'groovy/transform/stc/MissingMethod2TestExtension.groovy'
         try {
             assertScript '''
@@ -157,7 +163,8 @@ class TypeCheckingExtensionsTest extends StaticTypeCheckingTestCase {
         extension = 'groovy/transform/stc/PrefixChangerTestExtension.groovy'
         shouldFailWithMessages '''
            int x = 'foo'
-        ''', '[Custom] - Cannot assign value of type java.lang.String to variable of type int'
+        ''',
+        '[Custom] - Cannot assign value of type java.lang.String to variable of type int'
     }
 
     void testAfterMethodCallHook() {
@@ -165,8 +172,9 @@ class TypeCheckingExtensionsTest extends StaticTypeCheckingTestCase {
         shouldFailWithMessages '''
             String count = 'foo'
             sprintf("Count = %d", count)
-        ''', 'Parameter types didn\'t match types expected from the format String',
-                'For placeholder 1 [%d] expected \'int\' but was \'java.lang.String\''
+        ''',
+        'Parameter types didn\'t match types expected from the format String',
+        'For placeholder 1 [%d] expected \'int\' but was \'java.lang.String\''
     }
 
     void testBeforeMethodCallHook() {
@@ -176,7 +184,8 @@ class TypeCheckingExtensionsTest extends StaticTypeCheckingTestCase {
             String BOO() { 'bar' }
             method() // ok
             BOO() // error
-        ''', 'Calling a method which is all uppercase is not allowed'
+        ''',
+        'Calling a method which is all uppercase is not allowed'
     }
 
     void testBeforeMethodHook() {
@@ -184,7 +193,8 @@ class TypeCheckingExtensionsTest extends StaticTypeCheckingTestCase {
         shouldFailWithMessages '''
             String method() { 'foo' } // ok
             String BOO() { 'bar' } // error
-        ''', 'Defining method which is all uppercase is not allowed'
+        ''',
+        'Defining method which is all uppercase is not allowed'
     }
 
     void testAfterMethodHook() {
@@ -192,26 +202,27 @@ class TypeCheckingExtensionsTest extends StaticTypeCheckingTestCase {
         shouldFailWithMessages '''
             String method() { 'foo' } // ok
             String BOO() { 'bar' } // error
-        ''', 'Defining method which is all uppercase is not allowed'
+        ''',
+        'Defining method which is all uppercase is not allowed'
     }
 
     void testMethodSelection() {
         // first step checks that without extension, type checking works properly
         extension = null
         assertScript '''
-        @ASTTest(phase=INSTRUCTION_SELECTION, value={
-            assert node.getNodeMetaData('selected') == null
-        })
-        def str = 'foo'.toUpperCase()
+            @ASTTest(phase=INSTRUCTION_SELECTION, value={
+                assert node.getNodeMetaData('selected') == null
+            })
+            def str = 'foo'.toUpperCase()
         '''
 
         // then we use a type checking extension, we add node metadata
         extension = 'groovy/transform/stc/OnMethodSelectionTestExtension.groovy'
         assertScript '''
-        @ASTTest(phase=INSTRUCTION_SELECTION, value={
-            assert node.getNodeMetaData('selected') == true
-        })
-        def str = 'foo'.toUpperCase()
+            @ASTTest(phase=INSTRUCTION_SELECTION, value={
+                assert node.getNodeMetaData('selected') == true
+            })
+            def str = 'foo'.toUpperCase()
         '''
     }
 
@@ -219,7 +230,8 @@ class TypeCheckingExtensionsTest extends StaticTypeCheckingTestCase {
         extension = null
         shouldFailWithMessages '''
             'str'.FOO
-        ''', 'No such property: FOO for class: java.lang.String'
+        ''',
+        'No such property: FOO for class: java.lang.String'
 
         extension = 'groovy/transform/stc/UnresolvedPropertyTestExtension.groovy'
         assertScript '''
@@ -234,7 +246,8 @@ class TypeCheckingExtensionsTest extends StaticTypeCheckingTestCase {
         extension = null
         shouldFailWithMessages '''
             'str'.@FOO
-        ''', 'No such attribute: FOO for class: java.lang.String'
+        ''',
+        'No such attribute: FOO for class: java.lang.String'
 
         extension = 'groovy/transform/stc/UnresolvedAttributeTestExtension.groovy'
         assertScript '''
@@ -254,7 +267,8 @@ class TypeCheckingExtensionsTest extends StaticTypeCheckingTestCase {
             new Support().foo {
                 'a'.toUpperCase()
             }
-        ''', 'Scope enter and exit behave correctly' // we're using shouldFail just to verify that the extension is ran
+        ''',
+        'Scope enter and exit behave correctly' // we're using shouldFail just to verify that the extension is ran
     }
 
     void testMatchingArguments() {
@@ -268,11 +282,12 @@ class TypeCheckingExtensionsTest extends StaticTypeCheckingTestCase {
             two('foo', 1)
             three('foo', 2, new Date())
             three('foo', (Integer)2, new Date())
-        ''', 'Method [zero] with matching arguments found: 0',
-             'Method [concat] with matching arguments found: 1',
-                'Method [two] with matching arguments found: 2',
-                'Method [three] with matching arguments found: 3',
-                'Method [three] with matching arguments found: 3'
+        ''',
+        'Method [zero] with matching arguments found: 0',
+        'Method [concat] with matching arguments found: 1',
+        'Method [two] with matching arguments found: 2',
+        'Method [three] with matching arguments found: 3',
+        'Method [three] with matching arguments found: 3'
     }
 
     void testFirstArgsMatches() {
@@ -283,9 +298,10 @@ class TypeCheckingExtensionsTest extends StaticTypeCheckingTestCase {
             two('foo', 1)
             three('foo', 2, new Date())
             three('foo', (Integer)2, new Date())
-        ''', 'Method [two] with matching arguments found: 2',
-                'Method [three] with matching arguments found: 3',
-                'Method [three] with matching arguments found: 3'
+        ''',
+        'Method [two] with matching arguments found: 2',
+        'Method [three] with matching arguments found: 3',
+        'Method [three] with matching arguments found: 3'
     }
 
     void testNthArgMatches() {
@@ -296,21 +312,23 @@ class TypeCheckingExtensionsTest extends StaticTypeCheckingTestCase {
             two('foo', 1)
             three('foo', 2, new Date())
             three('foo', (Integer)2, new Date())
-        ''', 'Method [two] with matching argument found: [0, class java.lang.String]',
-             'Method [two] with matching argument found: [1, class java.lang.Integer]',
-             'Method [three] with matching argument found: [0, class java.lang.String]',
-             'Method [three] with matching argument found: [1, class java.lang.Integer]',
-             'Method [three] with matching argument found: [2, class java.util.Date]',
-             'Method [three] with matching argument found: [0, class java.lang.String]',
-             'Method [three] with matching argument found: [1, class java.lang.Integer]',
-             'Method [three] with matching argument found: [2, class java.util.Date]'
+        ''',
+        'Method [two] with matching argument found: [0, class java.lang.String]',
+        'Method [two] with matching argument found: [1, class java.lang.Integer]',
+        'Method [three] with matching argument found: [0, class java.lang.String]',
+        'Method [three] with matching argument found: [1, class java.lang.Integer]',
+        'Method [three] with matching argument found: [2, class java.util.Date]',
+        'Method [three] with matching argument found: [0, class java.lang.String]',
+        'Method [three] with matching argument found: [1, class java.lang.Integer]',
+        'Method [three] with matching argument found: [2, class java.util.Date]'
     }
 
     void testIncompatibleAssignment() {
         extension = null
         shouldFailWithMessages '''
             int x = 'foo'
-        ''', 'Cannot assign value of type java.lang.String to variable of type int'
+        ''',
+        'Cannot assign value of type java.lang.String to variable of type int'
 
         extension = 'groovy/transform/stc/IncompatibleAssignmentTestExtension.groovy'
         assertScript '''
@@ -326,7 +344,8 @@ class TypeCheckingExtensionsTest extends StaticTypeCheckingTestCase {
             int x = 1
             Date y = new Date()
             x+y
-        ''', 'Cannot find matching method int#plus(java.util.Date)'
+        ''',
+        'Cannot find matching method int#plus(java.util.Date)'
 
         extension = 'groovy/transform/stc/BinaryOperatorTestExtension.groovy'
         assertScript '''
@@ -344,7 +363,8 @@ class TypeCheckingExtensionsTest extends StaticTypeCheckingTestCase {
             int x = 1
             Date y = new Date()
             x << y
-        ''', 'Cannot find matching method int#leftShift(java.util.Date)'
+        ''',
+        'Cannot find matching method int#leftShift(java.util.Date)'
 
         extension = 'groovy/transform/stc/BinaryOperatorTestExtension.groovy'
         assertScript '''
@@ -380,17 +400,17 @@ class TypeCheckingExtensionsTest extends StaticTypeCheckingTestCase {
     void testIsAnnotatedBy() {
         extension = null
         assertScript '''
-        @groovy.transform.stc.MyType(String)
-        int foo() { 1 }
+            @groovy.transform.stc.MyType(String)
+            int foo() { 1 }
         '''
 
         extension = 'groovy/transform/stc/AnnotatedByTestExtension.groovy'
         assertScript '''
-        @groovy.transform.stc.MyType(String)
-        @ASTTest(phase=INSTRUCTION_SELECTION,value={
-            assert node.getNodeMetaData(INFERRED_RETURN_TYPE) == STRING_TYPE
-        })
-        int foo() { 1 }
+            @groovy.transform.stc.MyType(String)
+            @ASTTest(phase=INSTRUCTION_SELECTION,value={
+                assert node.getNodeMetaData(INFERRED_RETURN_TYPE) == STRING_TYPE
+            })
+            int foo() { 1 }
         '''
     }
 
@@ -439,7 +459,7 @@ class TypeCheckingExtensionsTest extends StaticTypeCheckingTestCase {
                 b.elems()
             '''
         } catch (MissingMethodException e) {
-            // it's ok
+            // expected
         }
     }
 
@@ -454,12 +474,14 @@ class TypeCheckingExtensionsTest extends StaticTypeCheckingTestCase {
         ''', 'Reference to method is ambiguous'
         // fail with error from runtime
         extension = 'groovy/transform/stc/AmbiguousMethods.groovy'
-        shouldFail { assertScript '''
-            int foo(Integer x) { 1 }
-            int foo(String s) { 2 }
-            int foo(Date d) { 3 }
-            assert foo(null) == 2
-        '''}
+        shouldFail {
+            assertScript '''
+                int foo(Integer x) { 1 }
+                int foo(String s) { 2 }
+                int foo(Date d) { 3 }
+                assert foo(null) == 2
+            '''
+        }
     }
 
     void testIncompatibleReturnType() {
@@ -467,7 +489,9 @@ class TypeCheckingExtensionsTest extends StaticTypeCheckingTestCase {
         shouldFailWithMessages '''
             Date foo() { '1' }
             true
-        ''', 'Cannot return value of type'
+        ''',
+        'Cannot return value of type'
+
         extension = 'groovy/transform/stc/IncompatibleReturnTypeTestExtension.groovy'
         assertScript '''
             Date foo() { '1' }
@@ -480,6 +504,7 @@ class TypeCheckingExtensionsTest extends StaticTypeCheckingTestCase {
         assertScript '''
             println 'Everything is ok'
         '''
+
         extension = 'groovy.transform.stc.PrecompiledExtension'
         shouldFailWithMessages '''
             println 'Everything is ok'
@@ -492,6 +517,7 @@ class TypeCheckingExtensionsTest extends StaticTypeCheckingTestCase {
         assertScript '''
             println 'Everything is ok'
         '''
+
         extension = 'groovy.transform.stc.PrecompiledExtensionNotExtendingDSL'
         shouldFailWithMessages '''
             println 'Everything is ok'