Fix invalid signature for generic UL method

Fixed #KT-38348
This commit is contained in:
Igor Yakovlev
2020-04-17 15:48:46 +03:00
parent 6f40ad7de2
commit ed3ae785fb
13 changed files with 85 additions and 58 deletions
@@ -10,6 +10,7 @@ import com.intellij.psi.impl.PsiImplUtil
import com.intellij.psi.impl.PsiSuperMethodImplUtil import com.intellij.psi.impl.PsiSuperMethodImplUtil
import com.intellij.psi.impl.light.LightMethodBuilder import com.intellij.psi.impl.light.LightMethodBuilder
import com.intellij.psi.impl.light.LightTypeParameterListBuilder import com.intellij.psi.impl.light.LightTypeParameterListBuilder
import com.intellij.psi.util.MethodSignature
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod import com.intellij.psi.util.MethodSignatureBackedByPsiMethod
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
@@ -113,6 +114,9 @@ internal abstract class KtUltraLightMethod(
override fun findSuperMethods(parentClass: PsiClass?): Array<out PsiMethod> = override fun findSuperMethods(parentClass: PsiClass?): Array<out PsiMethod> =
PsiSuperMethodImplUtil.findSuperMethods(this, parentClass) PsiSuperMethodImplUtil.findSuperMethods(this, parentClass)
override fun getSignature(substitutor: PsiSubstitutor): MethodSignature =
MethodSignatureBackedByPsiMethod.create(this, substitutor)
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (this === other) return true if (this === other) return true
if (other !is KtUltraLightMethod) return false if (other !is KtUltraLightMethod) return false
@@ -6,10 +6,10 @@ public final class TestClass /* TestClass*/ {
private int hello; private int hello;
@null() @null()
public TestClass(int); public TestClass(int);// .ctor(int)
public final int getHello(); public final int getHello();// getHello()
public final void setHello(@Anno() int); public final void setHello(@Anno() int);// setHello(int)
} }
@@ -1,42 +1,42 @@
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
public abstract @interface SimpleAnn /* SimpleAnn*/ { public abstract @interface SimpleAnn /* SimpleAnn*/ {
@null() @null()
public abstract java.lang.String value(); public abstract java.lang.String value();// value()
} }
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
public abstract @interface Ann /* Ann*/ { public abstract @interface Ann /* Ann*/ {
@null() @null()
public abstract SimpleAnn[] t(); public abstract SimpleAnn[] t();// t()
@null() @null()
public abstract java.lang.Class<?> z(); public abstract java.lang.Class<?> z();// z()
@null() @null()
public abstract java.lang.Class<?>[] e(); public abstract java.lang.Class<?>[] e();// e()
@null() @null()
public abstract java.lang.String y(); public abstract java.lang.String y();// y()
@null() @null()
public abstract kotlin.DeprecationLevel depr(); public abstract kotlin.DeprecationLevel depr();// depr()
public abstract int x(); public abstract int x();// x()
} }
public abstract interface Base /* Base*/ { public abstract interface Base /* Base*/ {
@Ann(x = 1, y = "134", z = String::class, e = {Int::class, Double::class}, depr = DeprecationLevel.WARNING, t = {@SimpleAnn(value = "243"), @SimpleAnn(value = "4324")}) @Ann(x = 1, y = "134", z = String::class, e = {Int::class, Double::class}, depr = DeprecationLevel.WARNING, t = {@SimpleAnn(value = "243"), @SimpleAnn(value = "4324")})
public abstract void foo(@Ann(x = 2, y = "324", z = Ann::class, e = {Byte::class, Base::class}, depr = DeprecationLevel.WARNING, t = {@SimpleAnn(value = "687"), @SimpleAnn(value = "78")}) @org.jetbrains.annotations.NotNull() java.lang.String); public abstract void foo(@Ann(x = 2, y = "324", z = Ann::class, e = {Byte::class, Base::class}, depr = DeprecationLevel.WARNING, t = {@SimpleAnn(value = "687"), @SimpleAnn(value = "78")}) @org.jetbrains.annotations.NotNull() java.lang.String);// foo(java.lang.String)
} }
public final class Derived /* Derived*/ implements Base { public final class Derived /* Derived*/ implements Base {
@Ann(x = 1, y = "134", z = java.lang.String.class, e = {int.class, double.class}, depr = kotlin.DeprecationLevel.WARNING, t = {@SimpleAnn(value="243"), @SimpleAnn(value="4324")}) @Ann(x = 1, y = "134", z = java.lang.String.class, e = {int.class, double.class}, depr = kotlin.DeprecationLevel.WARNING, t = {@SimpleAnn(value="243"), @SimpleAnn(value="4324")})
public void foo(@Ann(x = 2, y = "324", z = Ann.class, e = {byte.class, Base.class}, depr = kotlin.DeprecationLevel.WARNING, t = {@SimpleAnn(value="687"), @SimpleAnn(value="78")}) @org.jetbrains.annotations.NotNull() java.lang.String); public void foo(@Ann(x = 2, y = "324", z = Ann.class, e = {byte.class, Base.class}, depr = kotlin.DeprecationLevel.WARNING, t = {@SimpleAnn(value="687"), @SimpleAnn(value="78")}) @org.jetbrains.annotations.NotNull() java.lang.String);// foo(java.lang.String)
@null() @null()
public Derived(@org.jetbrains.annotations.NotNull() Base); public Derived(@org.jetbrains.annotations.NotNull() Base);// .ctor(Base)
} }
@@ -1,14 +1,14 @@
public final class Foo /* c.b.a.Foo*/ { public final class Foo /* c.b.a.Foo*/ {
@null() @null()
public Foo(); public Foo();// .ctor()
public final void bar(); public final void bar();// bar()
} }
public static final class A$B /* null*/ { public static final class A$B /* null*/ {
@null() @null()
public A$B(); public A$B();// .ctor()
class $$$$$$$ ... class $$$$$$$ ...
@@ -18,13 +18,13 @@ public static final class A$B /* null*/ {
public final class C$D /* null*/ { public final class C$D /* null*/ {
@null() @null()
public C$D(); public C$D();// .ctor()
} }
public final class $$$$$$$ /* null*/ { public final class $$$$$$$ /* null*/ {
@null() @null()
public $$$$$$$(); public $$$$$$$();// .ctor()
class G$G$ ... class G$G$ ...
@@ -32,6 +32,6 @@ public final class $$$$$$$ /* null*/ {
public final class G$G$ /* null*/ { public final class G$G$ /* null*/ {
@null() @null()
public G$G$(); public G$G$();// .ctor()
} }
@@ -2,12 +2,12 @@ public final class Prop /* Prop*/ {
private final java.lang.Object someProp; private final java.lang.Object someProp;
@null() @null()
public Prop(); public Prop();// .ctor()
} }
final class null /* null*/ { final class null /* null*/ {
private (); private ();// .ctor()
} }
@@ -17,20 +17,20 @@ final class C /* C*/ {
private final kotlin.jvm.functions.Function0<java.lang.Object> initChild; private final kotlin.jvm.functions.Function0<java.lang.Object> initChild;
@null() @null()
public C(int); public C(int);// .ctor(int)
@org.jetbrains.annotations.NotNull() @org.jetbrains.annotations.NotNull()
public final kotlin.jvm.functions.Function0<java.lang.Object> getInitChild(); public final kotlin.jvm.functions.Function0<java.lang.Object> getInitChild();// getInitChild()
public final int getY(); public final int getY();// getY()
} }
final class null /* null*/ { final class null /* null*/ {
@org.jetbrains.annotations.NotNull() @org.jetbrains.annotations.NotNull()
public java.lang.String toString(); public java.lang.String toString();// toString()
private (); private ();// .ctor()
} }
@@ -38,27 +38,27 @@ public final class ValidPublicSupertype /* ValidPublicSupertype*/ {
private final java.lang.Runnable x; private final java.lang.Runnable x;
@null() @null()
public ValidPublicSupertype(); public ValidPublicSupertype();// .ctor()
@org.jetbrains.annotations.NotNull() @org.jetbrains.annotations.NotNull()
public final java.lang.Runnable bar(); public final java.lang.Runnable bar();// bar()
@org.jetbrains.annotations.NotNull() @org.jetbrains.annotations.NotNull()
public final java.lang.Runnable getX(); public final java.lang.Runnable getX();// getX()
} }
final class null /* null*/ implements java.lang.Runnable { final class null /* null*/ implements java.lang.Runnable {
private (); private ();// .ctor()
public void run(); public void run();// run()
} }
final class null /* null*/ implements java.lang.Runnable { final class null /* null*/ implements java.lang.Runnable {
private (); private ();// .ctor()
public void run(); public void run();// run()
} }
@@ -69,26 +69,26 @@ public final class InvalidPublicSupertype /* InvalidPublicSupertype*/ {
private final java.lang.Runnable x; private final java.lang.Runnable x;
@null() @null()
public InvalidPublicSupertype(); public InvalidPublicSupertype();// .ctor()
@org.jetbrains.annotations.NotNull() @org.jetbrains.annotations.NotNull()
public final java.lang.Runnable bar(); public final java.lang.Runnable bar();// bar()
@org.jetbrains.annotations.NotNull() @org.jetbrains.annotations.NotNull()
public final java.lang.Runnable getX(); public final java.lang.Runnable getX();// getX()
} }
final class null /* null*/ implements I, java.lang.Runnable { final class null /* null*/ implements I, java.lang.Runnable {
private (); private ();// .ctor()
public void run(); public void run();// run()
} }
final class null /* null*/ implements I, java.lang.Runnable { final class null /* null*/ implements I, java.lang.Runnable {
private (); private ();// .ctor()
public void run(); public void run();// run()
} }
@@ -4,21 +4,21 @@ public final class UInt /* UInt*/ {
public enum Foo /* Foo*/ { public enum Foo /* Foo*/ {
; ;
public final int getX(); public final int getX();// getX()
} }
public final class InlinedDelegate /* InlinedDelegate*/<T> { public final class InlinedDelegate /* InlinedDelegate*/<T> {
@null() @null()
public final T getNode(); public final T getNode();// getNode()
} }
public final class InlineInheritance /* InlineInheritance*/ { public final class InlineInheritance /* InlineInheritance*/ {
public final int getV(); public final int getV();// getV()
public int getX(); public int getX();// getX()
public int y(); public int y();// y()
} }
@@ -1,9 +1,9 @@
public final class X /* X*/ { public final class X /* X*/ {
@null() @null()
public X(); public X();// .ctor()
public final int getW(); public final int getW();// getW()
public final void setV(int); public final void setV(int);// setV(int)
} }
@@ -1,19 +1,19 @@
public final class Boo /* Boo*/ { public final class Boo /* Boo*/ {
@null() @null()
public Boo(); public Boo();// .ctor()
public final void fooBar(); public final void fooBar();// fooBar()
} }
public static final class LocalClassBase /* null*/ { public static final class LocalClassBase /* null*/ {
@null() @null()
public LocalClassBase(); public LocalClassBase();// .ctor()
} }
public static final class LocalClassDerived /* null*/ extends LocalClassBase { public static final class LocalClassDerived /* null*/ extends LocalClassBase {
@null() @null()
public LocalClassDerived(); public LocalClassDerived();// .ctor()
} }
@@ -0,0 +1,5 @@
// PSI_ELEMENT: com.intellij.psi.PsiMethod
// OPTIONS: overrides
public interface Foo {
<T> void <caret>baz(T foo);
}
@@ -0,0 +1,3 @@
class FooImpl : Foo {
override fun <T : Any?> baz(foo: T) = Unit
}
@@ -0,0 +1 @@
Unclassified usage 2 override fun <T : Any?> baz(foo: T) = Unit
@@ -1759,6 +1759,11 @@ public class FindUsagesTestGenerated extends AbstractFindUsagesTest {
runTest("idea/testData/findUsages/java/findJavaMethodUsages/OverriddenMethodSyntheticAccessor.0.java"); runTest("idea/testData/findUsages/java/findJavaMethodUsages/OverriddenMethodSyntheticAccessor.0.java");
} }
@TestMetadata("OverridenRawGenericSignatureBase.0.java")
public void testOverridenRawGenericSignatureBase() throws Exception {
runTest("idea/testData/findUsages/java/findJavaMethodUsages/OverridenRawGenericSignatureBase.0.java");
}
@TestMetadata("SyntheticProperties.0.java") @TestMetadata("SyntheticProperties.0.java")
public void testSyntheticProperties() throws Exception { public void testSyntheticProperties() throws Exception {
runTest("idea/testData/findUsages/java/findJavaMethodUsages/SyntheticProperties.0.java"); runTest("idea/testData/findUsages/java/findJavaMethodUsages/SyntheticProperties.0.java");
@@ -12,6 +12,7 @@ import com.intellij.openapi.util.Conditions
import com.intellij.openapi.util.Disposer import com.intellij.openapi.util.Disposer
import com.intellij.psi.* import com.intellij.psi.*
import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.util.MethodSignature
import com.intellij.testFramework.UsefulTestCase import com.intellij.testFramework.UsefulTestCase
import com.intellij.util.PairProcessor import com.intellij.util.PairProcessor
import com.intellij.util.ref.DebugReflectionUtil import com.intellij.util.ref.DebugReflectionUtil
@@ -185,9 +186,9 @@ object UltraLightChecker {
return result return result
} }
private fun PsiTypeParameterListOwner.renderTypeParams() = private fun Array<PsiTypeParameter>.renderTypeParams() =
if (typeParameters.isEmpty()) "" if (isEmpty()) ""
else "<" + typeParameters.joinToString { else "<" + joinToString {
val bounds = val bounds =
if (it.extendsListTypes.isNotEmpty()) if (it.extendsListTypes.isNotEmpty())
" extends " + it.extendsListTypes.joinToString(" & ", transform = { it.renderType() }) " extends " + it.extendsListTypes.joinToString(" & ", transform = { it.renderType() })
@@ -204,7 +205,7 @@ object UltraLightChecker {
private fun PsiMethod.renderMethod() = private fun PsiMethod.renderMethod() =
renderModifiers(returnType) + renderModifiers(returnType) +
(if (isVarArgs) "/* vararg */ " else "") + (if (isVarArgs) "/* vararg */ " else "") +
renderTypeParams() + typeParameters.renderTypeParams() +
(returnType?.renderType() ?: "") + " " + (returnType?.renderType() ?: "") + " " +
name + name +
"(" + parameterList.parameters.joinToString { it.renderModifiers(it.type) + it.type.renderType() } + ")" + "(" + parameterList.parameters.joinToString { it.renderModifiers(it.type) + it.type.renderType() } + ")" +
@@ -213,7 +214,15 @@ object UltraLightChecker {
if (thrownTypes.isEmpty()) "" if (thrownTypes.isEmpty()) ""
else " throws " + thrownTypes.joinToString { it.renderType() } else " throws " + thrownTypes.joinToString { it.renderType() }
} + } +
";" ";" +
"// ${getSignature(PsiSubstitutor.EMPTY).renderSignature()}"
private fun MethodSignature.renderSignature(): String {
val typeParams = typeParameters.renderTypeParams()
val paramTypes = parameterTypes.joinToString(prefix = "(", postfix = ")") { it.renderType() }
val name = if (isConstructor) ".ctor" else name
return "$typeParams $name$paramTypes"
}
private fun PsiEnumConstant.renderEnumConstant(): String { private fun PsiEnumConstant.renderEnumConstant(): String {
val initializingClass = initializingClass ?: return name val initializingClass = initializingClass ?: return name
@@ -237,7 +246,7 @@ object UltraLightChecker {
append(renderModifiers()) append(renderModifiers())
append("$classWord ") append("$classWord ")
append("$name /* $qualifiedName*/") append("$name /* $qualifiedName*/")
append(renderTypeParams()) append(typeParameters.renderTypeParams())
append(extendsList.renderRefList("extends")) append(extendsList.renderRefList("extends"))
append(implementsList.renderRefList("implements")) append(implementsList.renderRefList("implements"))
appendln(" {") appendln(" {")