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/30 14:45:02 UTC
[groovy] branch GROOVY_4_0_X 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 GROOVY_4_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY_4_0_X by this push:
new 6919d3943b GROOVY-10771: STC: add `import org.codehaus.groovy.ast.*` for extensions
6919d3943b is described below
commit 6919d3943bf2385ac8d7413a310bde791118b1f2
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'