diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java index 5fd1d0c797b..2939528158d 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java @@ -214,8 +214,16 @@ public final class JavaFunctionResolver { FunctionDescriptor functionDescriptor ) { for (FunctionDescriptor superFunction : superFunctions) { - TypeSubstitutor substitutor = SubstitutionUtils.buildDeepSubstitutor( - ((ClassDescriptor) functionDescriptor.getContainingDeclaration()).getDefaultType()); + ClassDescriptor klass = (ClassDescriptor) functionDescriptor.getContainingDeclaration(); + List substitutions = Lists.newArrayList(); + while (true) { + substitutions.add(SubstitutionUtils.buildDeepSubstitutor(klass.getDefaultType()).getSubstitution()); + if (!klass.isInner()) { + break; + } + klass = (ClassDescriptor) klass.getContainingDeclaration(); + } + TypeSubstitutor substitutor = TypeSubstitutor.create(substitutions.toArray(new TypeSubstitution[substitutions.size()])); FunctionDescriptor superFunctionSubstituted = superFunction.substitute(substitutor); assert superFunctionSubstituted != null : diff --git a/compiler/testData/loadJavaCustom/returnInnerSubclassOfSupersInner/ReturnInnerSubclassOfSupersInner.txt b/compiler/testData/loadJavaCustom/returnInnerSubclassOfSupersInner/ReturnInnerSubclassOfSupersInner.txt new file mode 100644 index 00000000000..83e44cd68e8 --- /dev/null +++ b/compiler/testData/loadJavaCustom/returnInnerSubclassOfSupersInner/ReturnInnerSubclassOfSupersInner.txt @@ -0,0 +1,22 @@ +package test + +public trait ReturnInnerSubclassOfSupersInner : java.lang.Object { + + public open class Sub : test.ReturnInnerSubclassOfSupersInner.Super { + public constructor Sub() + + public/*package*/ open inner class Inner : test.ReturnInnerSubclassOfSupersInner.Super.Inner { + public/*package*/ constructor Inner() + public/*package*/ open override /*1*/ fun get() : test.ReturnInnerSubclassOfSupersInner.Sub? + } + } + + public open class Super : java.lang.Object { + public constructor Super() + + public/*package*/ open inner class Inner : java.lang.Object { + public/*package*/ constructor Inner() + public/*package*/ open fun get() : test.ReturnInnerSubclassOfSupersInner.Super? + } + } +} diff --git a/compiler/testData/loadJavaCustom/returnInnerSubclassOfSupersInner/test/ReturnInnerSubclassOfSupersInner.java b/compiler/testData/loadJavaCustom/returnInnerSubclassOfSupersInner/test/ReturnInnerSubclassOfSupersInner.java new file mode 100644 index 00000000000..d5104edfb6f --- /dev/null +++ b/compiler/testData/loadJavaCustom/returnInnerSubclassOfSupersInner/test/ReturnInnerSubclassOfSupersInner.java @@ -0,0 +1,20 @@ +package test; + +//Note: this test could be written in simple load java test, but KT-3128 prevents from writing Kotlin counterpart for it +public interface ReturnInnerSubclassOfSupersInner { + class Super { + class Inner { + Super get() { + throw new UnsupportedOperationException(); + } + } + } + + class Sub extends Super { + class Inner extends Super.Inner { + Sub get() { + throw new UnsupportedOperationException(); + } + } + } +} diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaCustomTest.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaCustomTest.java index 00f5195fd34..8dc0d6f7901 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaCustomTest.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaCustomTest.java @@ -182,6 +182,18 @@ public final class LoadJavaCustomTest extends KotlinTestWithEnvironment { dir + "MethodTypeParameterErased.java"); } + public void testReturnInnerSubclassOfSupersInner() throws Exception { + String dir = PATH + "/returnInnerSubclassOfSupersInner/"; + doTest(dir + "ReturnInnerSubclassOfSupersInner.txt", + dir + "test/ReturnInnerSubclassOfSupersInner.java"); + } + + public void testReturnInnerSubclassOfSupersInnerNoCompile() throws Exception { + // Test is here because Java PSI used to have some differences when loading parallel generic hierarchies from cls and source code. + String dir = PATH + "/returnInnerSubclassOfSupersInner/"; + doTestNoCompile(dir + "ReturnInnerSubclassOfSupersInner.txt", dir); + } + public void testReturnNotSubtype() throws Exception { String dir = PATH + "/returnNotSubtype/"; doTestNoCompile(dir + "ReturnNotSubtype.txt", dir);