Do not create error types in deserialization on not found classes

For a class which cannot be resolved in the current deserialization session,
create a special ClassDescriptor instance with an empty scope and put in the
correct package under the current module. Codegen will perfectly map such class
to its JVM signature (because only the precise FQ name is needed, which is
available). For more details on this approach, see the issue description.

 #KT-4328 Fixed
 #KT-11497 Fixed
This commit is contained in:
Alexander Udalov
2016-03-09 20:48:00 +03:00
parent 3944d56ac2
commit accf80a624
17 changed files with 228 additions and 34 deletions
@@ -0,0 +1,9 @@
package a
class A<T> {
inner class Inner<X : Number, Y>
}
class AA<T> {
inner class Inner<U, V>
}
@@ -0,0 +1,9 @@
package b
import a.A
import a.AA
interface B1 {
fun produceA(): A<String>.Inner<Int, Unit>
fun produceAA(): AA<Int>.Inner<Unit, String>
}
@@ -0,0 +1,9 @@
package a
class A<T, U: CharSequence, V> {
inner class Inner<Z>
}
class AA<T, U> {
inner class Inner<V>
}
@@ -0,0 +1,9 @@
package b
import a.A
import a.AA
interface B2 {
fun consumeA(a: A<Int, String, Double>.Inner<B2>)
fun consumeAA(a: AA<Int, Unit>.Inner<String>)
}
@@ -0,0 +1,7 @@
compiler/testData/compileKotlinAgainstCustomBinaries/missingDependencyConflictingLibraries/source.kt:7:17: error: type mismatch: inferred type is A<String>.Inner<Int, Unit> but A<Int, String, Double>.Inner<B2> was expected
b2.consumeA(b1.produceA())
^
compiler/testData/compileKotlinAgainstCustomBinaries/missingDependencyConflictingLibraries/source.kt:11:18: error: type mismatch: inferred type is AA<Int>.Inner<Unit, String> but AA<Int, Unit>.Inner<String> was expected
b2.consumeAA(b1.produceAA())
^
COMPILATION_ERROR
@@ -0,0 +1,12 @@
package c
import b.B1
import b.B2
fun testA(b1: B1, b2: B2) {
b2.consumeA(b1.produceA())
}
fun testAA(b1: B1, b2: B2) {
b2.consumeAA(b1.produceAA())
}
@@ -0,0 +1,3 @@
package a
interface A
@@ -0,0 +1,7 @@
package b
import a.A
interface B {
fun foo(): A
}
@@ -0,0 +1,4 @@
compiler/testData/compileKotlinAgainstCustomBinaries/missingDependencySimple/source.kt:10:21: error: type mismatch: inferred type is A but String was expected
val x: String = b.foo()
^
COMPILATION_ERROR
@@ -0,0 +1,11 @@
package c
import b.B
fun bar(b: B) {
// Implicit usage of (unavailable) a.A, return value is not used. It should still be an error as in Java
b.foo()
// Return value is used but the type is incorrect, also an error
val x: String = b.foo()
}
@@ -1,8 +1,8 @@
package test
public final annotation class Anno : kotlin.Annotation {
public constructor Anno(/*0*/ e: [ERROR : test.E])
public final val e: [ERROR : test.E]
public constructor Anno(/*0*/ e: test.E)
public final val e: test.E
}
@test.Anno(e = Unresolved enum entry: test/E.ENTRY) public open class Class {
@@ -290,6 +290,19 @@ public class CompileKotlinAgainstCustomBinariesTest extends TestCaseWithTmpdir {
doTestBrokenKotlinLibrary("library", "test/Super.class");
}
public void testMissingDependencySimple() throws Exception {
doTestBrokenKotlinLibrary("library", "a/A.class", "a/A$Inner.class");
}
public void testMissingDependencyConflictingLibraries() throws Exception {
File library1 = copyJarFileWithoutEntry(compileLibrary("library1"),
"a/A.class", "a/A$Inner.class", "a/AA.class", "a/AA$Inner.class");
File library2 = copyJarFileWithoutEntry(compileLibrary("library2"),
"a/A.class", "a/A$Inner.class", "a/AA.class", "a/AA$Inner.class");
Pair<String, ExitCode> output = compileKotlin("source.kt", tmpdir, library1, library2);
KotlinTestUtils.assertEqualsToFile(new File(getTestDataDirectory(), "output.txt"), normalizeOutput(output));
}
/*test source mapping generation when source info is absent*/
public void testInlineFunWithoutDebugInfo() throws Exception {
compileKotlin("sourceInline.kt", tmpdir);