From 70dbbd8fda5bfbd8c9562a0a23d203b4e9030871 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Fri, 29 May 2015 15:58:08 +0300 Subject: [PATCH] Resolve constructors declared in traits and objects It prevents exceptions and produces less red code #EA-68667 Fixed --- .../codegen/ImplementationBodyCodegen.java | 2 ++ .../kotlin/resolve/BodyResolver.java | 4 +-- .../kotlin/resolve/DeclarationsChecker.java | 11 ++++-- .../resolve/FunctionDescriptorResolver.kt | 2 +- .../kotlin/resolve/LazyTopDownAnalyzer.kt | 4 --- .../kotlin/resolve/calls/CallResolver.java | 9 +++-- .../lazy/descriptors/LazyClassMemberScope.kt | 16 +++------ .../tests/ObjectWithConstructor.kt | 24 +++++++++++++ .../tests/ObjectWithConstructor.txt | 36 +++++++++++++++++++ .../diagnostics/tests/SupertypeListChecks.txt | 1 + .../diagnostics/tests/TraitWithConstructor.kt | 8 +++-- .../tests/TraitWithConstructor.txt | 4 +++ .../constructorInObject.txt | 3 ++ .../constructorInTrait.txt | 1 + .../traitWithRequired/traitSupertypeList.kt | 2 +- .../traitWithRequired/traitSupertypeList.txt | 1 + .../renderer/ObjectWithConstructor.kt | 35 ++++++++++++++++++ .../testData/renderer/TraitWithConstructor.kt | 23 ++++++++++++ .../checkers/JetDiagnosticsTestGenerated.java | 6 ++++ .../AbstractDescriptorRendererTest.kt | 2 +- .../DescriptorRendererTestGenerated.java | 12 +++++++ .../kotlin/resolve/DescriptorUtils.java | 2 +- idea/testData/checker/TraitSupertypeList.kt | 2 +- 23 files changed, 179 insertions(+), 31 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/ObjectWithConstructor.kt create mode 100644 compiler/testData/diagnostics/tests/ObjectWithConstructor.txt create mode 100644 compiler/testData/renderer/ObjectWithConstructor.kt create mode 100644 compiler/testData/renderer/TraitWithConstructor.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java index c0cbb8bb18e..ee9a77443db 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java @@ -1067,6 +1067,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } private void generateSecondaryConstructor(@NotNull ConstructorDescriptor constructorDescriptor) { + if (!canHaveDeclaredConstructors(descriptor)) return; + ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor); functionCodegen.generateMethod(OtherOrigin(descriptorToDeclaration(constructorDescriptor), constructorDescriptor), diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java index 0294a8b959b..92d9b51797f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java @@ -371,6 +371,7 @@ public class BodyResolver { } if (descriptor.getKind() != ClassKind.INTERFACE && descriptor.getUnsubstitutedPrimaryConstructor() != null && + superClass.getKind() != ClassKind.INTERFACE && !superClass.getConstructors().isEmpty() && !ErrorUtils.isError(superClass) ) { @@ -500,8 +501,7 @@ public class BodyResolver { private void resolvePrimaryConstructorParameters(@NotNull BodiesResolveContext c) { for (Map.Entry entry : c.getDeclaredClasses().entrySet()) { - if (!(entry.getKey() instanceof JetClass)) continue; - JetClass klass = (JetClass) entry.getKey(); + JetClassOrObject klass = entry.getKey(); ClassDescriptorWithResolutionScopes classDescriptor = entry.getValue(); ConstructorDescriptor unsubstitutedPrimaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor(); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java index e689183576f..d588ff1404c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java @@ -87,6 +87,8 @@ public class DeclarationsChecker { checkObject((JetObjectDeclaration) classOrObject, classDescriptor); } + checkPrimaryConstructor(classOrObject, classDescriptor); + modifiersChecker.checkModifiersForDeclaration(classOrObject, classDescriptor); } @@ -244,7 +246,6 @@ public class DeclarationsChecker { private void checkClass(BodiesResolveContext c, JetClass aClass, ClassDescriptorWithResolutionScopes classDescriptor) { AnnotationResolver.reportDeprecatedAnnotationSyntax(aClass.getAnnotations(), trace); checkOpenMembers(classDescriptor); - checkPrimaryConstructor(aClass, classDescriptor); checkTypeParameters(aClass); if (aClass.isInterface()) { @@ -271,9 +272,9 @@ public class DeclarationsChecker { } } - private void checkPrimaryConstructor(JetClass aClass, ClassDescriptor classDescriptor) { + private void checkPrimaryConstructor(JetClassOrObject classOrObject, ClassDescriptor classDescriptor) { ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor(); - JetPrimaryConstructor declaration = aClass.getPrimaryConstructor(); + JetPrimaryConstructor declaration = classOrObject.getPrimaryConstructor(); if (primaryConstructor == null || declaration == null) return; for (JetParameter parameter : declaration.getValueParameters()) { @@ -287,6 +288,10 @@ public class DeclarationsChecker { trace.report(MISSING_CONSTRUCTOR_KEYWORD.on(declaration.getModifierList())); } + if (!(classOrObject instanceof JetClass)) { + trace.report(CONSTRUCTOR_IN_OBJECT.on(declaration)); + } + checkConstructorDeclaration(primaryConstructor, declaration); } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt index 261336854f8..f461222077b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt @@ -210,7 +210,7 @@ class FunctionDescriptorResolver( public fun resolvePrimaryConstructorDescriptor( scope: JetScope, classDescriptor: ClassDescriptor, - classElement: JetClass, + classElement: JetClassOrObject, trace: BindingTrace ): ConstructorDescriptorImpl? { if (classDescriptor.getKind() == ClassKind.ENUM_ENTRY || !classElement.hasPrimaryConstructor()) return null diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/LazyTopDownAnalyzer.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/LazyTopDownAnalyzer.kt index 8d45630aa04..019aca09c13 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/LazyTopDownAnalyzer.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/LazyTopDownAnalyzer.kt @@ -199,10 +199,6 @@ public class LazyTopDownAnalyzer { } override fun visitSecondaryConstructor(constructor: JetSecondaryConstructor) { - val classDescriptor = lazyDeclarationResolver!!.resolveToDescriptor(constructor.getClassOrObject()) as ClassDescriptor - if (!DescriptorUtils.canHaveSecondaryConstructors(classDescriptor)) { - return - } c.getSecondaryConstructors().put(constructor, lazyDeclarationResolver!!.resolveToDescriptor(constructor) as ConstructorDescriptor) registerScope(c, constructor) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java index 6e784637125..d4adc85a5cb 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java @@ -349,9 +349,12 @@ public class CallResolver { Collection constructors = delegateClassDescriptor.getConstructors(); if (!isThisCall && currentClassDescriptor.getUnsubstitutedPrimaryConstructor() != null) { - context.trace.report(PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED.on( - (JetConstructorDelegationCall) calleeExpression.getParent() - )); + if (DescriptorUtils.canHaveDeclaredConstructors(currentClassDescriptor)) { + // Diagnostic is meaningless when reporting on interfaces and object + context.trace.report(PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED.on( + (JetConstructorDelegationCall) calleeExpression.getParent() + )); + } if (call.isImplicit()) return OverloadResolutionResultsImpl.nameNotFound(); } 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 08e3c354257..56da54970f8 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 @@ -275,15 +275,12 @@ public open class LazyClassMemberScope( protected open fun resolvePrimaryConstructor(): ConstructorDescriptor? { 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 classOrObject = ownerInfo.getCorrespondingClassOrObject() ?: return null - if (DescriptorUtils.isTrait(thisDescriptor) && declarationProvider.getOwnerInfo().getPrimaryConstructorParameters().isEmpty()) { - return null - } + val hasPrimaryConstructor = classOrObject.hasExplicitPrimaryConstructor() + if (DescriptorUtils.isTrait(thisDescriptor) && !hasPrimaryConstructor) return null + if (DescriptorUtils.canHaveDeclaredConstructors(thisDescriptor) || hasPrimaryConstructor) { val constructor = c.functionDescriptorResolver.resolvePrimaryConstructorDescriptor( thisDescriptor.getScopeForClassHeaderResolution(), thisDescriptor, classOrObject, trace) constructor ?: return null @@ -298,10 +295,7 @@ public open class LazyClassMemberScope( } private fun resolveSecondaryConstructors(): Collection { - val classOrObject = declarationProvider.getOwnerInfo().getCorrespondingClassOrObject() - if (!DescriptorUtils.canHaveSecondaryConstructors(thisDescriptor)) return emptyList() - // Script classes have usual class descriptors but do not have conventional class body - if (classOrObject !is JetClass) return emptyList() + val classOrObject = declarationProvider.getOwnerInfo().getCorrespondingClassOrObject() ?: return emptyList() return classOrObject.getSecondaryConstructors().map { constructor -> val descriptor = c.functionDescriptorResolver.resolveSecondaryConstructorDescriptor( diff --git a/compiler/testData/diagnostics/tests/ObjectWithConstructor.kt b/compiler/testData/diagnostics/tests/ObjectWithConstructor.kt new file mode 100644 index 00000000000..59e91dd0898 --- /dev/null +++ b/compiler/testData/diagnostics/tests/ObjectWithConstructor.kt @@ -0,0 +1,24 @@ +object A1() { + constructor(x: Int = "", y: Int) : this() { + x + y + } +} + +object A2 public constructor(private val prop: Int) { + constructor(x: Int = "", y: Int) : this(x * y) { + x + y + } +} + +val x = object (val prop: Int) { + constructor() : this(1) { + val x = 1 + x * x + } +} + +class A3 { + companion object B(val prop: Int) { + public constructor() : this(2) + } +} diff --git a/compiler/testData/diagnostics/tests/ObjectWithConstructor.txt b/compiler/testData/diagnostics/tests/ObjectWithConstructor.txt new file mode 100644 index 00000000000..c3c7a4e0ef6 --- /dev/null +++ b/compiler/testData/diagnostics/tests/ObjectWithConstructor.txt @@ -0,0 +1,36 @@ +package + +internal val x: kotlin.Any + +internal object A1 { + private constructor A1() + private constructor A1(/*0*/ x: kotlin.Int = ..., /*1*/ y: 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 +} + +internal object A2 { + public constructor A2(/*0*/ prop: kotlin.Int) + private constructor A2(/*0*/ x: kotlin.Int = ..., /*1*/ y: kotlin.Int) + private final val prop: 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 +} + +internal final class A3 { + public constructor A3() + 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 companion object B { + public constructor B() + private constructor B(/*0*/ prop: kotlin.Int) + internal final val prop: 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/diagnostics/tests/SupertypeListChecks.txt b/compiler/testData/diagnostics/tests/SupertypeListChecks.txt index b4b45748e86..514d6bf8f80 100644 --- a/compiler/testData/diagnostics/tests/SupertypeListChecks.txt +++ b/compiler/testData/diagnostics/tests/SupertypeListChecks.txt @@ -83,6 +83,7 @@ internal interface T2 { } internal interface Test { + 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 diff --git a/compiler/testData/diagnostics/tests/TraitWithConstructor.kt b/compiler/testData/diagnostics/tests/TraitWithConstructor.kt index 5d8be591152..e2f5807c6ed 100644 --- a/compiler/testData/diagnostics/tests/TraitWithConstructor.kt +++ b/compiler/testData/diagnostics/tests/TraitWithConstructor.kt @@ -1,14 +1,16 @@ +// !DIAGNOSTICS: -MISSING_CONSTRUCTOR_KEYWORD + class C(val a: String) {} interface T1(val x: String) {} -interface T2() {} +interface T2 constructor() {} interface T3 private constructor(a: Int) {} interface T4 { - constructor(a: Int) { - val b: Int = 1 + constructor(a: Int) { + val b: Int = 1 } } diff --git a/compiler/testData/diagnostics/tests/TraitWithConstructor.txt b/compiler/testData/diagnostics/tests/TraitWithConstructor.txt index 22c5b532d11..9d247a299f5 100644 --- a/compiler/testData/diagnostics/tests/TraitWithConstructor.txt +++ b/compiler/testData/diagnostics/tests/TraitWithConstructor.txt @@ -17,6 +17,7 @@ internal interface T1 { } internal interface T2 { + public constructor 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 @@ -30,18 +31,21 @@ internal interface T3 { } internal interface T4 { + public constructor T4(/*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 } internal interface T5 : T4 { + private constructor T5() 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 interface T6 : T5 { + private constructor T6() 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/diagnostics/tests/secondaryConstructors/constructorInObject.txt b/compiler/testData/diagnostics/tests/secondaryConstructors/constructorInObject.txt index d00ae6ea107..f0684aa7a78 100644 --- a/compiler/testData/diagnostics/tests/secondaryConstructors/constructorInObject.txt +++ b/compiler/testData/diagnostics/tests/secondaryConstructors/constructorInObject.txt @@ -3,6 +3,7 @@ package internal val anonObject: kotlin.Any internal object A { + private constructor A() private constructor A() public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int @@ -11,6 +12,7 @@ internal object A { internal final enum class B : kotlin.Enum { public enum entry X : B { + private constructor X() private constructor X() public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: B): kotlin.Int public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean @@ -40,6 +42,7 @@ internal final class C { public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String internal companion object Companion { + private constructor Companion() private constructor Companion() public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int diff --git a/compiler/testData/diagnostics/tests/secondaryConstructors/constructorInTrait.txt b/compiler/testData/diagnostics/tests/secondaryConstructors/constructorInTrait.txt index d867f9e6a23..5ba251de3e9 100644 --- a/compiler/testData/diagnostics/tests/secondaryConstructors/constructorInTrait.txt +++ b/compiler/testData/diagnostics/tests/secondaryConstructors/constructorInTrait.txt @@ -1,6 +1,7 @@ package internal interface A { + public constructor A() 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/diagnostics/tests/traitWithRequired/traitSupertypeList.kt b/compiler/testData/diagnostics/tests/traitWithRequired/traitSupertypeList.kt index 219d5b6ff57..af9ead46dec 100644 --- a/compiler/testData/diagnostics/tests/traitWithRequired/traitSupertypeList.kt +++ b/compiler/testData/diagnostics/tests/traitWithRequired/traitSupertypeList.kt @@ -6,5 +6,5 @@ interface Foo() : barbar, Foo { } -open class Foo1() : bar(), bar, Foo, Foo() {} +open class Foo1() : bar(), bar, Foo, Foo() {} open class Foo12 : bar(), bar {} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/traitWithRequired/traitSupertypeList.txt b/compiler/testData/diagnostics/tests/traitWithRequired/traitSupertypeList.txt index 451d0ab9a09..63e3f5635c8 100644 --- a/compiler/testData/diagnostics/tests/traitWithRequired/traitSupertypeList.txt +++ b/compiler/testData/diagnostics/tests/traitWithRequired/traitSupertypeList.txt @@ -1,6 +1,7 @@ package internal interface Foo : bar, bar, bar { + public constructor Foo() 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/renderer/ObjectWithConstructor.kt b/compiler/testData/renderer/ObjectWithConstructor.kt new file mode 100644 index 00000000000..0e3d2f9f331 --- /dev/null +++ b/compiler/testData/renderer/ObjectWithConstructor.kt @@ -0,0 +1,35 @@ +object A1() { + constructor(x: Int = "", y: Int) : this() { + x + y + } +} + +object A2 public constructor(private val prop: Int) { + constructor(x: Int = "", y: Int) : this(x * y) { + x + y + } +} + +class A3 { + companion object B(val prop: Int) { + public constructor() : this(2) + } +} + +//internal object A1 defined in root package +//private constructor A1() defined in A1 +//private constructor A1(x: kotlin.Int = ..., y: kotlin.Int) defined in A1 +//value-parameter val x: kotlin.Int = ... defined in A1. +//value-parameter val y: kotlin.Int defined in A1. +//internal object A2 defined in root package +//public constructor A2(prop: kotlin.Int) defined in A2 +//value-parameter val prop: kotlin.Int defined in A2. +//private constructor A2(x: kotlin.Int = ..., y: kotlin.Int) defined in A2 +//value-parameter val x: kotlin.Int = ... defined in A2. +//value-parameter val y: kotlin.Int defined in A2. +//internal final class A3 defined in root package +//public constructor A3() defined in A3 +//internal companion object defined in A3 +//private constructor B(prop: kotlin.Int) defined in A3.B +//value-parameter val prop: kotlin.Int defined in A3.B. +//public constructor B() defined in A3.B diff --git a/compiler/testData/renderer/TraitWithConstructor.kt b/compiler/testData/renderer/TraitWithConstructor.kt new file mode 100644 index 00000000000..0b3d856a72e --- /dev/null +++ b/compiler/testData/renderer/TraitWithConstructor.kt @@ -0,0 +1,23 @@ +trait A1() { + constructor(x: Int = "", y: Int) : this() { + x + y + } +} + +trait A2 private constructor(private val prop: Int) { + constructor(x: Int = "", y: Int) : this(x * y) { + x + y + } +} + +//internal interface A1 defined in root package +//public constructor A1() defined in A1 +//public constructor A1(x: kotlin.Int = ..., y: kotlin.Int) defined in A1 +//value-parameter val x: kotlin.Int = ... defined in A1. +//value-parameter val y: kotlin.Int defined in A1. +//internal interface A2 defined in root package +//private constructor A2(prop: kotlin.Int) defined in A2 +//value-parameter val prop: kotlin.Int defined in A2. +//public constructor A2(x: kotlin.Int = ..., y: kotlin.Int) defined in A2 +//value-parameter val x: kotlin.Int = ... defined in A2. +//value-parameter val y: kotlin.Int defined in A2. diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index 922b765458c..18ef31fa22f 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -325,6 +325,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("ObjectWithConstructor.kt") + public void testObjectWithConstructor() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/ObjectWithConstructor.kt"); + doTest(fileName); + } + @TestMetadata("OverrideFunctionWithParamDefaultValue.kt") public void testOverrideFunctionWithParamDefaultValue() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/OverrideFunctionWithParamDefaultValue.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/renderer/AbstractDescriptorRendererTest.kt b/compiler/tests/org/jetbrains/kotlin/renderer/AbstractDescriptorRendererTest.kt index d520216f507..a9c9a21aa68 100644 --- a/compiler/tests/org/jetbrains/kotlin/renderer/AbstractDescriptorRendererTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/renderer/AbstractDescriptorRendererTest.kt @@ -105,7 +105,7 @@ public abstract class AbstractDescriptorRendererTest : KotlinTestWithEnvironment descriptors.add(descriptor) if (descriptor is ClassDescriptor) { // if class has primary constructor then we visit it later, otherwise add it artificially - if (element !is JetClass || !element.hasExplicitPrimaryConstructor()) { + if (element !is JetClassOrObject || !element.hasExplicitPrimaryConstructor()) { if (descriptor.getUnsubstitutedPrimaryConstructor() != null) { descriptors.add(descriptor.getUnsubstitutedPrimaryConstructor()) } diff --git a/compiler/tests/org/jetbrains/kotlin/renderer/DescriptorRendererTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/renderer/DescriptorRendererTestGenerated.java index f0d21c03903..7ca6b57382f 100644 --- a/compiler/tests/org/jetbrains/kotlin/renderer/DescriptorRendererTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/renderer/DescriptorRendererTestGenerated.java @@ -89,12 +89,24 @@ public class DescriptorRendererTestGenerated extends AbstractDescriptorRendererT doTest(fileName); } + @TestMetadata("ObjectWithConstructor.kt") + public void testObjectWithConstructor() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/renderer/ObjectWithConstructor.kt"); + doTest(fileName); + } + @TestMetadata("StarProjection.kt") public void testStarProjection() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/renderer/StarProjection.kt"); doTest(fileName); } + @TestMetadata("TraitWithConstructor.kt") + public void testTraitWithConstructor() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/renderer/TraitWithConstructor.kt"); + doTest(fileName); + } + @TestMetadata("UnitType.kt") public void testUnitType() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/renderer/UnitType.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java index d0e00fc178e..9ace3331f65 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java @@ -507,7 +507,7 @@ public class DescriptorUtils { return classDescriptor.getKind().isSingleton() || isAnonymousObject(classDescriptor); } - public static boolean canHaveSecondaryConstructors(@NotNull ClassDescriptor classDescriptor) { + public static boolean canHaveDeclaredConstructors(@NotNull ClassDescriptor classDescriptor) { return !isSingletonOrAnonymousObject(classDescriptor) && !isTrait(classDescriptor); } diff --git a/idea/testData/checker/TraitSupertypeList.kt b/idea/testData/checker/TraitSupertypeList.kt index 4bc79467c92..4d0411e6305 100644 --- a/idea/testData/checker/TraitSupertypeList.kt +++ b/idea/testData/checker/TraitSupertypeList.kt @@ -6,5 +6,5 @@ interface Foo() : bar(), bar, Foo { } -open class Foo1() : bar(), bar, Foo, Foo() {} +open class Foo1() : bar(), bar, Foo, Foo() {} open class Foo12 : bar(), bar {} \ No newline at end of file