diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml
index 075f1a5f4032..3a737880f10a 100644
--- a/plugins/groovy/src/META-INF/plugin.xml
+++ b/plugins/groovy/src/META-INF/plugin.xml
@@ -127,6 +127,7 @@
+
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppClosureParameterTypeProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppClosureParameterTypeProvider.java
index 6b9f4a2d19cc..457c98406cf0 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppClosureParameterTypeProvider.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppClosureParameterTypeProvider.java
@@ -114,7 +114,7 @@ public class GppClosureParameterTypeProvider extends AbstractClosureParameterEnh
}
@Nullable
- private static PsiType getSingleMethodParameterType(@Nullable PsiType type, int index, GrClosableBlock closure) {
+ public static PsiType getSingleMethodParameterType(@Nullable PsiType type, int index, GrClosableBlock closure) {
final PsiType[] signature = findSingleAbstractMethodSignature(type);
if (signature != null && GrClosureSignatureUtil.isSignatureApplicable(GrClosureSignatureUtil.createSignature(closure), signature, closure)) {
return signature.length > index ? signature[index] : PsiType.NULL;
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppTypeConverter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppTypeConverter.java
index a3f84e14109c..d36faf97e26a 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppTypeConverter.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppTypeConverter.java
@@ -76,7 +76,7 @@ public class GppTypeConverter extends GrTypeConverter {
return true;
}
}
- else if (rType instanceof GrClosureType) {
+ else if (rType instanceof GrClosureType && hasTypedContext(context)) {
final PsiType[] methodParameters = GppClosureParameterTypeProvider.findSingleAbstractMethodSignature(lType);
if (isClosureOverride(methodParameters, (GrClosureType)rType, context)) return true;
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureAsAnonymousParameterEnhancer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureAsAnonymousParameterEnhancer.java
new file mode 100644
index 000000000000..6ebe35af596f
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureAsAnonymousParameterEnhancer.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed 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 org.jetbrains.plugins.groovy.lang.psi.typeEnhancers;
+
+import com.intellij.psi.PsiManager;
+import com.intellij.psi.PsiType;
+import com.intellij.psi.search.GlobalSearchScope;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.groovy.gpp.GppClosureParameterTypeProvider;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSafeCastExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
+import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.GroovyExpectedTypesProvider;
+import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author Max Medvedev
+ */
+public class ClosureAsAnonymousParameterEnhancer extends AbstractClosureParameterEnhancer {
+ @Nullable
+ @Override
+ protected PsiType getClosureParameterType(GrClosableBlock closure, int index) {
+
+ Set expectedTypes;
+
+ if (closure.getParent() instanceof GrSafeCastExpression) {
+ GrSafeCastExpression safeCastExpression = (GrSafeCastExpression)closure.getParent();
+ GrTypeElement typeElement = safeCastExpression.getCastTypeElement();
+ if (typeElement != null) {
+ PsiType castType = typeElement.getType();
+ expectedTypes = new HashSet(GroovyExpectedTypesProvider.getDefaultExpectedTypes(safeCastExpression));
+ PsiManager manager = closure.getManager();
+ GlobalSearchScope scope = closure.getResolveScope();
+ for (PsiType expected : expectedTypes) {
+ if (!TypesUtil.isAssignable(expected, castType, manager, scope)) {
+ expectedTypes.remove(expected);
+ }
+ }
+
+ if (expectedTypes.isEmpty()) expectedTypes.add(castType);
+ }
+ else {
+ expectedTypes = GroovyExpectedTypesProvider.getDefaultExpectedTypes(closure);
+ }
+ }
+ else {
+ expectedTypes = GroovyExpectedTypesProvider.getDefaultExpectedTypes(closure);
+ }
+
+ for (PsiType constraint : expectedTypes) {
+ final PsiType suggestion = GppClosureParameterTypeProvider.getSingleMethodParameterType(constraint, index, closure);
+ if (suggestion != null) {
+ return suggestion;
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.groovy
index 6dfb40b48c7d..f973bd3303ac 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.groovy
@@ -1452,6 +1452,25 @@ List foo() {[]}
def (int x, String y) = foo()
List foo() {[]}
+''', GroovyAssignabilityCheckInspection)
+ }
+
+ void testCastClosureToInterface() {
+ testHighlighting('''\
+interface Function {
+ F fun(D d)
+}
+
+def foo(Function function) {
+ // print function.fun('abc')
+}
+
+
+foo({println it.byteValue()} as Function)
+foo({println it.substring(1)} as Function)
+foo({println it.substring(1)} as Function)
+foo({println it})
+
''', GroovyAssignabilityCheckInspection)
}