[LL FIR] fix user code leak from exceptions in :analysis:low-level-api-fir

Also, add more info to some exceptions
This commit is contained in:
Ilya Kirillov
2023-07-20 13:32:09 +02:00
committed by Space Team
parent df16fa3306
commit e3d2bccb33
16 changed files with 150 additions and 35 deletions
@@ -26,7 +26,6 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.util.FirElementFinder
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.errorWithFirSpecificEntries import org.jetbrains.kotlin.analysis.low.level.api.fir.util.errorWithFirSpecificEntries
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.originalDeclaration import org.jetbrains.kotlin.analysis.low.level.api.fir.util.originalDeclaration
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
import org.jetbrains.kotlin.analysis.utils.errors.withPsiEntry
import org.jetbrains.kotlin.analysis.utils.printer.parentOfType import org.jetbrains.kotlin.analysis.utils.printer.parentOfType
import org.jetbrains.kotlin.analysis.utils.printer.parentsOfType import org.jetbrains.kotlin.analysis.utils.printer.parentsOfType
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirElement
@@ -38,11 +37,13 @@ import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirResolveContextCollector import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirResolveContextCollector
import org.jetbrains.kotlin.fir.scopes.createImportingScopes import org.jetbrains.kotlin.fir.scopes.createImportingScopes
import org.jetbrains.kotlin.fir.scopes.kotlinScopeProvider import org.jetbrains.kotlin.fir.scopes.kotlinScopeProvider
import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
import org.jetbrains.kotlin.psi.psiUtil.isAncestor import org.jetbrains.kotlin.psi.psiUtil.isAncestor
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.utils.exceptions.withPsiEntry
object LowLevelFirApiFacadeForResolveOnAir { object LowLevelFirApiFacadeForResolveOnAir {
private fun KtDeclaration.isApplicableForOnAirResolve(): Boolean = when (this) { private fun KtDeclaration.isApplicableForOnAirResolve(): Boolean = when (this) {
@@ -92,8 +93,8 @@ object LowLevelFirApiFacadeForResolveOnAir {
declaration.accept(expressionLocator) declaration.accept(expressionLocator)
return expressionLocator.result ?: errorWithFirSpecificEntries("Resolved on-air element was not found in containing declaration") { return expressionLocator.result ?: errorWithFirSpecificEntries("Resolved on-air element was not found in containing declaration") {
withPsiEntry("place", place, firResolveSession::getModule) withPsiEntry("place", place)
withPsiEntry("elementToResolve", elementToResolve, firResolveSession::getModule) withPsiEntry("elementToResolve", elementToResolve)
} }
} }
@@ -188,8 +189,8 @@ object LowLevelFirApiFacadeForResolveOnAir {
val originalNonLocalDeclaration = PsiTreeUtil.findSameElementInCopy(copiedNonLocalDeclaration, originalKtFile) val originalNonLocalDeclaration = PsiTreeUtil.findSameElementInCopy(copiedNonLocalDeclaration, originalKtFile)
?: errorWithAttachment("Cannot find original function matching") { ?: errorWithAttachment("Cannot find original function matching") {
withPsiEntry("matchingPsi", elementToAnalyze, originalFirResolveSession::getModule) withPsiEntry("matchingPsi", elementToAnalyze)
withPsiEntry("originalFile", originalKtFile, originalFirResolveSession::getModule) withPsiEntry("originalFile", originalKtFile)
} }
recordOriginalDeclaration(targetDeclaration = copiedNonLocalDeclaration, originalDeclaration = originalNonLocalDeclaration) recordOriginalDeclaration(targetDeclaration = copiedNonLocalDeclaration, originalDeclaration = originalNonLocalDeclaration)
@@ -289,7 +290,10 @@ object LowLevelFirApiFacadeForResolveOnAir {
?: errorWithFirSpecificEntries(message = "Impossible to collect designation", fir = originalFirFile, psi = originalDeclaration) ?: errorWithFirSpecificEntries(message = "Impossible to collect designation", fir = originalFirFile, psi = originalDeclaration)
val originalFirDeclaration = originalDesignationPath.target val originalFirDeclaration = originalDesignationPath.target
val session = originalFirDeclaration.llFirResolvableSession ?: error("Expected resolvable session") val session = originalFirDeclaration.llFirResolvableSession
?: errorWithAttachment("Expected resolvable session, found ${originalFirDeclaration.llFirSession::class}") {
withFirEntry("sessionOwner", originalFirDeclaration)
}
/** /**
* Special case for [getOnAirGetTowerContextProvider]. Can be dropped after KT-59498 * Special case for [getOnAirGetTowerContextProvider]. Can be dropped after KT-59498
@@ -371,7 +375,9 @@ object LowLevelFirApiFacadeForResolveOnAir {
is KtClassOrObject -> check(ktDeclaration.body) is KtClassOrObject -> check(ktDeclaration.body)
is KtScript -> check(ktDeclaration.blockExpression) is KtScript -> check(ktDeclaration.blockExpression)
is KtTypeAlias -> false is KtTypeAlias -> false
else -> error("Not supported type ${ktDeclaration::class.simpleName}") else -> errorWithAttachment("Not supported type ${ktDeclaration::class}") {
withPsiEntry("declaration", ktDeclaration)
}
} }
} }
} }
@@ -19,6 +19,9 @@ import org.jetbrains.kotlin.fir.declarations.utils.classId
import org.jetbrains.kotlin.fir.renderWithType import org.jetbrains.kotlin.fir.renderWithType
import org.jetbrains.kotlin.fir.resolve.SessionHolder import org.jetbrains.kotlin.fir.resolve.SessionHolder
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
import org.jetbrains.kotlin.utils.exceptions.requireWithAttachment
private class ContextCollectingDiagnosticCollectorVisitor private constructor( private class ContextCollectingDiagnosticCollectorVisitor private constructor(
sessionHolder: SessionHolder, sessionHolder: SessionHolder,
@@ -65,11 +68,16 @@ internal object PersistenceContextCollector {
is FirDanglingModifierList -> declaration.containingClass()?.classId?.isLocal == true is FirDanglingModifierList -> declaration.containingClass()?.classId?.isLocal == true
is FirAnonymousInitializer -> declaration.containingClass().classId.isLocal is FirAnonymousInitializer -> declaration.containingClass().classId.isLocal
is FirScript -> false is FirScript -> false
else -> error("Unsupported declaration ${declaration.renderWithType()}") else -> errorWithAttachment("Unsupported declaration ${declaration::class}") {
withFirEntry("declaration", declaration)
}
} }
require(!isLocal) { requireWithAttachment(
"Cannot collect context for local declaration ${declaration.renderWithType()}" !isLocal,
{ "Cannot collect context for local declaration ${declaration::class}" }
) {
withFirEntry("declaration", declaration)
} }
val designation = declaration.collectDesignation(firFile) val designation = declaration.collectDesignation(firFile)
@@ -36,6 +36,8 @@ import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.isObjectLiteral import org.jetbrains.kotlin.psi.psiUtil.isObjectLiteral
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
import org.jetbrains.kotlin.utils.exceptions.withPsiEntry
@ThreadSafe @ThreadSafe
internal class FirElementBuilder( internal class FirElementBuilder(
@@ -51,7 +53,9 @@ internal class FirElementBuilder(
KtQualifiedExpression with KtCallExpression in selector transformed in FIR to FirFunctionCall expression KtQualifiedExpression with KtCallExpression in selector transformed in FIR to FirFunctionCall expression
Which will have a receiver as qualifier Which will have a receiver as qualifier
*/ */
deparenthesized.selectorExpression ?: error("Incomplete code:\n${element.getElementTextWithContext()}") deparenthesized.selectorExpression ?: errorWithAttachment("Incomplete code") {
withPsiEntry("psi", deparenthesized)
}
} }
deparenthesized is KtValueArgument -> { deparenthesized is KtValueArgument -> {
// null will be return in case of invalid KtValueArgument // null will be return in case of invalid KtValueArgument
@@ -26,6 +26,8 @@ import java.util.concurrent.ConcurrentHashMap
import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.canBePartOfParentDeclaration import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.canBePartOfParentDeclaration
import org.jetbrains.kotlin.fir.correspondingProperty import org.jetbrains.kotlin.fir.correspondingProperty
import org.jetbrains.kotlin.fir.declarations.impl.FirPrimaryConstructor import org.jetbrains.kotlin.fir.declarations.impl.FirPrimaryConstructor
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
import org.jetbrains.kotlin.utils.exceptions.withPsiEntry
internal class FileStructure private constructor( internal class FileStructure private constructor(
private val ktFile: KtFile, private val ktFile: KtFile,
@@ -203,6 +205,8 @@ internal class FileStructure private constructor(
} }
container is KtDeclaration -> createDeclarationStructure(container) container is KtDeclaration -> createDeclarationStructure(container)
container is KtModifierList && container.nextSibling is PsiErrorElement -> createDanglingModifierListStructure(container) container is KtModifierList && container.nextSibling is PsiErrorElement -> createDanglingModifierListStructure(container)
else -> error("Invalid container $container") else -> errorWithAttachment("Invalid container ${container::class}") {
withPsiEntry("container", container)
}
} }
} }
@@ -14,6 +14,8 @@ import org.jetbrains.kotlin.psi
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
import org.jetbrains.kotlin.utils.exceptions.withPsiEntry
internal fun FirDeclaration.getKtDeclarationForFirElement(): KtDeclaration { internal fun FirDeclaration.getKtDeclarationForFirElement(): KtDeclaration {
require(this !is FirFile) require(this !is FirFile)
@@ -63,5 +65,7 @@ internal fun declarationCanBeLazilyResolved(declaration: KtDeclaration): Boolean
!is KtNamedDeclaration -> false !is KtNamedDeclaration -> false
is KtClassOrObject -> !declaration.isLocal is KtClassOrObject -> !declaration.isLocal
is KtTypeAlias -> declaration.isTopLevel() || declaration.getClassId() != null is KtTypeAlias -> declaration.isTopLevel() || declaration.getClassId() != null
else -> error("Unexpected ${declaration::class.qualifiedName}") else -> errorWithAttachment("Unexpected ${declaration::class}") {
withPsiEntry("declaration", declaration)
}
} }
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.resolve.providers.* import org.jetbrains.kotlin.fir.resolve.providers.*
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.utils.exceptions.withFirSymbolEntry
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
@@ -24,6 +25,7 @@ import org.jetbrains.kotlin.psi.KtCallableDeclaration
import org.jetbrains.kotlin.psi.KtClassLikeDeclaration import org.jetbrains.kotlin.psi.KtClassLikeDeclaration
import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
@ThreadSafeMutableState @ThreadSafeMutableState
internal class LLFirProvider( internal class LLFirProvider(
@@ -62,7 +64,9 @@ internal class LLFirProvider(
override fun getFirClassifierContainerFile(fqName: ClassId): FirFile { override fun getFirClassifierContainerFile(fqName: ClassId): FirFile {
return getFirClassifierContainerFileIfAny(fqName) return getFirClassifierContainerFileIfAny(fqName)
?: error("Couldn't find container for $fqName") ?: errorWithAttachment("Couldn't find container") {
withEntry("classId", fqName.asString())
}
} }
override fun getFirClassifierContainerFileIfAny(fqName: ClassId): FirFile? { override fun getFirClassifierContainerFileIfAny(fqName: ClassId): FirFile? {
@@ -72,7 +76,9 @@ internal class LLFirProvider(
override fun getFirClassifierContainerFile(symbol: FirClassLikeSymbol<*>): FirFile { override fun getFirClassifierContainerFile(symbol: FirClassLikeSymbol<*>): FirFile {
return getFirClassifierContainerFileIfAny(symbol) return getFirClassifierContainerFileIfAny(symbol)
?: error("Couldn't find container for ${symbol.classId}") ?: errorWithAttachment("Couldn't find container") {
withFirSymbolEntry("symbol", symbol)
}
} }
override fun getFirClassifierContainerFileIfAny(symbol: FirClassLikeSymbol<*>): FirFile? { override fun getFirClassifierContainerFileIfAny(symbol: FirClassLikeSymbol<*>): FirFile? {
@@ -34,6 +34,8 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtClassLikeDeclaration import org.jetbrains.kotlin.psi.KtClassLikeDeclaration
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
import org.jetbrains.kotlin.utils.exceptions.withVirtualFileEntry
internal class LLFirProviderHelper( internal class LLFirProviderHelper(
firSession: LLFirSession, firSession: LLFirSession,
@@ -78,7 +80,10 @@ internal class LLFirProviderHelper(
if (ktClass.getClassId() == null) return@createCache null if (ktClass.getClassId() == null) return@createCache null
val firFile = firFileBuilder.buildRawFirFileWithCaching(ktClass.containingKtFile) val firFile = firFileBuilder.buildRawFirFileWithCaching(ktClass.containingKtFile)
FirElementFinder.findClassifierWithClassId(firFile, classId) FirElementFinder.findClassifierWithClassId(firFile, classId)
?: error("Classifier $classId was found in file ${ktClass.containingKtFile.virtualFilePath} but was not found in FirFile") ?: errorWithAttachment("Classifier was found in KtFile but was not found in FirFile") {
withEntry("classifierClassId", classId) { it.asString() }
withVirtualFileEntry("virtualFile", ktClass.containingKtFile.virtualFile)
}
} }
private val callablesByCallableId = private val callablesByCallableId =
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.analysis.providers.createAnnotationResolver
import org.jetbrains.kotlin.analysis.providers.createDeclarationProvider import org.jetbrains.kotlin.analysis.providers.createDeclarationProvider
import org.jetbrains.kotlin.analysis.providers.impl.declarationProviders.FileBasedKotlinDeclarationProvider import org.jetbrains.kotlin.analysis.providers.impl.declarationProviders.FileBasedKotlinDeclarationProvider
import org.jetbrains.kotlin.analysis.providers.impl.util.mergeInto import org.jetbrains.kotlin.analysis.providers.impl.util.mergeInto
import org.jetbrains.kotlin.analysis.utils.errors.withKtModuleEntry
import org.jetbrains.kotlin.analysis.utils.trackers.CompositeModificationTracker import org.jetbrains.kotlin.analysis.utils.trackers.CompositeModificationTracker
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.LanguageVersionSettings
@@ -48,6 +49,8 @@ import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
import org.jetbrains.kotlin.scripting.compiler.plugin.FirScriptingSamWithReceiverExtensionRegistrar import org.jetbrains.kotlin.scripting.compiler.plugin.FirScriptingSamWithReceiverExtensionRegistrar
import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
import org.jetbrains.kotlin.utils.exceptions.withVirtualFileEntry
import kotlin.script.experimental.host.ScriptingHostConfiguration import kotlin.script.experimental.host.ScriptingHostConfiguration
import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration
@@ -158,7 +161,9 @@ internal abstract class LLFirAbstractSessionFactory(protected val project: Proje
FirSessionConfigurator(this).apply { FirSessionConfigurator(this).apply {
val hostConfiguration = ScriptingHostConfiguration(defaultJvmScriptingHostConfiguration) {} val hostConfiguration = ScriptingHostConfiguration(defaultJvmScriptingHostConfiguration) {}
val scriptDefinition = module.file.findScriptDefinition() val scriptDefinition = module.file.findScriptDefinition()
?: error("Cannot load script definition for ${module.file.virtualFilePath}") ?: errorWithAttachment("Cannot load script definition") {
withVirtualFileEntry("file", module.file.virtualFile)
}
val extensionRegistrar = FirScriptingCompilerExtensionIdeRegistrar( val extensionRegistrar = FirScriptingCompilerExtensionIdeRegistrar(
project, project,
@@ -325,7 +330,9 @@ internal abstract class LLFirAbstractSessionFactory(protected val project: Proje
val libraryModule = when (module) { val libraryModule = when (module) {
is KtLibraryModule -> module is KtLibraryModule -> module
is KtLibrarySourceModule -> module.binaryLibrary is KtLibrarySourceModule -> module.binaryLibrary
else -> error("Unexpected module ${module::class.simpleName}") else -> errorWithAttachment("Unexpected module ${module::class.simpleName}") {
withKtModuleEntry("module", module)
}
} }
val platform = module.platform val platform = module.platform
@@ -480,7 +487,13 @@ internal abstract class LLFirAbstractSessionFactory(protected val project: Proje
is KtScriptModule, is KtScriptModule,
is KtScriptDependencyModule, is KtScriptDependencyModule,
is KtNotUnderContentRootModule, is KtNotUnderContentRootModule,
is KtLibrarySourceModule -> error("Module $module cannot depend on ${dependency::class}: $dependency") is KtLibrarySourceModule,
-> {
errorWithAttachment("Module ${module::class} cannot depend on ${dependency::class}") {
withKtModuleEntry("module", module)
withKtModuleEntry("dependency", dependency)
}
}
} }
val dependencyModules = buildSet { val dependencyModules = buildSet {
@@ -16,6 +16,8 @@ import org.jetbrains.kotlin.load.java.JavaClassFinder
import org.jetbrains.kotlin.load.java.structure.JavaClass import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.java.structure.classId import org.jetbrains.kotlin.load.java.structure.classId
import org.jetbrains.kotlin.load.java.structure.impl.VirtualFileBoundJavaClass import org.jetbrains.kotlin.load.java.structure.impl.VirtualFileBoundJavaClass
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
import org.jetbrains.kotlin.utils.exceptions.withVirtualFileEntry
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.Paths import java.nio.file.Paths
@@ -34,7 +36,9 @@ internal class LLFirJavaFacadeForBinaries(
private fun getBinaryPath(javaClass: VirtualFileBoundJavaClass): Path { private fun getBinaryPath(javaClass: VirtualFileBoundJavaClass): Path {
val virtualFile = javaClass.virtualFile val virtualFile = javaClass.virtualFile
?: error("no virtual file for ${javaClass.classId}") ?: errorWithAttachment("no virtual file") {
withEntry("javaClass", javaClass) { it.toString() }
}
val path = virtualFile.path val path = virtualFile.path
return when { return when {
JAR_DELIMITER in path -> JAR_DELIMITER in path ->
@@ -35,6 +35,8 @@ import org.jetbrains.kotlin.psi.stubs.impl.KotlinAnnotationEntryStubImpl
import org.jetbrains.kotlin.psi.stubs.impl.KotlinClassTypeBean import org.jetbrains.kotlin.psi.stubs.impl.KotlinClassTypeBean
import org.jetbrains.kotlin.psi.stubs.impl.KotlinPropertyStubImpl import org.jetbrains.kotlin.psi.stubs.impl.KotlinPropertyStubImpl
import org.jetbrains.kotlin.types.ConstantValueKind import org.jetbrains.kotlin.types.ConstantValueKind
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
import org.jetbrains.kotlin.utils.exceptions.withPsiEntry
class StubBasedAnnotationDeserializer( class StubBasedAnnotationDeserializer(
private val session: FirSession, private val session: FirSession,
@@ -151,7 +153,9 @@ class StubBasedAnnotationDeserializer(
is IntValue -> const(ConstantValueKind.Int, value.value, session.builtinTypes.intType, sourceElement) is IntValue -> const(ConstantValueKind.Int, value.value, session.builtinTypes.intType, sourceElement)
NullValue -> const(ConstantValueKind.Null, null, session.builtinTypes.nullableAnyType, sourceElement) NullValue -> const(ConstantValueKind.Null, null, session.builtinTypes.nullableAnyType, sourceElement)
is StringValue -> const(ConstantValueKind.String, value.value, session.builtinTypes.stringType, sourceElement) is StringValue -> const(ConstantValueKind.String, value.value, session.builtinTypes.stringType, sourceElement)
else -> error("Unexpected value $value") else -> errorWithAttachment("Unexpected value ${value::class}") {
withEntry("value", value.toString())
}
} }
} }
@@ -31,6 +31,8 @@ import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.* import org.jetbrains.kotlin.name.*
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
import org.jetbrains.kotlin.utils.exceptions.withPsiEntry
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
internal val KtModifierListOwner.visibility: Visibility internal val KtModifierListOwner.visibility: Visibility
@@ -98,7 +100,9 @@ internal fun deserializeClassToSymbol(
classOrObject.isAnnotation() -> ClassKind.ANNOTATION_CLASS classOrObject.isAnnotation() -> ClassKind.ANNOTATION_CLASS
else -> ClassKind.CLASS else -> ClassKind.CLASS
} }
else -> throw AssertionError("Unexpected class or object: ${classOrObject.text}") else -> errorWithAttachment("Unexpected class or object: ${classOrObject::class}") {
withPsiEntry("class", classOrObject)
}
} }
val modality = classOrObject.modality val modality = classOrObject.modality
val visibility = classOrObject.visibility val visibility = classOrObject.visibility
@@ -155,9 +159,12 @@ internal fun deserializeClassToSymbol(
val superTypeList = classOrObject.getSuperTypeList() val superTypeList = classOrObject.getSuperTypeList()
if (superTypeList != null) { if (superTypeList != null) {
superTypeRefs.addAll(superTypeList.entries.map { superTypeRefs.addAll(superTypeList.entries.map { superTypeReference ->
typeDeserializer.typeRef( typeDeserializer.typeRef(
it.typeReference ?: error("Super entry doesn't have type reference $it") superTypeReference.typeReference
?: errorWithAttachment("Super entry doesn't have type reference") {
withPsiEntry("superTypeReference", superTypeReference)
}
) )
}) })
} else if (StandardClassIds.Any != classId && StandardClassIds.Nothing != classId) { } else if (StandardClassIds.Any != classId && StandardClassIds.Nothing != classId) {
@@ -176,8 +183,12 @@ internal fun deserializeClassToSymbol(
is KtProperty -> addDeclaration(memberDeserializer.loadProperty(declaration, symbol)) is KtProperty -> addDeclaration(memberDeserializer.loadProperty(declaration, symbol))
is KtEnumEntry -> addDeclaration(memberDeserializer.loadEnumEntry(declaration, symbol, classId)) is KtEnumEntry -> addDeclaration(memberDeserializer.loadEnumEntry(declaration, symbol, classId))
is KtClassOrObject -> { is KtClassOrObject -> {
val name = declaration.name
?: errorWithAttachment("Class doesn't have name $declaration") {
withPsiEntry("class", declaration)
}
val nestedClassId = val nestedClassId =
classId.createNestedClassId(Name.identifier(declaration.name ?: error("Class doesn't have name $declaration"))) classId.createNestedClassId(Name.identifier(name))
deserializeNestedClass(nestedClassId, context)?.fir?.let { addDeclaration(it) } deserializeNestedClass(nestedClassId, context)?.fir?.let { addDeclaration(it) }
} }
is KtTypeAlias -> addDeclaration( is KtTypeAlias -> addDeclaration(
@@ -31,12 +31,15 @@ import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.fir.types.impl.FirImplicitUnitTypeRef import org.jetbrains.kotlin.fir.types.impl.FirImplicitUnitTypeRef
import org.jetbrains.kotlin.fir.utils.exceptions.withFirSymbolEntry
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.* import org.jetbrains.kotlin.name.*
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
import org.jetbrains.kotlin.toKtPsiSourceElement import org.jetbrains.kotlin.toKtPsiSourceElement
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
import org.jetbrains.kotlin.utils.exceptions.withPsiEntry
internal class StubBasedFirDeserializationContext( internal class StubBasedFirDeserializationContext(
val moduleData: FirModuleData, val moduleData: FirModuleData,
@@ -185,7 +188,10 @@ internal class StubBasedFirMemberDeserializer(
annotations += c.annotationDeserializer.loadAnnotations(typeAlias) annotations += c.annotationDeserializer.loadAnnotations(typeAlias)
symbol = aliasSymbol symbol = aliasSymbol
expandedTypeRef = typeAlias.getTypeReference()?.toTypeRef(local) ?: error("Type alias doesn't have type reference $typeAlias") expandedTypeRef = typeAlias.getTypeReference()?.toTypeRef(local)
?: errorWithAttachment("Type alias doesn't have type reference") {
withPsiEntry("property", typeAlias)
}
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
typeParameters += local.typeDeserializer.ownTypeParameters.map { it.fir } typeParameters += local.typeDeserializer.ownTypeParameters.map { it.fir }
}.apply { }.apply {
@@ -269,7 +275,10 @@ internal class StubBasedFirMemberDeserializer(
val symbol = existingSymbol ?: FirPropertySymbol(callableId) val symbol = existingSymbol ?: FirPropertySymbol(callableId)
val local = c.childContext(property, containingDeclarationSymbol = symbol) val local = c.childContext(property, containingDeclarationSymbol = symbol)
val returnTypeRef = property.typeReference?.toTypeRef(local) ?: error("Property doesn't have type reference, $property") val returnTypeRef = property.typeReference?.toTypeRef(local)
?: errorWithAttachment("Property doesn't have type reference") {
withPsiEntry("property", property)
}
val getter = property.getter val getter = property.getter
val receiverTypeReference = property.receiverTypeReference val receiverTypeReference = property.receiverTypeReference
@@ -525,7 +534,11 @@ internal class StubBasedFirMemberDeserializer(
this.containingFunctionSymbol = functionSymbol this.containingFunctionSymbol = functionSymbol
origin = initialOrigin origin = initialOrigin
returnTypeRef = returnTypeRef =
ktParameter.typeReference?.toTypeRef(c) ?: error("KtParameter $ktParameter doesn't have type, $functionSymbol") ktParameter.typeReference?.toTypeRef(c)
?: errorWithAttachment("KtParameter doesn't have type") {
withPsiEntry("ktParameter", ktParameter)
withFirSymbolEntry("functionSymbol", functionSymbol)
}
isVararg = ktParameter.isVarArg isVararg = ktParameter.isVarArg
if (isVararg) { if (isVararg) {
returnTypeRef = returnTypeRef.withReplacedReturnType(returnTypeRef.coneType.createOutArrayType()) returnTypeRef = returnTypeRef.withReplacedReturnType(returnTypeRef.coneType.createOutArrayType())
@@ -554,7 +567,10 @@ internal class StubBasedFirMemberDeserializer(
symbol: FirRegularClassSymbol, symbol: FirRegularClassSymbol,
classId: ClassId classId: ClassId
): FirEnumEntry { ): FirEnumEntry {
val enumEntryName = declaration.name ?: error("Enum entry doesn't provide name $declaration") val enumEntryName = declaration.name
?: errorWithAttachment("Enum entry doesn't provide name") {
withPsiEntry("declaration", declaration)
}
val enumType = ConeClassLikeTypeImpl(symbol.toLookupTag(), emptyArray(), false) val enumType = ConeClassLikeTypeImpl(symbol.toLookupTag(), emptyArray(), false)
val enumEntry = buildEnumEntry { val enumEntry = buildEnumEntry {
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.fir.utils.exceptions.withConeTypeEntry
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
@@ -36,6 +37,8 @@ import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
import org.jetbrains.kotlin.psi.stubs.impl.* import org.jetbrains.kotlin.psi.stubs.impl.*
import org.jetbrains.kotlin.types.ConstantValueKind import org.jetbrains.kotlin.types.ConstantValueKind
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
import org.jetbrains.kotlin.utils.exceptions.withPsiEntry
internal class StubBasedFirTypeDeserializer( internal class StubBasedFirTypeDeserializer(
private val moduleData: FirModuleData, private val moduleData: FirModuleData,
@@ -141,7 +144,10 @@ internal class StubBasedFirTypeDeserializer(
return@map ConeStarProjection return@map ConeStarProjection
} }
val argBean = typeArgumentBean.type!! val argBean = typeArgumentBean.type!!
val lowerBound = type(argBean) ?: error("Broken type argument ${typeArgumentBean.type}") val lowerBound = type(argBean)
?: errorWithAttachment("Broken type argument ${typeArgumentBean.type?.let { it::class }}") {
withEntry("type", typeArgumentBean.type) { it.toString() }
}
typeArgument(lowerBound, kind) typeArgument(lowerBound, kind)
} }
return ConeClassLikeTypeImpl( return ConeClassLikeTypeImpl(
@@ -155,8 +161,14 @@ internal class StubBasedFirTypeDeserializer(
val lowerBound = type(type.lowerBound) val lowerBound = type(type.lowerBound)
val upperBound = type(type.upperBound) val upperBound = type(type.upperBound)
return ConeFlexibleType( return ConeFlexibleType(
lowerBound as? ConeSimpleKotlinType ?: error("Unexpected lower bound $lowerBound"), lowerBound as? ConeSimpleKotlinType
upperBound as? ConeSimpleKotlinType ?: error("Unexpected upper bound $upperBound") ?: errorWithAttachment("Unexpected lower bound ${lowerBound?.let { it::class }}") {
withConeTypeEntry("lowerBound", lowerBound)
},
upperBound as? ConeSimpleKotlinType
?: errorWithAttachment("Unexpected lower bound ${upperBound?.let { it::class }}") {
withConeTypeEntry("upperBound", upperBound)
},
) )
} }
} }
@@ -208,7 +220,9 @@ internal class StubBasedFirTypeDeserializer(
addAll(typeElement.parameters.map { type(it.typeReference!!).toTypeProjection(Variance.INVARIANT) }) addAll(typeElement.parameters.map { type(it.typeReference!!).toTypeProjection(Variance.INVARIANT) })
add(type(typeElement.returnTypeReference!!).toTypeProjection(Variance.INVARIANT)) add(type(typeElement.returnTypeReference!!).toTypeProjection(Variance.INVARIANT))
}.toTypedArray() }.toTypedArray()
else -> error("not supported $typeElement") else -> errorWithAttachment("not supported ${typeElement?.let { it::class }}") {
withPsiEntry("typeElement", typeElement)
}
} }
return ConeClassLikeTypeImpl( return ConeClassLikeTypeImpl(
@@ -25,7 +25,9 @@ import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirResolveCont
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry
import org.jetbrains.kotlin.fir.visitors.transformSingle import org.jetbrains.kotlin.fir.visitors.transformSingle
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
internal object LLFirTypeLazyResolver : LLFirLazyResolver(FirResolvePhase.TYPES) { internal object LLFirTypeLazyResolver : LLFirLazyResolver(FirResolvePhase.TYPES) {
override fun resolve( override fun resolve(
@@ -128,7 +130,9 @@ private class LLFirTypeTargetResolver(
resolveClassTypes(target) resolveClassTypes(target)
} }
is FirAnonymousInitializer -> {} is FirAnonymousInitializer -> {}
else -> error("Unknown declaration ${target::class.java}") else -> errorWithAttachment("Unknown declaration ${target::class}") {
withFirEntry("declaration", target)
}
} }
} }
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.compiler.based package org.jetbrains.kotlin.analysis.low.level.api.fir.compiler.based
import org.jetbrains.kotlin.analysis.utils.errors.withKtModuleEntry
import org.jetbrains.kotlin.diagnostics.* import org.jetbrains.kotlin.diagnostics.*
import org.jetbrains.kotlin.diagnostics.rendering.RootDiagnosticRendererFactory import org.jetbrains.kotlin.diagnostics.rendering.RootDiagnosticRendererFactory
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeKotlinType
@@ -15,6 +16,8 @@ import org.jetbrains.kotlin.test.frontend.fir.handlers.FirAnalysisHandler
import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.assertions import org.jetbrains.kotlin.test.services.assertions
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
import org.jetbrains.kotlin.utils.exceptions.withPsiEntry
internal class LLDiagnosticParameterChecker(testServices: TestServices) : FirAnalysisHandler(testServices) { internal class LLDiagnosticParameterChecker(testServices: TestServices) : FirAnalysisHandler(testServices) {
override fun processModule(module: TestModule, info: FirOutputArtifact) { override fun processModule(module: TestModule, info: FirOutputArtifact) {
@@ -56,7 +59,9 @@ internal class LLDiagnosticParameterChecker(testServices: TestServices) : FirAna
is KtPsiDiagnosticWithParameters3<*, *, *> -> listOf(a, b, c) is KtPsiDiagnosticWithParameters3<*, *, *> -> listOf(a, b, c)
is KtPsiDiagnosticWithParameters4<*, *, *, *> -> listOf(a, b, c, d) is KtPsiDiagnosticWithParameters4<*, *, *, *> -> listOf(a, b, c, d)
is KtPsiSimpleDiagnostic -> emptyList() is KtPsiSimpleDiagnostic -> emptyList()
else -> error("Unexpected diagnostic $this") else -> errorWithAttachment("Unexpected diagnostic ${this::class}, $factoryName") {
withPsiEntry("onElement", psiElement)
}
} }
override fun processAfterAllModules(someAssertionWasFailed: Boolean) {} override fun processAfterAllModules(someAssertionWasFailed: Boolean) {}
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.utils.exceptions package org.jetbrains.kotlin.utils.exceptions
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.utils.getElementTextWithContext import org.jetbrains.kotlin.utils.getElementTextWithContext
@@ -13,3 +14,9 @@ fun ExceptionAttachmentBuilder.withPsiEntry(name: String, psi: PsiElement?) {
getElementTextWithContext(psiElement) getElementTextWithContext(psiElement)
} }
} }
fun ExceptionAttachmentBuilder.withVirtualFileEntry(name: String, virtualFile: VirtualFile?) {
withEntry(name, virtualFile) { file ->
"path: ${file.path}, filetype: ${file.fileType} ,filesystem,${file.fileSystem}"
}
}