[Low Level API FIR] fix invalid traverse of supertypes list
the supertypes list should not be traversed without proper locking, otherwise some transformer may transform it concurrently In case of looking for a declaration by class id it just should not be traversed ^KTIJ-21791
This commit is contained in:
+6
-3
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LLFirFileBui
|
|||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCache
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCache
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.FirElementFinder
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.FirElementFinder
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.executeOrReturnDefaultValueOnPCE
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.executeOrReturnDefaultValueOnPCE
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
import org.jetbrains.kotlin.name.CallableId
|
import org.jetbrains.kotlin.name.CallableId
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -39,9 +40,11 @@ internal class LLFirProviderHelper(
|
|||||||
?: return@computeIfAbsent Optional.empty()
|
?: return@computeIfAbsent Optional.empty()
|
||||||
if (ktClass.getClassId() == null) return@computeIfAbsent Optional.empty()
|
if (ktClass.getClassId() == null) return@computeIfAbsent Optional.empty()
|
||||||
val firFile = firFileBuilder.buildRawFirFileWithCaching(ktClass.containingKtFile)
|
val firFile = firFileBuilder.buildRawFirFileWithCaching(ktClass.containingKtFile)
|
||||||
val classifier = FirElementFinder.findElementIn<FirClassLikeDeclaration>(firFile) { classifier ->
|
val classifier = FirElementFinder.findElementIn<FirClassLikeDeclaration>(
|
||||||
classifier.symbol.classId == classId
|
firFile,
|
||||||
}
|
canGoInside = { it is FirRegularClass },
|
||||||
|
predicate = { it.symbol.classId == classId },
|
||||||
|
)
|
||||||
?: error("Classifier $classId was found in file ${ktClass.containingKtFile.virtualFilePath} but was not found in FirFile")
|
?: error("Classifier $classId was found in file ${ktClass.containingKtFile.virtualFilePath} but was not found in FirFile")
|
||||||
Optional.of(classifier)
|
Optional.of(classifier)
|
||||||
}.getOrNull()
|
}.getOrNull()
|
||||||
|
|||||||
+2
-6
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.fir.FirElement
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.classId
|
import org.jetbrains.kotlin.fir.declarations.utils.classId
|
||||||
import org.jetbrains.kotlin.fir.psi
|
|
||||||
import org.jetbrains.kotlin.fir.render
|
import org.jetbrains.kotlin.fir.render
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
@@ -17,7 +16,7 @@ import org.jetbrains.kotlin.psi.KtElement
|
|||||||
object FirElementFinder {
|
object FirElementFinder {
|
||||||
inline fun <reified E : FirElement> findElementIn(
|
inline fun <reified E : FirElement> findElementIn(
|
||||||
container: FirElement,
|
container: FirElement,
|
||||||
crossinline goInside: (E) -> Boolean = { true },
|
crossinline canGoInside: (E) -> Boolean = { true },
|
||||||
crossinline predicate: (E) -> Boolean,
|
crossinline predicate: (E) -> Boolean,
|
||||||
): E? {
|
): E? {
|
||||||
var result: E? = null
|
var result: E? = null
|
||||||
@@ -31,7 +30,7 @@ object FirElementFinder {
|
|||||||
predicate(element) -> {
|
predicate(element) -> {
|
||||||
result = element
|
result = element
|
||||||
}
|
}
|
||||||
goInside(element) -> {
|
canGoInside(element) -> {
|
||||||
element.acceptChildren(this)
|
element.acceptChildren(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -61,7 +60,4 @@ object FirElementFinder {
|
|||||||
})
|
})
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <reified E : FirElement> findElementByPsiIn(container: FirElement, ktElement: KtElement): E? =
|
|
||||||
findElementIn(container) { it.psi === ktElement }
|
|
||||||
}
|
}
|
||||||
+1
-2
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
|||||||
import org.jetbrains.kotlin.fir.psi
|
import org.jetbrains.kotlin.fir.psi
|
||||||
import org.jetbrains.kotlin.fir.realPsi
|
import org.jetbrains.kotlin.fir.realPsi
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||||
|
|
||||||
@@ -63,7 +62,7 @@ private fun KtDeclaration.findSourceOfNonLocalFirDeclarationByTraversingWholeTre
|
|||||||
): FirDeclaration? {
|
): FirDeclaration? {
|
||||||
val firFile = containerFirFile ?: firFileBuilder.buildRawFirFileWithCaching(containingKtFile)
|
val firFile = containerFirFile ?: firFileBuilder.buildRawFirFileWithCaching(containingKtFile)
|
||||||
val originalDeclaration = originalDeclaration
|
val originalDeclaration = originalDeclaration
|
||||||
return FirElementFinder.findElementIn(firFile, goInside = { it is FirRegularClass }) { firDeclaration ->
|
return FirElementFinder.findElementIn(firFile, canGoInside = { it is FirRegularClass }) { firDeclaration ->
|
||||||
firDeclaration.psi == this || firDeclaration.psi == originalDeclaration
|
firDeclaration.psi == this || firDeclaration.psi == originalDeclaration
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user