FIR: fix class / constructor type parameter duplication

This commit is contained in:
Mikhail Glukhikh
2020-02-27 11:42:59 +03:00
parent 2308e5bb7c
commit 883dd95e3c
37 changed files with 38 additions and 64 deletions
@@ -28,7 +28,6 @@ import org.jetbrains.kotlin.fir.scopes.impl.lazyNestedClassifierScope
import org.jetbrains.kotlin.fir.scopes.impl.nestedClassifierScope
import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.ConeNullability
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.fir.toFirSourceElement
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
@@ -77,23 +76,33 @@ class JavaSymbolProvider(
}
}
private fun JavaTypeParameter.toFirTypeParameter(javaTypeParameterStack: JavaTypeParameterStack): FirTypeParameterBuilder {
javaTypeParameterStack.getBuilder(this)?.let { return it }
private fun JavaTypeParameter.toFirTypeParameterSymbol(
javaTypeParameterStack: JavaTypeParameterStack
): Pair<FirTypeParameterSymbol, Boolean> {
val stored = javaTypeParameterStack.safeGet(this)
if (stored != null) return stored to true
val firSymbol = FirTypeParameterSymbol()
javaTypeParameterStack.add(this, firSymbol)
return firSymbol to false
}
private fun JavaTypeParameter.toFirTypeParameter(
firSymbol: FirTypeParameterSymbol,
javaTypeParameterStack: JavaTypeParameterStack
): FirTypeParameter {
return FirTypeParameterBuilder().apply {
session = this@JavaSymbolProvider.session
name = this@toFirTypeParameter.name
this.session = this@JavaSymbolProvider.session
this.name = this@toFirTypeParameter.name
symbol = firSymbol
variance = INVARIANT
isReified = false
}.also {
javaTypeParameterStack.add(this, it)
}
addBounds(this@toFirTypeParameter, javaTypeParameterStack)
}.build()
}
private fun FirTypeParameterBuilder.addBounds(
javaTypeParameter: JavaTypeParameter,
stack: JavaTypeParameterStack,
stack: JavaTypeParameterStack
) {
for (upperBound in javaTypeParameter.upperBounds) {
bounds += upperBound.toFirResolvedTypeRef(
@@ -107,14 +116,12 @@ class JavaSymbolProvider(
}
private fun List<JavaTypeParameter>.convertTypeParameters(stack: JavaTypeParameterStack): List<FirTypeParameter> {
return this
.map { it.toFirTypeParameter(stack) }
.mapIndexed { index, typeParameterBuilder ->
if (typeParameterBuilder.bounds.isEmpty()) {
typeParameterBuilder.addBounds(this[index], stack)
}
typeParameterBuilder.build()
}
return map { it.toFirTypeParameterSymbol(stack) }.mapIndexed { index, (symbol, initialized) ->
// This nasty logic is required, because type parameter bound can refer other type parameter from the list
// So we have to create symbols first, and type parameters themselves after them
if (initialized) symbol.fir
else this[index].toFirTypeParameter(symbol, stack)
}
}
override fun getClassLikeSymbolByFqName(classId: ClassId): FirRegularClassSymbol? {
@@ -5,16 +5,15 @@
package org.jetbrains.kotlin.fir.java
import org.jetbrains.kotlin.fir.declarations.builder.FirTypeParameterBuilder
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter
internal class JavaTypeParameterStack {
private val typeParameterMap = mutableMapOf<JavaTypeParameter, FirTypeParameterBuilder>()
private val typeParameterMap = mutableMapOf<JavaTypeParameter, FirTypeParameterSymbol>()
fun add(javaTypeParameter: JavaTypeParameter, firTypeParameterBuilder: FirTypeParameterBuilder) {
typeParameterMap[javaTypeParameter] = firTypeParameterBuilder
fun add(javaTypeParameter: JavaTypeParameter, symbol: FirTypeParameterSymbol) {
typeParameterMap[javaTypeParameter] = symbol
}
fun addStack(javaTypeParameterStack: JavaTypeParameterStack) {
@@ -30,9 +29,7 @@ internal class JavaTypeParameterStack {
?: throw IllegalArgumentException("Cannot find Java type parameter $javaTypeParameter in stack")
}
fun safeGet(javaTypeParameter: JavaTypeParameter) = typeParameterMap[javaTypeParameter]?.symbol
fun getBuilder(javaTypeParameter: JavaTypeParameter) = typeParameterMap[javaTypeParameter]
fun safeGet(javaTypeParameter: JavaTypeParameter) = typeParameterMap[javaTypeParameter]
companion object {
val EMPTY: JavaTypeParameterStack = JavaTypeParameterStack()