FIR IDE: extract variable-like symbol building from KtSymbolByFirBuilder

This commit is contained in:
Ilya Kirillov
2021-03-12 18:59:30 +01:00
parent bafc61b56f
commit c06bcbad39
10 changed files with 60 additions and 47 deletions
@@ -160,7 +160,7 @@ private object FirToKtConversionCreator {
KtType::class.createType() KtType::class.createType()
), ),
FirPropertySymbol::class to HLFunctionCallConversion( FirPropertySymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.buildVariableSymbol({0}.fir as FirProperty)", "firSymbolBuilder.variableLikeBuilder.buildVariableSymbol({0}.fir as FirProperty)",
KtVariableSymbol::class.createType(), KtVariableSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirProperty") importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirProperty")
), ),
@@ -54,6 +54,7 @@ internal class KtSymbolByFirBuilder private constructor(
val classifierBuilder = ClassifierSymbolBuilder() val classifierBuilder = ClassifierSymbolBuilder()
val functionLikeBuilder = FunctionLikeSymbolBuilder() val functionLikeBuilder = FunctionLikeSymbolBuilder()
val variableLikeBuilder = VariableLikeSymbolBuilder()
constructor( constructor(
resolveState: FirModuleResolveState, resolveState: FirModuleResolveState,
@@ -99,29 +100,13 @@ internal class KtSymbolByFirBuilder private constructor(
fun buildCallableSymbol(fir: FirCallableDeclaration<*>): KtCallableSymbol { fun buildCallableSymbol(fir: FirCallableDeclaration<*>): KtCallableSymbol {
return when (fir) { return when (fir) {
is FirValueParameter -> buildParameterSymbol(fir)
is FirPropertyAccessor -> buildPropertyAccessorSymbol(fir) is FirPropertyAccessor -> buildPropertyAccessorSymbol(fir)
is FirFunction<*> -> functionLikeSymbolBuilder.buildFunctionLikeSymbol(fir) is FirFunction<*> -> functionLikeSymbolBuilder.buildFunctionLikeSymbol(fir)
is FirVariable<*> -> buildVariableLikeSymbol(fir) is FirVariable<*> -> variableLikeSymbolBuilder.buildVariableLikeSymbol(fir)
else -> error("Unexpected ${fir::class.simpleName}") else -> error("Unexpected ${fir::class.simpleName}")
} }
} }
// TODO it can be a constructor parameter, which may be split into parameter & property
// we should handle them both
fun buildParameterSymbol(fir: FirValueParameter) =
symbolsCache.cache(fir) { KtFirFunctionValueParameterSymbol(fir, resolveState, token, this) }
fun buildFirConstructorParameter(fir: FirValueParameter) =
symbolsCache.cache(fir) { KtFirConstructorValueParameterSymbol(fir, resolveState, token, this) }
// todo handle cases
fun buildFieldSymbol(fir: FirField): KtFirJavaFieldSymbol {
return symbolsCache.cache(fir) { KtFirJavaFieldSymbol(fir, resolveState, token, this) }
}
fun buildPropertyAccessorSymbol(fir: FirPropertyAccessor): KtPropertyAccessorSymbol { fun buildPropertyAccessorSymbol(fir: FirPropertyAccessor): KtPropertyAccessorSymbol {
return when { return when {
@@ -142,25 +127,6 @@ internal class KtSymbolByFirBuilder private constructor(
fun buildFileSymbol(fir: FirFile) = filesCache.cache(fir) { KtFirFileSymbol(fir, resolveState, token) } fun buildFileSymbol(fir: FirFile) = filesCache.cache(fir) { KtFirFileSymbol(fir, resolveState, token) }
fun buildVariableLikeSymbol(fir: FirVariable<*>): KtVariableLikeSymbol {
return when (fir) {
is FirProperty -> buildVariableSymbol(fir)
is FirValueParameter -> buildParameterSymbol(fir)
is FirField -> buildFieldSymbol(fir)
is FirEnumEntry -> buildEnumEntrySymbol(fir) // TODO enum entry should not be callable
else -> error("Unexpected ${fir::class.simpleName}")
}
}
fun buildVariableSymbol(fir: FirProperty): KtVariableSymbol {
return symbolsCache.cache(fir) {
when {
fir.isLocal -> KtFirLocalVariableSymbol(fir, resolveState, token, this)
fir is FirSyntheticProperty -> KtFirSyntheticJavaPropertySymbol(fir, resolveState, token, this)
else -> KtFirKotlinPropertySymbol(fir, resolveState, token, this)
}
}
}
fun createPackageSymbolIfOneExists(packageFqName: FqName): KtFirPackageSymbol? { fun createPackageSymbolIfOneExists(packageFqName: FqName): KtFirPackageSymbol? {
val exists = PackageIndexUtil.packageExists(packageFqName, GlobalSearchScope.allScope(project), project) val exists = PackageIndexUtil.packageExists(packageFqName, GlobalSearchScope.allScope(project), project)
@@ -290,6 +256,53 @@ internal class KtSymbolByFirBuilder private constructor(
} }
} }
} }
inner class VariableLikeSymbolBuilder {
fun buildVariableLikeSymbol(fir: FirVariable<*>): KtVariableLikeSymbol {
return when (fir) {
is FirProperty -> buildVariableSymbol(fir)
is FirValueParameter -> buildParameterSymbol(fir)
is FirField -> buildFieldSymbol(fir)
is FirEnumEntry -> buildEnumEntrySymbol(fir) // TODO enum entry should not be callable
else -> error("Unexpected ${fir::class.simpleName}")
}
}
//TODO separate to functions
fun buildVariableSymbol(fir: FirProperty): KtVariableSymbol {
return symbolsCache.cache(fir) {
when {
fir.isLocal -> KtFirLocalVariableSymbol(fir, resolveState, token, this@KtSymbolByFirBuilder)
fir is FirSyntheticProperty -> KtFirSyntheticJavaPropertySymbol(fir, resolveState, token, this@KtSymbolByFirBuilder)
else -> KtFirKotlinPropertySymbol(fir, resolveState, token, this@KtSymbolByFirBuilder)
}
}
}
fun buildParameterSymbol(fir: FirValueParameter): KtParameterSymbol {
@Suppress("IntroduceWhenSubject")
return when {
fir.isConstructorParameter == true -> buildConstructorParameterSymbol(fir)
else -> buildFunctionParameterSymbol(fir)
}
}
fun buildConstructorParameterSymbol(fir: FirValueParameter): KtFirConstructorValueParameterSymbol {
require(fir.isConstructorParameter == true)
return symbolsCache.cache(fir) { KtFirConstructorValueParameterSymbol(fir, resolveState, token, this@KtSymbolByFirBuilder) }
}
fun buildFunctionParameterSymbol(fir: FirValueParameter): KtFirFunctionParameterSymbol {
require(fir.isConstructorParameter != true)
return symbolsCache.cache(fir) { KtFirFunctionParameterSymbol(fir, resolveState, token, this@KtSymbolByFirBuilder) }
}
// todo handle cases
fun buildFieldSymbol(fir: FirField): KtFirJavaFieldSymbol {
return symbolsCache.cache(fir) { KtFirJavaFieldSymbol(fir, resolveState, token, this@KtSymbolByFirBuilder) }
}
}
} }
@@ -1217,14 +1217,14 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
} }
add(FirErrors.UNINITIALIZED_VARIABLE) { firDiagnostic -> add(FirErrors.UNINITIALIZED_VARIABLE) { firDiagnostic ->
UninitializedVariableImpl( UninitializedVariableImpl(
firSymbolBuilder.buildVariableSymbol(firDiagnostic.a.fir as FirProperty), firSymbolBuilder.variableLikeBuilder.buildVariableSymbol(firDiagnostic.a.fir as FirProperty),
firDiagnostic as FirPsiDiagnostic<*>, firDiagnostic as FirPsiDiagnostic<*>,
token, token,
) )
} }
add(FirErrors.VAL_REASSIGNMENT) { firDiagnostic -> add(FirErrors.VAL_REASSIGNMENT) { firDiagnostic ->
ValReassignmentImpl( ValReassignmentImpl(
firSymbolBuilder.buildVariableSymbol(firDiagnostic.a.fir as FirProperty), firSymbolBuilder.variableLikeBuilder.buildVariableSymbol(firDiagnostic.a.fir as FirProperty),
firDiagnostic as FirPsiDiagnostic<*>, firDiagnostic as FirPsiDiagnostic<*>,
token, token,
) )
@@ -69,7 +69,7 @@ internal fun FirScope.getCallableSymbols(callableNames: Collection<Name>, builde
processPropertiesByName(name) { firSymbol -> processPropertiesByName(name) { firSymbol ->
val symbol = when { val symbol = when {
firSymbol is FirPropertySymbol && firSymbol.fir.isSubstitutionOverride -> { firSymbol is FirPropertySymbol && firSymbol.fir.isSubstitutionOverride -> {
builder.buildVariableSymbol(firSymbol.fir) builder.variableLikeBuilder.buildVariableSymbol(firSymbol.fir)
} }
else -> builder.buildCallableSymbol(firSymbol.fir) else -> builder.buildCallableSymbol(firSymbol.fir)
} }
@@ -36,7 +36,7 @@ internal class KtFirAnonymousFunctionSymbol(
override val valueParameters: List<KtParameterSymbol> by firRef.withFirAndCache { fir -> override val valueParameters: List<KtParameterSymbol> by firRef.withFirAndCache { fir ->
fir.valueParameters.map { valueParameter -> fir.valueParameters.map { valueParameter ->
builder.buildParameterSymbol(valueParameter) builder.variableLikeBuilder.buildParameterSymbol(valueParameter)
} }
} }
@@ -50,7 +50,7 @@ internal class KtFirConstructorSymbol(
override val valueParameters: List<KtConstructorParameterSymbol> by firRef.withFirAndCache { fir -> override val valueParameters: List<KtConstructorParameterSymbol> by firRef.withFirAndCache { fir ->
fir.valueParameters.map { valueParameter -> fir.valueParameters.map { valueParameter ->
builder.buildFirConstructorParameter(valueParameter) builder.variableLikeBuilder.buildConstructorParameterSymbol(valueParameter)
} }
} }
@@ -45,7 +45,7 @@ internal class KtFirFunctionSymbol(
} }
override val valueParameters: List<KtFirFunctionValueParameterSymbol> by firRef.withFirAndCache { fir -> override val valueParameters: List<KtFirFunctionValueParameterSymbol> by firRef.withFirAndCache { fir ->
fir.valueParameters.map { valueParameter -> fir.valueParameters.map { valueParameter ->
builder.buildParameterSymbol(valueParameter) builder.variableLikeBuilder.buildFunctionParameterSymbol(valueParameter)
} }
} }
override val typeParameters by firRef.withFirAndCache { fir -> override val typeParameters by firRef.withFirAndCache { fir ->
@@ -53,7 +53,7 @@ internal class KtFirPropertySetterSymbol(
override val annotationClassIds: Collection<ClassId> by cached { firRef.getAnnotationClassIds() } override val annotationClassIds: Collection<ClassId> by cached { firRef.getAnnotationClassIds() }
override val parameter: KtFunctionParameterSymbol by firRef.withFirAndCache { fir -> override val parameter: KtFunctionParameterSymbol by firRef.withFirAndCache { fir ->
builder.buildFunctionParameterSymbol(fir.valueParameters.single()) builder.variableLikeBuilder.buildFunctionParameterSymbol(fir.valueParameters.single())
} }
override val annotatedType: KtTypeAndAnnotations by cached { override val annotatedType: KtTypeAndAnnotations by cached {
@@ -35,7 +35,7 @@ internal class KtFirSymbolProvider(
override fun getParameterSymbol(psi: KtParameter): KtParameterSymbol = withValidityAssertion { override fun getParameterSymbol(psi: KtParameter): KtParameterSymbol = withValidityAssertion {
psi.withFirDeclarationOfType<FirValueParameter, KtParameterSymbol>(resolveState) { psi.withFirDeclarationOfType<FirValueParameter, KtParameterSymbol>(resolveState) {
firSymbolBuilder.buildParameterSymbol(it) firSymbolBuilder.variableLikeBuilder.buildParameterSymbol(it)
} }
} }
@@ -88,7 +88,7 @@ internal class KtFirSymbolProvider(
override fun getVariableSymbol(psi: KtProperty): KtVariableSymbol = withValidityAssertion { override fun getVariableSymbol(psi: KtProperty): KtVariableSymbol = withValidityAssertion {
psi.withFirDeclarationOfType<FirProperty, KtVariableSymbol>(resolveState) { psi.withFirDeclarationOfType<FirProperty, KtVariableSymbol>(resolveState) {
firSymbolBuilder.buildVariableSymbol(it) firSymbolBuilder.variableLikeBuilder.buildVariableSymbol(it)
} }
} }
@@ -22,7 +22,7 @@ internal class KtFirMemberPropertySymbolPointer(
firSession: FirSession firSession: FirSession
): KtPropertySymbol? { ): KtPropertySymbol? {
val firProperty = candidates.findDeclarationWithSignature<FirProperty>(signature, firSession) ?: return null val firProperty = candidates.findDeclarationWithSignature<FirProperty>(signature, firSession) ?: return null
return firSymbolBuilder.buildVariableSymbol(firProperty) as? KtPropertySymbol return firSymbolBuilder.variableLikeBuilder.buildVariableSymbol(firProperty) as? KtPropertySymbol
} }
} }