You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2021/03/24 14:43:36 UTC
[groovy] 02/02: GROOVY-9997: infer closure/lambda params + return
types from cast/coerce
This is an automated email from the ASF dual-hosted git repository.
sunlan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 9a63e8cc7bd9bdb1efd97046907549199260e715
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon Mar 22 21:54:30 2021 -0500
GROOVY-9997: infer closure/lambda params + return types from cast/coerce
---
.../transform/stc/StaticTypeCheckingVisitor.java | 21 ++++++++++++---------
src/test/groovy/transform/stc/LambdaTest.groovy | 15 +++++++++++++++
.../groovy/console/ui/ButtonOrTextEditor.groovy | 4 ++--
3 files changed, 29 insertions(+), 11 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 e611cee..888a1c5 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -4092,16 +4092,19 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
@Override
public void visitCastExpression(final CastExpression expression) {
- super.visitCastExpression(expression);
- if (!expression.isCoerce()) {
- ClassNode targetType = expression.getType();
- Expression source = expression.getExpression();
- ClassNode expressionType = getType(source);
- if (!checkCast(targetType, source) && !isDelegateOrOwnerInClosure(source)) {
- addStaticTypeError("Inconvertible types: cannot cast " + prettyPrintType(expressionType) + " to " + prettyPrintType(targetType), expression);
- }
+ ClassNode type = expression.getType();
+ Expression source = expression.getExpression();
+ if (isFunctionalInterface(type)) { // GROOVY-9997
+ processFunctionalInterfaceAssignment(type, source);
+ } else if (isClosureWithType(type) && source instanceof ClosureExpression) {
+ storeInferredReturnType(source, getCombinedBoundType(type.getGenericsTypes()[0]));
+ }
+
+ source.visit(this);
+
+ if (!expression.isCoerce() && !checkCast(type, source) && !isDelegateOrOwnerInClosure(source)) {
+ addStaticTypeError("Inconvertible types: cannot cast " + prettyPrintType(getType(source)) + " to " + prettyPrintType(type), expression);
}
- storeType(expression, expression.getType());
}
private boolean isDelegateOrOwnerInClosure(final Expression exp) {
diff --git a/src/test/groovy/transform/stc/LambdaTest.groovy b/src/test/groovy/transform/stc/LambdaTest.groovy
index 618f18f..be0e437 100644
--- a/src/test/groovy/transform/stc/LambdaTest.groovy
+++ b/src/test/groovy/transform/stc/LambdaTest.groovy
@@ -330,6 +330,21 @@ final class LambdaTest {
'''
}
+ @Test // GROOVY-9997
+ void testComparator3() {
+ assertScript '''
+ @groovy.transform.TypeChecked
+ void test() {
+ def cast = (Comparator<Integer>) (a, b) -> Integer.compare(a, b)
+ assert cast.compare(0,0) == 0
+
+ def coerce = ((a, b) -> Integer.compare(a, b)) as Comparator<Integer>
+ assert coerce.compare(0,0) == 0
+ }
+ test()
+ '''
+ }
+
@Test
void testFunctionWithLocalVariables() {
assertScript '''
diff --git a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ButtonOrTextEditor.groovy b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ButtonOrTextEditor.groovy
index ddb97ce..38992ce 100644
--- a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ButtonOrTextEditor.groovy
+++ b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ButtonOrTextEditor.groovy
@@ -44,12 +44,12 @@ class ButtonOrTextEditor extends AbstractCellEditor implements TableCellEditor {
Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
if (value instanceof JButton) {
editorComponent = value
- ((JButton) editorComponent).addActionListener({ fireEditingStopped() } as ActionListener)
+ ((JButton) editorComponent).addActionListener({ e -> fireEditingStopped() } as ActionListener)
} else if (value instanceof JTextArea) {
editorComponent = value
} else if (value) {
editorComponent = new JTextArea(value.toString())
- editorComponent.addFocusListener({ fireEditingCanceled() } as FocusListener)
+ editorComponent.addFocusListener({ e -> fireEditingCanceled() } as FocusListener)
} else {
editorComponent = null
}