KT-13161 java static methods call not working for typealias
Introduce special qualifier for type aliases with member scope containing static class members only.
This commit is contained in:
@@ -2330,6 +2330,15 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
return intermediateValueForProperty(propertyDescriptor, directToField, directToField, superCallTarget, false, receiver, resolvedCall);
|
return intermediateValueForProperty(propertyDescriptor, directToField, directToField, superCallTarget, false, receiver, resolvedCall);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (descriptor instanceof TypeAliasDescriptor) {
|
||||||
|
ClassDescriptor classDescriptor = ((TypeAliasDescriptor) descriptor).getClassDescriptor();
|
||||||
|
if (classDescriptor == null) {
|
||||||
|
throw new IllegalStateException("Type alias " + descriptor + " static member refernece should be rejected by type checker, " +
|
||||||
|
"since there is no class corresponding to this type alias.");
|
||||||
|
}
|
||||||
|
descriptor = classDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
if (descriptor instanceof ClassDescriptor) {
|
if (descriptor instanceof ClassDescriptor) {
|
||||||
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
|
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
|
||||||
if (isObject(classDescriptor)) {
|
if (isObject(classDescriptor)) {
|
||||||
|
|||||||
@@ -654,6 +654,10 @@ class QualifiedExpressionResolver(val classifierUsageCheckers: Iterable<Classifi
|
|||||||
is PackageViewDescriptor -> PackageQualifier(referenceExpression, descriptor)
|
is PackageViewDescriptor -> PackageQualifier(referenceExpression, descriptor)
|
||||||
is ClassDescriptor -> ClassQualifier(referenceExpression, descriptor)
|
is ClassDescriptor -> ClassQualifier(referenceExpression, descriptor)
|
||||||
is TypeParameterDescriptor -> TypeParameterQualifier(referenceExpression, descriptor)
|
is TypeParameterDescriptor -> TypeParameterQualifier(referenceExpression, descriptor)
|
||||||
|
is TypeAliasDescriptor -> {
|
||||||
|
val classDescriptor = descriptor.classDescriptor ?: return null
|
||||||
|
TypeAliasQualifier(referenceExpression, descriptor, classDescriptor)
|
||||||
|
}
|
||||||
else -> return null
|
else -> return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,10 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.scopes.receivers
|
package org.jetbrains.kotlin.resolve.scopes.receivers
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
|
||||||
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getTopmostParentQualifiedExpressionForSelector
|
import org.jetbrains.kotlin.psi.psiUtil.getTopmostParentQualifiedExpressionForSelector
|
||||||
@@ -56,10 +53,12 @@ class TypeParameterQualifier(
|
|||||||
override fun toString() = "TypeParameter{$descriptor}"
|
override fun toString() = "TypeParameter{$descriptor}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ClassifierQualifier : Qualifier
|
||||||
|
|
||||||
class ClassQualifier(
|
class ClassQualifier(
|
||||||
override val referenceExpression: KtSimpleNameExpression,
|
override val referenceExpression: KtSimpleNameExpression,
|
||||||
override val descriptor: ClassDescriptor
|
override val descriptor: ClassDescriptor
|
||||||
) : Qualifier {
|
) : ClassifierQualifier {
|
||||||
override val classValueReceiver: ClassValueReceiver? = descriptor.classValueType?.let {
|
override val classValueReceiver: ClassValueReceiver? = descriptor.classValueType?.let {
|
||||||
ClassValueReceiver(this, it)
|
ClassValueReceiver(this, it)
|
||||||
}
|
}
|
||||||
@@ -79,7 +78,21 @@ class ClassQualifier(
|
|||||||
override fun toString() = "Class{$descriptor}"
|
override fun toString() = "Class{$descriptor}"
|
||||||
}
|
}
|
||||||
|
|
||||||
class ClassValueReceiver(val classQualifier: ClassQualifier, private val type: KotlinType) : ExpressionReceiver {
|
class TypeAliasQualifier(
|
||||||
|
override val referenceExpression: KtSimpleNameExpression,
|
||||||
|
override val descriptor: TypeAliasDescriptor,
|
||||||
|
val classDescriptor: ClassDescriptor
|
||||||
|
) : ClassifierQualifier {
|
||||||
|
override val classValueReceiver: ClassValueReceiver?
|
||||||
|
get() = classDescriptor.classValueType?.let {
|
||||||
|
ClassValueReceiver(this, it)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val staticScope: MemberScope
|
||||||
|
get() = classDescriptor.staticScope
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClassValueReceiver(val classQualifier: ClassifierQualifier, private val type: KotlinType) : ExpressionReceiver {
|
||||||
override fun getType() = type
|
override fun getType() = type
|
||||||
|
|
||||||
override val expression: KtExpression
|
override val expression: KtExpression
|
||||||
|
|||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
// FILE: JTest.java
|
||||||
|
public class JTest {
|
||||||
|
public static String o() { return "O"; }
|
||||||
|
public static final String K = "K";
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: 1.kt
|
||||||
|
typealias JT = JTest
|
||||||
|
|
||||||
|
fun box(): String = JT.o() + JT.K
|
||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
// FILE: JTest.java
|
||||||
|
public class JTest {
|
||||||
|
public static String foo() { return ""; }
|
||||||
|
public static class Nested {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: JDerived.java
|
||||||
|
public class JDerived extends JTest {
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: test.kt
|
||||||
|
class KTest {
|
||||||
|
class Nested
|
||||||
|
inner class Inner
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ITest {
|
||||||
|
class Nested
|
||||||
|
}
|
||||||
|
|
||||||
|
typealias JT = JTest
|
||||||
|
typealias JD = JDerived
|
||||||
|
typealias KT = KTest
|
||||||
|
typealias IT = ITest
|
||||||
|
|
||||||
|
// Referencing Java class static members via type alias should be ok
|
||||||
|
val testFoo: String = JT.foo()
|
||||||
|
val seeAlsoFoo: String = JTest.foo()
|
||||||
|
// Referencing base Java class static members via type alias for derived Java class should be ok
|
||||||
|
val testDerivedFoo: String = JD.foo()
|
||||||
|
val seeAlsoDerivedFoo: String = JDerived.foo()
|
||||||
|
|
||||||
|
// Referencing nested classes via type alias should be prohibited
|
||||||
|
// (in type position and in expression position)
|
||||||
|
val testNested1: JT.<!UNRESOLVED_REFERENCE!>Nested<!> = JT.<!UNRESOLVED_REFERENCE!>Nested<!>()
|
||||||
|
val testNested2: KT.<!UNRESOLVED_REFERENCE!>Nested<!> = KT.<!UNRESOLVED_REFERENCE!>Nested<!>()
|
||||||
|
val testNested3: IT.<!UNRESOLVED_REFERENCE!>Nested<!> = IT.<!UNRESOLVED_REFERENCE!>Nested<!>()
|
||||||
|
val testInner1: JT.<!UNRESOLVED_REFERENCE!>Inner<!> = JT.<!UNRESOLVED_REFERENCE!>Inner<!>()
|
||||||
|
val testInner2: KT.<!UNRESOLVED_REFERENCE!>Inner<!> = KT.<!UNRESOLVED_REFERENCE!>Inner<!>()
|
||||||
|
fun testNestedAsTypeArgument1(x: List<JT.<!UNRESOLVED_REFERENCE!>Nested<!>>) {}
|
||||||
|
fun testNestedAsTypeArgument2(x: List<KT.<!UNRESOLVED_REFERENCE!>Nested<!>>) {}
|
||||||
|
fun testNestedAsTypeArgument3(x: List<IT.<!UNRESOLVED_REFERENCE!>Nested<!>>) {}
|
||||||
|
fun testInnerAsTypeArgument1(x: List<JT.<!UNRESOLVED_REFERENCE!>Inner<!>>) {}
|
||||||
|
fun testInnerAsTypeArgument2(x: List<KT.<!UNRESOLVED_REFERENCE!>Inner<!>>) {}
|
||||||
|
|
||||||
+81
@@ -0,0 +1,81 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public typealias IT = ITest
|
||||||
|
public typealias JD = JDerived
|
||||||
|
public typealias JT = JTest
|
||||||
|
public typealias KT = KTest
|
||||||
|
public val seeAlsoDerivedFoo: kotlin.String
|
||||||
|
public val seeAlsoFoo: kotlin.String
|
||||||
|
public val testDerivedFoo: kotlin.String
|
||||||
|
public val testFoo: kotlin.String
|
||||||
|
public val testInner1: [ERROR : JT.Inner]
|
||||||
|
public val testInner2: [ERROR : KT.Inner]
|
||||||
|
public val testNested1: [ERROR : JT.Nested]
|
||||||
|
public val testNested2: [ERROR : KT.Nested]
|
||||||
|
public val testNested3: [ERROR : IT.Nested]
|
||||||
|
public fun testInnerAsTypeArgument1(/*0*/ x: kotlin.collections.List<[ERROR : JT.Inner]>): kotlin.Unit
|
||||||
|
public fun testInnerAsTypeArgument2(/*0*/ x: kotlin.collections.List<[ERROR : KT.Inner]>): kotlin.Unit
|
||||||
|
public fun testNestedAsTypeArgument1(/*0*/ x: kotlin.collections.List<[ERROR : JT.Nested]>): kotlin.Unit
|
||||||
|
public fun testNestedAsTypeArgument2(/*0*/ x: kotlin.collections.List<[ERROR : KT.Nested]>): kotlin.Unit
|
||||||
|
public fun testNestedAsTypeArgument3(/*0*/ x: kotlin.collections.List<[ERROR : IT.Nested]>): kotlin.Unit
|
||||||
|
|
||||||
|
public interface ITest {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public final class Nested {
|
||||||
|
public constructor Nested()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public open class JDerived : JTest {
|
||||||
|
public constructor JDerived()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public open override /*1*/ /*fake_override*/ fun foo(): kotlin.String!
|
||||||
|
}
|
||||||
|
|
||||||
|
public open class JTest {
|
||||||
|
public constructor JTest()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public open class Nested {
|
||||||
|
public constructor Nested()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public open fun foo(): kotlin.String!
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class KTest {
|
||||||
|
public constructor KTest()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public final inner class Inner {
|
||||||
|
public constructor Inner()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Nested {
|
||||||
|
public constructor Nested()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19953,6 +19953,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("javaStaticMembersViaTypeAlias.kt")
|
||||||
|
public void testJavaStaticMembersViaTypeAlias() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/javaStaticMembersViaTypeAlias.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("localTypeAlias.kt")
|
@TestMetadata("localTypeAlias.kt")
|
||||||
public void testLocalTypeAlias() throws Exception {
|
public void testLocalTypeAlias() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/localTypeAlias.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/localTypeAlias.kt");
|
||||||
|
|||||||
+15
@@ -875,6 +875,21 @@ public class BlackBoxAgainstJavaCodegenTestGenerated extends AbstractBlackBoxAga
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/boxAgainstJava/typealias")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Typealias extends AbstractBlackBoxAgainstJavaCodegenTest {
|
||||||
|
public void testAllFilesPresentInTypealias() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxAgainstJava/typealias"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("javaStaticMembersViaTypeAlias.kt")
|
||||||
|
public void testJavaStaticMembersViaTypeAlias() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxAgainstJava/typealias/javaStaticMembersViaTypeAlias.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/boxAgainstJava/visibility")
|
@TestMetadata("compiler/testData/codegen/boxAgainstJava/visibility")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Reference in New Issue
Block a user