mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[groovy] make closure always assignable to SAM type
Make closure always assignable to SAM type independently of closure parameter types. This fixes (IDEA-175184)
This commit is contained in:
+26
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 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.
|
||||
@@ -15,18 +15,20 @@
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.lang.psi.typeEnhancers;
|
||||
|
||||
import com.intellij.psi.PsiSubstitutor;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiClassType;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.PsiWildcardType;
|
||||
import com.intellij.psi.util.MethodSignature;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.config.GroovyConfigUtils;
|
||||
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 org.jetbrains.plugins.groovy.lang.sam.SamConversionKt;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@@ -35,10 +37,10 @@ import java.util.List;
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public class ClosureAsAnonymousParameterEnhancer extends AbstractClosureParameterEnhancer {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected PsiType getClosureParameterType(GrClosableBlock closure, int index) {
|
||||
|
||||
List<PsiType> expectedTypes;
|
||||
|
||||
if (closure.getParent() instanceof GrSafeCastExpression) {
|
||||
@@ -64,16 +66,28 @@ public class ClosureAsAnonymousParameterEnhancer extends AbstractClosureParamete
|
||||
}
|
||||
|
||||
for (PsiType constraint : expectedTypes) {
|
||||
final PsiType suggestion = GppClosureParameterTypeProvider.getSingleMethodParameterType(constraint, index, closure);
|
||||
if (suggestion != null) {
|
||||
if (GroovyConfigUtils.getInstance().isVersionAtLeast(closure, GroovyConfigUtils.GROOVY2_3)) {
|
||||
if (suggestion instanceof PsiWildcardType && ((PsiWildcardType)suggestion).isSuper()) {
|
||||
return ((PsiWildcardType)suggestion).getBound();
|
||||
}
|
||||
}
|
||||
if (!(constraint instanceof PsiClassType)) continue;
|
||||
|
||||
return TypesUtil.substituteAndNormalizeType(suggestion, PsiSubstitutor.EMPTY, null, closure);
|
||||
PsiClassType.ClassResolveResult result = ((PsiClassType)constraint).resolveGenerics();
|
||||
PsiClass resolved = result.getElement();
|
||||
if (resolved == null) continue;
|
||||
|
||||
MethodSignature sam = SamConversionKt.findSingleAbstractSignature(resolved);
|
||||
if (sam == null) continue;
|
||||
|
||||
PsiType[] parameterTypes = sam.getParameterTypes();
|
||||
if (index >= parameterTypes.length) continue;
|
||||
|
||||
final PsiType suggestion = result.getSubstitutor().substitute(parameterTypes[index]);
|
||||
if (suggestion == null) continue;
|
||||
|
||||
if (GroovyConfigUtils.getInstance().isVersionAtLeast(closure, GroovyConfigUtils.GROOVY2_3)) {
|
||||
if (suggestion instanceof PsiWildcardType && ((PsiWildcardType)suggestion).isSuper()) {
|
||||
return ((PsiWildcardType)suggestion).getBound();
|
||||
}
|
||||
}
|
||||
|
||||
return TypesUtil.substituteAndNormalizeType(suggestion, result.getSubstitutor(), null, closure);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
-126
@@ -1,126 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.codeInsight.generation.OverrideImplementExploreUtil;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.MethodSignature;
|
||||
import com.intellij.psi.util.MethodSignatureUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.config.GroovyConfigUtils;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
|
||||
import org.jetbrains.plugins.groovy.util.LightCacheKey;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public class ClosureToSamConverter extends GrTypeConverter {
|
||||
private static final LightCacheKey<Ref<MethodSignature>> SAM_SIGNATURE_LIGHT_CACHE_KEY = LightCacheKey.createByJavaModificationCount();
|
||||
|
||||
@Override
|
||||
public boolean isAllowedInMethodCall() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isConvertible(@NotNull PsiType ltype, @NotNull PsiType rtype, @NotNull final GroovyPsiElement context) {
|
||||
if (rtype instanceof GrClosureType &&
|
||||
ltype instanceof PsiClassType &&
|
||||
isSamConversionAllowed(context) &&
|
||||
!TypesUtil.isClassType(ltype, GroovyCommonClassNames.GROOVY_LANG_CLOSURE)) {
|
||||
MethodSignature signature = findSAMSignature(ltype);
|
||||
if (signature != null) {
|
||||
final PsiType[] samParameterTypes = signature.getParameterTypes();
|
||||
|
||||
GrSignature closureSignature = ((GrClosureType)rtype).getSignature();
|
||||
|
||||
boolean raw = ((PsiClassType)ltype).isRaw();
|
||||
if (raw) return true;
|
||||
|
||||
if (GrClosureSignatureUtil.isSignatureApplicable(closureSignature, samParameterTypes, context)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isSamConversionAllowed(PsiElement context) {
|
||||
return GroovyConfigUtils.getInstance().isVersionAtLeast(context, GroovyConfigUtils.GROOVY2_2);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static MethodSignature findSingleAbstractMethod(@NotNull PsiClass aClass, @NotNull PsiSubstitutor substitutor) {
|
||||
MethodSignature signature;
|
||||
Ref<MethodSignature> cached = SAM_SIGNATURE_LIGHT_CACHE_KEY.getCachedValue(aClass);
|
||||
if (cached != null) {
|
||||
signature = cached.get();
|
||||
}
|
||||
else {
|
||||
Ref<MethodSignature> newCached = Ref.create(doFindSingleAbstractMethodClass(aClass));
|
||||
signature = SAM_SIGNATURE_LIGHT_CACHE_KEY.putCachedValue(aClass, newCached).get();
|
||||
}
|
||||
|
||||
return signature != null ? substitute(signature, substitutor): null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static MethodSignature doFindSingleAbstractMethodClass(@NotNull PsiClass aClass) {
|
||||
Collection<MethodSignature> toImplement = OverrideImplementExploreUtil.getMethodSignaturesToImplement(aClass);
|
||||
if (toImplement.size() > 1) return null;
|
||||
|
||||
MethodSignature abstractSignature = toImplement.isEmpty() ? null : toImplement.iterator().next();
|
||||
for (PsiMethod method : aClass.getMethods()) {
|
||||
if (method.hasModifierProperty(PsiModifier.ABSTRACT)) {
|
||||
if (abstractSignature != null) return null;
|
||||
abstractSignature = method.getSignature(PsiSubstitutor.EMPTY);
|
||||
}
|
||||
}
|
||||
|
||||
return abstractSignature;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static MethodSignature substitute(@NotNull MethodSignature signature, @NotNull PsiSubstitutor substitutor) {
|
||||
return MethodSignatureUtil.createMethodSignature(signature.getName(), signature.getParameterTypes(), PsiTypeParameter.EMPTY_ARRAY, substitutor, false);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static MethodSignature findSAMSignature(@Nullable PsiType type) {
|
||||
if (type instanceof PsiClassType) {
|
||||
if (TypesUtil.isClassType(type, GroovyCommonClassNames.GROOVY_LANG_CLOSURE)) return null;
|
||||
|
||||
PsiClassType.ClassResolveResult result = ((PsiClassType)type).resolveGenerics();
|
||||
PsiClass aClass = result.getElement();
|
||||
|
||||
if (aClass != null) {
|
||||
return findSingleAbstractMethod(aClass, result.getSubstitutor());
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+31
-27
@@ -20,7 +20,10 @@ import com.intellij.openapi.util.NotNullLazyValue;
|
||||
import com.intellij.openapi.util.VolatileNotNullLazyValue;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.psi.PsiClassType.ClassResolveResult;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
|
||||
@@ -41,7 +44,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMe
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ClosureToSamConverter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GdkMethodUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
@@ -50,6 +52,8 @@ import java.util.Collection;
|
||||
|
||||
import static com.intellij.util.containers.ContainerUtil.emptyList;
|
||||
import static com.intellij.util.containers.ContainerUtil.newHashSet;
|
||||
import static org.jetbrains.plugins.groovy.lang.sam.SamConversionKt.findSingleAbstractMethod;
|
||||
import static org.jetbrains.plugins.groovy.lang.sam.SamConversionKt.isSamConversionAllowed;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
@@ -214,7 +218,7 @@ public class SubstitutorComputer {
|
||||
@Nullable
|
||||
private PsiType handleConversion(@Nullable PsiType paramType, @Nullable PsiType argType) {
|
||||
if (argType instanceof PsiClassType &&
|
||||
ClosureToSamConverter.isSamConversionAllowed(myPlace) &&
|
||||
isSamConversionAllowed(myPlace) &&
|
||||
InheritanceUtil.isInheritor(argType, GroovyCommonClassNames.GROOVY_LANG_CLOSURE) &&
|
||||
!TypesUtil.isClassType(paramType, GroovyCommonClassNames.GROOVY_LANG_CLOSURE)) {
|
||||
PsiType converted = handleConversionOfSAMType(paramType, (PsiClassType)argType);
|
||||
@@ -235,34 +239,34 @@ public class SubstitutorComputer {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiType handleConversionOfSAMType(@Nullable PsiType samType, @NotNull PsiClassType closure) {
|
||||
if (samType instanceof PsiClassType) {
|
||||
PsiClassType.ClassResolveResult resolveResult = ((PsiClassType)samType).resolveGenerics();
|
||||
PsiClass samClass = resolveResult.getElement();
|
||||
private PsiType handleConversionOfSAMType(@Nullable PsiType targetType, @NotNull PsiClassType closure) {
|
||||
if (!(targetType instanceof PsiClassType)) return null;
|
||||
|
||||
if (samClass != null && samClass.getTypeParameters().length != 0) {
|
||||
MethodSignature samSignature = ClosureToSamConverter.findSingleAbstractMethod(samClass, PsiSubstitutor.EMPTY);
|
||||
if (samSignature != null) {
|
||||
ClassResolveResult resolveResult = ((PsiClassType)targetType).resolveGenerics();
|
||||
|
||||
PsiMethod samMethod = MethodSignatureUtil.findMethodBySignature(samClass, samSignature, true);
|
||||
if (samMethod != null) {
|
||||
PsiType[] closureArgs = closure.getParameters();
|
||||
if (closureArgs.length == 1 && samMethod.getReturnType() != null) {
|
||||
PsiSubstitutor substitutor = myHelper.inferTypeArguments(samClass.getTypeParameters(),
|
||||
new PsiType[]{samMethod.getReturnType()},
|
||||
closureArgs,
|
||||
LanguageLevel.JDK_1_7);
|
||||
PsiClass samClass = resolveResult.getElement();
|
||||
if (samClass == null) return null;
|
||||
|
||||
if (!substitutor.getSubstitutionMap().isEmpty()) {
|
||||
return JavaPsiFacade.getElementFactory(myPlace.getProject()).createType(samClass, substitutor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
PsiTypeParameter[] samClassTypeParameters = samClass.getTypeParameters();
|
||||
if (samClassTypeParameters.length == 0) return null;
|
||||
|
||||
return null;
|
||||
PsiMethod sam = findSingleAbstractMethod(samClass);
|
||||
if (sam == null) return null;
|
||||
|
||||
// at this point we know that target type is actually a SAM type
|
||||
|
||||
PsiType samReturnType = sam.getReturnType();
|
||||
if (samReturnType == null) return null;
|
||||
|
||||
PsiType[] closureParameters = closure.getParameters();
|
||||
if (closureParameters.length != 1) return null;
|
||||
|
||||
PsiSubstitutor substitutor = myHelper.inferTypeArguments(
|
||||
samClassTypeParameters, new PsiType[]{samReturnType}, closureParameters, LanguageLevel.JDK_1_7
|
||||
);
|
||||
if (substitutor.getSubstitutionMap().isEmpty()) return null;
|
||||
|
||||
return JavaPsiFacade.getElementFactory(myPlace.getProject()).createType(samClass, substitutor);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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.sam
|
||||
|
||||
import com.intellij.psi.PsiClassType
|
||||
import com.intellij.psi.PsiType
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.ConversionResult
|
||||
import org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrTypeConverter
|
||||
import org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrTypeConverter.ApplicableTo.*
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames.GROOVY_LANG_CLOSURE
|
||||
|
||||
class ClosureToSamConverter : GrTypeConverter() {
|
||||
|
||||
private val myPositions = setOf(ASSIGNMENT, RETURN_VALUE, METHOD_PARAMETER)
|
||||
|
||||
override fun isApplicableTo(position: ApplicableTo) = position in myPositions
|
||||
|
||||
override fun isConvertibleEx(targetType: PsiType, actualType: PsiType, context: GroovyPsiElement,
|
||||
currentPosition: ApplicableTo): ConversionResult? {
|
||||
if (targetType !is PsiClassType || actualType !is GrClosureType) return null
|
||||
if (!isSamConversionAllowed(context)) return null
|
||||
|
||||
val result = targetType.resolveGenerics()
|
||||
val targetClass = result.element ?: return null
|
||||
|
||||
val targetFqn = targetClass.qualifiedName ?: return null // anonymous classes has no fqn
|
||||
if (targetFqn == GROOVY_LANG_CLOSURE) return null
|
||||
|
||||
findSingleAbstractSignature(targetClass) ?: return null
|
||||
return ConversionResult.OK
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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.sam
|
||||
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.CommonClassNames.JAVA_LANG_OBJECT
|
||||
import com.intellij.psi.util.CachedValueProvider
|
||||
import com.intellij.psi.util.CachedValuesManager
|
||||
import com.intellij.psi.util.MethodSignature
|
||||
import org.jetbrains.plugins.groovy.config.GroovyConfigUtils
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GrTraitUtil.isTrait
|
||||
|
||||
fun findSingleAbstractMethod(clazz: PsiClass): PsiMethod? = findSingleAbstractSignatureCached(clazz)?.method
|
||||
|
||||
fun findSingleAbstractSignature(clazz: PsiClass): MethodSignature? = findSingleAbstractSignatureCached(clazz)
|
||||
|
||||
private fun findSingleAbstractSignatureCached(clazz: PsiClass): HierarchicalMethodSignature? {
|
||||
return CachedValuesManager.getCachedValue(clazz) {
|
||||
CachedValueProvider.Result.create(doFindSingleAbstractSignature(clazz), clazz)
|
||||
}
|
||||
}
|
||||
|
||||
private fun doFindSingleAbstractSignature(clazz: PsiClass): HierarchicalMethodSignature? {
|
||||
var result: HierarchicalMethodSignature? = null
|
||||
for (signature in clazz.visibleSignatures) {
|
||||
if (!isEffectivelyAbstractMethod(signature)) continue
|
||||
if (result != null) return null // found another abstract method
|
||||
result = signature
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun isEffectivelyAbstractMethod(signature: HierarchicalMethodSignature): Boolean {
|
||||
val method = signature.method
|
||||
if (!method.hasModifierProperty(PsiModifier.ABSTRACT)) return false
|
||||
if (isObjectMethod(signature)) return false
|
||||
if (isImplementedTraitMethod(method)) return false
|
||||
return true
|
||||
}
|
||||
|
||||
private fun isObjectMethod(signature: HierarchicalMethodSignature): Boolean {
|
||||
return signature.superSignatures.any {
|
||||
it.method.containingClass?.qualifiedName == JAVA_LANG_OBJECT
|
||||
}
|
||||
}
|
||||
|
||||
private fun isImplementedTraitMethod(method: PsiMethod): Boolean {
|
||||
val clazz = method.containingClass ?: return false
|
||||
if (!isTrait(clazz)) return false
|
||||
val traitMethod = method as? GrMethod ?: return false
|
||||
return traitMethod.block != null
|
||||
}
|
||||
|
||||
fun isSamConversionAllowed(context: PsiElement): Boolean {
|
||||
return GroovyConfigUtils.getInstance().isVersionAtLeast(context, GroovyConfigUtils.GROOVY2_2)
|
||||
}
|
||||
@@ -235,7 +235,7 @@
|
||||
|
||||
<typeConverter implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrEnumConverter"/>
|
||||
<typeConverter implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrContainerTypeConverter"/>
|
||||
<typeConverter implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ClosureToSamConverter"/>
|
||||
<typeConverter implementation="org.jetbrains.plugins.groovy.lang.sam.ClosureToSamConverter"/>
|
||||
<typeConverter implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrContainerConverter"/>
|
||||
|
||||
<typeConverter implementation="org.jetbrains.plugins.groovy.gpp.GppTypeConverter"/>
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 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.
|
||||
@@ -39,7 +39,7 @@ interface B {}
|
||||
|
||||
A a = {print 1}
|
||||
A a1 = {->print 1}
|
||||
A <warning>a2</warning> = {String s->print 1}
|
||||
A a2 = {String s->print 1}
|
||||
B <warning>b</warning> = {print 2}
|
||||
''')
|
||||
}
|
||||
@@ -66,7 +66,7 @@ interface A<T> {
|
||||
|
||||
A<String> a1 = {print 1}
|
||||
A<String> a2 = {String s -> print 1}
|
||||
A<String> <warning>a3</warning> = {int s -> print 1}
|
||||
A<String> a3 = {int s -> print 1}
|
||||
A a4 = {int s -> print 1}
|
||||
A a7 = {int s, String y -> print 1}
|
||||
A a5 = { print 1}
|
||||
@@ -84,7 +84,7 @@ interface B extends A<String> {}
|
||||
|
||||
B b1 = {print 1}
|
||||
B b2 = {String s -> print 1}
|
||||
B <warning>b3</warning> = {int s -> print 1}
|
||||
B b3 = {int s -> print 1}
|
||||
''')
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 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.
|
||||
@@ -52,7 +52,7 @@ public <T, X> void exec(T t, Action<T, X> f, X x) {
|
||||
|
||||
def foo() {
|
||||
exec('foo', { String t, Integer x -> ; }, 1)
|
||||
exec<warning descr="'exec' in '_' cannot be applied to '(java.lang.String, groovy.lang.Closure<java.lang.Void>, java.lang.Integer)'">('foo', { Integer t, Integer x -> ; }, 1)</warning>
|
||||
exec('foo', { Integer t, Integer x -> ; }, 1)
|
||||
}
|
||||
''')
|
||||
}
|
||||
@@ -85,7 +85,7 @@ public <T, X> void exec(T t, Action<T, X> f, X x) {
|
||||
|
||||
def foo() {
|
||||
exec('foo', { String s, Integer x -> print s + x }, 1)
|
||||
exec<warning descr="'exec' in '_' cannot be applied to '(java.lang.String, groovy.lang.Closure, java.lang.Integer)'">('foo', { Integer s, Integer x -> print 9 }, 1)</warning>
|
||||
exec('foo', { Integer s, Integer x -> print 9 }, 1)
|
||||
}
|
||||
''')
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user