diff --git a/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/output/output.kt b/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/output/output.kt index ad1d0b2c733..1fc1aeec9a3 100644 --- a/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/output/output.kt +++ b/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/output/output.kt @@ -33,8 +33,6 @@ public interface OutputFile { public val sourceFiles: List public fun asByteArray(): ByteArray public fun asText(): String - - override fun toString() = "$relativePath (compiled from $sourceFiles)" } public class SimpleOutputFile( @@ -44,4 +42,6 @@ public class SimpleOutputFile( ) : OutputFile { override fun asByteArray(): ByteArray = content.toByteArray() override fun asText(): String = content + + override fun toString() = "$relativePath (compiled from $sourceFiles)" } \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index c950824329e..3829fac7f80 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -217,6 +217,7 @@ public interface Errors { .create(WARNING, ABSTRACT_MODIFIER); DiagnosticFactory0 CONSTRUCTOR_IN_TRAIT = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE); + DiagnosticFactory0 METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 SUPERTYPE_INITIALIZED_IN_TRAIT = DiagnosticFactory0.create(ERROR); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index 14e5e7b419c..eda027aae88 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -439,6 +439,7 @@ public class DefaultErrorMessages { MAP.put(SUPERTYPE_INITIALIZED_IN_TRAIT, "Interfaces cannot initialize supertypes"); MAP.put(CLASS_IN_SUPERTYPE_FOR_ENUM, "Enum class cannot inherit from classes"); MAP.put(CONSTRUCTOR_IN_TRAIT, "An interface may not have a constructor"); + MAP.put(METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE, "An interface may not implement a method of 'kotlin.Any'"); MAP.put(TRAIT_WITH_SUPERCLASS, "An interface cannot inherit from a class"); MAP.put(SUPERTYPE_APPEARS_TWICE, "A supertype appears twice"); MAP.put(FINAL_SUPERTYPE, "This type is final, so it cannot be inherited from"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java index 4a746b72333..36c2d85cfd0 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.resolve; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Multimap; import com.google.common.collect.Sets; import com.intellij.psi.PsiElement; @@ -288,7 +289,8 @@ public class DeclarationsChecker { checkTypeParameterConstraints(aClass); if (aClass.isInterface()) { - checkConstructorInTrait(aClass); + checkConstructorInInterface(aClass); + checkMethodsOfAnyInInterface(classDescriptor); if (aClass.isLocal() && !(classDescriptor.getContainingDeclaration() instanceof ClassDescriptor)) { trace.report(LOCAL_INTERFACE_NOT_ALLOWED.on(aClass, classDescriptor)); } @@ -367,13 +369,71 @@ public class DeclarationsChecker { return false; } - private void checkConstructorInTrait(JetClass klass) { + private void checkConstructorInInterface(JetClass klass) { JetPrimaryConstructor primaryConstructor = klass.getPrimaryConstructor(); if (primaryConstructor != null) { trace.report(CONSTRUCTOR_IN_TRAIT.on(primaryConstructor)); } } + private void checkMethodsOfAnyInInterface(ClassDescriptorWithResolutionScopes classDescriptor) { + for (CallableMemberDescriptor declaredCallableMember : classDescriptor.getDeclaredCallableMembers()) { + if (!(declaredCallableMember instanceof FunctionDescriptor)) continue; + FunctionDescriptor functionDescriptor = (FunctionDescriptor) declaredCallableMember; + + PsiElement declaration = DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor); + if (!(declaration instanceof JetNamedFunction)) continue; + JetNamedFunction functionDeclaration = (JetNamedFunction) declaration; + + if (isHidingParentMemberIfPresent(declaredCallableMember)) continue; + + if (isImplementingMethodOfAny(declaredCallableMember)) { + trace.report(METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE.on(functionDeclaration)); + } + } + } + + private static final Set METHOD_OF_ANY_NAMES = ImmutableSet.of("toString", "hashCode", "equals"); + + private static boolean isImplementingMethodOfAny(CallableMemberDescriptor member) { + if (!METHOD_OF_ANY_NAMES.contains(member.getName().asString())) return false; + if (member.getModality() == Modality.ABSTRACT) return false; + + return isImplementingMethodOfAnyInternal(member, new HashSet()); + } + + private static boolean isImplementingMethodOfAnyInternal(CallableMemberDescriptor member, Set visitedClasses) { + for (CallableMemberDescriptor overridden : member.getOverriddenDescriptors()) { + DeclarationDescriptor containingDeclaration = overridden.getContainingDeclaration(); + if (!(containingDeclaration instanceof ClassDescriptor)) continue; + ClassDescriptor containingClass = (ClassDescriptor) containingDeclaration; + if (visitedClasses.contains(containingClass)) continue; + + if (DescriptorUtils.getFqName(containingClass).equals(KotlinBuiltIns.FQ_NAMES.any)) { + return true; + } + + if (isHidingParentMemberIfPresent(overridden)) continue; + + visitedClasses.add(containingClass); + + if (isImplementingMethodOfAnyInternal(overridden, visitedClasses)) { + return true; + } + } + + return false; + } + + private static boolean isHidingParentMemberIfPresent(CallableMemberDescriptor member) { + JetNamedDeclaration declaration = (JetNamedDeclaration) DescriptorToSourceUtils.descriptorToDeclaration(member); + if (declaration != null) { + JetModifierList modifierList = declaration.getModifierList(); + return modifierList == null || !modifierList.hasModifier(JetTokens.OVERRIDE_KEYWORD); + } + return false; + } + private void checkAnnotationClassWithBody(JetClassOrObject classOrObject) { if (classOrObject.getBody() != null) { trace.report(ANNOTATION_CLASS_WITH_BODY.on(classOrObject.getBody())); diff --git a/compiler/testData/codegen/box/classes/kt285.kt b/compiler/testData/codegen/box/classes/kt285.kt index 514d086e8d3..945b250f7dc 100644 --- a/compiler/testData/codegen/box/classes/kt285.kt +++ b/compiler/testData/codegen/box/classes/kt285.kt @@ -1,12 +1,15 @@ interface Trait { fun foo() = "O" - override fun toString() = "K" + fun bar(): String } -class SimpleClass : Trait +class SimpleClass : Trait { + override fun bar() = "K" +} +// Delegating 'toString' doesn't work, see KT-9519 class ComplexClass : Trait by SimpleClass() { - override fun toString() = foo() + super.toString() + fun qux() = foo() + bar() } -fun box() = ComplexClass().toString() +fun box() = ComplexClass().qux() diff --git a/compiler/testData/codegen/box/super/unqualifiedSuperWithMethodsOfAny.kt b/compiler/testData/codegen/box/super/unqualifiedSuperWithMethodsOfAny.kt index 90faa3a9a69..b0eb1ec0d01 100644 --- a/compiler/testData/codegen/box/super/unqualifiedSuperWithMethodsOfAny.kt +++ b/compiler/testData/codegen/box/super/unqualifiedSuperWithMethodsOfAny.kt @@ -8,10 +8,6 @@ interface IWithToString { override fun toString(): String } -interface IWithDefaultToString { - override fun toString(): String = "I" -} - class C1 : ClassWithToString(), ISomething { override fun toString(): String = super.toString() } @@ -20,15 +16,10 @@ class C2 : ClassWithToString(), IWithToString, ISomething { override fun toString(): String = super.toString() } -class C3 : IWithDefaultToString, ISomething { - override fun toString(): String = super.toString() -} - fun box(): String { return when { C1().toString() != "C" -> "Failed #1" C2().toString() != "C" -> "Failed #2" - C3().toString() != "I" -> "Failed #3" else -> "OK" } } \ No newline at end of file diff --git a/compiler/testData/codegen/box/traits/kt5393_toString.kt b/compiler/testData/codegen/box/traits/kt5393_toString.kt deleted file mode 100644 index 42bf45ced97..00000000000 --- a/compiler/testData/codegen/box/traits/kt5393_toString.kt +++ /dev/null @@ -1,15 +0,0 @@ -interface A { - override fun toString(): String { - return "OK" - } -} - -interface B : A - -class C : B { - override fun toString(): String { - return super.toString() - } -} - -fun box() = "${C()}" diff --git a/compiler/testData/codegen/boxInline/builders/builders.2.kt b/compiler/testData/codegen/boxInline/builders/builders.2.kt index cb4bc6eac25..2b498347798 100644 --- a/compiler/testData/codegen/boxInline/builders/builders.2.kt +++ b/compiler/testData/codegen/boxInline/builders/builders.2.kt @@ -3,8 +3,8 @@ package builders import java.util.ArrayList import java.util.HashMap -interface Element { - fun render(builder: StringBuilder, indent: String) +abstract class Element { + abstract fun render(builder: StringBuilder, indent: String) override fun toString(): String { val builder = StringBuilder() @@ -13,13 +13,13 @@ interface Element { } } -class TextElement(val text: String) : Element { +class TextElement(val text: String) : Element() { override fun render(builder: StringBuilder, indent: String) { builder.append("$indent$text\n") } } -abstract class Tag(val name: String) : Element { +abstract class Tag(val name: String) : Element() { val children = ArrayList() val attributes = HashMap() diff --git a/compiler/testData/codegen/boxInline/builders/buildersAndLambdaCapturing.2.kt b/compiler/testData/codegen/boxInline/builders/buildersAndLambdaCapturing.2.kt index 2fc26f262e8..917b4ae720e 100644 --- a/compiler/testData/codegen/boxInline/builders/buildersAndLambdaCapturing.2.kt +++ b/compiler/testData/codegen/boxInline/builders/buildersAndLambdaCapturing.2.kt @@ -3,8 +3,8 @@ package builders import java.util.ArrayList import java.util.HashMap -interface Element { - fun render(builder: StringBuilder, indent: String) +abstract class Element { + abstract fun render(builder: StringBuilder, indent: String) override fun toString(): String { val builder = StringBuilder() @@ -13,13 +13,13 @@ interface Element { } } -class TextElement(val text: String) : Element { +class TextElement(val text: String) : Element() { override fun render(builder: StringBuilder, indent: String) { builder.append("$indent$text\n") } } -abstract class Tag(val name: String) : Element { +abstract class Tag(val name: String) : Element() { val children = ArrayList() val attributes = HashMap() diff --git a/compiler/testData/codegen/boxWithStdlib/dataClasses/tostring/alreadyInherited.kt b/compiler/testData/codegen/boxWithStdlib/dataClasses/tostring/alreadyInherited.kt index 52cefe0fa66..cc4b0195b07 100644 --- a/compiler/testData/codegen/boxWithStdlib/dataClasses/tostring/alreadyInherited.kt +++ b/compiler/testData/codegen/boxWithStdlib/dataClasses/tostring/alreadyInherited.kt @@ -1,8 +1,8 @@ -interface SuperTrait { +abstract class SuperTrait { override fun toString(): String = "!" } -data class A(val x: Int): SuperTrait { +data class A(val x: Int): SuperTrait() { } fun box(): String { diff --git a/compiler/testData/diagnostics/tests/Builders.kt b/compiler/testData/diagnostics/tests/Builders.kt index 943688bfb49..b3bfbf4bf99 100644 --- a/compiler/testData/diagnostics/tests/Builders.kt +++ b/compiler/testData/diagnostics/tests/Builders.kt @@ -49,8 +49,8 @@ fun main(args : Array) { println(result) } -interface Element { - fun render(builder : StringBuilder, indent : String) +abstract class Element { + abstract fun render(builder : StringBuilder, indent : String) override fun toString() : String { val builder = StringBuilder() @@ -59,13 +59,13 @@ interface Element { } } -class TextElement(val text : String) : Element { +class TextElement(val text : String) : Element() { override fun render(builder : StringBuilder, indent : String) { builder.append("$indent$text\n") } } -abstract class Tag(val name : String) : Element { +abstract class Tag(val name : String) : Element() { val children = ArrayList() val attributes = HashMap() diff --git a/compiler/testData/diagnostics/tests/Builders.txt b/compiler/testData/diagnostics/tests/Builders.txt index bad460e67db..a25fe43ffce 100644 --- a/compiler/testData/diagnostics/tests/Builders.txt +++ b/compiler/testData/diagnostics/tests/Builders.txt @@ -84,7 +84,8 @@ package html { public final override /*1*/ /*fake_override*/ fun kotlin.String.plus(): kotlin.Unit } - public interface Element { + public abstract class Element { + public constructor Element() 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 abstract fun render(/*0*/ builder: java.lang.StringBuilder, /*1*/ indent: kotlin.String): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/java8Overrides/hidingMethodOfAny.kt b/compiler/testData/diagnostics/tests/java8Overrides/hidingMethodOfAny.kt new file mode 100644 index 00000000000..b472b0df38b --- /dev/null +++ b/compiler/testData/diagnostics/tests/java8Overrides/hidingMethodOfAny.kt @@ -0,0 +1,5 @@ +interface IA { + fun toString(): String = "IB" + + override fun equals(other: Any?): Boolean +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/java8Overrides/hidingMethodOfAny.txt b/compiler/testData/diagnostics/tests/java8Overrides/hidingMethodOfAny.txt new file mode 100644 index 00000000000..097e1881d15 --- /dev/null +++ b/compiler/testData/diagnostics/tests/java8Overrides/hidingMethodOfAny.txt @@ -0,0 +1,7 @@ +package + +public interface IA { + public abstract override /*1*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/java8Overrides/implementingMethodOfAny.kt b/compiler/testData/diagnostics/tests/java8Overrides/implementingMethodOfAny.kt new file mode 100644 index 00000000000..4f5a06bb33b --- /dev/null +++ b/compiler/testData/diagnostics/tests/java8Overrides/implementingMethodOfAny.kt @@ -0,0 +1,9 @@ +interface IA { + override fun toString(): String = "IA" + + override fun equals(other: Any?): Boolean = super.equals(other) + + override fun hashCode(): Int { + return 42; + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/java8Overrides/implementingMethodOfAny.txt b/compiler/testData/diagnostics/tests/java8Overrides/implementingMethodOfAny.txt new file mode 100644 index 00000000000..103564d9b2d --- /dev/null +++ b/compiler/testData/diagnostics/tests/java8Overrides/implementingMethodOfAny.txt @@ -0,0 +1,7 @@ +package + +public interface IA { + public open override /*1*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ fun hashCode(): kotlin.Int + public open override /*1*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/java8Overrides/notAMethodOfAny.kt b/compiler/testData/diagnostics/tests/java8Overrides/notAMethodOfAny.kt new file mode 100644 index 00000000000..3c918e0f098 --- /dev/null +++ b/compiler/testData/diagnostics/tests/java8Overrides/notAMethodOfAny.kt @@ -0,0 +1,3 @@ +interface IC { + fun toString(x: String): String = "IC$x" +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/java8Overrides/notAMethodOfAny.txt b/compiler/testData/diagnostics/tests/java8Overrides/notAMethodOfAny.txt new file mode 100644 index 00000000000..6175784b753 --- /dev/null +++ b/compiler/testData/diagnostics/tests/java8Overrides/notAMethodOfAny.txt @@ -0,0 +1,8 @@ +package + +public interface IC { + 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 fun toString(/*0*/ x: kotlin.String): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/java8Overrides/overridingMethodOfAnyChain.kt b/compiler/testData/diagnostics/tests/java8Overrides/overridingMethodOfAnyChain.kt new file mode 100644 index 00000000000..15a455488ad --- /dev/null +++ b/compiler/testData/diagnostics/tests/java8Overrides/overridingMethodOfAnyChain.kt @@ -0,0 +1,13 @@ +interface IA + +interface IB : IA { + override fun toString(): String = "IB" +} + +interface IC : IB { + override fun toString(): String = "IC" +} + +interface ID : IC { + override fun toString(): String = "ID" +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withMethodOfAnyImplementedInSuperInterface.txt b/compiler/testData/diagnostics/tests/java8Overrides/overridingMethodOfAnyChain.txt similarity index 68% rename from compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withMethodOfAnyImplementedInSuperInterface.txt rename to compiler/testData/diagnostics/tests/java8Overrides/overridingMethodOfAnyChain.txt index 70c761c75b5..9506a4fb477 100644 --- a/compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withMethodOfAnyImplementedInSuperInterface.txt +++ b/compiler/testData/diagnostics/tests/java8Overrides/overridingMethodOfAnyChain.txt @@ -1,19 +1,24 @@ package -public interface 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*/ fun toString(): kotlin.String -} - -public interface B : A { +public interface IA { 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 C : B { - public constructor C() +public interface IB : IA { + 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*/ fun toString(): kotlin.String +} + +public interface IC : IB { + 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*/ fun toString(): kotlin.String +} + +public interface ID : IC { 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*/ fun toString(): kotlin.String diff --git a/compiler/testData/diagnostics/tests/java8Overrides/overridingMethodOfAnyDiamond.kt b/compiler/testData/diagnostics/tests/java8Overrides/overridingMethodOfAnyDiamond.kt new file mode 100644 index 00000000000..ddffaeddf01 --- /dev/null +++ b/compiler/testData/diagnostics/tests/java8Overrides/overridingMethodOfAnyDiamond.kt @@ -0,0 +1,11 @@ +interface ILeft { + override fun toString(): String +} + +interface IRight { + override fun toString(): String +} + +interface IDiamond : ILeft, IRight { + override fun toString(): String = "IDiamond" +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withAmbiguousMethodOfAny.txt b/compiler/testData/diagnostics/tests/java8Overrides/overridingMethodOfAnyDiamond.txt similarity index 73% rename from compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withAmbiguousMethodOfAny.txt rename to compiler/testData/diagnostics/tests/java8Overrides/overridingMethodOfAnyDiamond.txt index 10c13b0b08a..237f01e3b95 100644 --- a/compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withAmbiguousMethodOfAny.txt +++ b/compiler/testData/diagnostics/tests/java8Overrides/overridingMethodOfAnyDiamond.txt @@ -1,20 +1,19 @@ package -public final class C : IA, IB { - public constructor C() +public interface IDiamond : ILeft, IRight { public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*2*/ fun toString(): kotlin.String } -public interface IA { +public interface ILeft { 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*/ fun toString(): kotlin.String + public abstract override /*1*/ fun toString(): kotlin.String } -public interface IB { +public interface IRight { 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*/ fun toString(): kotlin.String + public abstract override /*1*/ fun toString(): kotlin.String } diff --git a/compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withAmbiguousMethodOfAny.kt b/compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withAmbiguousMethodOfAny.kt deleted file mode 100644 index e4c511db505..00000000000 --- a/compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withAmbiguousMethodOfAny.kt +++ /dev/null @@ -1,12 +0,0 @@ -interface IA { - override fun toString(): String = "IA" -} - -interface IB { - override fun toString(): String = "IB" -} - -class C : IA, IB { - override fun toString(): String = - super.toString() -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withMethodOfAnyImplementedInSuperInterface.kt b/compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withMethodOfAnyImplementedInSuperInterface.kt deleted file mode 100644 index 84ef5bbc1ed..00000000000 --- a/compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withMethodOfAnyImplementedInSuperInterface.kt +++ /dev/null @@ -1,12 +0,0 @@ -interface A { - override fun toString(): String { - return "OK" - } -} - -interface B : A - -class C : B { - override fun toString(): String = - super.toString() -} diff --git a/compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withMethodOfAnyOverridenInInterface.kt b/compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withMethodOfAnyOverridenInInterface.kt index bb9f295dae7..ba5f4f70298 100644 --- a/compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withMethodOfAnyOverridenInInterface.kt +++ b/compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withMethodOfAnyOverridenInInterface.kt @@ -5,12 +5,4 @@ interface IWithToString { class A : IWithToString { // Should be Any#toString(), even though IWithToString defines an abstract toString. override fun toString(): String = super.toString() -} - -interface IWithImplementedToString { - override fun toString(): String = "Heh" -} - -class B : IWithImplementedToString { - override fun toString(): String = super.toString() -} +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withMethodOfAnyOverridenInInterface.txt b/compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withMethodOfAnyOverridenInInterface.txt index a353d0ecffb..5f7526c8e1b 100644 --- a/compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withMethodOfAnyOverridenInInterface.txt +++ b/compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withMethodOfAnyOverridenInInterface.txt @@ -7,19 +7,6 @@ public final class A : IWithToString { public open override /*1*/ fun toString(): kotlin.String } -public final class B : IWithImplementedToString { - public constructor B() - 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*/ fun toString(): kotlin.String -} - -public interface IWithImplementedToString { - 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*/ fun toString(): kotlin.String -} - public interface IWithToString { 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/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index 2c27deef057..3e5d6e79b4e 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -9184,57 +9184,66 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { } } - @TestMetadata("compiler/testData/diagnostics/tests/jdk-annotations") + @TestMetadata("compiler/testData/diagnostics/tests/java8Overrides") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) - public static class Jdk_annotations extends AbstractJetDiagnosticsTest { - public void testAllFilesPresentInJdk_annotations() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/jdk-annotations"), Pattern.compile("^(.+)\\.kt$"), true); - } - - @TestMetadata("ArrayListAndMap.kt") - public void testArrayListAndMap() throws Exception { - String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/jdk-annotations/ArrayListAndMap.kt"); + public static class Java8Overrides extends AbstractJetDiagnosticsTest { + @TestMetadata("abstractBaseClassMemberNotImplemented.kt") + public void testAbstractBaseClassMemberNotImplemented() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/java8Overrides/abstractBaseClassMemberNotImplemented.kt"); doTest(fileName); } - @TestMetadata("ArrayListClone.kt") - public void testArrayListClone() throws Exception { - String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/jdk-annotations/ArrayListClone.kt"); + @TestMetadata("abstractVsAbstract.kt") + public void testAbstractVsAbstract() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/java8Overrides/abstractVsAbstract.kt"); doTest(fileName); } - @TestMetadata("ArrayListToArray.kt") - public void testArrayListToArray() throws Exception { - String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/jdk-annotations/ArrayListToArray.kt"); + public void testAllFilesPresentInJava8Overrides() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/java8Overrides"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("defaultVsAbstract.kt") + public void testDefaultVsAbstract() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/java8Overrides/defaultVsAbstract.kt"); doTest(fileName); } - @TestMetadata("compiler/testData/diagnostics/tests/jdk-annotations/sql") - @TestDataPath("$PROJECT_ROOT") - @RunWith(JUnit3RunnerWithInners.class) - public static class Sql extends AbstractJetDiagnosticsTest { - public void testAllFilesPresentInSql() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/jdk-annotations/sql"), Pattern.compile("^(.+)\\.kt$"), true); - } + @TestMetadata("hidingMethodOfAny.kt") + public void testHidingMethodOfAny() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/java8Overrides/hidingMethodOfAny.kt"); + doTest(fileName); + } - @TestMetadata("DriverManager.kt") - public void testDriverManager() throws Exception { - String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/jdk-annotations/sql/DriverManager.kt"); - doTest(fileName); - } + @TestMetadata("implementingMethodOfAny.kt") + public void testImplementingMethodOfAny() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/java8Overrides/implementingMethodOfAny.kt"); + doTest(fileName); + } - @TestMetadata("ResultSet.kt") - public void testResultSet() throws Exception { - String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/jdk-annotations/sql/ResultSet.kt"); - doTest(fileName); - } + @TestMetadata("notAMethodOfAny.kt") + public void testNotAMethodOfAny() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/java8Overrides/notAMethodOfAny.kt"); + doTest(fileName); + } - @TestMetadata("Statement.kt") - public void testStatement() throws Exception { - String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/jdk-annotations/sql/Statement.kt"); - doTest(fileName); - } + @TestMetadata("overridingMethodOfAnyChain.kt") + public void testOverridingMethodOfAnyChain() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/java8Overrides/overridingMethodOfAnyChain.kt"); + doTest(fileName); + } + + @TestMetadata("overridingMethodOfAnyDiamond.kt") + public void testOverridingMethodOfAnyDiamond() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/java8Overrides/overridingMethodOfAnyDiamond.kt"); + doTest(fileName); + } + + @TestMetadata("singleRelevantDefault.kt") + public void testSingleRelevantDefault() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/java8Overrides/singleRelevantDefault.kt"); + doTest(fileName); } } @@ -15668,18 +15677,6 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } - @TestMetadata("withAmbiguousMethodOfAny.kt") - public void testWithAmbiguousMethodOfAny() throws Exception { - String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withAmbiguousMethodOfAny.kt"); - doTest(fileName); - } - - @TestMetadata("withMethodOfAnyImplementedInSuperInterface.kt") - public void testWithMethodOfAnyImplementedInSuperInterface() throws Exception { - String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withMethodOfAnyImplementedInSuperInterface.kt"); - doTest(fileName); - } - @TestMetadata("withMethodOfAnyOverridenInInterface.kt") public void testWithMethodOfAnyOverridenInInterface() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withMethodOfAnyOverridenInInterface.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java index a6cc25b2190..0723ae6dfd4 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -7540,12 +7540,6 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } - @TestMetadata("kt5393_toString.kt") - public void testKt5393_toString() throws Exception { - String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/traits/kt5393_toString.kt"); - doTest(fileName); - } - @TestMetadata("multiple.kt") public void testMultiple() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/traits/multiple.kt"); diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/SamConstructorDescriptor.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/SamConstructorDescriptor.kt index 060d1d52f92..c17e97e63e0 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/SamConstructorDescriptor.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/SamConstructorDescriptor.kt @@ -33,7 +33,7 @@ public class SamConstructorDescriptor( samInterface.getSource() ) -public object SamConstructorDescriptorKindExclude : DescriptorKindExclude { +public object SamConstructorDescriptorKindExclude : DescriptorKindExclude() { override fun excludes(descriptor: DeclarationDescriptor) = descriptor is SamConstructorDescriptor override val fullyExcludedDescriptorKinds: Int get() = 0 diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/JetScope.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/JetScope.kt index e88ba548144..218fd3c9061 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/JetScope.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/JetScope.kt @@ -211,21 +211,21 @@ public class DescriptorKindFilter( } } -public interface DescriptorKindExclude { - public fun excludes(descriptor: DeclarationDescriptor): Boolean +public abstract class DescriptorKindExclude { + public abstract fun excludes(descriptor: DeclarationDescriptor): Boolean - public val fullyExcludedDescriptorKinds: Int + public abstract val fullyExcludedDescriptorKinds: Int override fun toString() = this.javaClass.getSimpleName() - public object Extensions : DescriptorKindExclude { + public object Extensions : DescriptorKindExclude() { override fun excludes(descriptor: DeclarationDescriptor) = descriptor is CallableDescriptor && descriptor.getExtensionReceiverParameter() != null override val fullyExcludedDescriptorKinds: Int get() = 0 } - public object NonExtensions : DescriptorKindExclude { + public object NonExtensions : DescriptorKindExclude() { override fun excludes(descriptor: DeclarationDescriptor) = descriptor !is CallableDescriptor || descriptor.getExtensionReceiverParameter() == null @@ -233,14 +233,14 @@ public interface DescriptorKindExclude { get() = DescriptorKindFilter.ALL_KINDS_MASK and (DescriptorKindFilter.FUNCTIONS_MASK or DescriptorKindFilter.VARIABLES_MASK).inv() } - public object EnumEntry : DescriptorKindExclude { + public object EnumEntry : DescriptorKindExclude() { override fun excludes(descriptor: DeclarationDescriptor) = descriptor is ClassDescriptor && descriptor.getKind() == ClassKind.ENUM_ENTRY override val fullyExcludedDescriptorKinds: Int get() = 0 } - public object TopLevelPackages : DescriptorKindExclude { + public object TopLevelPackages : DescriptorKindExclude() { override fun excludes(descriptor: DeclarationDescriptor): Boolean { val fqName = when (descriptor) { is PackageFragmentDescriptor -> descriptor.fqName diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/CallType.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/CallType.kt index 4b60388cf94..d96df6ccfbf 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/CallType.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/CallType.kt @@ -56,7 +56,7 @@ public sealed class CallType(val descriptorKindFilter: object TYPE : CallType(DescriptorKindFilter(DescriptorKindFilter.CLASSIFIERS_MASK or DescriptorKindFilter.PACKAGES_MASK)) - private object NonInfixExclude : DescriptorKindExclude { + private object NonInfixExclude : DescriptorKindExclude() { //TODO: check 'infix' modifier override fun excludes(descriptor: DeclarationDescriptor) = !(descriptor is SimpleFunctionDescriptor && descriptor.valueParameters.size() == 1) @@ -65,7 +65,7 @@ public sealed class CallType(val descriptorKindFilter: get() = 0 } - private object NonOperatorExclude : DescriptorKindExclude { + private object NonOperatorExclude : DescriptorKindExclude() { override fun excludes(descriptor: DeclarationDescriptor) = !(descriptor is SimpleFunctionDescriptor && descriptor.isOperator) @@ -73,7 +73,7 @@ public sealed class CallType(val descriptorKindFilter: get() = 0 } - private object CallableReferenceExclude : DescriptorKindExclude { + private object CallableReferenceExclude : DescriptorKindExclude() { override fun excludes(descriptor: DeclarationDescriptor) /* currently not supported for locals, synthetic and genetic */ = descriptor !is CallableMemberDescriptor || descriptor.kind == CallableMemberDescriptor.Kind.SYNTHESIZED || descriptor.typeParameters.isNotEmpty() diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicCompletionSession.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicCompletionSession.kt index 047d3fb0bb9..b2c955d279d 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicCompletionSession.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicCompletionSession.kt @@ -397,7 +397,7 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration, } private companion object { - object NonAnnotationClassifierExclude : DescriptorKindExclude { + object NonAnnotationClassifierExclude : DescriptorKindExclude() { override fun excludes(descriptor: DeclarationDescriptor): Boolean { if (descriptor !is ClassifierDescriptor) return false return descriptor !is ClassDescriptor || descriptor.getKind() != ClassKind.ANNOTATION_CLASS diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallInfo.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallInfo.kt index 6d73413b1a2..27d4c1e5d23 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallInfo.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallInfo.kt @@ -40,7 +40,9 @@ interface CallInfo { val extensionReceiver: JsExpression? fun constructSafeCallIsNeeded(result: JsExpression): JsExpression +} +abstract class AbstractCallInfo : CallInfo { override fun toString(): String { val location = DiagnosticUtils.atLocation(callableDescriptor) val name = callableDescriptor.getName().asString() @@ -49,9 +51,9 @@ interface CallInfo { } // if value == null, it is get access -class VariableAccessInfo(callInfo: CallInfo, val value: JsExpression? = null) : CallInfo by callInfo +class VariableAccessInfo(callInfo: CallInfo, val value: JsExpression? = null) : AbstractCallInfo(), CallInfo by callInfo -class FunctionCallInfo(callInfo: CallInfo, val argumentsInfo: CallArgumentTranslator.ArgumentsInfo) : CallInfo by callInfo +class FunctionCallInfo(callInfo: CallInfo, val argumentsInfo: CallArgumentTranslator.ArgumentsInfo) : AbstractCallInfo(), CallInfo by callInfo /** * no receivers - extensionOrDispatchReceiver = null, extensionReceiver = null @@ -146,7 +148,7 @@ private fun TranslationContext.createCallInfo(resolvedCall: ResolvedCall = resolvedCall override val dispatchReceiver: JsExpression? = dispatchReceiver diff --git a/js/js.translator/testData/inlineMultiFile/cases/builders/builders.2.kt b/js/js.translator/testData/inlineMultiFile/cases/builders/builders.2.kt index 18cfaf8c041..88b38dbd239 100644 --- a/js/js.translator/testData/inlineMultiFile/cases/builders/builders.2.kt +++ b/js/js.translator/testData/inlineMultiFile/cases/builders/builders.2.kt @@ -8,8 +8,8 @@ package foo import java.util.ArrayList import java.util.HashMap -interface Element { - fun render(builder: StringBuilder, indent: String) +abstract class Element { + abstract fun render(builder: StringBuilder, indent: String) override fun toString(): String { val builder = StringBuilder() @@ -18,13 +18,13 @@ interface Element { } } -class TextElement(val text: String) : Element { +class TextElement(val text: String) : Element() { override fun render(builder: StringBuilder, indent: String) { builder.append("$indent$text\n") } } -abstract class Tag(val name: String) : Element { +abstract class Tag(val name: String) : Element() { val children = ArrayList() val attributes = HashMap() diff --git a/js/js.translator/testData/inlineMultiFile/cases/buildersAndLambdaCapturing/buildersAndLambdaCapturing.2.kt b/js/js.translator/testData/inlineMultiFile/cases/buildersAndLambdaCapturing/buildersAndLambdaCapturing.2.kt index d27a8e86038..1324303525b 100644 --- a/js/js.translator/testData/inlineMultiFile/cases/buildersAndLambdaCapturing/buildersAndLambdaCapturing.2.kt +++ b/js/js.translator/testData/inlineMultiFile/cases/buildersAndLambdaCapturing/buildersAndLambdaCapturing.2.kt @@ -8,8 +8,8 @@ package foo import java.util.ArrayList import java.util.HashMap -interface Element { - fun render(builder: StringBuilder, indent: String) +abstract class Element { + abstract fun render(builder: StringBuilder, indent: String) override fun toString(): String { val builder = StringBuilder() @@ -18,13 +18,13 @@ interface Element { } } -class TextElement(val text: String) : Element { +class TextElement(val text: String) : Element() { override fun render(builder: StringBuilder, indent: String) { builder.append("$indent$text\n") } } -abstract class Tag(val name: String) : Element { +abstract class Tag(val name: String) : Element() { val children = ArrayList() val attributes = HashMap() diff --git a/js/js.translator/testData/webDemoExamples2/cases/builder.kt b/js/js.translator/testData/webDemoExamples2/cases/builder.kt index 608f9227057..682a5732f64 100644 --- a/js/js.translator/testData/webDemoExamples2/cases/builder.kt +++ b/js/js.translator/testData/webDemoExamples2/cases/builder.kt @@ -45,8 +45,8 @@ fun main(args: Array) { println(result) } -interface Element { - fun render(builder: StringBuilder, indent: String) +abstract class Element { + abstract fun render(builder: StringBuilder, indent: String) override fun toString(): String { val builder = StringBuilder() @@ -55,13 +55,13 @@ interface Element { } } -class TextElement(val text: String) : Element { +class TextElement(val text: String) : Element() { override fun render(builder: StringBuilder, indent: String) { builder.append("$indent$text\n") } } -abstract class Tag(val name: String) : Element { +abstract class Tag(val name: String) : Element() { val children = ArrayList() val attributes = HashMap()