FIR: temporarily drop parent manipulation code around super type entries
This commit is contained in:
+3
-4
@@ -102,6 +102,9 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
val NON_PRIVATE_OR_PROTECTED_CONSTRUCTOR_IN_SEALED by error<FirSourceElement, PsiElement>()
|
||||
val CYCLIC_CONSTRUCTOR_DELEGATION_CALL by warning<FirSourceElement, PsiElement>()
|
||||
val PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED by warning<FirSourceElement, PsiElement>(PositioningStrategy.SECONDARY_CONSTRUCTOR_DELEGATION_CALL)
|
||||
|
||||
// TODO: change it to KtSuperTypeEntry when possible (after re-targeter implementation)
|
||||
val SUPERTYPE_NOT_INITIALIZED by error<FirSourceElement, KtTypeReference>()
|
||||
val SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR by error<FirSourceElement, PsiElement>()
|
||||
val DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR by warning<FirSourceElement, PsiElement>()
|
||||
val PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS by error<FirSourceElement, KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME)
|
||||
@@ -168,10 +171,6 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
}
|
||||
}
|
||||
|
||||
val CLASSES_AND_INTERFACES by object : DiagnosticGroup("Classes and interfaces") {
|
||||
val SUPERTYPE_NOT_INITIALIZED by error<FirSourceElement, KtSuperTypeEntry>()
|
||||
}
|
||||
|
||||
val INLINE_CLASSES by object : DiagnosticGroup("Inline classes") {
|
||||
val INLINE_CLASS_NOT_TOP_LEVEL by error<FirSourceElement, KtDeclaration>(PositioningStrategy.INLINE_OR_VALUE_MODIFIER)
|
||||
val INLINE_CLASS_NOT_FINAL by error<FirSourceElement, KtDeclaration>(PositioningStrategy.MODALITY_MODIFIER)
|
||||
|
||||
+1
-4
@@ -41,7 +41,6 @@ import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.psi.KtPropertyAccessor
|
||||
import org.jetbrains.kotlin.psi.KtPropertyDelegate
|
||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||
import org.jetbrains.kotlin.psi.KtSuperTypeEntry
|
||||
import org.jetbrains.kotlin.psi.KtTypeParameter
|
||||
import org.jetbrains.kotlin.psi.KtTypeParameterList
|
||||
import org.jetbrains.kotlin.psi.KtTypeReference
|
||||
@@ -106,6 +105,7 @@ object FirErrors {
|
||||
val NON_PRIVATE_OR_PROTECTED_CONSTRUCTOR_IN_SEALED by error0<FirSourceElement, PsiElement>()
|
||||
val CYCLIC_CONSTRUCTOR_DELEGATION_CALL by warning0<FirSourceElement, PsiElement>()
|
||||
val PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED by warning0<FirSourceElement, PsiElement>(SourceElementPositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL)
|
||||
val SUPERTYPE_NOT_INITIALIZED by error0<FirSourceElement, KtTypeReference>()
|
||||
val SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR by error0<FirSourceElement, PsiElement>()
|
||||
val DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR by warning0<FirSourceElement, PsiElement>()
|
||||
val PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS by error0<FirSourceElement, KtNamedDeclaration>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||
@@ -150,9 +150,6 @@ object FirErrors {
|
||||
val REDUNDANT_OPEN_IN_INTERFACE by warning0<FirSourceElement, KtModifierListOwner>(SourceElementPositioningStrategies.OPEN_MODIFIER)
|
||||
val WRONG_MODIFIER_TARGET by error2<FirSourceElement, PsiElement, KtModifierKeywordToken, String>()
|
||||
|
||||
// Classes and interfaces
|
||||
val SUPERTYPE_NOT_INITIALIZED by error0<FirSourceElement, KtSuperTypeEntry>()
|
||||
|
||||
// Inline classes
|
||||
val INLINE_CLASS_NOT_TOP_LEVEL by error0<FirSourceElement, KtDeclaration>(SourceElementPositioningStrategies.INLINE_OR_VALUE_MODIFIER)
|
||||
val INLINE_CLASS_NOT_FINAL by error0<FirSourceElement, KtDeclaration>(SourceElementPositioningStrategies.MODALITY_MODIFIER)
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis
|
||||
|
||||
import com.intellij.lang.LighterASTNode
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.tree.IElementType
|
||||
import com.intellij.psi.tree.TokenSet
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
@@ -38,54 +36,6 @@ private fun FirPsiSourceElement<*>.getChild(types: Set<IElementType>, index: Int
|
||||
|
||||
private fun FirLightSourceElement.getChild(types: Set<IElementType>, index: Int, depth: Int): FirSourceElement? {
|
||||
val visitor = LighterTreeElementFinderByType(treeStructure, types, index, depth)
|
||||
return visitor.find(lighterASTNode)?.let { withNode(it) }
|
||||
return visitor.find(lighterASTNode)?.toFirLightSourceElement(treeStructure)
|
||||
}
|
||||
|
||||
fun FirSourceElement.getParent(type: IElementType, includingSelf: Boolean = false): FirSourceElement? {
|
||||
return getParent(setOf(type), includingSelf)
|
||||
}
|
||||
|
||||
fun FirSourceElement.getParent(types: TokenSet, includingSelf: Boolean = false): FirSourceElement? {
|
||||
return getParent(types.types.toSet(), includingSelf)
|
||||
}
|
||||
|
||||
fun FirSourceElement.getParent(types: Set<IElementType>, includingSelf: Boolean = false): FirSourceElement? {
|
||||
return when (this) {
|
||||
is FirPsiSourceElement<*> -> {
|
||||
getParent(types, includingSelf)
|
||||
}
|
||||
is FirLightSourceElement -> {
|
||||
getParent(types, includingSelf)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirPsiSourceElement<*>.getParent(types: Set<IElementType>, includingSelf: Boolean): FirSourceElement? {
|
||||
var parent: PsiElement? = if (includingSelf) psi else psi.parent
|
||||
while (parent != null && parent.node.elementType !in types) {
|
||||
parent = parent.parent
|
||||
}
|
||||
return parent?.toFirPsiSourceElement()
|
||||
}
|
||||
|
||||
private fun FirLightSourceElement.getParent(types: Set<IElementType>, includingSelf: Boolean): FirSourceElement? {
|
||||
var parent: LighterASTNode? = if (includingSelf) lighterASTNode else treeStructure.getParent(lighterASTNode)
|
||||
while (parent != null && parent.tokenType !in types) {
|
||||
parent = treeStructure.getParent(parent)
|
||||
}
|
||||
return parent?.let { withNode(it) }
|
||||
}
|
||||
|
||||
private fun FirLightSourceElement.withNode(newNode: LighterASTNode): FirLightSourceElement {
|
||||
// It seems sometimes the `startOffset` from a `LighterASTNode` could count from some partial sub tree of the file. If this is the case,
|
||||
// we need to compute the delta between the corresponding position in this partial tree and the file start. The latter can be retrieved
|
||||
// from `FirLightSourceElement`.
|
||||
val startDelta = this.startOffset - lighterASTNode.startOffset
|
||||
val endDelta = this.endOffset - lighterASTNode.endOffset
|
||||
return newNode.toFirLightSourceElement(
|
||||
treeStructure,
|
||||
startOffset = startDelta + newNode.startOffset,
|
||||
endOffset = endDelta + newNode.endOffset
|
||||
)
|
||||
}
|
||||
|
||||
+11
-10
@@ -6,17 +6,18 @@
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
||||
|
||||
import org.jetbrains.kotlin.KtNodeTypes
|
||||
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClass
|
||||
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.analysis.getParent
|
||||
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.isInterface
|
||||
import org.jetbrains.kotlin.fir.declarations.primaryConstructor
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitAnyTypeRef
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.lastIsInstanceOrNull
|
||||
|
||||
@@ -54,8 +55,9 @@ object FirPrimaryConstructorSuperTypeChecker : FirRegularClassChecker() {
|
||||
val containingClass = context.containingDeclarations.lastIsInstanceOrNull<FirRegularClass>()
|
||||
val delegatedConstructorCall = primaryConstructor.delegatedConstructor ?: return
|
||||
// No need to check implicit call to the constructor of `kotlin.Any`.
|
||||
if (delegatedConstructorCall.constructedTypeRef is FirImplicitAnyTypeRef) return
|
||||
val superClass = delegatedConstructorCall.constructedTypeRef.coneType.toRegularClass(context.session) ?: return
|
||||
val constructedTypeRef = delegatedConstructorCall.constructedTypeRef
|
||||
if (constructedTypeRef is FirImplicitAnyTypeRef) return
|
||||
val superClass = constructedTypeRef.coneType.toRegularClass(context.session) ?: return
|
||||
// Subclassing a singleton should be reported as SINGLETON_IN_SUPERTYPE
|
||||
if (superClass.classKind.isSingleton) return
|
||||
if (regularClass.isEffectivelyExpect(containingClass, context) ||
|
||||
@@ -63,12 +65,11 @@ object FirPrimaryConstructorSuperTypeChecker : FirRegularClassChecker() {
|
||||
) {
|
||||
return
|
||||
}
|
||||
if (delegatedConstructorCall.source?.elementType != KtNodeTypes.SUPER_TYPE_CALL_ENTRY) {
|
||||
reporter.reportOn(
|
||||
delegatedConstructorCall.constructedTypeRef.source?.getParent(KtNodeTypes.SUPER_TYPE_ENTRY),
|
||||
FirErrors.SUPERTYPE_NOT_INITIALIZED,
|
||||
context
|
||||
)
|
||||
val delegatedCallSource = delegatedConstructorCall.source ?: return
|
||||
if (delegatedCallSource.kind !is FirFakeSourceElementKind) return
|
||||
if (superClass.symbol.classId == StandardClassIds.Enum) return
|
||||
if (delegatedCallSource.elementType != KtNodeTypes.SUPER_TYPE_CALL_ENTRY) {
|
||||
reporter.reportOn(constructedTypeRef.source, FirErrors.SUPERTYPE_NOT_INITIALIZED, context)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ open class Foo() {
|
||||
|
||||
}
|
||||
|
||||
class Barrr() : Foo by Foo() {}
|
||||
class Barrr() : <!SUPERTYPE_NOT_INITIALIZED!>Foo<!> by Foo() {}
|
||||
|
||||
interface T {}
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// JAVAC_EXPECTED_FILE
|
||||
class TestIface(r : Runnable) : Runnable by r {}
|
||||
|
||||
class TestObject(o : Object) : Object by o {}
|
||||
class TestObject(o : Object) : <!SUPERTYPE_NOT_INITIALIZED!>Object<!> by o {}
|
||||
|
||||
@@ -11,4 +11,4 @@ public abstract class A {
|
||||
// FILE: main.kt
|
||||
import foo.A
|
||||
|
||||
class DelegatedA(val a: A) : A by a
|
||||
class DelegatedA(val a: A) : <!SUPERTYPE_NOT_INITIALIZED!>A<!> by a
|
||||
|
||||
+6
-7
@@ -32,7 +32,6 @@ import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.psi.KtPropertyAccessor
|
||||
import org.jetbrains.kotlin.psi.KtPropertyDelegate
|
||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||
import org.jetbrains.kotlin.psi.KtSuperTypeEntry
|
||||
import org.jetbrains.kotlin.psi.KtTypeParameter
|
||||
import org.jetbrains.kotlin.psi.KtTypeParameterList
|
||||
import org.jetbrains.kotlin.psi.KtTypeReference
|
||||
@@ -296,6 +295,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.SUPERTYPE_NOT_INITIALIZED) { firDiagnostic ->
|
||||
SupertypeNotInitializedImpl(
|
||||
firDiagnostic as FirPsiDiagnostic<*>,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR) { firDiagnostic ->
|
||||
SupertypeInitializedWithoutPrimaryConstructorImpl(
|
||||
firDiagnostic as FirPsiDiagnostic<*>,
|
||||
@@ -555,12 +560,6 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.SUPERTYPE_NOT_INITIALIZED) { firDiagnostic ->
|
||||
SupertypeNotInitializedImpl(
|
||||
firDiagnostic as FirPsiDiagnostic<*>,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.INLINE_CLASS_NOT_TOP_LEVEL) { firDiagnostic ->
|
||||
InlineClassNotTopLevelImpl(
|
||||
firDiagnostic as FirPsiDiagnostic<*>,
|
||||
|
||||
+4
-5
@@ -36,7 +36,6 @@ import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.psi.KtPropertyAccessor
|
||||
import org.jetbrains.kotlin.psi.KtPropertyDelegate
|
||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||
import org.jetbrains.kotlin.psi.KtSuperTypeEntry
|
||||
import org.jetbrains.kotlin.psi.KtTypeParameter
|
||||
import org.jetbrains.kotlin.psi.KtTypeParameterList
|
||||
import org.jetbrains.kotlin.psi.KtTypeReference
|
||||
@@ -219,6 +218,10 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
override val diagnosticClass get() = PrimaryConstructorDelegationCallExpected::class
|
||||
}
|
||||
|
||||
abstract class SupertypeNotInitialized : KtFirDiagnostic<KtTypeReference>() {
|
||||
override val diagnosticClass get() = SupertypeNotInitialized::class
|
||||
}
|
||||
|
||||
abstract class SupertypeInitializedWithoutPrimaryConstructor : KtFirDiagnostic<PsiElement>() {
|
||||
override val diagnosticClass get() = SupertypeInitializedWithoutPrimaryConstructor::class
|
||||
}
|
||||
@@ -404,10 +407,6 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
abstract val target: String
|
||||
}
|
||||
|
||||
abstract class SupertypeNotInitialized : KtFirDiagnostic<KtSuperTypeEntry>() {
|
||||
override val diagnosticClass get() = SupertypeNotInitialized::class
|
||||
}
|
||||
|
||||
abstract class InlineClassNotTopLevel : KtFirDiagnostic<KtDeclaration>() {
|
||||
override val diagnosticClass get() = InlineClassNotTopLevel::class
|
||||
}
|
||||
|
||||
+7
-8
@@ -38,7 +38,6 @@ import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.psi.KtPropertyAccessor
|
||||
import org.jetbrains.kotlin.psi.KtPropertyDelegate
|
||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||
import org.jetbrains.kotlin.psi.KtSuperTypeEntry
|
||||
import org.jetbrains.kotlin.psi.KtTypeParameter
|
||||
import org.jetbrains.kotlin.psi.KtTypeParameterList
|
||||
import org.jetbrains.kotlin.psi.KtTypeReference
|
||||
@@ -343,6 +342,13 @@ internal class PrimaryConstructorDelegationCallExpectedImpl(
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class SupertypeNotInitializedImpl(
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.SupertypeNotInitialized(), KtAbstractFirDiagnostic<KtTypeReference> {
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class SupertypeInitializedWithoutPrimaryConstructorImpl(
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
override val token: ValidityToken,
|
||||
@@ -639,13 +645,6 @@ internal class WrongModifierTargetImpl(
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class SupertypeNotInitializedImpl(
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.SupertypeNotInitialized(), KtAbstractFirDiagnostic<KtSuperTypeEntry> {
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class InlineClassNotTopLevelImpl(
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
override val token: ValidityToken,
|
||||
|
||||
Reference in New Issue
Block a user