FIR: JavaSymbolProviderWrapper -> JavaSymbolProvider

This commit is contained in:
pyos
2021-09-13 14:25:34 +02:00
committed by TeamCityServer
parent 30c8fa89f6
commit 032cf5a892
5 changed files with 69 additions and 51 deletions
@@ -28,8 +28,6 @@ import org.jetbrains.kotlin.fir.java.declarations.*
import org.jetbrains.kotlin.fir.java.enhancement.FirSignatureEnhancement
import org.jetbrains.kotlin.fir.resolve.constructType
import org.jetbrains.kotlin.fir.resolve.defaultType
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.ConeFlexibleType
@@ -47,49 +45,6 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.Variance.INVARIANT
import org.jetbrains.kotlin.util.OperatorNameConventions
// This symbol provider only loads JVM classes *not* annotated with Kotlin `@Metadata` annotation.
// Use it in application sessions for loading classes from Java files listed on the command line.
// For library and incremental compilation sessions use `KotlinDeserializedJvmSymbolsProvider`
// in order to load Kotlin classes as well.
class JavaSymbolProviderWrapper(session: FirSession, baseModuleData: FirModuleData, facade: JavaClassFinder) : FirSymbolProvider(session) {
private val javaClassConverter = JavaClassConverter(session, baseModuleData, facade)
private val classCache =
session.firCachesFactory.createCacheWithPostCompute(
createValue = { classId: ClassId, parentClassSymbol: FirRegularClassSymbol? ->
javaClassConverter.findClass(classId)?.let { FirRegularClassSymbol(classId) to (it to parentClassSymbol) }
?: null to (null to null)
},
postCompute = { _, classSymbol, (javaClass, parentClassSymbol) ->
if (classSymbol != null && javaClass != null) {
javaClassConverter.convertJavaClassToFir(classSymbol, parentClassSymbol, javaClass)
}
}
)
override fun getPackage(fqName: FqName): FqName? =
javaClassConverter.getPackage(fqName)
override fun getClassLikeSymbolByClassId(classId: ClassId): FirRegularClassSymbol? =
try {
if (javaClassConverter.hasTopLevelClassOf(classId)) getFirJavaClass(classId) else null
} catch (e: ProcessCanceledException) {
null
}
private fun getFirJavaClass(classId: ClassId): FirRegularClassSymbol? =
classCache.getValue(classId, classId.outerClassId?.let { getFirJavaClass(it) })
@OptIn(FirSymbolProviderInternals::class)
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {}
@OptIn(FirSymbolProviderInternals::class)
override fun getTopLevelFunctionSymbolsTo(destination: MutableList<FirNamedFunctionSymbol>, packageFqName: FqName, name: Name) {}
@OptIn(FirSymbolProviderInternals::class)
override fun getTopLevelPropertySymbolsTo(destination: MutableList<FirPropertySymbol>, packageFqName: FqName, name: Name) {}
}
@ThreadSafeMutableState
class JavaClassConverter(
private val session: FirSession,
@@ -0,0 +1,64 @@
/*
* 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.fir.java
import com.intellij.openapi.progress.ProcessCanceledException
import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.caches.firCachesFactory
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.load.java.JavaClassFinder
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
// This symbol provider only loads JVM classes *not* annotated with Kotlin `@Metadata` annotation.
// Use it in application sessions for loading classes from Java files listed on the command line.
// For library and incremental compilation sessions use `KotlinDeserializedJvmSymbolsProvider`
// in order to load Kotlin classes as well.
class JavaSymbolProvider(session: FirSession, baseModuleData: FirModuleData, facade: JavaClassFinder) : FirSymbolProvider(session) {
private val javaClassConverter = JavaClassConverter(session, baseModuleData, facade)
private val classCache =
session.firCachesFactory.createCacheWithPostCompute(
createValue = { classId: ClassId, parentClassSymbol: FirRegularClassSymbol? ->
javaClassConverter.findClass(classId)?.let { FirRegularClassSymbol(classId) to (it to parentClassSymbol) }
?: null to (null to null)
},
postCompute = { _, classSymbol, (javaClass, parentClassSymbol) ->
if (classSymbol != null && javaClass != null) {
javaClassConverter.convertJavaClassToFir(classSymbol, parentClassSymbol, javaClass)
}
}
)
override fun getPackage(fqName: FqName): FqName? =
javaClassConverter.getPackage(fqName)
override fun getClassLikeSymbolByClassId(classId: ClassId): FirRegularClassSymbol? =
try {
if (javaClassConverter.hasTopLevelClassOf(classId)) getFirJavaClass(classId) else null
} catch (e: ProcessCanceledException) {
null
}
private fun getFirJavaClass(classId: ClassId): FirRegularClassSymbol? =
classCache.getValue(classId, classId.outerClassId?.let { getFirJavaClass(it) })
@OptIn(FirSymbolProviderInternals::class)
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {}
@OptIn(FirSymbolProviderInternals::class)
override fun getTopLevelFunctionSymbolsTo(destination: MutableList<FirNamedFunctionSymbol>, packageFqName: FqName, name: Name) {}
@OptIn(FirSymbolProviderInternals::class)
override fun getTopLevelPropertySymbolsTo(destination: MutableList<FirPropertySymbol>, packageFqName: FqName, name: Name) {}
}
@@ -33,7 +33,7 @@ import java.nio.file.Paths
// This symbol provider loads JVM classes, reading extra info from Kotlin `@Metadata` annotations
// if present. Use it for library and incremental compilation sessions. For source sessions use
// `JavaSymbolProviderWrapper`, as Kotlin classes should be parsed first.
// `JavaSymbolProvider`, as Kotlin classes should be parsed first.
@ThreadSafeMutableState
class KotlinDeserializedJvmSymbolsProvider(
session: FirSession,