FIR LC: add support for inline class
This commit is contained in:
committed by
Ilya Kirillov
parent
0e7d1b3945
commit
5880d80d26
+1
-1
@@ -28,7 +28,7 @@ import org.jetbrains.kotlin.util.OperatorNameConventions.EQUALS
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.TO_STRING
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.applyIf
|
||||
|
||||
internal class FirLightClassForSymbol(
|
||||
internal open class FirLightClassForSymbol(
|
||||
private val classOrObjectSymbol: KtNamedClassOrObjectSymbol,
|
||||
manager: PsiManager
|
||||
) : FirLightClassForClassOrObjectSymbol(classOrObjectSymbol, manager) {
|
||||
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.PsiManager
|
||||
import com.intellij.psi.PsiMethod
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol
|
||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightField
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||
import org.jetbrains.kotlin.light.classes.symbol.classes.createMethods
|
||||
import org.jetbrains.kotlin.light.classes.symbol.classes.createPropertyAccessors
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue
|
||||
|
||||
internal class FirLightInlineClass(
|
||||
private val classOrObjectSymbol: KtNamedClassOrObjectSymbol,
|
||||
manager: PsiManager
|
||||
) : FirLightClassForSymbol(classOrObjectSymbol, manager) {
|
||||
|
||||
init {
|
||||
require(classOrObjectSymbol.isInline)
|
||||
}
|
||||
|
||||
private val _ownMethods: List<KtLightMethod> by lazyPub {
|
||||
val result = mutableListOf<KtLightMethod>()
|
||||
|
||||
analyzeWithSymbolAsContext(classOrObjectSymbol) {
|
||||
val declaredMemberScope = classOrObjectSymbol.getDeclaredMemberScope()
|
||||
val applicableDeclarations = declaredMemberScope.getCallableSymbols()
|
||||
.filter {
|
||||
(it as? KtPropertySymbol)?.isOverride == true || (it as? KtFunctionSymbol)?.isOverride == true
|
||||
}
|
||||
.filterNot {
|
||||
it.deprecationStatus?.deprecationLevel == DeprecationLevelValue.HIDDEN
|
||||
}
|
||||
|
||||
createMethods(applicableDeclarations, result, suppressStaticForMethods = false)
|
||||
|
||||
val inlineClassParameterSymbol =
|
||||
declaredMemberScope.getConstructors().singleOrNull { it.isPrimary }?.valueParameters?.singleOrNull()
|
||||
if (inlineClassParameterSymbol != null) {
|
||||
val propertySymbol = declaredMemberScope.getCallableSymbols { it == inlineClassParameterSymbol.name }
|
||||
.singleOrNull { it is KtPropertySymbol && it.isFromPrimaryConstructor } as? KtPropertySymbol
|
||||
if (propertySymbol != null) {
|
||||
// (inline or) value class primary constructor must have only final read-only (val) property parameter
|
||||
// Even though the property parameter is mutable (for some reasons, e.g., testing or not checked yet),
|
||||
// we can enforce immutability here.
|
||||
createPropertyAccessors(result, propertySymbol, isTopLevel = false, isMutable = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
override fun getOwnMethods(): List<PsiMethod> = _ownMethods
|
||||
|
||||
override fun getOwnFields(): List<KtLightField> = emptyList()
|
||||
|
||||
override fun copy(): FirLightInlineClass =
|
||||
FirLightInlineClass(classOrObjectSymbol, manager)
|
||||
}
|
||||
+7
-2
@@ -70,7 +70,11 @@ fun createFirLightClassNoCache(classOrObject: KtClassOrObject): KtLightClass? =
|
||||
|
||||
return when {
|
||||
classOrObject is KtEnumEntry -> lightClassForEnumEntry(classOrObject)
|
||||
classOrObject.hasModifier(KtTokens.INLINE_KEYWORD) -> return null //TODO
|
||||
classOrObject.hasModifier(KtTokens.INLINE_KEYWORD) -> {
|
||||
analyseForLightClasses(classOrObject) {
|
||||
classOrObject.getNamedClassOrObjectSymbol()?.let { FirLightInlineClass(it, classOrObject.manager) }
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
analyseForLightClasses(classOrObject) {
|
||||
classOrObject.getClassOrObjectSymbol().createLightClassNoCache(classOrObject.manager)
|
||||
@@ -210,6 +214,7 @@ internal fun FirLightClassBase.createPropertyAccessors(
|
||||
result: MutableList<KtLightMethod>,
|
||||
declaration: KtPropertySymbol,
|
||||
isTopLevel: Boolean,
|
||||
isMutable: Boolean = !declaration.isVal,
|
||||
) {
|
||||
if (declaration is KtKotlinPropertySymbol && declaration.isConst) return
|
||||
|
||||
@@ -258,7 +263,7 @@ internal fun FirLightClassBase.createPropertyAccessors(
|
||||
!isAnnotationType && it.needToCreateAccessor(AnnotationUseSiteTarget.PROPERTY_SETTER)
|
||||
}
|
||||
|
||||
if (setter != null) {
|
||||
if (isMutable && setter != null) {
|
||||
val lightMemberOrigin = originalElement?.let {
|
||||
LightMemberOriginForDeclaration(
|
||||
originalElement = it,
|
||||
|
||||
+3
@@ -57,6 +57,9 @@ class KtUltraLightInlineClass(
|
||||
if (inlineClassParameter != null) {
|
||||
membersBuilder.propertyAccessors(
|
||||
inlineClassParameter,
|
||||
// (inline or) value class primary constructor must have only final read-only (val) property parameter
|
||||
// Even though the property parameter is mutable (for some reasons, e.g., testing or not checked yet),
|
||||
// we can enforce immutability here.
|
||||
mutable = false,
|
||||
forceStatic = false,
|
||||
onlyJvmStatic = false
|
||||
|
||||
@@ -26,4 +26,6 @@ inline class InlineInheritance(val v: Int) : I {
|
||||
override val x get() = 5
|
||||
|
||||
fun z() = 7
|
||||
}
|
||||
}
|
||||
|
||||
// FIR_COMPARISON
|
||||
|
||||
Reference in New Issue
Block a user