diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MethodReturnTypeFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MethodReturnTypeFix.java index 308ffa30cef1..a369dbe93176 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MethodReturnTypeFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MethodReturnTypeFix.java @@ -35,6 +35,7 @@ import com.intellij.psi.controlFlow.ControlFlow; import com.intellij.psi.controlFlow.ControlFlowUtil; import com.intellij.psi.search.LocalSearchScope; import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.util.PsiTypesUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor; @@ -47,10 +48,7 @@ import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; +import java.util.*; public class MethodReturnTypeFix extends LocalQuickFixAndIntentionActionOnPsiElement implements HighPriorityAction { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.MethodReturnBooleanFix"); @@ -345,10 +343,11 @@ public class MethodReturnTypeFix extends LocalQuickFixAndIntentionActionOnPsiEle TypeConversionUtil.getSuperClassSubstitutor(superClass, baseClass, PsiSubstitutor.EMPTY); final PsiType superReturnTypeInBaseClassType = superClassSubstitutor.substitute(superReturnType); final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(project).getResolveHelper(); - final PsiSubstitutor psiSubstitutor = resolveHelper.inferTypeArguments(baseClass.getTypeParameters(), - new PsiType[]{superReturnTypeInBaseClassType}, - new PsiType[]{returnType}, - PsiUtil.getLanguageLevel(superClass)); + final PsiSubstitutor psiSubstitutor = + resolveHelper.inferTypeArguments(PsiTypesUtil.filterUnusedTypeParameters(superReturnTypeInBaseClassType, baseClass.getTypeParameters()), + new PsiType[]{superReturnTypeInBaseClassType}, + new PsiType[]{returnType}, + PsiUtil.getLanguageLevel(superClass)); final TypeMigrationRules rules = new TypeMigrationRules(); final PsiSubstitutor compoundSubstitutor = diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiTypesUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiTypesUtil.java index d00dfbf658e4..4c81c52b19ac 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/PsiTypesUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/PsiTypesUtil.java @@ -22,12 +22,15 @@ import com.intellij.openapi.util.Condition; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.tree.IElementType; +import com.intellij.util.ArrayUtil; import gnu.trove.THashMap; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.HashSet; import java.util.Map; +import java.util.Set; public class PsiTypesUtil { @NonNls private static final Map ourUnboxedTypes = new THashMap(); @@ -309,4 +312,40 @@ public class PsiTypesUtil { } return parameterType; } + + public static PsiTypeParameter[] filterUnusedTypeParameters(final PsiType superReturnTypeInBaseClassType, + final PsiTypeParameter[] typeParameters) { + if (typeParameters.length == 0) return typeParameters; + + final Set usedParameters = new HashSet(); + superReturnTypeInBaseClassType.accept(new PsiTypeVisitor(){ + @Nullable + @Override + public Object visitClassType(PsiClassType classType) { + final PsiClass aClass = classType.resolve(); + if (aClass instanceof PsiTypeParameter && ArrayUtil.find(typeParameters, aClass) > -1) { + usedParameters.add((PsiTypeParameter)aClass); + return null; + } + for (PsiType type : classType.getParameters()) { + type.accept(this); + } + return null; + } + + @Nullable + @Override + public Object visitWildcardType(PsiWildcardType wildcardType) { + final PsiType bound = wildcardType.getBound(); + return bound != null ? bound.accept(this) : null; + } + + @Nullable + @Override + public Object visitArrayType(PsiArrayType arrayType) { + return arrayType.getComponentType().accept(this); + } + }); + return usedParameters.toArray(new PsiTypeParameter[usedParameters.size()]); + } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn8/afterMultipleParameters.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn8/afterMultipleParameters.java new file mode 100644 index 000000000000..8ff4d81c0bd5 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn8/afterMultipleParameters.java @@ -0,0 +1,16 @@ +// "Make 'foo' return 'java.util.List'" "true" +import java.util.List; +interface Main { + List foo(); +} + +class MainImpl implements Main { + @Override + public List foo() { + return bar(); + } + + private List bar() { + return null; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn8/beforeMultipleParameters.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn8/beforeMultipleParameters.java new file mode 100644 index 000000000000..0ac6ea8f3c1d --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn8/beforeMultipleParameters.java @@ -0,0 +1,16 @@ +// "Make 'foo' return 'java.util.List'" "true" +import java.util.List; +interface Main { + List foo(); +} + +class MainImpl implements Main { + @Override + public List foo() { + return bar(); + } + + private List bar() { + return null; + } +}