[java] override from kotlin method with type parameters is fixed

EA-266833 - T: GenerateMembersUtil.substituteTypeParameter

GitOrigin-RevId: 049f4f10689c8d15de598315b9ae0a793cc50f37
This commit is contained in:
Anna Kozlova
2022-01-13 11:59:43 +00:00
committed by intellij-monorepo-bot
parent a44edd4edc
commit 72e1f5f4c4
4 changed files with 57 additions and 3 deletions
@@ -1,4 +1,4 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.generation;
import com.intellij.application.options.CodeStyle;
@@ -382,7 +382,10 @@ public final class GenerateMembersUtil {
@NotNull PsiSubstitutor substitutor,
@NotNull PsiMethod sourceMethod) {
final PsiElement copy = ObjectUtils.notNull(typeParameter instanceof PsiCompiledElement ? ((PsiCompiledElement)typeParameter).getMirror() : typeParameter, typeParameter).copy();
LOG.assertTrue(copy != null, typeParameter);
if (copy == null) {
List<PsiClassType> substitutedSupers = ContainerUtil.map(typeParameter.getSuperTypes(), t -> ObjectUtils.notNull(toClassType(substitutor.substitute(t)), t));
return factory.createTypeParameter(Objects.requireNonNull(typeParameter.getName()), substitutedSupers.toArray(PsiClassType.EMPTY_ARRAY));
}
final Map<PsiElement, PsiElement> replacementMap = new HashMap<>();
copy.accept(new JavaRecursiveElementVisitor() {
@Override
@@ -398,6 +401,19 @@ public final class GenerateMembersUtil {
return (PsiTypeParameter)RefactoringUtil.replaceElementsWithMap(copy, replacementMap);
}
private static PsiClassType toClassType(PsiType type) {
if (type instanceof PsiClassType) {
return (PsiClassType)type;
}
if (type instanceof PsiCapturedWildcardType) {
return toClassType(((PsiCapturedWildcardType)type).getUpperBound());
}
if (type instanceof PsiWildcardType) {
return toClassType(((PsiWildcardType)type).getBound());
}
return null;
}
private static void substituteParameters(@NotNull JVMElementFactory factory,
@NotNull JavaCodeStyleManager codeStyleManager,
@NotNull PsiParameterList sourceParameterList,
@@ -1,9 +1,17 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.codeInsight
import com.intellij.codeInsight.generation.OverrideImplementExploreUtil
import com.intellij.codeInsight.generation.OverrideImplementUtil
import com.intellij.codeInsight.generation.PsiMethodMember
import com.intellij.psi.PsiJavaFile
import com.intellij.psi.PsiSubstitutor
import com.intellij.psi.util.TypeConversionUtil
import org.jetbrains.kotlin.idea.test.IDEA_TEST_DATA_DIR
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
import org.jetbrains.kotlin.psi.KtFile
import org.junit.internal.runners.JUnit38ClassRunner
import org.junit.runner.RunWith
import java.io.File
@@ -16,4 +24,24 @@ class Java8OverrideImplementTest : AbstractOverrideImplementTest() {
override fun getProjectDescriptor() = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE_FULL_JDK
fun testOverrideCollectionStream() = doOverrideFileTest("stream")
fun testImplementKotlinInterface() {
val file = myFixture.addFileToProject(
"A.kt", """interface A<T> {
fun <L : T> foo(l : L)
}"""
)
val superClass = (file as KtFile).classes[0]
val javaFile = myFixture.configureByFile(getTestName(true) + ".java")
val psiClass = (javaFile as PsiJavaFile).classes[0]
val method = superClass.methods[0]
val substitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, psiClass, PsiSubstitutor.EMPTY)
val candidates = listOf(PsiMethodMember(method, OverrideImplementExploreUtil.correctSubstitutor(method, substitutor)))
myFixture.project.executeWriteCommand("") {
OverrideImplementUtil.overrideOrImplementMethodsInRightPlace(myFixture.editor, psiClass, candidates, false, true)
}
myFixture.checkResultByFile(getTestName(true) + ".after.java")
}
}
@@ -0,0 +1,7 @@
class B extends A<String> {
@Override
public <L extends String> void foo(L l) {
}
}
@@ -0,0 +1,3 @@
class B extends A<String> {
}