diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index a0c05bd1045..664b61b918b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -4049,11 +4049,27 @@ public class ExpressionCodegen extends KtVisitor impleme @NotNull public ClassConstructorDescriptor getConstructorDescriptor(@NotNull ResolvedCall resolvedCall) { FunctionDescriptor accessibleDescriptor = accessibleFunctionDescriptor(resolvedCall); - assert accessibleDescriptor instanceof ConstructorDescriptor : + assert accessibleDescriptor instanceof ClassConstructorDescriptor : "getConstructorDescriptor must be called only for constructors: " + accessibleDescriptor; return (ClassConstructorDescriptor) accessibleDescriptor; } + @Nullable + private static ReceiverValue getConstructorReceiver(@NotNull ResolvedCall resolvedCall) { + CallableDescriptor constructor = resolvedCall.getResultingDescriptor(); + if (constructor.getExtensionReceiverParameter() != null) { + assert constructor instanceof TypeAliasConstructorDescriptor : + "Only type alias constructor can have an extension receiver: " + constructor; + return resolvedCall.getExtensionReceiver(); + } + else if (constructor.getDispatchReceiverParameter() != null) { + return resolvedCall.getDispatchReceiver(); + } + else { + return null; + } + } + @NotNull public StackValue generateConstructorCall(@NotNull final ResolvedCall resolvedCall, @NotNull final Type objectType) { return StackValue.functionCall(objectType, new Function1() { @@ -4068,7 +4084,7 @@ public class ExpressionCodegen extends KtVisitor impleme ClassDescriptor containingDeclaration = constructor.getContainingDeclaration(); if (dispatchReceiver != null) { Type receiverType = typeMapper.mapType(dispatchReceiver.getType()); - ReceiverValue receiver = resolvedCall.getDispatchReceiver(); + ReceiverValue receiver = getConstructorReceiver(resolvedCall); boolean callSuper = containingDeclaration.isInner() && receiver instanceof ImplicitClassReceiver; generateReceiverValue(receiver, callSuper).put(receiverType, v); } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolverUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolverUtil.kt index c9876bf2f19..0e74f018087 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolverUtil.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolverUtil.kt @@ -248,7 +248,8 @@ private fun ClassConstructorDescriptor.getConstructorDescriptorForResolution( typeAliasDescriptor: TypeAliasDescriptor? ): ConstructorDescriptor = if (typeAliasDescriptor != null) - TypeAliasConstructorDescriptorImpl.create(typeAliasDescriptor, this, knownSubstitutor ?: TypeSubstitutor.EMPTY) + TypeAliasConstructorDescriptorImpl.createIfAvailable(typeAliasDescriptor, this, knownSubstitutor ?: TypeSubstitutor.EMPTY, + withDispatchReceiver = true) ?: throw AssertionError("Failed to create type alias constructor with substitutor: $knownSubstitutor") else this diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt index 0add0ef22c9..d75b7214b45 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt @@ -39,6 +39,7 @@ import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.typeUtil.getImmediateSuperclassNotAny import org.jetbrains.kotlin.utils.SmartList import org.jetbrains.kotlin.utils.addIfNotNull +import org.jetbrains.kotlin.utils.toReadOnlyList import java.util.* internal abstract class AbstractScopeTowerLevel( @@ -265,14 +266,26 @@ private fun ResolutionScope.getContributedFunctionsAndConstructors( location: LookupLocation, syntheticConstructorsProvider: SyntheticConstructorsProvider ): Collection { + val result = ArrayList(getContributedFunctions(name, location)) + val classifier = getContributedClassifier(name, location) - return getContributedFunctions(name, location) + - (getClassWithConstructors(classifier)?.constructors?.filter { it.dispatchReceiverParameter == null } ?: emptyList()) + - (classifier?.getTypeAliasConstructors()?.filter { it.dispatchReceiverParameter == null } ?: emptyList()) + - (classifier?.let { syntheticConstructorsProvider.getSyntheticConstructors(it, location) } - ?.filter { it.dispatchReceiverParameter == null } ?: emptyList()) + if (classifier != null) { + classifier.getCallableConstructors().filterTo(result) { it.dispatchReceiverParameter == null } + syntheticConstructorsProvider.getSyntheticConstructors(classifier, location).filterTo(result) { it.dispatchReceiverParameter == null } + } + + return result.toReadOnlyList() } +private fun ClassifierDescriptor.getCallableConstructors(): Collection = + when (this) { + is TypeAliasDescriptor -> + getTypeAliasConstructors() + is ClassDescriptor -> + if (canHaveCallableConstructors) constructors else emptyList() + else -> emptyList() + } + private fun ResolutionScope.getContributedObjectVariables(name: Name, location: LookupLocation): Collection { val objectDescriptor = getFakeDescriptorForObject(getContributedClassifier(name, location)) return listOfNotNull(objectDescriptor) @@ -304,19 +317,15 @@ private fun getClassWithConstructors(classifier: ClassifierDescriptor?): ClassDe private val ClassDescriptor.canHaveCallableConstructors: Boolean get() = !ErrorUtils.isError(this) && !kind.isSingleton -fun ClassifierDescriptor.getTypeAliasConstructors(): Collection { - if (this !is TypeAliasDescriptor) return emptyList() - +fun TypeAliasDescriptor.getTypeAliasConstructors(): Collection { val classDescriptor = this.classDescriptor ?: return emptyList() if (!classDescriptor.canHaveCallableConstructors) return emptyList() - val substitutor = this.getTypeSubstitutorForUnderlyingClass() ?: throw AssertionError("classDescriptor should be non-null for $this") + val substitutor = this.getTypeSubstitutorForUnderlyingClass() ?: + throw AssertionError("classDescriptor should be non-null for $this") return classDescriptor.constructors.mapNotNull { - if (it.dispatchReceiverParameter == null) - TypeAliasConstructorDescriptorImpl.create(this, it, substitutor) - else - null + TypeAliasConstructorDescriptorImpl.createIfAvailable(this, it, substitutor) } } diff --git a/compiler/testData/codegen/box/typealias/innerClassTypeAliasConstructor.kt b/compiler/testData/codegen/box/typealias/innerClassTypeAliasConstructor.kt new file mode 100644 index 00000000000..6193b148048 --- /dev/null +++ b/compiler/testData/codegen/box/typealias/innerClassTypeAliasConstructor.kt @@ -0,0 +1,10 @@ +class Outer(val x: String) { + inner class Inner(val y: String) { + val z = x + y + } +} + +typealias OI = Outer.Inner + +fun box(): String = + Outer("O").OI("K").z \ No newline at end of file diff --git a/compiler/testData/codegen/box/typealias/innerClassTypeAliasConstructorInSupertypes.kt b/compiler/testData/codegen/box/typealias/innerClassTypeAliasConstructorInSupertypes.kt new file mode 100644 index 00000000000..0c1b2ee469f --- /dev/null +++ b/compiler/testData/codegen/box/typealias/innerClassTypeAliasConstructorInSupertypes.kt @@ -0,0 +1,12 @@ +class Outer(val x: String) { + abstract inner class InnerBase + + inner class Inner(val y: String) : OIB() { + val z = x + y + } +} + +typealias OIB = Outer.InnerBase + +fun box(): String = + Outer("O").Inner("K").z \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/typealias/innerClassTypeAliasConstructor.kt b/compiler/testData/diagnostics/tests/typealias/innerClassTypeAliasConstructor.kt new file mode 100644 index 00000000000..4aea2e00941 --- /dev/null +++ b/compiler/testData/diagnostics/tests/typealias/innerClassTypeAliasConstructor.kt @@ -0,0 +1,21 @@ +class Outer { + inner class Inner +} + +typealias OI = Outer.Inner + +fun test1(x: Outer) = x.OI() + + +class Generic { + inner class Inner +} + +typealias GI = Generic.Inner +typealias GIntI = Generic.Inner + +fun test2(x: Generic) = x.GI() +fun test3(x: Generic) = x.GI() +fun test4(x: Generic>) = x.GI() +fun test5(x: Generic) = x.GIntI() +fun Generic.test6() = GIntI() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/typealias/innerClassTypeAliasConstructor.txt b/compiler/testData/diagnostics/tests/typealias/innerClassTypeAliasConstructor.txt new file mode 100644 index 00000000000..c0fcde5e43e --- /dev/null +++ b/compiler/testData/diagnostics/tests/typealias/innerClassTypeAliasConstructor.txt @@ -0,0 +1,39 @@ +package + +public fun test1(/*0*/ x: Outer): Outer.Inner +public fun test2(/*0*/ x: Generic): Generic.Inner +public fun test3(/*0*/ x: Generic): Generic.Inner +public fun test4(/*0*/ x: Generic>): Generic>.Inner +public fun test5(/*0*/ x: Generic): Generic.Inner +public fun Generic.test6(): Generic.Inner + +public final class Generic { + public constructor Generic() + 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 /*captured type parameters: /*0*/ T*/ { + 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 Outer { + public constructor Outer() + 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 typealias GI = Generic.Inner +public typealias GIntI = Generic.Inner +public typealias OI = Outer.Inner diff --git a/compiler/testData/diagnostics/tests/typealias/innerClassTypeAliasConstructorInSupertypes.kt b/compiler/testData/diagnostics/tests/typealias/innerClassTypeAliasConstructorInSupertypes.kt new file mode 100644 index 00000000000..6db8f0d767d --- /dev/null +++ b/compiler/testData/diagnostics/tests/typealias/innerClassTypeAliasConstructorInSupertypes.kt @@ -0,0 +1,39 @@ +package test + +typealias OI = Outer.Inner + +class Outer { + open inner class Inner + + inner class Test : OI() +} + + +typealias GI = Generic.Inner +typealias GIInt = Generic.Inner +typealias GIStar = Generic<*>.Inner +typealias GG = Generic.Generic +typealias GIntG = Generic.Generic +typealias GGInt = Generic.Generic + +class Generic { + open inner class Inner + open inner class Generic + + inner class Test1 : GI() + inner class Test2 : GIInt() + inner class Test3 : GIStar() + inner class Test3a : test.Generic<*>.Inner() + + inner class Test4 : GG() + inner class Test5 : GG() + inner class Test6 : GG() + inner class Test7 : GG() + inner class Test8 : GIntG() + inner class Test9 : GGInt() + inner class Test10 : GGInt() + + inner class Test11 : GG { + constructor() : super() + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/typealias/innerClassTypeAliasConstructorInSupertypes.txt b/compiler/testData/diagnostics/tests/typealias/innerClassTypeAliasConstructorInSupertypes.txt new file mode 100644 index 00000000000..dd6281ff064 --- /dev/null +++ b/compiler/testData/diagnostics/tests/typealias/innerClassTypeAliasConstructorInSupertypes.txt @@ -0,0 +1,137 @@ +package + +package test { + + public final class Generic { + public constructor Generic() + 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 inner class Generic /*captured type parameters: /*1*/ T1*/ { + public constructor Generic() + 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 inner class Inner /*captured type parameters: /*0*/ T1*/ { + 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 inner class Test1 /*captured type parameters: /*0*/ T1*/ : test.GI /* = test.Generic.Inner */ { + public constructor Test1() + 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 Test10 /*captured type parameters: /*0*/ T1*/ : test.GGInt /* = test.Generic.Generic */ { + public constructor Test10() + 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 Test11 /*captured type parameters: /*0*/ T1*/ : test.GG /* = test.Generic.Generic */ { + public constructor Test11() + 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 Test2 /*captured type parameters: /*0*/ T1*/ : test.GIInt /* = test.Generic.Inner */ { + public constructor Test2() + 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 Test3 /*captured type parameters: /*0*/ T1*/ : test.GIStar /* = test.Generic<*>.Inner */ { + public constructor Test3() + 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 Test3a /*captured type parameters: /*0*/ T1*/ : test.Generic<*>.Inner { + public constructor Test3a() + 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 Test4 /*captured type parameters: /*1*/ T1*/ : test.GG /* = test.Generic.Generic */ { + public constructor Test4() + 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 Test5 /*captured type parameters: /*0*/ T1*/ : test.GG /* = test.Generic.Generic */ { + public constructor Test5() + 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 Test6 /*captured type parameters: /*0*/ T1*/ : test.GG /* = test.Generic.Generic */ { + public constructor Test6() + 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 Test7 /*captured type parameters: /*0*/ T1*/ : test.GG /* = test.Generic.Generic */ { + public constructor Test7() + 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 Test8 /*captured type parameters: /*0*/ T1*/ : test.GIntG /* = test.Generic.Generic */ { + public constructor Test8() + 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 Test9 /*captured type parameters: /*0*/ T1*/ : test.GGInt /* = test.Generic.Generic */ { + public constructor Test9() + 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 Outer { + public constructor Outer() + 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 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 inner class Test : test.OI /* = test.Outer.Inner */ { + public constructor Test() + 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 typealias GG = test.Generic.Generic + public typealias GGInt = test.Generic.Generic + public typealias GI = test.Generic.Inner + public typealias GIInt = test.Generic.Inner + public typealias GIStar = test.Generic<*>.Inner + public typealias GIntG = test.Generic.Generic + public typealias OI = test.Outer.Inner +} diff --git a/compiler/testData/diagnostics/tests/typealias/typeAliasConstructorWrongClass.kt b/compiler/testData/diagnostics/tests/typealias/typeAliasConstructorWrongClass.kt index c2a6412fd1e..e8278e5fe0d 100644 --- a/compiler/testData/diagnostics/tests/typealias/typeAliasConstructorWrongClass.kt +++ b/compiler/testData/diagnostics/tests/typealias/typeAliasConstructorWrongClass.kt @@ -29,6 +29,6 @@ typealias Test5 = Outer.Inner val test5 = Test5() val test5a = Outer.Inner() val test5b = Outer.TestInner() -val test5c = Outer().TestInner() // TODO extension type alias constructors? +val test5c = Outer().TestInner() val test5d = Outer().Inner() -val test5e = Outer().Test5() // TODO extension type alias constructors? \ No newline at end of file +val test5e = Outer().Test5() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/typealias/typeAliasConstructorWrongClass.txt b/compiler/testData/diagnostics/tests/typealias/typeAliasConstructorWrongClass.txt index c51cd13371f..d62977ae320 100644 --- a/compiler/testData/diagnostics/tests/typealias/typeAliasConstructorWrongClass.txt +++ b/compiler/testData/diagnostics/tests/typealias/typeAliasConstructorWrongClass.txt @@ -13,7 +13,7 @@ public val test5a: [ERROR : Type for Outer.Inner()] public val test5b: [ERROR : Type for Outer.TestInner()] public val test5c: [ERROR : Type for Outer().TestInner()] public val test5d: Outer.Inner -public val test5e: [ERROR : Type for Outer().Test5()] +public val test5e: Outer.Inner public abstract class AbstractClass { public constructor AbstractClass() diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 3c1550df7bc..0a618920822 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -16193,6 +16193,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("innerClassTypeAliasConstructor.kt") + public void testInnerClassTypeAliasConstructor() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/innerClassTypeAliasConstructor.kt"); + doTest(fileName); + } + + @TestMetadata("innerClassTypeAliasConstructorInSupertypes.kt") + public void testInnerClassTypeAliasConstructorInSupertypes() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/innerClassTypeAliasConstructorInSupertypes.kt"); + doTest(fileName); + } + @TestMetadata("simple.kt") public void testSimple() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/simple.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 7eddcd81531..41f618b8f94 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -20926,6 +20926,18 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("innerClassTypeAliasConstructor.kt") + public void testInnerClassTypeAliasConstructor() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/innerClassTypeAliasConstructor.kt"); + doTest(fileName); + } + + @TestMetadata("innerClassTypeAliasConstructorInSupertypes.kt") + public void testInnerClassTypeAliasConstructorInSupertypes() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/innerClassTypeAliasConstructorInSupertypes.kt"); + doTest(fileName); + } + @TestMetadata("innerTypeAliasAsType.kt") public void testInnerTypeAliasAsType() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/innerTypeAliasAsType.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index d83f5816943..55c36831d01 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -16193,6 +16193,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("innerClassTypeAliasConstructor.kt") + public void testInnerClassTypeAliasConstructor() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/innerClassTypeAliasConstructor.kt"); + doTest(fileName); + } + + @TestMetadata("innerClassTypeAliasConstructorInSupertypes.kt") + public void testInnerClassTypeAliasConstructorInSupertypes() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/innerClassTypeAliasConstructorInSupertypes.kt"); + doTest(fileName); + } + @TestMetadata("simple.kt") public void testSimple() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/simple.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/TypeAliasConstructorDescriptor.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/TypeAliasConstructorDescriptor.kt index 274e4333883..ad19f11017d 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/TypeAliasConstructorDescriptor.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/TypeAliasConstructorDescriptor.kt @@ -108,42 +108,43 @@ class TypeAliasConstructorDescriptorImpl private constructor( } companion object { - fun create( + fun createIfAvailable( typeAliasDescriptor: TypeAliasDescriptor, constructor: ClassConstructorDescriptor, - substitutor: TypeSubstitutor? + substitutor: TypeSubstitutor, + withDispatchReceiver: Boolean = false ): TypeAliasConstructorDescriptor? { - val actualSubstitutor = substitutor ?: TypeSubstitutor.EMPTY val typeAliasConstructor = TypeAliasConstructorDescriptorImpl(typeAliasDescriptor, constructor, null, constructor.annotations, constructor.kind, typeAliasDescriptor.source) - val valueParameters = FunctionDescriptorImpl.getSubstitutedValueParameters(typeAliasConstructor, constructor.valueParameters, actualSubstitutor, false) + val valueParameters = FunctionDescriptorImpl.getSubstitutedValueParameters(typeAliasConstructor, constructor.valueParameters, substitutor, false) ?: return null - val returnType = actualSubstitutor.substitute(constructor.returnType, Variance.INVARIANT) + val returnType = substitutor.substitute(constructor.returnType, Variance.INVARIANT) ?: return null - val containingDeclaration = constructor.containingDeclaration - val dispatchReceiverParameter = - if (containingDeclaration.isInner) - containingDeclaration.thisAsReceiverParameter - else - null + val receiverParameterType = + if (withDispatchReceiver) null + else constructor.dispatchReceiverParameter?.let { substitutor.safeSubstitute(it.type, Variance.INVARIANT) } - typeAliasConstructor.initialize(null, - dispatchReceiverParameter, - typeAliasDescriptor.declaredTypeParameters, - valueParameters, - returnType, - Modality.FINAL, - typeAliasDescriptor.visibility) + val dispatchReceiver = + if (withDispatchReceiver) constructor.dispatchReceiverParameter?.let { it.substitute(substitutor) } + else null + + typeAliasConstructor.initialize( + receiverParameterType, + dispatchReceiver, + typeAliasDescriptor.declaredTypeParameters, + valueParameters, + returnType, + Modality.FINAL, + typeAliasDescriptor.visibility + ) return typeAliasConstructor } - - } } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index b9ebe4283c1..e3d1d0e0a44 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -21098,6 +21098,18 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { doTest(fileName); } + @TestMetadata("innerClassTypeAliasConstructor.kt") + public void testInnerClassTypeAliasConstructor() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/innerClassTypeAliasConstructor.kt"); + doTest(fileName); + } + + @TestMetadata("innerClassTypeAliasConstructorInSupertypes.kt") + public void testInnerClassTypeAliasConstructorInSupertypes() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/innerClassTypeAliasConstructorInSupertypes.kt"); + doTest(fileName); + } + @TestMetadata("simple.kt") public void testSimple() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/simple.kt"); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/FunctionCallCases.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/FunctionCallCases.kt index b5b07e0669f..8d9611b0c14 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/FunctionCallCases.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/FunctionCallCases.kt @@ -206,6 +206,8 @@ object ConstructorCallCase : FunctionCallCase() { override fun FunctionCallInfo.dispatchReceiver() = doTranslate { argsWithReceiver(dispatchReceiver!!) } + override fun FunctionCallInfo.extensionReceiver() = doTranslate { argsWithReceiver(extensionReceiver!!) } + private inline fun FunctionCallInfo.doTranslate( getArguments: CallArgumentTranslator.ArgumentsInfo.() -> List ): JsExpression { diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/initializer/ClassInitializerTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/initializer/ClassInitializerTranslator.java index 9faf81ed7a7..d2da90056cf 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/initializer/ClassInitializerTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/initializer/ClassInitializerTranslator.java @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.js.translate.initializer; import com.google.dart.compiler.backend.js.ast.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.descriptors.*; +import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor; import org.jetbrains.kotlin.js.translate.callTranslator.CallTranslator; import org.jetbrains.kotlin.js.translate.context.Namer; import org.jetbrains.kotlin.js.translate.context.TranslationContext; @@ -170,6 +171,9 @@ public final class ClassInitializerTranslator extends AbstractTranslator { List arguments = new ArrayList(); ConstructorDescriptor superDescriptor = (ConstructorDescriptor) superCall.getResultingDescriptor(); + if (superDescriptor instanceof TypeAliasConstructorDescriptor) { + superDescriptor = ((TypeAliasConstructorDescriptor) superDescriptor).getUnderlyingConstructorDescriptor(); + } List superclassClosure = context.getClassOrConstructorClosure(superDescriptor); if (superclassClosure != null) { @@ -182,7 +186,7 @@ public final class ClassInitializerTranslator extends AbstractTranslator { } } - if (superDescriptor.getContainingDeclaration().isInner() && classDescriptor.isInner()) { + if (superDescriptor.getConstructedClass().isInner() && classDescriptor.isInner()) { arguments.add(pureFqn(Namer.OUTER_FIELD_NAME, JsLiteral.THIS)); }