diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java index 27a7d79b21f7..25eec5f4999a 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java @@ -28,7 +28,6 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.codeStyle.*; import com.intellij.psi.impl.light.LightTypeElement; -import com.intellij.psi.impl.source.tree.LeafElement; import com.intellij.psi.impl.source.tree.PsiWhiteSpaceImpl; import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.util.PsiTreeUtil; @@ -263,10 +262,10 @@ public class GenerateMembersUtil { copyDocComment(sourceMethod, resultMethod); copyModifiers(sourceMethod.getModifierList(), resultMethod.getModifierList()); final PsiSubstitutor collisionResolvedSubstitutor = - substituteTypeParameters(factory, target, sourceMethod.getTypeParameterList(), resultMethod.getTypeParameterList(), substitutor); + substituteTypeParameters(factory, target, sourceMethod.getTypeParameterList(), resultMethod.getTypeParameterList(), substitutor, sourceMethod); substituteReturnType(PsiManager.getInstance(project), resultMethod, sourceMethod.getReturnType(), collisionResolvedSubstitutor); substituteParameters(factory, codeStyleManager, sourceMethod.getParameterList(), resultMethod.getParameterList(), collisionResolvedSubstitutor, target); - substituteThrows(factory, sourceMethod.getThrowsList(), resultMethod.getThrowsList(), collisionResolvedSubstitutor); + substituteThrows(factory, sourceMethod.getThrowsList(), resultMethod.getThrowsList(), collisionResolvedSubstitutor, sourceMethod); return resultMethod; } catch (IncorrectOperationException e) { @@ -285,14 +284,15 @@ public class GenerateMembersUtil { @Nullable PsiElement target, @Nullable PsiTypeParameterList sourceTypeParameterList, @Nullable PsiTypeParameterList targetTypeParameterList, - @NotNull PsiSubstitutor substitutor) { + @NotNull PsiSubstitutor substitutor, + @NotNull PsiMethod sourceMethod) { if (sourceTypeParameterList == null || targetTypeParameterList == null) { return substitutor; } final Map substitutionMap = new HashMap(substitutor.getSubstitutionMap()); for (PsiTypeParameter typeParam : sourceTypeParameterList.getTypeParameters()) { - final PsiTypeParameter substitutedTypeParam = substituteTypeParameter(factory, typeParam, substitutor); + final PsiTypeParameter substitutedTypeParam = substituteTypeParameter(factory, typeParam, substitutor, sourceMethod); final PsiTypeParameter resolvedTypeParam = resolveTypeParametersCollision(factory, sourceTypeParameterList, target, substitutedTypeParam, substitutor); targetTypeParameterList.add(resolvedTypeParam); @@ -347,7 +347,8 @@ public class GenerateMembersUtil { @NotNull private static PsiTypeParameter substituteTypeParameter(final @NotNull JVMElementFactory factory, @NotNull PsiTypeParameter typeParameter, - final @NotNull PsiSubstitutor substitutor) { + final @NotNull PsiSubstitutor substitutor, + @NotNull final PsiMethod sourceMethod) { final PsiElement copy = typeParameter.copy(); final Map replacementMap = new HashMap(); copy.accept(new JavaRecursiveElementVisitor() { @@ -357,7 +358,7 @@ public class GenerateMembersUtil { final PsiElement resolve = reference.resolve(); if (resolve instanceof PsiTypeParameter) { final PsiType type = factory.createType((PsiTypeParameter)resolve); - replacementMap.put(reference, factory.createReferenceElementByType((PsiClassType)substituteType(substitutor, type))); + replacementMap.put(reference, factory.createReferenceElementByType((PsiClassType)substituteType(substitutor, type, sourceMethod))); } } }); @@ -374,7 +375,7 @@ public class GenerateMembersUtil { for (int i = 0; i < parameters.length; i++) { PsiParameter parameter = parameters[i]; final PsiType parameterType = parameter.getType(); - final PsiType substituted = substituteType(substitutor, parameterType); + final PsiType substituted = substituteType(substitutor, parameterType, (PsiMethod)parameter.getDeclarationScope()); @NonNls String paramName = parameter.getName(); boolean isBaseNameGenerated = true; final boolean isSubstituted = substituted.equals(parameterType); @@ -400,9 +401,10 @@ public class GenerateMembersUtil { private static void substituteThrows(@NotNull JVMElementFactory factory, @NotNull PsiReferenceList sourceThrowsList, @NotNull PsiReferenceList targetThrowsList, - @NotNull PsiSubstitutor substitutor) { + @NotNull PsiSubstitutor substitutor, + @NotNull PsiMethod sourceMethod) { for (PsiClassType thrownType : sourceThrowsList.getReferencedTypes()) { - targetThrowsList.add(factory.createReferenceElementByType((PsiClassType)substituteType(substitutor, thrownType))); + targetThrowsList.add(factory.createReferenceElementByType((PsiClassType)substituteType(substitutor, thrownType, sourceMethod))); } } @@ -433,7 +435,7 @@ public class GenerateMembersUtil { if (returnTypeElement == null || returnType == null) { return; } - final PsiType substitutedReturnType = substituteType(substitutor, returnType); + final PsiType substitutedReturnType = substituteType(substitutor, returnType, method); returnTypeElement.replace(new LightTypeElement(manager, substitutedReturnType instanceof PsiWildcardType ? TypeConversionUtil.erasure(substitutedReturnType) : substitutedReturnType)); } @@ -451,7 +453,10 @@ public class GenerateMembersUtil { return Arrays.asList(csManager.suggestVariableName(VariableKind.PARAMETER, null, null, parameterType).names).contains(paramName); } - private static PsiType substituteType(final PsiSubstitutor substitutor, final PsiType type) { + private static PsiType substituteType(final PsiSubstitutor substitutor, final PsiType type, @NotNull PsiTypeParameterListOwner owner) { + if (PsiUtil.isRawSubstitutor(owner, substitutor)) { + return TypeConversionUtil.erasure(type); + } final PsiType psiType = substitutor.substitute(type); if (psiType != null) { final PsiType deepComponentType = psiType.getDeepComponentType(); diff --git a/java/java-tests/testData/codeInsight/overrideImplement/afterRawInheritance.java b/java/java-tests/testData/codeInsight/overrideImplement/afterRawInheritance.java new file mode 100644 index 000000000000..75297f76f92b --- /dev/null +++ b/java/java-tests/testData/codeInsight/overrideImplement/afterRawInheritance.java @@ -0,0 +1,11 @@ +class Obj {} +abstract class A1{ + abstract void foo(Obj x); +} + +class B1 extends A1{ + @Override + void foo(Obj x) { + + } +} diff --git a/java/java-tests/testData/codeInsight/overrideImplement/beforeRawInheritance.java b/java/java-tests/testData/codeInsight/overrideImplement/beforeRawInheritance.java new file mode 100644 index 000000000000..f546cae063b9 --- /dev/null +++ b/java/java-tests/testData/codeInsight/overrideImplement/beforeRawInheritance.java @@ -0,0 +1,8 @@ +class Obj {} +abstract class A1{ + abstract void foo(Obj x); +} + +class B1 extends A1{ + +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/OverrideImplementTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/OverrideImplementTest.java index 3ed1526c4433..95de8239e763 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/OverrideImplementTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/OverrideImplementTest.java @@ -65,6 +65,7 @@ public class OverrideImplementTest extends LightCodeInsightTestCase { public void testErasureWildcard() { doTest(false); } public void testMultipleInterfaceInheritance() { doTest(false); } public void testResolveTypeParamConflict() { doTest(false); } + public void testRawInheritance() { doTest(false); } public void testImplementExtensionMethods() { doTest8(false, true); } public void testOverrideExtensionMethods() { doTest8(false, false); }