FIR LC: introduce modifier list for members

to simulate `default` modifier of methods in interface
This commit is contained in:
Jinseong Jeon
2021-09-23 12:04:46 -07:00
committed by Ilya Kirillov
parent ec5c06238d
commit aad02c1259
9 changed files with 60 additions and 9 deletions
@@ -22,7 +22,7 @@ internal class FirLightFieldForEnumEntry(
) : FirLightField(containingClass, lightMemberOrigin), PsiEnumConstant {
private val _modifierList by lazyPub {
FirLightClassModifierList(
FirLightMemberModifierList(
containingDeclaration = this@FirLightFieldForEnumEntry,
modifiers = setOf(PsiModifier.STATIC, PsiModifier.FINAL, PsiModifier.PUBLIC),
annotations = emptyList()
@@ -27,7 +27,7 @@ internal class FirLightFieldForObjectSymbol(
private val _modifierList: PsiModifierList by lazyPub {
val modifiers = setOf(objectSymbol.toPsiVisibilityForMember(isTopLevel = false), PsiModifier.STATIC, PsiModifier.FINAL)
val notNullAnnotation = FirLightSimpleAnnotation("org.jetbrains.annotations.NotNull", this)
FirLightClassModifierList(this, modifiers, listOf(notNullAnnotation))
FirLightMemberModifierList(this, modifiers, listOf(notNullAnnotation))
}
private val _isDeprecated: Boolean by lazyPub {
@@ -92,7 +92,7 @@ internal class FirLightFieldForPropertySymbol(
annotationUseSiteTarget = AnnotationUseSiteTarget.FIELD,
)
FirLightClassModifierList(this, modifiers, annotations)
FirLightMemberModifierList(this, modifiers, annotations)
}
override fun getModifierList(): PsiModifierList = _modifierList
@@ -131,7 +131,7 @@ internal class FirLightAccessorMethodForSymbol(
private val _modifierList: PsiModifierList by lazyPub {
val modifiers = computeModifiers()
val annotations = computeAnnotations(modifiers.contains(PsiModifier.PRIVATE))
FirLightClassModifierList(this, modifiers, annotations)
FirLightMemberModifierList(this, modifiers, annotations)
}
override fun getModifierList(): PsiModifierList = _modifierList
@@ -47,7 +47,7 @@ internal class FirLightConstructorForSymbol(
}
private val _modifierList: PsiModifierList by lazyPub {
FirLightClassModifierList(this, _modifiers, _annotations)
FirLightMemberModifierList(this, _modifiers, _annotations)
}
override fun getModifierList(): PsiModifierList = _modifierList
@@ -63,4 +63,4 @@ internal class FirLightConstructorForSymbol(
override fun hashCode(): Int = kotlinOrigin.hashCode()
override fun isValid(): Boolean = super.isValid() && constructorSymbol.isValid()
}
}
@@ -115,7 +115,7 @@ internal class FirLightSimpleMethodForSymbol(
private val _modifierList: PsiModifierList by lazyPub {
val modifiers = computeModifiers()
val annotations = computeAnnotations(modifiers.contains(PsiModifier.PRIVATE))
FirLightClassModifierList(this, modifiers, annotations)
FirLightMemberModifierList(this, modifiers, annotations)
}
override fun getModifierList(): PsiModifierList = _modifierList
@@ -0,0 +1,49 @@
/*
* 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.light.classes.symbol
import com.intellij.psi.PsiAnnotation
import com.intellij.psi.PsiModifier
import org.jetbrains.kotlin.asJava.elements.KtLightAbstractAnnotation
import org.jetbrains.kotlin.asJava.elements.KtLightMember
import org.jetbrains.kotlin.psi.psiUtil.hasBody
internal class FirLightMemberModifierList<T : KtLightMember<*>>(
containingDeclaration: T,
private val modifiers: Set<String>,
private val annotations: List<PsiAnnotation>
) : FirLightModifierList<T>(containingDeclaration) {
override fun hasModifierProperty(name: String): Boolean {
return when {
name == PsiModifier.ABSTRACT && isImplementationInInterface() -> false
// Pretend this method behaves like a `default` method
name == PsiModifier.DEFAULT && isImplementationInInterface() -> true
// TODO: FINAL && isPossiblyAffectedByAllOpen
else -> {
name in modifiers
}
}
}
private fun isImplementationInInterface(): Boolean {
return owner.containingClass.isInterface && owner is FirLightMethod && owner.kotlinOrigin?.hasBody() == true
}
override fun hasExplicitModifier(name: String): Boolean {
// Kotlin methods can't be truly default atm, that way we can avoid being reported on by diagnostics, namely UAST
return if (name == PsiModifier.DEFAULT) false else super.hasExplicitModifier(name)
}
override val givenAnnotations: List<KtLightAbstractAnnotation>?
get() = invalidAccess()
override fun getAnnotations(): Array<out PsiAnnotation> = annotations.toTypedArray()
override fun findAnnotation(qualifiedName: String) = annotations.firstOrNull { it.qualifiedName == qualifiedName }
override fun equals(other: Any?): Boolean = this === other
override fun hashCode(): Int = kotlinOrigin.hashCode()
}
@@ -107,7 +107,7 @@ private class KtLightMemberModifierList(
}
override fun hasExplicitModifier(name: String) =
// kotlin methods can't be truly default atm, that way we can avoid being reported on by diagnostics, namely android lint
// Kotlin methods can't be truly default atm, that way we can avoid being reported on by diagnostics, namely UAST
if (name == PsiModifier.DEFAULT) false else super.hasExplicitModifier(name)
private fun isMethodOverride() = owner is KtLightMethod && owner.kotlinOrigin?.hasModifier(KtTokens.OVERRIDE_KEYWORD) ?: false
@@ -7,4 +7,6 @@ interface KtInterface {
}
fun withoutBody()
}
}
// FIR_COMPARISON