From 6ba120bba8efbfac97c46bb6c27ccf0589adc1af Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 10 Mar 2015 20:52:46 +0300 Subject: [PATCH] Generate descriptor for trait constructor. Exception is thrown otherwise (EA-38416) --- .../lazy/descriptors/LazyClassMemberScope.kt | 43 ++++++++-------- .../diagnostics/tests/TraitWithConstructor.kt | 7 +++ .../tests/TraitWithConstructor.txt | 30 +++++++++++ compiler/testData/psi/TraitConstructor.kt | 2 + compiler/testData/psi/TraitConstructor.txt | 50 +++++++++++++++++++ .../checkers/JetDiagnosticsTestGenerated.java | 6 +++ .../parsing/JetParsingTestGenerated.java | 6 +++ 7 files changed, 121 insertions(+), 23 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/TraitWithConstructor.kt create mode 100644 compiler/testData/diagnostics/tests/TraitWithConstructor.txt create mode 100644 compiler/testData/psi/TraitConstructor.kt create mode 100644 compiler/testData/psi/TraitConstructor.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt index 5496cbdfc8d..b42221e68b9 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt @@ -274,25 +274,28 @@ public open class LazyClassMemberScope( public fun getPrimaryConstructor(): ConstructorDescriptor? = primaryConstructor() protected open fun resolvePrimaryConstructor(): ConstructorDescriptor? { - if (GENERATE_CONSTRUCTORS_FOR.contains(thisDescriptor.getKind())) { - val ownerInfo = declarationProvider.getOwnerInfo() - val classOrObject = ownerInfo.getCorrespondingClassOrObject() - if (!thisDescriptor.getKind().isSingleton() && !classOrObject.isObjectLiteral()) { - assert(classOrObject is JetClass) { "No JetClass for $thisDescriptor" } - classOrObject as JetClass - val constructor = c.descriptorResolver.resolvePrimaryConstructorDescriptor( - thisDescriptor.getScopeForClassHeaderResolution(), thisDescriptor, classOrObject, trace) - constructor ?: return null - setDeferredReturnType(constructor) - return constructor - } - else { - val constructor = DescriptorResolver.createAndRecordPrimaryConstructorForObject(classOrObject, thisDescriptor, trace) - setDeferredReturnType(constructor) - return constructor + val ownerInfo = declarationProvider.getOwnerInfo() + val classOrObject = ownerInfo.getCorrespondingClassOrObject() + if (!thisDescriptor.getKind().isSingleton() && !classOrObject.isObjectLiteral()) { + assert(classOrObject is JetClass) { "No JetClass for $thisDescriptor" } + classOrObject as JetClass + + if (DescriptorUtils.isTrait(thisDescriptor) && declarationProvider.getOwnerInfo().getPrimaryConstructorParameters().isEmpty()) { + return null } + + val constructor = c.descriptorResolver.resolvePrimaryConstructorDescriptor( + thisDescriptor.getScopeForClassHeaderResolution(), thisDescriptor, classOrObject, trace) + + assert(constructor != null) { "No constructor created for $thisDescriptor" } + setDeferredReturnType(constructor) + return constructor + } + else { + val constructor = DescriptorResolver.createAndRecordPrimaryConstructorForObject(classOrObject, thisDescriptor, trace) + setDeferredReturnType(constructor) + return constructor } - return null } private fun resolveSecondaryConstructors(): Collection { @@ -318,12 +321,6 @@ public open class LazyClassMemberScope( override fun toString() = "lazy scope for class ${thisDescriptor.getName()}" default object { - private val GENERATE_CONSTRUCTORS_FOR = setOf(ClassKind.CLASS, - ClassKind.ANNOTATION_CLASS, - ClassKind.OBJECT, - ClassKind.ENUM_CLASS, - ClassKind.ENUM_ENTRY) - private val EXTRACT_FUNCTIONS: MemberExtractor = object : MemberExtractor { override fun extract(extractFrom: JetType, name: Name): Collection { return extractFrom.getMemberScope().getFunctions(name) diff --git a/compiler/testData/diagnostics/tests/TraitWithConstructor.kt b/compiler/testData/diagnostics/tests/TraitWithConstructor.kt new file mode 100644 index 00000000000..11bb77d3649 --- /dev/null +++ b/compiler/testData/diagnostics/tests/TraitWithConstructor.kt @@ -0,0 +1,7 @@ +class C(val a: String) {} + +trait T1(val x: String) {} + +trait T2() {} + +trait T3(a: Int) {} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/TraitWithConstructor.txt b/compiler/testData/diagnostics/tests/TraitWithConstructor.txt new file mode 100644 index 00000000000..913dd50cf1e --- /dev/null +++ b/compiler/testData/diagnostics/tests/TraitWithConstructor.txt @@ -0,0 +1,30 @@ +package + +internal final class C { + public constructor C(/*0*/ a: kotlin.String) + internal final val a: kotlin.String + 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 +} + +internal trait T1 { + public constructor T1(/*0*/ x: kotlin.String) + internal final val x: kotlin.String + 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 +} + +internal trait T2 { + 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 +} + +internal trait T3 { + public constructor T3(/*0*/ a: kotlin.Int) + 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 +} diff --git a/compiler/testData/psi/TraitConstructor.kt b/compiler/testData/psi/TraitConstructor.kt new file mode 100644 index 00000000000..31fe90fd1ab --- /dev/null +++ b/compiler/testData/psi/TraitConstructor.kt @@ -0,0 +1,2 @@ +trait TestTrait(val a: Int, var b: String, c: Double) +trait TestTrait() \ No newline at end of file diff --git a/compiler/testData/psi/TraitConstructor.txt b/compiler/testData/psi/TraitConstructor.txt new file mode 100644 index 00000000000..c820aef5628 --- /dev/null +++ b/compiler/testData/psi/TraitConstructor.txt @@ -0,0 +1,50 @@ +JetFile: TraitConstructor.kt + PACKAGE_DIRECTIVE + + CLASS + PsiElement(trait)('trait') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('TestTrait') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + PsiElement(val)('val') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('a') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Int') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + VALUE_PARAMETER + PsiElement(var)('var') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('b') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('String') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('c') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Double') + PsiElement(RPAR)(')') + PsiWhiteSpace('\n') + CLASS + PsiElement(trait)('trait') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('TestTrait') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index 4c8eefbb73f..06c3ba8ebe7 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -563,6 +563,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("TraitWithConstructor.kt") + public void testTraitWithConstructor() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/TraitWithConstructor.kt"); + doTest(fileName); + } + @TestMetadata("TypeInference.kt") public void testTypeInference() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/TypeInference.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/parsing/JetParsingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/parsing/JetParsingTestGenerated.java index e6745ccf648..ccc6f65c512 100644 --- a/compiler/tests/org/jetbrains/kotlin/parsing/JetParsingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/parsing/JetParsingTestGenerated.java @@ -543,6 +543,12 @@ public class JetParsingTestGenerated extends AbstractJetParsingTest { doParsingTest(fileName); } + @TestMetadata("TraitConstructor.kt") + public void testTraitConstructor() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/TraitConstructor.kt"); + doParsingTest(fileName); + } + @TestMetadata("TryRecovery.kt") public void testTryRecovery() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/TryRecovery.kt");