diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index fedc5d5f5f2..7187ff1f467 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -485,7 +485,7 @@ public class FunctionCodegen extends ParentCodegenAware { } @NotNull - private static String[] getThrownExceptions(@NotNull FunctionDescriptor function, @NotNull final JetTypeMapper mapper) { + public static String[] getThrownExceptions(@NotNull FunctionDescriptor function, @NotNull final JetTypeMapper mapper) { AnnotationDescriptor annotation = function.getAnnotations().findAnnotation(new FqName("kotlin.throws")); if (annotation == null) return ArrayUtil.EMPTY_STRING_ARRAY; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PlatformStaticGenerator.kt b/compiler/backend/src/org/jetbrains/jet/codegen/PlatformStaticGenerator.kt index 8fc8bb813f8..e596cada53a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PlatformStaticGenerator.kt +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PlatformStaticGenerator.kt @@ -39,7 +39,8 @@ class PlatformStaticGenerator( Opcodes.ACC_STATIC or AsmUtil.getMethodAsmFlags(descriptor, OwnerKind.IMPLEMENTATION), asmMethod.getName()!!, asmMethod.getDescriptor()!!, - null, null) + typeMapper.mapSignature(descriptor).getGenericsSignature(), + FunctionCodegen.getThrownExceptions(descriptor, typeMapper)) AnnotationCodegen.forMethod(methodVisitor, typeMapper)!!.genAnnotations(descriptor, asmMethod.getReturnType()) diff --git a/compiler/testData/asJava/lightClassStructure/PlatformStaticMethodsGenerics.kt b/compiler/testData/asJava/lightClassStructure/PlatformStaticMethodsGenerics.kt new file mode 100644 index 00000000000..30901b547f4 --- /dev/null +++ b/compiler/testData/asJava/lightClassStructure/PlatformStaticMethodsGenerics.kt @@ -0,0 +1,13 @@ +package test + +import kotlin.platform.platformStatic + +class PlatformStaticClass { + class object { + platformStatic + fun inClassObject() {} + } + + fun inClass() {} +} + diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/genericSignature/kt6106.kt b/compiler/testData/codegen/boxWithStdlib/reflection/genericSignature/kt6106.kt new file mode 100644 index 00000000000..6bb8ce7dcc5 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reflection/genericSignature/kt6106.kt @@ -0,0 +1,28 @@ +package test + +import kotlin.platform.platformStatic + +open class B + +class A { + + class object { + [platformStatic] + fun a(s: T) : T { + return s + } + } +} + +fun box(): String { + val method = javaClass().getDeclaredMethod("a", javaClass()) + val genericParameterTypes = method.getGenericParameterTypes() + + if (genericParameterTypes.size != 1) return "Wrong number of generic parameters" + + if (genericParameterTypes[0].toString() != "T") return "Wrong parameter type ${genericParameterTypes[0].toString()}" + + if (method.getGenericReturnType().toString() != "T") return "Wrong return type ${method.getGenericReturnType()}" + + return "OK" +} diff --git a/compiler/tests/org/jetbrains/jet/asJava/KotlinLightClassStructureTest.java b/compiler/tests/org/jetbrains/jet/asJava/KotlinLightClassStructureTest.java index 3e3cac00223..798a0a30bd0 100644 --- a/compiler/tests/org/jetbrains/jet/asJava/KotlinLightClassStructureTest.java +++ b/compiler/tests/org/jetbrains/jet/asJava/KotlinLightClassStructureTest.java @@ -23,6 +23,8 @@ import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.codegen.forTestCompile.ForTestCompileRuntime; +import org.jetbrains.jet.config.CompilerConfiguration; import java.io.File; import java.util.Arrays; @@ -31,6 +33,7 @@ import java.util.List; import java.util.Set; import static org.jetbrains.jet.asJava.KotlinLightClassStructureTest.ClassProperty.*; +import static org.jetbrains.jet.cli.jvm.JVMConfigurationKeys.CLASSPATH_KEY; @SuppressWarnings("JUnitTestClassNamingConvention") public abstract class KotlinLightClassStructureTest extends KotlinAsJavaTestBase { @@ -105,21 +108,47 @@ public abstract class KotlinLightClassStructureTest extends KotlinAsJavaTestBase } public void testGeneric1() throws Exception { - checkGenericParameter("test.Generic1", 0, "T"); + checkClassGenericParameter("test.Generic1", 0, "T"); } public void testGeneric1WithBounds() throws Exception { - checkGenericParameter("test.Generic1WithBounds", 0, "T", "test.Bound1"); + checkClassGenericParameter("test.Generic1WithBounds", 0, "T", "test.Bound1"); } public void testGeneric2() throws Exception { - checkGenericParameter("test.Generic2", 0, "A"); - checkGenericParameter("test.Generic2", 1, "B"); + checkClassGenericParameter("test.Generic2", 0, "A"); + checkClassGenericParameter("test.Generic2", 1, "B"); } public void testGeneric2WithBounds() throws Exception { - checkGenericParameter("test.Generic2WithBounds", 0, "A", "test.Bound1", "test.Bound2"); - checkGenericParameter("test.Generic2WithBounds", 1, "B", "test.Generic1"); + checkClassGenericParameter("test.Generic2WithBounds", 0, "A", "test.Bound1", "test.Bound2"); + checkClassGenericParameter("test.Generic2WithBounds", 1, "B", "test.Generic1"); + } + } + + public static class PlatformStaticMethodsWithGenerics extends KotlinLightClassStructureTest { + @Override + protected List getKotlinSourceRoots() { + return Collections.singletonList( + new File("compiler/testData/asJava/lightClassStructure/PlatformStaticMethodsGenerics.kt") + ); + } + + public void testInClassObjectSynthetic() throws Exception { + checkMethodGenericParameter("test.PlatformStaticClass", "inClassObject", 0, "T"); + } + + public void testInClassObjectActual() throws Exception { + checkMethodGenericParameter("test.PlatformStaticClass.object", "inClassObject", 0, "T"); + } + + public void testInClass() throws Exception { + checkMethodGenericParameter("test.PlatformStaticClass", "inClass", 0, "T"); + } + + @Override + protected void extraConfiguration(@NotNull CompilerConfiguration configuration) { + configuration.add(CLASSPATH_KEY, ForTestCompileRuntime.runtimeJarForTests()); } } @@ -183,8 +212,27 @@ public abstract class KotlinLightClassStructureTest extends KotlinAsJavaTestBase checkModifiers(findClass(classFqName), properties); } - protected static void checkGenericParameter(PsiClass psiClass, int index, String name, String... bounds) { - PsiTypeParameter typeParameter = psiClass.getTypeParameters()[index]; + protected void checkClassGenericParameter(String classFqName, int index, String name, String... bounds) { + checkGenericParameter(findClass(classFqName).getTypeParameters()[index], index, name, bounds); + } + + protected void checkMethodGenericParameter(String classFqName, String methodName, int index, String name, String... bounds) { + PsiClass aClass = findClass(classFqName); + + PsiMethod method = null; + for (PsiMethod psiMethod : aClass.getMethods()) { + if (methodName.equals(psiMethod.getName())) { + assertNull(String.format("Several methods with name '%s' found in class '%s'", methodName, classFqName), method); + method = psiMethod; + } + } + + assertNotNull(String.format("Methods name '%s' wasn't found in class '%s'", methodName, classFqName), method); + + checkGenericParameter(method.getTypeParameters()[index], index, name, bounds); + } + + protected static void checkGenericParameter(PsiTypeParameter typeParameter, int index, String name, String[] bounds) { assertEquals(name, typeParameter.getName()); assertEquals(index, typeParameter.getIndex()); Set expectedBounds = Sets.newHashSet(bounds); @@ -201,10 +249,6 @@ public abstract class KotlinLightClassStructureTest extends KotlinAsJavaTestBase assertEquals(expectedBounds, actualBounds); } - protected void checkGenericParameter(String classFqName, int index, String name, String... bounds) { - checkGenericParameter(findClass(classFqName), index, name, bounds); - } - enum ClassProperty { PUBLIC(PsiModifier.PUBLIC), PROTECTED(PsiModifier.PROTECTED), diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index fc34509c4d6..fcbef27cde4 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -2079,6 +2079,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/genericSignature/kt5112.kt"); doTestWithStdlib(fileName); } + + @TestMetadata("kt6106.kt") + public void testKt6106() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/genericSignature/kt6106.kt"); + doTestWithStdlib(fileName); + } } @TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection/mapping")