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 2017/12/13 03:27:21 UTC
groovy git commit: GROOVY-8241 SAM parameter type inference for
explicit parameter (closes #643)
Repository: groovy
Updated Branches:
refs/heads/master 22e45ebe2 -> bd5191d9a
GROOVY-8241 SAM parameter type inference for explicit parameter (closes #643)
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/bd5191d9
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/bd5191d9
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/bd5191d9
Branch: refs/heads/master
Commit: bd5191d9a8858945a4d83df58e261eb56bec0ab7
Parents: 22e45eb
Author: alexey.afanasiev <Al...@jetbrains.com>
Authored: Mon Dec 11 16:01:02 2017 +0300
Committer: sunlan <su...@apache.org>
Committed: Wed Dec 13 11:22:51 2017 +0800
----------------------------------------------------------------------
.../stc/StaticTypeCheckingVisitor.java | 37 +++++--
.../transform/stc/MethodCallsSTCTest.groovy | 111 +++++++++++++++++++
2 files changed, 141 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/groovy/blob/bd5191d9/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index cee30e4..a372284 100644
--- a/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -2584,7 +2584,14 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
// implicit it
blockParameterTypes = parameterTypesForSAM;
} else {
- blockParameterTypes = extractTypesFromParameters(p);
+ blockParameterTypes = new ClassNode[p.length];
+ for (int i = 0; i < p.length; i++) {
+ if (p[i] != null && !p[i].isDynamicTyped()) {
+ blockParameterTypes[i] = p[i].getType();
+ } else {
+ blockParameterTypes[i] = typeOrNull(parameterTypesForSAM, i);
+ }
+ }
}
}
for (int i=0; i<blockParameterTypes.length; i++) {
@@ -4271,12 +4278,8 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
}
// now check for closure override
TypeCheckingContext.EnclosingClosure enclosingClosure = typeCheckingContext.getEnclosingClosure();
- ClassNode[] closureParamTypes = (ClassNode[]) (enclosingClosure != null ? enclosingClosure.getClosureExpression().getNodeMetaData(StaticTypesMarker.CLOSURE_ARGUMENTS) : null);
- if (type == null && enclosingClosure != null && "it".equals(variable.getName()) && closureParamTypes != null) {
- final Parameter[] parameters = enclosingClosure.getClosureExpression().getParameters();
- if (parameters.length == 0 && temporaryTypesForExpression == null && closureParamTypes.length != 0) {
- type = closureParamTypes[0];
- }
+ if (type == null && enclosingClosure != null && temporaryTypesForExpression == null) {
+ type = getTypeFromClosureArguments(parameter, enclosingClosure);
}
if (type != null) {
storeType(vexp, type);
@@ -4356,6 +4359,26 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
return ((Expression) exp).getType();
}
+ private ClassNode getTypeFromClosureArguments(Parameter parameter, TypeCheckingContext.EnclosingClosure enclosingClosure) {
+ ClosureExpression closureExpression = enclosingClosure.getClosureExpression();
+ ClassNode[] closureParamTypes = (ClassNode[]) closureExpression.getNodeMetaData(StaticTypesMarker.CLOSURE_ARGUMENTS);
+ if (closureParamTypes == null) return null;
+ final Parameter[] parameters = closureExpression.getParameters();
+ String name = parameter.getName();
+
+ if (parameters.length == 0) {
+ return "it".equals(name) && closureParamTypes.length != 0 ? closureParamTypes[0] : null;
+ }
+
+ for (int index = 0; index < parameters.length; index++) {
+ if (name.equals(parameters[index].getName())) {
+ return closureParamTypes.length > index ? closureParamTypes[index] : null;
+ }
+ }
+
+ return null;
+ }
+
/**
* resolves a Field or Property node generics by using the current class and
* the declaring class to extract the right meaning of the generics symbols
http://git-wip-us.apache.org/repos/asf/groovy/blob/bd5191d9/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy b/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy
index 12e9cd2..74c2095 100644
--- a/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy
@@ -364,6 +364,29 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
'''
}
+ void testShouldNotFailThanksToInstanceOfChecksAndWithoutExplicitCasts2() {
+ assertScript '''
+ static String foo(String s) {
+ 'String'
+ }
+ static String foo(Integer s) {
+ 'Integer'
+ }
+ static String foo(Boolean s) {
+ 'Boolean'
+ }
+ ['foo',123,true].each { argument ->
+ if (argument instanceof String) {
+ foo(argument)
+ } else if (argument instanceof Boolean) {
+ foo(argument)
+ } else if (argument instanceof Integer) {
+ foo(argument)
+ }
+ }
+ '''
+ }
+
void testShouldFailWithMultiplePossibleMethods() {
shouldFailWithMessages '''
static String foo(String s) {
@@ -383,6 +406,94 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
''', 'Reference to method is ambiguous'
}
+ void testShouldFailWithMultiplePossibleMethods2() {
+ shouldFailWithMessages '''
+ static String foo(String s) {
+ 'String'
+ }
+ static String foo(Integer s) {
+ 'Integer'
+ }
+ static String foo(Boolean s) {
+ 'Boolean'
+ }
+ ['foo',123,true].each { argument ->
+ if (argument instanceof String || argument instanceof Boolean || argument instanceof Integer) {
+ foo(argument)
+ }
+ }
+ ''', 'Reference to method is ambiguous'
+ }
+
+ void testInstanceOfOnExplicitParameter() {
+ assertScript '''
+ 1.with { obj ->
+ if (obj instanceof String) {
+ obj.toUpperCase()
+ }
+ }
+ '''
+ }
+
+ void testSAMWithExplicitParameter() {
+ assertScript '''
+ public interface SAM {
+ boolean run(String var1, Thread th);
+ }
+
+ static boolean foo(SAM sam) {
+ sam.run("foo", new Thread())
+ }
+
+ static def callSAM() {
+ foo { str, th ->
+ str.toUpperCase().equals(th.getName())
+ }
+ }
+ '''
+ }
+
+ void testGroovy8241() {
+ assertScript '''
+ import java.util.function.Predicate
+
+ static boolean foo(Predicate<? super String> p) {
+ p.test("foo")
+ }
+
+ static def testPredicate() {
+ foo { it ->
+ it.toUpperCase()
+ true
+ }
+ }
+ '''
+ }
+
+ void testGroovy7061() {
+ assertScript '''
+ void doIt() {
+ List<Integer> nums = [1, 2, 3, -2, -5, 6]
+ Collections.sort(nums, { a, b -> a.abs() <=> b.abs() })
+ }
+ '''
+ }
+
+ void testGroovy7061ex2() {
+ assertScript '''
+ def doIt(List<String> strings) {
+ return strings.
+ stream().
+ filter { s -> s.length() < 10 }.
+ toArray()
+ }
+
+ final words = ["orange", "sit", "test", "flabbergasted", "honorific"]
+
+ println doIt(words)
+ '''
+ }
+
void testShouldFailBecauseVariableIsReassigned() {
shouldFailWithMessages '''
static String foo(String s) {