diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/LowLevelFirApiFacadeForResolveOnAir.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/LowLevelFirApiFacadeForResolveOnAir.kt index 7e684e2379a..db9fcc8d923 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/LowLevelFirApiFacadeForResolveOnAir.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/LowLevelFirApiFacadeForResolveOnAir.kt @@ -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.originalDeclaration 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.parentsOfType 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.scopes.createImportingScopes 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.psi.* import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType import org.jetbrains.kotlin.psi.psiUtil.isAncestor import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf +import org.jetbrains.kotlin.utils.exceptions.withPsiEntry object LowLevelFirApiFacadeForResolveOnAir { private fun KtDeclaration.isApplicableForOnAirResolve(): Boolean = when (this) { @@ -92,8 +93,8 @@ object LowLevelFirApiFacadeForResolveOnAir { declaration.accept(expressionLocator) return expressionLocator.result ?: errorWithFirSpecificEntries("Resolved on-air element was not found in containing declaration") { - withPsiEntry("place", place, firResolveSession::getModule) - withPsiEntry("elementToResolve", elementToResolve, firResolveSession::getModule) + withPsiEntry("place", place) + withPsiEntry("elementToResolve", elementToResolve) } } @@ -188,8 +189,8 @@ object LowLevelFirApiFacadeForResolveOnAir { val originalNonLocalDeclaration = PsiTreeUtil.findSameElementInCopy(copiedNonLocalDeclaration, originalKtFile) ?: errorWithAttachment("Cannot find original function matching") { - withPsiEntry("matchingPsi", elementToAnalyze, originalFirResolveSession::getModule) - withPsiEntry("originalFile", originalKtFile, originalFirResolveSession::getModule) + withPsiEntry("matchingPsi", elementToAnalyze) + withPsiEntry("originalFile", originalKtFile) } recordOriginalDeclaration(targetDeclaration = copiedNonLocalDeclaration, originalDeclaration = originalNonLocalDeclaration) @@ -289,7 +290,10 @@ object LowLevelFirApiFacadeForResolveOnAir { ?: errorWithFirSpecificEntries(message = "Impossible to collect designation", fir = originalFirFile, psi = originalDeclaration) 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 @@ -371,7 +375,9 @@ object LowLevelFirApiFacadeForResolveOnAir { is KtClassOrObject -> check(ktDeclaration.body) is KtScript -> check(ktDeclaration.blockExpression) is KtTypeAlias -> false - else -> error("Not supported type ${ktDeclaration::class.simpleName}") + else -> errorWithAttachment("Not supported type ${ktDeclaration::class}") { + withPsiEntry("declaration", ktDeclaration) + } } } } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/fir/ContextCollectingDiagnosticCollectorVisitor.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/fir/ContextCollectingDiagnosticCollectorVisitor.kt index 9f25349140d..4cbaad75efc 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/fir/ContextCollectingDiagnosticCollectorVisitor.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/fir/ContextCollectingDiagnosticCollectorVisitor.kt @@ -19,6 +19,9 @@ import org.jetbrains.kotlin.fir.declarations.utils.classId import org.jetbrains.kotlin.fir.renderWithType import org.jetbrains.kotlin.fir.resolve.SessionHolder 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( sessionHolder: SessionHolder, @@ -65,11 +68,16 @@ internal object PersistenceContextCollector { is FirDanglingModifierList -> declaration.containingClass()?.classId?.isLocal == true is FirAnonymousInitializer -> declaration.containingClass().classId.isLocal is FirScript -> false - else -> error("Unsupported declaration ${declaration.renderWithType()}") + else -> errorWithAttachment("Unsupported declaration ${declaration::class}") { + withFirEntry("declaration", declaration) + } } - require(!isLocal) { - "Cannot collect context for local declaration ${declaration.renderWithType()}" + requireWithAttachment( + !isLocal, + { "Cannot collect context for local declaration ${declaration::class}" } + ) { + withFirEntry("declaration", declaration) } val designation = declaration.collectDesignation(firFile) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/FirElementBuilder.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/FirElementBuilder.kt index ea47a28d96b..f39671cc617 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/FirElementBuilder.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/FirElementBuilder.kt @@ -36,6 +36,8 @@ import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.isObjectLiteral import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf +import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment +import org.jetbrains.kotlin.utils.exceptions.withPsiEntry @ThreadSafe internal class FirElementBuilder( @@ -51,7 +53,9 @@ internal class FirElementBuilder( KtQualifiedExpression with KtCallExpression in selector transformed in FIR to FirFunctionCall expression 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 -> { // null will be return in case of invalid KtValueArgument diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructure.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructure.kt index 791c050bbbe..e3a08759468 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructure.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructure.kt @@ -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.fir.correspondingProperty 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( private val ktFile: KtFile, @@ -203,6 +205,8 @@ internal class FileStructure private constructor( } container is KtDeclaration -> createDeclarationStructure(container) container is KtModifierList && container.nextSibling is PsiErrorElement -> createDanglingModifierListStructure(container) - else -> error("Invalid container $container") + else -> errorWithAttachment("Invalid container ${container::class}") { + withPsiEntry("container", container) + } } } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/NonLocalDeclarationUtils.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/NonLocalDeclarationUtils.kt index c0b84b46f20..afb887c86b2 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/NonLocalDeclarationUtils.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/NonLocalDeclarationUtils.kt @@ -14,6 +14,8 @@ import org.jetbrains.kotlin.psi import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject 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 { require(this !is FirFile) @@ -63,5 +65,7 @@ internal fun declarationCanBeLazilyResolved(declaration: KtDeclaration): Boolean !is KtNamedDeclaration -> false is KtClassOrObject -> !declaration.isLocal is KtTypeAlias -> declaration.isTopLevel() || declaration.getClassId() != null - else -> error("Unexpected ${declaration::class.qualifiedName}") + else -> errorWithAttachment("Unexpected ${declaration::class}") { + withPsiEntry("declaration", declaration) + } } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProvider.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProvider.kt index 591ecc606bd..bf2aff36a85 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProvider.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProvider.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.resolve.providers.* 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.ClassId 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.KtNamedFunction import org.jetbrains.kotlin.psi.KtProperty +import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment @ThreadSafeMutableState internal class LLFirProvider( @@ -62,7 +64,9 @@ internal class LLFirProvider( override fun getFirClassifierContainerFile(fqName: ClassId): FirFile { 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? { @@ -72,7 +76,9 @@ internal class LLFirProvider( override fun getFirClassifierContainerFile(symbol: FirClassLikeSymbol<*>): FirFile { 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? { diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProviderHelper.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProviderHelper.kt index 0d556e50a4d..3bfb7f7a188 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProviderHelper.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProviderHelper.kt @@ -34,6 +34,8 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtClassLikeDeclaration import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment +import org.jetbrains.kotlin.utils.exceptions.withVirtualFileEntry internal class LLFirProviderHelper( firSession: LLFirSession, @@ -78,7 +80,10 @@ internal class LLFirProviderHelper( if (ktClass.getClassId() == null) return@createCache null val firFile = firFileBuilder.buildRawFirFileWithCaching(ktClass.containingKtFile) 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 = diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirAbstractSessionFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirAbstractSessionFactory.kt index df200002ce0..eccd2ca6c8f 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirAbstractSessionFactory.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirAbstractSessionFactory.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.analysis.providers.createAnnotationResolver import org.jetbrains.kotlin.analysis.providers.createDeclarationProvider import org.jetbrains.kotlin.analysis.providers.impl.declarationProviders.FileBasedKotlinDeclarationProvider 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.config.LanguageFeature 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.scripting.compiler.plugin.FirScriptingSamWithReceiverExtensionRegistrar 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.jvm.defaultJvmScriptingHostConfiguration @@ -158,7 +161,9 @@ internal abstract class LLFirAbstractSessionFactory(protected val project: Proje FirSessionConfigurator(this).apply { val hostConfiguration = ScriptingHostConfiguration(defaultJvmScriptingHostConfiguration) {} 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( project, @@ -325,7 +330,9 @@ internal abstract class LLFirAbstractSessionFactory(protected val project: Proje val libraryModule = when (module) { is KtLibraryModule -> module 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 @@ -480,7 +487,13 @@ internal abstract class LLFirAbstractSessionFactory(protected val project: Proje is KtScriptModule, is KtScriptDependencyModule, 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 { diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirJavaFacadeForBinaries.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirJavaFacadeForBinaries.kt index 4e59224c379..df062e7ace4 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirJavaFacadeForBinaries.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirJavaFacadeForBinaries.kt @@ -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.classId 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.Paths @@ -34,7 +36,9 @@ internal class LLFirJavaFacadeForBinaries( private fun getBinaryPath(javaClass: VirtualFileBoundJavaClass): Path { val virtualFile = javaClass.virtualFile - ?: error("no virtual file for ${javaClass.classId}") + ?: errorWithAttachment("no virtual file") { + withEntry("javaClass", javaClass) { it.toString() } + } val path = virtualFile.path return when { JAR_DELIMITER in path -> diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedAnnotationDeserializer.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedAnnotationDeserializer.kt index cf963cb2e24..0a388c52eac 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedAnnotationDeserializer.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedAnnotationDeserializer.kt @@ -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.KotlinPropertyStubImpl import org.jetbrains.kotlin.types.ConstantValueKind +import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment +import org.jetbrains.kotlin.utils.exceptions.withPsiEntry class StubBasedAnnotationDeserializer( private val session: FirSession, @@ -151,7 +153,9 @@ class StubBasedAnnotationDeserializer( is IntValue -> const(ConstantValueKind.Int, value.value, session.builtinTypes.intType, sourceElement) NullValue -> const(ConstantValueKind.Null, null, session.builtinTypes.nullableAnyType, 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()) + } } } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedClassDeserialization.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedClassDeserialization.kt index 960419ec278..565cbf5cae5 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedClassDeserialization.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedClassDeserialization.kt @@ -31,6 +31,8 @@ import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.name.* import org.jetbrains.kotlin.psi.* 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 internal val KtModifierListOwner.visibility: Visibility @@ -98,7 +100,9 @@ internal fun deserializeClassToSymbol( classOrObject.isAnnotation() -> ClassKind.ANNOTATION_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 visibility = classOrObject.visibility @@ -155,9 +159,12 @@ internal fun deserializeClassToSymbol( val superTypeList = classOrObject.getSuperTypeList() if (superTypeList != null) { - superTypeRefs.addAll(superTypeList.entries.map { + superTypeRefs.addAll(superTypeList.entries.map { superTypeReference -> 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) { @@ -176,8 +183,12 @@ internal fun deserializeClassToSymbol( is KtProperty -> addDeclaration(memberDeserializer.loadProperty(declaration, symbol)) is KtEnumEntry -> addDeclaration(memberDeserializer.loadEnumEntry(declaration, symbol, classId)) is KtClassOrObject -> { + val name = declaration.name + ?: errorWithAttachment("Class doesn't have name $declaration") { + withPsiEntry("class", declaration) + } 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) } } is KtTypeAlias -> addDeclaration( diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedFirMemberDeserializer.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedFirMemberDeserializer.kt index f408acbdb70..17c3035ed0c 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedFirMemberDeserializer.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedFirMemberDeserializer.kt @@ -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.ConeTypeParameterTypeImpl 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.name.* import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource import org.jetbrains.kotlin.toKtPsiSourceElement +import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment +import org.jetbrains.kotlin.utils.exceptions.withPsiEntry internal class StubBasedFirDeserializationContext( val moduleData: FirModuleData, @@ -185,7 +188,10 @@ internal class StubBasedFirMemberDeserializer( annotations += c.annotationDeserializer.loadAnnotations(typeAlias) 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 typeParameters += local.typeDeserializer.ownTypeParameters.map { it.fir } }.apply { @@ -269,7 +275,10 @@ internal class StubBasedFirMemberDeserializer( val symbol = existingSymbol ?: FirPropertySymbol(callableId) 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 receiverTypeReference = property.receiverTypeReference @@ -525,7 +534,11 @@ internal class StubBasedFirMemberDeserializer( this.containingFunctionSymbol = functionSymbol origin = initialOrigin 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 if (isVararg) { returnTypeRef = returnTypeRef.withReplacedReturnType(returnTypeRef.coneType.createOutArrayType()) @@ -554,7 +567,10 @@ internal class StubBasedFirMemberDeserializer( symbol: FirRegularClassSymbol, classId: ClassId ): 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 enumEntry = buildEnumEntry { diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedFirTypeDeserializer.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedFirTypeDeserializer.kt index d9377085d80..292f527ddf4 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedFirTypeDeserializer.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedFirTypeDeserializer.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl 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.name.ClassId 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.types.ConstantValueKind import org.jetbrains.kotlin.types.Variance +import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment +import org.jetbrains.kotlin.utils.exceptions.withPsiEntry internal class StubBasedFirTypeDeserializer( private val moduleData: FirModuleData, @@ -141,7 +144,10 @@ internal class StubBasedFirTypeDeserializer( return@map ConeStarProjection } 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) } return ConeClassLikeTypeImpl( @@ -155,8 +161,14 @@ internal class StubBasedFirTypeDeserializer( val lowerBound = type(type.lowerBound) val upperBound = type(type.upperBound) return ConeFlexibleType( - lowerBound as? ConeSimpleKotlinType ?: error("Unexpected lower bound $lowerBound"), - upperBound as? ConeSimpleKotlinType ?: error("Unexpected upper bound $upperBound") + lowerBound as? ConeSimpleKotlinType + ?: 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) }) add(type(typeElement.returnTypeReference!!).toTypeProjection(Variance.INVARIANT)) }.toTypedArray() - else -> error("not supported $typeElement") + else -> errorWithAttachment("not supported ${typeElement?.let { it::class }}") { + withPsiEntry("typeElement", typeElement) + } } return ConeClassLikeTypeImpl( diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirTypeLazyResolver.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirTypeLazyResolver.kt index 10e2d13b867..26b07482341 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirTypeLazyResolver.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirTypeLazyResolver.kt @@ -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.types.FirResolvedTypeRef 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.utils.exceptions.errorWithAttachment internal object LLFirTypeLazyResolver : LLFirLazyResolver(FirResolvePhase.TYPES) { override fun resolve( @@ -128,7 +130,9 @@ private class LLFirTypeTargetResolver( resolveClassTypes(target) } is FirAnonymousInitializer -> {} - else -> error("Unknown declaration ${target::class.java}") + else -> errorWithAttachment("Unknown declaration ${target::class}") { + withFirEntry("declaration", target) + } } } diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/LLDiagnosticParameterChecker.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/LLDiagnosticParameterChecker.kt index f144af39dde..05b668959d9 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/LLDiagnosticParameterChecker.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/LLDiagnosticParameterChecker.kt @@ -5,6 +5,7 @@ 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.rendering.RootDiagnosticRendererFactory 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.services.TestServices 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) { override fun processModule(module: TestModule, info: FirOutputArtifact) { @@ -56,7 +59,9 @@ internal class LLDiagnosticParameterChecker(testServices: TestServices) : FirAna is KtPsiDiagnosticWithParameters3<*, *, *> -> listOf(a, b, c) is KtPsiDiagnosticWithParameters4<*, *, *, *> -> listOf(a, b, c, d) is KtPsiSimpleDiagnostic -> emptyList() - else -> error("Unexpected diagnostic $this") + else -> errorWithAttachment("Unexpected diagnostic ${this::class}, $factoryName") { + withPsiEntry("onElement", psiElement) + } } override fun processAfterAllModules(someAssertionWasFailed: Boolean) {} diff --git a/compiler/util/src/org/jetbrains/kotlin/utils/exceptions/exceptionAttachementBuilderUtils.kt b/compiler/util/src/org/jetbrains/kotlin/utils/exceptions/exceptionAttachementBuilderUtils.kt index 0f2a0dbc675..3e1ec20a825 100644 --- a/compiler/util/src/org/jetbrains/kotlin/utils/exceptions/exceptionAttachementBuilderUtils.kt +++ b/compiler/util/src/org/jetbrains/kotlin/utils/exceptions/exceptionAttachementBuilderUtils.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.utils.exceptions +import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.PsiElement import org.jetbrains.kotlin.utils.getElementTextWithContext @@ -12,4 +13,10 @@ fun ExceptionAttachmentBuilder.withPsiEntry(name: String, psi: PsiElement?) { withEntry(name, psi) { psiElement -> getElementTextWithContext(psiElement) } +} + +fun ExceptionAttachmentBuilder.withVirtualFileEntry(name: String, virtualFile: VirtualFile?) { + withEntry(name, virtualFile) { file -> + "path: ${file.path}, filetype: ${file.fileType} ,filesystem,${file.fileSystem}" + } } \ No newline at end of file