提交 9ce84204 编写于 作者: M Mikhail Glukhikh

FIR: introduce not implemented checker

上级 9ae41f5c
......@@ -16,7 +16,7 @@ abstract class A : C() {
}
}
class B : A() {
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class B<!> : A() {
override fun f() {
}
......
......@@ -39,7 +39,7 @@ public class LightMember<D> : Member<D>, Light() {
override fun getName(): String = "Light"
}
public class LightClassWrapper : Light(), Klass {
public <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class LightClassWrapper<!> : Light(), Klass {
fun test() = typeParameters.single()
}
......
......@@ -291,6 +291,23 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
parameter<Name>("containingClassName")
}
val ABSTRACT_MEMBER_NOT_IMPLEMENTED by error<FirSourceElement, KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
parameter<FirClass<*>>("classOrObject")
parameter<FirCallableDeclaration<*>>("missingDeclaration")
}
val ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED by error<FirSourceElement, KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
parameter<FirClass<*>>("classOrObject")
parameter<FirCallableDeclaration<*>>("missingDeclaration")
}
val MANY_IMPL_MEMBER_NOT_IMPLEMENTED by error<FirSourceElement, KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
parameter<FirClass<*>>("classOrObject")
parameter<FirCallableDeclaration<*>>("missingDeclaration")
}
val MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED by error<FirSourceElement, KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
parameter<FirClass<*>>("classOrObject")
parameter<FirCallableDeclaration<*>>("missingDeclaration")
}
val RETURN_TYPE_MISMATCH_ON_OVERRIDE by error<FirSourceElement, KtNamedDeclaration>(PositioningStrategy.DECLARATION_RETURN_TYPE) {
parameter<FirMemberDeclaration>("function")
parameter<FirMemberDeclaration>("superFunction")
......
......@@ -208,6 +208,10 @@ object FirErrors {
val CANNOT_WEAKEN_ACCESS_PRIVILEGE by error3<FirSourceElement, KtModifierListOwner, Visibility, FirCallableDeclaration<*>, Name>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
val CANNOT_CHANGE_ACCESS_PRIVILEGE by error3<FirSourceElement, KtModifierListOwner, Visibility, FirCallableDeclaration<*>, Name>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
val OVERRIDING_FINAL_MEMBER by error2<FirSourceElement, KtNamedDeclaration, FirCallableDeclaration<*>, Name>(SourceElementPositioningStrategies.OVERRIDE_MODIFIER)
val ABSTRACT_MEMBER_NOT_IMPLEMENTED by error2<FirSourceElement, KtClassOrObject, FirClass<*>, FirCallableDeclaration<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED by error2<FirSourceElement, KtClassOrObject, FirClass<*>, FirCallableDeclaration<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val MANY_IMPL_MEMBER_NOT_IMPLEMENTED by error2<FirSourceElement, KtClassOrObject, FirClass<*>, FirCallableDeclaration<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED by error2<FirSourceElement, KtClassOrObject, FirClass<*>, FirCallableDeclaration<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val RETURN_TYPE_MISMATCH_ON_OVERRIDE by error2<FirSourceElement, KtNamedDeclaration, FirMemberDeclaration, FirMemberDeclaration>(SourceElementPositioningStrategies.DECLARATION_RETURN_TYPE)
val PROPERTY_TYPE_MISMATCH_ON_OVERRIDE by error2<FirSourceElement, KtNamedDeclaration, FirMemberDeclaration, FirMemberDeclaration>(SourceElementPositioningStrategies.DECLARATION_RETURN_TYPE)
val VAR_TYPE_MISMATCH_ON_OVERRIDE by error2<FirSourceElement, KtNamedDeclaration, FirMemberDeclaration, FirMemberDeclaration>(SourceElementPositioningStrategies.DECLARATION_RETURN_TYPE)
......
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.HASHCODE_NAME
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClass
import org.jetbrains.kotlin.fir.analysis.checkers.modality
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.isNullableAny
import org.jetbrains.kotlin.util.OperatorNameConventions
object FirNotImplementedOverrideChecker : FirClassChecker() {
override fun check(declaration: FirClass<*>, context: CheckerContext, reporter: DiagnosticReporter) {
// TODO: kt4763Property: reporting on `object` literal causes invalid error in test...FirDiagnosticHandler
if (declaration !is FirRegularClass) return
val source = declaration.source ?: return
if (source.kind is FirFakeSourceElementKind) return
val modality = declaration.modality()
if (modality == Modality.ABSTRACT || modality == Modality.SEALED) return
if (declaration.isExpect) return
val classKind = declaration.classKind
// TODO: we should check enum entries (probably as anonymous objects, see above)
if (classKind == ClassKind.ANNOTATION_CLASS || classKind == ClassKind.ENUM_CLASS) return
val classScope = declaration.unsubstitutedScope(
context.session, context.sessionHolder.scopeSession, withForcedTypeCalculator = false
)
val notImplementedSymbols = mutableListOf<FirCallableSymbol<*>>()
val classPackage = declaration.symbol.classId.packageFqName
fun FirCallableMemberDeclaration<*>.isInvisible(): Boolean {
if (visibility == Visibilities.Private ||
!visibility.visibleFromPackage(classPackage, symbol.callableId.packageName)
) return true
if (visibility == Visibilities.Internal &&
session !== declaration.session
) return true
return false
}
fun FirCallableMemberDeclaration<*>.shouldBeImplemented(): Boolean {
if (!isAbstract) return false
val containingClass = getContainingClass(context)
if (containingClass === declaration) return false
if (containingClass is FirRegularClass && containingClass.isExpect) return false
return true
}
for (name in classScope.getCallableNames()) {
classScope.processFunctionsByName(name) { namedFunctionSymbol ->
val simpleFunction = namedFunctionSymbol.fir
if (!simpleFunction.shouldBeImplemented()) return@processFunctionsByName
// TODO: private & package-private functions / properties require another diagnostic
// (INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER)
if (simpleFunction.isInvisible()) return@processFunctionsByName
if (declaration.isData && simpleFunction.matchesDataClassSyntheticMemberSignatures) return@processFunctionsByName
// TODO: suspend function overridden by a Java class in the middle is not properly regarded as an override
if (simpleFunction.isSuspend) return@processFunctionsByName
notImplementedSymbols += namedFunctionSymbol
}
classScope.processPropertiesByName(name) { propertySymbol ->
val property = propertySymbol.fir as? FirProperty ?: return@processPropertiesByName
if (!property.shouldBeImplemented()) return@processPropertiesByName
if (property.isInvisible()) return@processPropertiesByName
notImplementedSymbols += propertySymbol
}
}
if (notImplementedSymbols.isNotEmpty()) {
val notImplemented = notImplementedSymbols.first().fir
if (notImplemented.isFromInterface(context)) {
reporter.reportOn(source, FirErrors.ABSTRACT_MEMBER_NOT_IMPLEMENTED, declaration, notImplemented, context)
} else {
reporter.reportOn(source, FirErrors.ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED, declaration, notImplemented, context)
}
}
}
private fun FirCallableDeclaration<*>.isFromInterface(context: CheckerContext): Boolean =
(getContainingClass(context) as? FirRegularClass)?.isInterface == true
private val FirSimpleFunction.matchesDataClassSyntheticMemberSignatures: Boolean
get() = (this.name == OperatorNameConventions.EQUALS && matchesEqualsSignature) ||
(this.name == HASHCODE_NAME && matchesHashCodeSignature) ||
(this.name == OperatorNameConventions.TO_STRING && matchesToStringSignature)
// NB: we intentionally do not check return types
private val FirSimpleFunction.matchesEqualsSignature: Boolean
get() = valueParameters.size == 1 && valueParameters[0].returnTypeRef.coneType.isNullableAny
private val FirSimpleFunction.matchesHashCodeSignature: Boolean
get() = valueParameters.isEmpty()
private val FirSimpleFunction.matchesToStringSignature: Boolean
get() = valueParameters.isEmpty()
}
......@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FQ_N
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NAME
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NULLABLE_STRING
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.PROPERTY_NAME
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_CLASS_OR_OBJECT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_TYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOLS
......@@ -21,9 +22,11 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.TO_S
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.VISIBILITY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.WHEN_MISSING_CASES
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSENCE_OF_PRIMARY_CONSTRUCTOR_FOR_INLINE_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_DELEGATED_PROPERTY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_FUNCTION_WITH_BODY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_MEMBER_NOT_IMPLEMENTED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_PROPERTY_WITH_GETTER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_PROPERTY_WITH_INITIALIZER
......@@ -117,6 +120,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_ANNOTATION_
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_INTERFACE_NOT_ALLOWED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_OBJECT_NOT_ALLOWED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MANY_COMPANION_OBJECTS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MANY_IMPL_MEMBER_NOT_IMPLEMENTED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MISSING_VAL_ON_ANNOTATION_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MULTIPLE_VARARG_PARAMETERS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MUST_BE_INITIALIZED
......@@ -455,6 +459,31 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
TO_STRING
)
map.put(
ABSTRACT_MEMBER_NOT_IMPLEMENTED,
"{0} is not abstract and does not implement abstract member {1}",
RENDER_CLASS_OR_OBJECT,
FQ_NAMES_IN_TYPES
)
map.put(
ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED,
"{0} is not abstract and does not implement abstract base class member {1}",
RENDER_CLASS_OR_OBJECT,
FQ_NAMES_IN_TYPES
)
map.put(
MANY_IMPL_MEMBER_NOT_IMPLEMENTED,
"{0} must override {1} because it inherits many implementations of it",
RENDER_CLASS_OR_OBJECT,
FQ_NAMES_IN_TYPES
)
map.put(
MANY_IMPL_MEMBER_NOT_IMPLEMENTED,
"{0} must override {1} because it inherits multiple interface methods of it",
RENDER_CLASS_OR_OBJECT,
FQ_NAMES_IN_TYPES
)
map.put(
RETURN_TYPE_MISMATCH_ON_OVERRIDE,
"Return type of ''{0}'' is not a subtype of the return type of the overridden member ''{1}''",
......
......@@ -77,6 +77,12 @@ object FirDiagnosticRenderers {
name.asString()
}
val RENDER_CLASS_OR_OBJECT = Renderer { firClass: FirClass<*> ->
val name = firClass.classId.relativeClassName.asString()
val classOrObject = if (firClass is FirRegularClass) "Class" else "Object"
"$classOrObject $name"
}
val RENDER_TYPE = Renderer { t: ConeKotlinType ->
// TODO: need a way to tune granuality, e.g., without parameter names in functional types.
t.render()
......
......@@ -40,6 +40,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
override val classCheckers: Set<FirClassChecker> = setOf(
FirOverrideChecker,
FirNotImplementedOverrideChecker,
FirThrowableSubclassChecker,
FirOpenMemberChecker,
)
......
......@@ -23,8 +23,8 @@ abstract class D {
abstract val d: @An Int
}
class E : D(), A
class F : A
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class E<!> : D(), A
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class F<!> : A
@An
interface G {
......
......@@ -12,9 +12,9 @@ fun foo() {
x.foo()
}
object Rr : SomeTrait {}
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>object Rr<!> : SomeTrait {}
class C : SomeTrait {}
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class C<!> : SomeTrait {}
fun foo2() {
val r = object : Runnable {} //no error
......
//KT-559 Forbid abstract method call through super
package kt559
abstract class A {
abstract val i : Int
abstract fun foo() : Int
fun fff() {}
}
abstract class D(): A() {
override val i : Int = 34
}
class C() : D() {
fun test() {
super.i
}
}
class B() : A() {
override fun foo(): Int {
super.<!ABSTRACT_SUPER_CALL!>i<!>
super.fff() //everything is ok
return super.<!ABSTRACT_SUPER_CALL!>foo<!>()
}
}
\ No newline at end of file
// FIR_IDENTICAL
//KT-559 Forbid abstract method call through super
package kt559
......
......@@ -5,11 +5,11 @@ interface T {
val v : Int
}
open class Br(t : T) : T {
open <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class Br<!>(t : T) : T {
}
class Br3(t : T) : Br(t) {
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class Br3<!>(t : T) : Br(t) {
}
......
......@@ -108,7 +108,7 @@ public class A extends AImpl implements List<String> {
}
// FILE: X.kt
class X : A()
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class X<!> : A()
fun main() {
val x = X()
......
......@@ -95,7 +95,7 @@ public class A extends AImpl implements List<String> {
}
// FILE: X.kt
class X : A()
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class X<!> : A()
fun main() {
val x = X()
......
......@@ -11,7 +11,7 @@ public abstract class B implements A {
// FILE: C.kt
class C : B()
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class C<!> : B()
fun main() {
C().a
......
......@@ -24,7 +24,7 @@ abstract class C {
}
}
object D : C() {
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>object D<!> : C() {
<!INCOMPATIBLE_MODIFIERS!>override<!> <!INCOMPATIBLE_MODIFIERS!>const<!> val x: Int = 9
const val inObject = 10
......
// !LANGUAGE: +MultiPlatformProjects
// MODULE: m1-common
// FILE: common.kt
interface Foo {
fun foo()
}
expect class ImplicitFoo : Foo
expect class ExplicitFoo : Foo {
override fun foo()
}
expect class ImplicitFooCheck : Foo
// MODULE: m2-jvm(m1-common)
// FILE: jvm.kt
actual class ImplicitFoo : Foo {
override fun foo() {}
}
actual class ExplicitFoo : Foo {
actual override fun foo() {}
}
actual class ImplicitFooCheck : Foo
\ No newline at end of file
// FIR_IDENTICAL
// !LANGUAGE: +MultiPlatformProjects
// MODULE: m1-common
// FILE: common.kt
......
abstract class A {
abstract fun foo(): Int
}
class B() : A() {
}
\ No newline at end of file
// FIR_IDENTICAL
abstract class A {
abstract fun foo(): Int
}
......
......@@ -21,21 +21,21 @@ open class MyClass() : MyTrait, MyAbstractClass() {
class MyChildClass() : MyClass() {}
class MyIllegalClass : MyTrait, MyAbstractClass() {}
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class MyIllegalClass<!> : MyTrait, MyAbstractClass() {}
class MyIllegalClass2() : MyTrait, MyAbstractClass() {
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class MyIllegalClass2<!>() : MyTrait, MyAbstractClass() {
override fun foo() {}
override val pr : Unit = Unit
override val prr : Unit = Unit
}
class MyIllegalClass3() : MyTrait, MyAbstractClass() {
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class MyIllegalClass3<!>() : MyTrait, MyAbstractClass() {
override fun bar() {}
override val pr : Unit = Unit
override val prr : Unit = Unit
}
class MyIllegalClass4() : MyTrait, MyAbstractClass() {
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class MyIllegalClass4<!>() : MyTrait, MyAbstractClass() {
fun foo() {}
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>val pr : Unit<!>
override fun other() {}
......
abstract class A {
abstract override fun toString(): String
}
interface B
abstract class C : A(), B
class Test : C()
// FIR_IDENTICAL
abstract class A {
abstract override fun toString(): String
}
......
interface A {
fun test() {
}
}
interface B : A {
override fun test()
}
interface C : A
interface D : C, B
class K : D
interface Runnable {
fun run()
}
class C {
fun f() {
class MyRunnable(): Runnable {
}
}
}
\ No newline at end of file
// FIR_IDENTICAL
interface Runnable {
fun run()
}
......
......@@ -6,6 +6,6 @@ open class Q {
val x: Int = 42
}
class R : P, Q()
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class R<!> : P, Q()
val s: Q = object : Q(), P {}
......@@ -22,7 +22,7 @@ abstract class A2 {
abstract fun foo()
}
class B2 : A2()
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class B2<!> : A2()
class C2 : B2() {
override fun foo() {}
}
......@@ -33,7 +33,7 @@ class E : D(), B {
override fun bar(x: CharSequence?, y: List<*>?): String = ""
}
class E2 : B {
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class E2<!> : B {
override fun foo(x: Any, y: List<String?>): String = ""
}
......
......@@ -36,6 +36,6 @@ class E1 : C.D(), B {
override fun foo(x: Any, y: Fun<Any?>) {}
}
class E2 : B {
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class E2<!> : B {
override fun foo(x: Any, y: Fun<String?>) {}
}
......@@ -14,20 +14,20 @@ public interface B {
// FILE: C.kt
class C1 : A, B {
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class C1<!> : A, B {
override fun foo(x: String) {}
}
class C2 : A, B {
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class C2<!> : A, B {
override fun foo(x: String?) {}
}
interface I : A, B
class C3 : I {
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class C3<!> : I {
override fun foo(x: String) {}
}
class C4 : I {
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class C4<!> : I {
override fun foo(x: String?) {}
}
\ No newline at end of file
......@@ -57,7 +57,7 @@ interface I {
fun foo2()
}
class X : I {
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class X<!> : I {
override fun foo1() {
}
}
......
......@@ -10,5 +10,5 @@ class BasicRecord(val x: String)
data class BasicDataRecord(val x: String)
@JvmRecord
class BasicRecordWithSuperClass(val x: String) : Record()
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class BasicRecordWithSuperClass<!>(val x: String) : Record()
......@@ -2,4 +2,4 @@
import kotlin.reflect.*
class A: KSuspendFunction0<Unit> {}
\ No newline at end of file
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class A<!>: KSuspendFunction0<Unit> {}
......@@ -24,7 +24,7 @@ interface C : A {
}
}
class D : J {
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class D<!> : J {
suspend override fun foo() {
}
......
......@@ -67,7 +67,7 @@ fun case3() {
ImplBaseCase3()
}
class ImplBaseCase3() : Base() {
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class ImplBaseCase3<!>() : Base() {
override var b: Any
get() = TODO()
set(value) {}
......@@ -95,7 +95,7 @@ fun case4() {
ImplBaseCase4()
}
class ImplBaseCase4() : Base() {
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class ImplBaseCase4<!>() : Base() {
override var b: Any
get() = TODO()
set(value) {}
......
......@@ -26,7 +26,7 @@ class Case2Outer {
}
inner
class A() : Case2Base() {
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class A<!>() : Case2Base() {
}
}
......@@ -36,7 +36,7 @@ fun case3() {
object : CaseOuter.CaseBase() {}.outerFoo()
}
class B() : CaseOuter.CaseBase() {}
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class B<!>() : CaseOuter.CaseBase() {}
sealed class CaseOuter {
val v = "v"
......@@ -46,6 +46,6 @@ sealed class CaseOuter {
abstract fun foo(): String
}
class A() : CaseBase() {
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class A<!>() : CaseBase() {
}
}
......@@ -41,7 +41,7 @@ class Case2(override val a: String, override var b: <!VAR_TYPE_MISMATCH_ON_OVERR
*/
class Case3 {
class ImplBase1 : MainClass.Base1() {}
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class ImplBase1<!> : MainClass.Base1() {}
}
class MainClass {
......
......@@ -30,7 +30,7 @@ class Case1 {
inner
class ImplBase2_1 : ImplBase2() {
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class ImplBase2_1<!> : ImplBase2() {
override var b: CharSequence = ""
override fun boo(x: Int) {}
}
......@@ -80,7 +80,7 @@ abstract class BaseCase3{
* NOTE: abstract class implements kotlin interface
*/
class Case4(a: String) : BaseCase4(a) {}
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class Case4<!>(a: String) : BaseCase4(a) {}
interface InterfaceCase4 {
fun foo(): String
......@@ -97,7 +97,7 @@ abstract class BaseCase4(val a: String) : InterfaceCase4 {}
* NOTE: abstract class implements java interface
*/
class Case5(a: String) : BaseCase5(a) {}
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class Case5<!>(a: String) : BaseCase5(a) {}
abstract class BaseCase5(val a: String) : java.util.Deque<String> {}
......@@ -106,6 +106,6 @@ abstract class BaseCase5(val a: String) : java.util.Deque<String> {}
* NOTE: abstract class implements java abstract class
*/
class Case6(a: String) : BaseCase6(a) {}
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class Case6<!>(a: String) : BaseCase6(a) {}
abstract class BaseCase6(val a: String) : java.util.AbstractCollection<String>() {}
......@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.descriptors.java
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.name.FqName
object JavaVisibilities {
object PackageVisibility : Visibility("package", isPublicAPI = false) {
......@@ -32,6 +33,10 @@ object JavaVisibilities {
override fun customEffectiveVisibility(): EffectiveVisibility? {
return EffectiveVisibility.PackagePrivate
}
override fun visibleFromPackage(fromPackage: FqName, myPackage: FqName): Boolean {
return fromPackage == myPackage
}
}
object ProtectedStaticVisibility : Visibility("protected_static", isPublicAPI = true) {
......
......@@ -5,6 +5,8 @@
package org.jetbrains.kotlin.descriptors
import org.jetbrains.kotlin.name.FqName
abstract class Visibility protected constructor(
val name: String,
val isPublicAPI: Boolean
......@@ -27,4 +29,6 @@ abstract class Visibility protected constructor(
// Should be overloaded in Java visibilities
open fun customEffectiveVisibility(): EffectiveVisibility? = null
open fun visibleFromPackage(fromPackage: FqName, myPackage: FqName): Boolean = true
}
......@@ -880,6 +880,38 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.ABSTRACT_MEMBER_NOT_IMPLEMENTED) { firDiagnostic ->
AbstractMemberNotImplementedImpl(
firSymbolBuilder.buildClassLikeSymbol(firDiagnostic.a),
firSymbolBuilder.buildCallableSymbol(firDiagnostic.b as FirCallableDeclaration),
firDiagnostic as FirPsiDiagnostic<*>,
token,
)
}
add(FirErrors.ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED) { firDiagnostic ->
AbstractClassMemberNotImplementedImpl(
firSymbolBuilder.buildClassLikeSymbol(firDiagnostic.a),
firSymbolBuilder.buildCallableSymbol(firDiagnostic.b as FirCallableDeclaration),
firDiagnostic as FirPsiDiagnostic<*>,
token,
)
}
add(FirErrors.MANY_IMPL_MEMBER_NOT_IMPLEMENTED) { firDiagnostic ->
ManyImplMemberNotImplementedImpl(
firSymbolBuilder.buildClassLikeSymbol(firDiagnostic.a),
firSymbolBuilder.buildCallableSymbol(firDiagnostic.b as FirCallableDeclaration),
firDiagnostic as FirPsiDiagnostic<*>,
token,
)
}
add(FirErrors.MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED) { firDiagnostic ->
ManyInterfacesMemberNotImplementedImpl(
firSymbolBuilder.buildClassLikeSymbol(firDiagnostic.a),
firSymbolBuilder.buildCallableSymbol(firDiagnostic.b as FirCallableDeclaration),
firDiagnostic as FirPsiDiagnostic<*>,
token,
)
}
add(FirErrors.RETURN_TYPE_MISMATCH_ON_OVERRIDE) { firDiagnostic ->
ReturnTypeMismatchOnOverrideImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a as FirDeclaration),
......
......@@ -625,6 +625,30 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
abstract val containingClassName: Name
}
abstract class AbstractMemberNotImplemented : KtFirDiagnostic<KtClassOrObject>() {
override val diagnosticClass get() = AbstractMemberNotImplemented::class
abstract val classOrObject: KtClassLikeSymbol
abstract val missingDeclaration: KtCallableSymbol
}
abstract class AbstractClassMemberNotImplemented : KtFirDiagnostic<KtClassOrObject>() {
override val diagnosticClass get() = AbstractClassMemberNotImplemented::class
abstract val classOrObject: KtClassLikeSymbol
abstract val missingDeclaration: KtCallableSymbol
}
abstract class ManyImplMemberNotImplemented : KtFirDiagnostic<KtClassOrObject>() {
override val diagnosticClass get() = ManyImplMemberNotImplemented::class
abstract val classOrObject: KtClassLikeSymbol
abstract val missingDeclaration: KtCallableSymbol
}
abstract class ManyInterfacesMemberNotImplemented : KtFirDiagnostic<KtClassOrObject>() {
override val diagnosticClass get() = ManyInterfacesMemberNotImplemented::class
abstract val classOrObject: KtClassLikeSymbol
abstract val missingDeclaration: KtCallableSymbol
}
abstract class ReturnTypeMismatchOnOverride : KtFirDiagnostic<KtNamedDeclaration>() {
override val diagnosticClass get() = ReturnTypeMismatchOnOverride::class
abstract val function: KtSymbol
......
......@@ -1007,6 +1007,42 @@ internal class OverridingFinalMemberImpl(
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
}
internal class AbstractMemberNotImplementedImpl(
override val classOrObject: KtClassLikeSymbol,
override val missingDeclaration: KtCallableSymbol,
firDiagnostic: FirPsiDiagnostic<*>,
override val token: ValidityToken,
) : KtFirDiagnostic.AbstractMemberNotImplemented(), KtAbstractFirDiagnostic<KtClassOrObject> {
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
}
internal class AbstractClassMemberNotImplementedImpl(
override val classOrObject: KtClassLikeSymbol,
override val missingDeclaration: KtCallableSymbol,
firDiagnostic: FirPsiDiagnostic<*>,
override val token: ValidityToken,
) : KtFirDiagnostic.AbstractClassMemberNotImplemented(), KtAbstractFirDiagnostic<KtClassOrObject> {
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
}
internal class ManyImplMemberNotImplementedImpl(
override val classOrObject: KtClassLikeSymbol,
override val missingDeclaration: KtCallableSymbol,
firDiagnostic: FirPsiDiagnostic<*>,
override val token: ValidityToken,
) : KtFirDiagnostic.ManyImplMemberNotImplemented(), KtAbstractFirDiagnostic<KtClassOrObject> {
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
}
internal class ManyInterfacesMemberNotImplementedImpl(
override val classOrObject: KtClassLikeSymbol,
override val missingDeclaration: KtCallableSymbol,
firDiagnostic: FirPsiDiagnostic<*>,
override val token: ValidityToken,
) : KtFirDiagnostic.ManyInterfacesMemberNotImplemented(), KtAbstractFirDiagnostic<KtClassOrObject> {
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
}
internal class ReturnTypeMismatchOnOverrideImpl(
override val function: KtSymbol,
override val superFunction: KtSymbol,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册