Discriminate header classes in favor of non-header type aliases

In the test case, the problem was that Foo.a's type was resolved to the
_class A_, which was written to metadata on JVM instead of the class
AImpl with typealias A as an abbreviation. This metadata was incorrect
because there's no class A from the JVM compiler's point of view; that's
why the error "cannot access class A" was reported

 #KT-19151 Fixed
This commit is contained in:
Alexander Udalov
2017-07-21 00:17:42 +03:00
parent 6ee94dae6f
commit ebdf5aa223
6 changed files with 34 additions and 4 deletions
@@ -69,13 +69,17 @@ protected constructor(
// NB we should resolve type alias descriptors even if a class descriptor with corresponding name is present
val classes = classDescriptors(name)
val typeAliases = typeAliasDescriptors(name)
var resultingClass: ClassDescriptor? = null
// See getFirstClassifierDiscriminateHeaders()
var result: ClassifierDescriptor? = null
for (klass in classes) {
// See getFirstClassifierDiscriminateHeaders()
if (!klass.isHeader) return klass
if (resultingClass == null) resultingClass = klass
if (result == null) result = klass
}
return resultingClass ?: typeAliases.firstOrNull()
for (typeAlias in typeAliases) {
if (!typeAlias.isHeader) return typeAlias
if (result == null) result = typeAlias
}
return result
}
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> {
@@ -0,0 +1,3 @@
class Foo(val a: A? = null)
header class A
@@ -0,0 +1,5 @@
impl typealias A = AImpl
class AImpl {
fun jvm(): A = this
}
@@ -0,0 +1 @@
val a = Foo().a?.jvm()
@@ -0,0 +1,11 @@
-- Common --
Exit code: OK
Output:
-- JVM --
Exit code: OK
Output:
-- JVM (2) --
Exit code: OK
Output:
@@ -155,6 +155,12 @@ public class MultiPlatformIntegrationTestGenerated extends AbstractMultiPlatform
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/multiplatform/implTypeAlias"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
@TestMetadata("discriminateHeaderClassInFavorOfTypeAlias")
public void testDiscriminateHeaderClassInFavorOfTypeAlias() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/multiplatform/implTypeAlias/discriminateHeaderClassInFavorOfTypeAlias/");
doTest(fileName);
}
@TestMetadata("generic")
public void testGeneric() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/multiplatform/implTypeAlias/generic/");