[FIR] KT-44698: Print file:line:offset on K2 crash
diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/FileStructureElementDiagnosticRetriever.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/FileStructureElementDiagnosticRetriever.kt
index 14a4c0b..298e99e 100644
--- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/FileStructureElementDiagnosticRetriever.kt
+++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/FileStructureElementDiagnosticRetriever.kt
@@ -14,6 +14,7 @@
import org.jetbrains.kotlin.fir.analysis.collectors.DiagnosticCollectorComponents
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.SessionHolderImpl
+import org.jetbrains.kotlin.fir.withFileAnalysisExceptionWrapping
import org.jetbrains.kotlin.name.StandardClassIds
internal abstract class FileStructureElementDiagnosticRetriever {
@@ -36,8 +37,10 @@
val context = moduleComponents.globalResolveComponents.lockProvider.withWriteLock(firFile) {
PersistenceContextCollector.collectContext(sessionHolder, firFile, structureElementDeclaration)
}
- return collector.collectForStructureElement(structureElementDeclaration) { components ->
- Visitor(structureElementDeclaration, context, components)
+ return withFileAnalysisExceptionWrapping(firFile) {
+ collector.collectForStructureElement(structureElementDeclaration) { components ->
+ Visitor(structureElementDeclaration, context, components)
+ }
}
}
@@ -102,8 +105,10 @@
collector: FileStructureElementDiagnosticsCollector,
moduleComponents: LLFirModuleResolveComponents,
): FileStructureElementDiagnosticList =
- collector.collectForStructureElement(firFile) { components ->
- Visitor(components, moduleComponents)
+ withFileAnalysisExceptionWrapping(firFile) {
+ collector.collectForStructureElement(firFile) { components ->
+ Visitor(components, moduleComponents)
+ }
}
private class Visitor(
diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/AbstractDiagnosticCollectorVisitor.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/AbstractDiagnosticCollectorVisitor.kt
index d1fa19d..7d74247 100644
--- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/AbstractDiagnosticCollectorVisitor.kt
+++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/AbstractDiagnosticCollectorVisitor.kt
@@ -16,6 +16,7 @@
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
+import org.jetbrains.kotlin.fir.whileAnalysing
import org.jetbrains.kotlin.name.Name
abstract class AbstractDiagnosticCollectorVisitor(
@@ -71,7 +72,9 @@
override fun visitRegularClass(regularClass: FirRegularClass, data: Nothing?) {
withAnnotationContainer(regularClass) {
- visitClassAndChildren(regularClass, regularClass.defaultType())
+ whileAnalysing(regularClass) {
+ visitClassAndChildren(regularClass, regularClass.defaultType())
+ }
}
}
@@ -87,13 +90,17 @@
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: Nothing?) {
withAnnotationContainer(simpleFunction) {
- visitWithDeclarationAndReceiver(simpleFunction, simpleFunction.name, simpleFunction.receiverTypeRef)
+ whileAnalysing(simpleFunction) {
+ visitWithDeclarationAndReceiver(simpleFunction, simpleFunction.name, simpleFunction.receiverTypeRef)
+ }
}
}
override fun visitConstructor(constructor: FirConstructor, data: Nothing?) {
withAnnotationContainer(constructor) {
- visitWithDeclaration(constructor)
+ whileAnalysing(constructor) {
+ visitWithDeclaration(constructor)
+ }
}
}
@@ -114,13 +121,17 @@
override fun visitProperty(property: FirProperty, data: Nothing?) {
withAnnotationContainer(property) {
- visitWithDeclaration(property)
+ whileAnalysing(property) {
+ visitWithDeclaration(property)
+ }
}
}
override fun visitTypeAlias(typeAlias: FirTypeAlias, data: Nothing?) {
withAnnotationContainer(typeAlias) {
- visitWithDeclaration(typeAlias)
+ whileAnalysing(typeAlias) {
+ visitWithDeclaration(typeAlias)
+ }
}
}
@@ -139,7 +150,9 @@
override fun visitEnumEntry(enumEntry: FirEnumEntry, data: Nothing?) {
withAnnotationContainer(enumEntry) {
- visitWithDeclaration(enumEntry)
+ whileAnalysing(enumEntry) {
+ visitWithDeclaration(enumEntry)
+ }
}
}
@@ -211,7 +224,9 @@
}
override fun visitVariableAssignment(variableAssignment: FirVariableAssignment, data: Nothing?) {
- visitWithQualifiedAccessOrAnnotationCall(variableAssignment)
+ whileAnalysing(variableAssignment) {
+ visitWithQualifiedAccessOrAnnotationCall(variableAssignment)
+ }
}
override fun visitGetClassCall(getClassCall: FirGetClassCall, data: Nothing?) {
diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/pipeline/analyse.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/pipeline/analyse.kt
index 814858e..16a32d9e 100644
--- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/pipeline/analyse.kt
+++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/pipeline/analyse.kt
@@ -9,6 +9,7 @@
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.collectors.FirDiagnosticsCollector
import org.jetbrains.kotlin.fir.declarations.FirFile
+import org.jetbrains.kotlin.fir.forEachWrappingFileAnalysisException
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveProcessor
@@ -20,7 +21,5 @@
fun FirSession.runCheckers(scopeSession: ScopeSession, firFiles: List<FirFile>, reporter: DiagnosticReporter) {
val collector = FirDiagnosticsCollector.create(this, scopeSession)
- for (file in firFiles) {
- collector.collectDiagnostics(file, reporter)
- }
+ firFiles.forEachWrappingFileAnalysisException { collector.collectDiagnostics(it, reporter) }
}
diff --git a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt
index 145bcd9..acb2e99 100644
--- a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt
+++ b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt
@@ -67,7 +67,7 @@
) {
private val contractSerializer = FirContractSerializer()
- fun packagePartProto(packageFqName: FqName, file: FirFile): ProtoBuf.Package.Builder {
+ fun packagePartProto(packageFqName: FqName, file: FirFile): ProtoBuf.Package.Builder = whileAnalysing(file) {
val builder = ProtoBuf.Package.newBuilder()
for (declaration in file.declarations) {
@@ -84,10 +84,10 @@
typeTable.serialize()?.let { builder.typeTable = it }
versionRequirementTable?.serialize()?.let { builder.versionRequirementTable = it }
- return builder
+ builder
}
- fun classProto(klass: FirClass): ProtoBuf.Class.Builder {
+ fun classProto(klass: FirClass): ProtoBuf.Class.Builder = whileAnalysing(klass) {
val builder = ProtoBuf.Class.newBuilder()
val regularClass = klass as? FirRegularClass
@@ -211,7 +211,7 @@
typeTable.serialize()?.let { builder.typeTable = it }
versionRequirementTable.serialize()?.let { builder.versionRequirementTable = it }
- return builder
+ builder
}
private fun FirClass.declarations(): List<FirCallableDeclaration> = buildList {
@@ -247,8 +247,8 @@
useSiteTarget == AnnotationUseSiteTarget.SETTER_PARAMETER && isSetter
}
- fun propertyProto(property: FirProperty): ProtoBuf.Property.Builder? {
- if (!extension.shouldSerializeProperty(property)) return null
+ fun propertyProto(property: FirProperty): ProtoBuf.Property.Builder? = whileAnalysing(property) {
+ if (!extension.shouldSerializeProperty(property)) return@whileAnalysing null
val builder = ProtoBuf.Property.newBuilder()
@@ -351,11 +351,11 @@
extension.serializeProperty(property, builder, versionRequirementTable, local)
- return builder
+ builder
}
- fun functionProto(function: FirFunction): ProtoBuf.Function.Builder? {
- if (!extension.shouldSerializeFunction(function)) return null
+ fun functionProto(function: FirFunction): ProtoBuf.Function.Builder? = whileAnalysing(function) {
+ if (!extension.shouldSerializeFunction(function)) return@whileAnalysing null
val builder = ProtoBuf.Function.newBuilder()
val simpleFunction = function as? FirSimpleFunction
@@ -444,11 +444,11 @@
}
}
- return builder
+ builder
}
- private fun typeAliasProto(typeAlias: FirTypeAlias): ProtoBuf.TypeAlias.Builder? {
- if (!extension.shouldSerializeTypeAlias(typeAlias)) return null
+ private fun typeAliasProto(typeAlias: FirTypeAlias): ProtoBuf.TypeAlias.Builder? = whileAnalysing(typeAlias) {
+ if (!extension.shouldSerializeTypeAlias(typeAlias)) return@whileAnalysing null
val builder = ProtoBuf.TypeAlias.newBuilder()
val local = createChildSerializer(typeAlias)
@@ -491,17 +491,17 @@
extension.serializeTypeAlias(typeAlias, builder)
- return builder
+ builder
}
- private fun enumEntryProto(enumEntry: FirEnumEntry): ProtoBuf.EnumEntry.Builder {
+ private fun enumEntryProto(enumEntry: FirEnumEntry): ProtoBuf.EnumEntry.Builder = whileAnalysing(enumEntry) {
val builder = ProtoBuf.EnumEntry.newBuilder()
builder.name = getSimpleNameIndex(enumEntry.name)
extension.serializeEnumEntry(enumEntry, builder)
- return builder
+ builder
}
- private fun constructorProto(constructor: FirConstructor): ProtoBuf.Constructor.Builder {
+ private fun constructorProto(constructor: FirConstructor): ProtoBuf.Constructor.Builder = whileAnalysing(constructor) {
val builder = ProtoBuf.Constructor.newBuilder()
val local = createChildSerializer(constructor)
@@ -534,13 +534,13 @@
extension.serializeConstructor(constructor, builder, local)
- return builder
+ builder
}
private fun valueParameterProto(
parameter: FirValueParameter,
additionalAnnotations: List<FirAnnotation> = emptyList()
- ): ProtoBuf.ValueParameter.Builder {
+ ): ProtoBuf.ValueParameter.Builder = whileAnalysing(parameter) {
val builder = ProtoBuf.ValueParameter.newBuilder()
val declaresDefaultValue = parameter.defaultValue != null // TODO: || parameter.isActualParameterWithAnyExpectedDefault
@@ -574,10 +574,10 @@
extension.serializeValueParameter(parameter, builder)
- return builder
+ builder
}
- private fun typeParameterProto(typeParameter: FirTypeParameter): ProtoBuf.TypeParameter.Builder {
+ private fun typeParameterProto(typeParameter: FirTypeParameter): ProtoBuf.TypeParameter.Builder = whileAnalysing(typeParameter) {
val builder = ProtoBuf.TypeParameter.newBuilder()
builder.id = getTypeParameterId(typeParameter)
@@ -595,7 +595,7 @@
extension.serializeTypeParameter(typeParameter, builder)
val upperBounds = typeParameter.bounds
- if (upperBounds.size == 1 && upperBounds.single() is FirImplicitNullableAnyTypeRef) return builder
+ if (upperBounds.size == 1 && upperBounds.single() is FirImplicitNullableAnyTypeRef) return@whileAnalysing builder
for (upperBound in upperBounds) {
if (useTypeTable()) {
@@ -605,7 +605,7 @@
}
}
- return builder
+ builder
}
fun typeId(typeRef: FirTypeRef): Int {
diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt
index 7163b04..6d7e719 100644
--- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt
+++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt
@@ -16,7 +16,7 @@
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
-import org.jetbrains.kotlin.fir.FirSession
+import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.backend.generators.*
import org.jetbrains.kotlin.fir.backend.generators.DataClassMembersGenerator
import org.jetbrains.kotlin.fir.declarations.*
@@ -27,9 +27,6 @@
import org.jetbrains.kotlin.fir.extensions.extensionService
import org.jetbrains.kotlin.fir.extensions.generatedMembers
import org.jetbrains.kotlin.fir.extensions.generatedNestedClassifiers
-import org.jetbrains.kotlin.fir.languageVersionSettings
-import org.jetbrains.kotlin.fir.packageFqName
-import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.signaturer.FirBasedSignatureComposer
import org.jetbrains.kotlin.fir.signaturer.FirMangler
@@ -92,9 +89,7 @@
// 5. Body processing
// If we encounter local class / anonymous object here, then we perform all (1)-(5) stages immediately
delegatedMemberGenerator.generateBodies()
- for (firFile in allFirFiles) {
- firFile.accept(fir2irVisitor, null)
- }
+ allFirFiles.forEachWrappingFileAnalysisException { it.accept(fir2irVisitor, null) }
if (irGenerationExtensions.isNotEmpty()) {
val pluginContext = Fir2IrPluginContext(components, irModuleFragment.descriptor)
diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt
index f7e6a72..5b843db 100644
--- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt
+++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt
@@ -212,9 +212,9 @@
// ==================================================================================
- override fun visitConstructor(constructor: FirConstructor, data: Any?): IrElement {
+ override fun visitConstructor(constructor: FirConstructor, data: Any?): IrElement = whileAnalysing(constructor) {
val irConstructor = declarationStorage.getCachedIrConstructor(constructor)!!
- return conversionScope.withFunction(irConstructor) {
+ conversionScope.withFunction(irConstructor) {
memberGenerator.convertFunctionContent(irConstructor, constructor, containingClass = conversionScope.containerFirClass())
}
}
@@ -227,7 +227,7 @@
return irAnonymousInitializer
}
- override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: Any?): IrElement {
+ override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: Any?): IrElement = whileAnalysing(simpleFunction) {
val irFunction = if (simpleFunction.visibility == Visibilities.Local) {
declarationStorage.createIrFunction(
simpleFunction, irParent = conversionScope.parent(), predefinedOrigin = IrDeclarationOrigin.LOCAL_FUNCTION, isLocal = true
@@ -235,7 +235,7 @@
} else {
declarationStorage.getCachedIrFunction(simpleFunction)!!
}
- return conversionScope.withFunction(irFunction) {
+ conversionScope.withFunction(irFunction) {
memberGenerator.convertFunctionContent(
irFunction, simpleFunction, containingClass = conversionScope.containerFirClass()
)
@@ -318,24 +318,24 @@
this@insertImplicitCast.cast(baseExpression, valueType, expectedType)
}
- override fun visitProperty(property: FirProperty, data: Any?): IrElement {
+ override fun visitProperty(property: FirProperty, data: Any?): IrElement = whileAnalysing(property) {
if (property.isLocal) return visitLocalVariable(property)
val irProperty = declarationStorage.getCachedIrProperty(property)
- ?: return IrErrorExpressionImpl(
+ ?: return@whileAnalysing IrErrorExpressionImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
IrErrorTypeImpl(null, emptyList(), Variance.INVARIANT),
"Stub for Enum.entries"
)
- return conversionScope.withProperty(irProperty, property) {
+ conversionScope.withProperty(irProperty, property) {
memberGenerator.convertPropertyContent(irProperty, property, containingClass = conversionScope.containerFirClass())
}
}
// ==================================================================================
- override fun visitReturnExpression(returnExpression: FirReturnExpression, data: Any?): IrElement {
+ override fun visitReturnExpression(returnExpression: FirReturnExpression, data: Any?): IrElement = whileAnalysing(returnExpression) {
val irTarget = conversionScope.returnTarget(returnExpression, declarationStorage)
- return returnExpression.convertWithOffsets { startOffset, endOffset ->
+ returnExpression.convertWithOffsets { startOffset, endOffset ->
val result = returnExpression.result
// For implicit returns, use the expression endOffset to generate the expected line number for debugging.
val returnStartOffset = if (returnExpression.source?.kind is KtFakeSourceElementKind.ImplicitReturn) endOffset else startOffset
@@ -582,15 +582,16 @@
)
}
- override fun visitVariableAssignment(variableAssignment: FirVariableAssignment, data: Any?): IrElement {
+ override fun visitVariableAssignment(variableAssignment: FirVariableAssignment, data: Any?) = whileAnalysing(variableAssignment) {
val explicitReceiverExpression = convertToIrReceiverExpression(
variableAssignment.explicitReceiver, variableAssignment.calleeReference
)
- return callGenerator.convertToIrSetCall(variableAssignment, explicitReceiverExpression)
+ callGenerator.convertToIrSetCall(variableAssignment, explicitReceiverExpression)
}
- override fun <T> visitConstExpression(constExpression: FirConstExpression<T>, data: Any?): IrElement =
+ override fun <T> visitConstExpression(constExpression: FirConstExpression<T>, data: Any?) = whileAnalysing(constExpression) {
constExpression.toIrConst(constExpression.typeRef.toIrType())
+ }
// ==================================================================================
@@ -721,7 +722,7 @@
return if (origin == IrStatementOrigin.EQ) null else origin
}
- internal fun convertToIrBlockBody(block: FirBlock): IrBlockBody {
+ internal fun convertToIrBlockBody(block: FirBlock): IrBlockBody = whileAnalysing(block) {
return block.convertWithOffsets { startOffset, endOffset ->
val irStatements = block.statements.mapToIrStatements()
irFactory.createBlockBody(
diff --git a/compiler/fir/modularized-tests/tests/org/jetbrains/kotlin/fir/FirResolveModularizedTotalKotlinTest.kt b/compiler/fir/modularized-tests/tests/org/jetbrains/kotlin/fir/FirResolveModularizedTotalKotlinTest.kt
index 6a6e487..3cc17fd 100644
--- a/compiler/fir/modularized-tests/tests/org/jetbrains/kotlin/fir/FirResolveModularizedTotalKotlinTest.kt
+++ b/compiler/fir/modularized-tests/tests/org/jetbrains/kotlin/fir/FirResolveModularizedTotalKotlinTest.kt
@@ -336,9 +336,10 @@
return element
}
- override fun transformFile(file: FirFile, data: Nothing?): FirFile {
- val reporter = DiagnosticReporterFactory.createPendingReporter()
- diagnosticCollector.collectDiagnostics(file, reporter)
- return file
+ override fun transformFile(file: FirFile, data: Nothing?) = file.also {
+ withFileAnalysisExceptionWrapping(file) {
+ val reporter = DiagnosticReporterFactory.createPendingReporter()
+ diagnosticCollector.collectDiagnostics(file, reporter)
+ }
}
}
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSealedClassInheritorsProcessor.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSealedClassInheritorsProcessor.kt
index 3f27205..bda7f98 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSealedClassInheritorsProcessor.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSealedClassInheritorsProcessor.kt
@@ -15,6 +15,7 @@
import org.jetbrains.kotlin.fir.declarations.utils.classId
import org.jetbrains.kotlin.fir.declarations.utils.modality
import org.jetbrains.kotlin.fir.expressions.FirStatement
+import org.jetbrains.kotlin.fir.forEachWrappingFileAnalysisException
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.getSymbolByLookupTag
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
@@ -38,8 +39,8 @@
override fun process(files: Collection<FirFile>) {
val sealedClassInheritorsMap = mutableMapOf<FirRegularClass, MutableList<ClassId>>()
val inheritorsCollector = InheritorsCollector(session)
- files.forEach { it.accept(inheritorsCollector, sealedClassInheritorsMap) }
- files.forEach { it.transformSingle(InheritorsTransformer(sealedClassInheritorsMap), null) }
+ files.forEachWrappingFileAnalysisException { it.accept(inheritorsCollector, sealedClassInheritorsMap) }
+ files.forEachWrappingFileAnalysisException { it.transformSingle(InheritorsTransformer(sealedClassInheritorsMap), null) }
}
class InheritorsCollector(val session: FirSession) : FirDefaultVisitor<Unit, MutableMap<FirRegularClass, MutableList<ClassId>>>() {
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt
index 1299cf5..96a065e 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt
@@ -29,6 +29,7 @@
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.toSymbol
import org.jetbrains.kotlin.fir.visitors.transformSingle
+import org.jetbrains.kotlin.fir.whileAnalysing
class FirStatusResolveProcessor(
session: FirSession,
@@ -165,8 +166,8 @@
override fun transformRegularClass(
regularClass: FirRegularClass,
data: FirResolvedDeclarationStatus?
- ): FirStatement {
- if (shouldSkipClass(regularClass)) return regularClass
+ ): FirStatement = whileAnalysing(regularClass) {
+ if (shouldSkipClass(regularClass)) return@whileAnalysing regularClass
regularClass.symbol.lazyResolveToPhase(FirResolvePhase.TYPES)
val classLocated = this.classLocated
/*
@@ -185,7 +186,7 @@
statusComputationSession.computeOnlyClassStatus(regularClass)
}
}
- return transformClass(regularClass, data).also {
+ transformClass(regularClass, data).also {
if (classLocated) statusComputationSession.endComputing(regularClass)
}
}
@@ -308,10 +309,10 @@
override fun transformTypeAlias(
typeAlias: FirTypeAlias,
data: FirResolvedDeclarationStatus?
- ): FirStatement {
+ ): FirStatement = whileAnalysing(typeAlias) {
typeAlias.typeParameters.forEach { transformDeclaration(it, data) }
typeAlias.transformStatus(this, statusResolver.resolveStatus(typeAlias, containingClass, isLocal = false))
- return transformDeclaration(typeAlias, data) as FirTypeAlias
+ transformDeclaration(typeAlias, data) as FirTypeAlias
}
abstract override fun transformRegularClass(
@@ -464,26 +465,26 @@
override fun transformConstructor(
constructor: FirConstructor,
data: FirResolvedDeclarationStatus?
- ): FirStatement {
+ ): FirStatement = whileAnalysing(constructor) {
constructor.transformStatus(this, statusResolver.resolveStatus(constructor, containingClass, isLocal = false))
calculateDeprecations(constructor)
- return transformDeclaration(constructor, data) as FirStatement
+ transformDeclaration(constructor, data) as FirStatement
}
override fun transformSimpleFunction(
simpleFunction: FirSimpleFunction,
data: FirResolvedDeclarationStatus?
- ): FirStatement {
+ ): FirStatement = whileAnalysing(simpleFunction) {
val resolvedStatus = statusResolver.resolveStatus(simpleFunction, containingClass, isLocal = false)
simpleFunction.transformStatus(this, resolvedStatus)
calculateDeprecations(simpleFunction)
- return transformDeclaration(simpleFunction, data) as FirStatement
+ transformDeclaration(simpleFunction, data) as FirStatement
}
override fun transformProperty(
property: FirProperty,
data: FirResolvedDeclarationStatus?
- ): FirStatement {
+ ): FirStatement = whileAnalysing(property) {
val overridden = statusResolver.getOverriddenProperties(property, containingClass)
val overriddenProperties = overridden.map {
@@ -512,25 +513,25 @@
}
calculateDeprecations(property)
- return property
+ property
}
override fun transformField(
field: FirField,
data: FirResolvedDeclarationStatus?
- ): FirStatement {
+ ): FirStatement = whileAnalysing(field) {
field.transformStatus(this, statusResolver.resolveStatus(field, containingClass, isLocal = false))
calculateDeprecations(field)
- return transformDeclaration(field, data) as FirField
+ transformDeclaration(field, data) as FirField
}
override fun transformEnumEntry(
enumEntry: FirEnumEntry,
data: FirResolvedDeclarationStatus?
- ): FirStatement {
+ ): FirStatement = whileAnalysing(enumEntry) {
enumEntry.transformStatus(this, statusResolver.resolveStatus(enumEntry, containingClass, isLocal = false))
calculateDeprecations(enumEntry)
- return transformDeclaration(enumEntry, data) as FirEnumEntry
+ transformDeclaration(enumEntry, data) as FirEnumEntry
}
override fun transformValueParameter(
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTotalResolveProcessor.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTotalResolveProcessor.kt
index 15bd522..112a0ae 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTotalResolveProcessor.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTotalResolveProcessor.kt
@@ -9,6 +9,7 @@
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase.*
+import org.jetbrains.kotlin.fir.forEachWrappingFileAnalysisException
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirBodyResolveProcessor
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirImplicitTypeBodyResolveProcessor
@@ -29,9 +30,7 @@
processor.beforePhase()
when (processor) {
is FirTransformerBasedResolveProcessor -> {
- for (file in files) {
- processor.processFile(file)
- }
+ files.forEachWrappingFileAnalysisException { processor.processFile(it) }
}
is FirGlobalResolveProcessor -> {
processor.process(files)
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt
index ee96cb9..a280ded 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.resolve.transformers
import kotlinx.collections.immutable.toImmutableList
+import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isFromVararg
@@ -21,6 +22,7 @@
import org.jetbrains.kotlin.fir.scopes.impl.wrapNestedClassifierScopeWithSubstitutionForSuperType
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
+import org.jetbrains.kotlin.fir.whileAnalysing
class FirTypeResolveProcessor(
session: FirSession,
@@ -73,7 +75,7 @@
}
}
- override fun transformRegularClass(regularClass: FirRegularClass, data: Any?): FirStatement {
+ override fun transformRegularClass(regularClass: FirRegularClass, data: Any?) = whileAnalysing(regularClass) {
withClassDeclarationCleanup(classDeclarationsStack, regularClass) {
withScopeCleanup {
regularClass.addTypeParametersScope()
@@ -83,7 +85,7 @@
unboundCyclesInTypeParametersSupertypes(regularClass)
}
- return resolveClassContent(regularClass, data)
+ resolveClassContent(regularClass, data)
}
}
@@ -93,29 +95,29 @@
}
}
- override fun transformConstructor(constructor: FirConstructor, data: Any?): FirConstructor {
- return withScopeCleanup {
+ override fun transformConstructor(constructor: FirConstructor, data: Any?) = whileAnalysing(constructor) {
+ withScopeCleanup {
constructor.addTypeParametersScope()
transformDeclaration(constructor, data)
} as FirConstructor
}
- override fun transformTypeAlias(typeAlias: FirTypeAlias, data: Any?): FirTypeAlias {
- return withScopeCleanup {
+ override fun transformTypeAlias(typeAlias: FirTypeAlias, data: Any?) = whileAnalysing(typeAlias) {
+ withScopeCleanup {
typeAlias.addTypeParametersScope()
transformDeclaration(typeAlias, data)
} as FirTypeAlias
}
- override fun transformEnumEntry(enumEntry: FirEnumEntry, data: Any?): FirEnumEntry {
+ override fun transformEnumEntry(enumEntry: FirEnumEntry, data: Any?) = whileAnalysing(enumEntry) {
enumEntry.transformReturnTypeRef(this, data)
enumEntry.transformTypeParameters(this, data)
enumEntry.transformAnnotations(this, data)
- return enumEntry
+ enumEntry
}
- override fun transformProperty(property: FirProperty, data: Any?): FirProperty {
- return withScopeCleanup {
+ override fun transformProperty(property: FirProperty, data: Any?) = whileAnalysing(property) {
+ withScopeCleanup {
property.addTypeParametersScope()
property.transformTypeParameters(this, data)
.transformReturnTypeRef(this, data)
@@ -153,8 +155,8 @@
}
}
- override fun transformSimpleFunction(simpleFunction: FirSimpleFunction, data: Any?): FirSimpleFunction {
- return withScopeCleanup {
+ override fun transformSimpleFunction(simpleFunction: FirSimpleFunction, data: Any?) = whileAnalysing(simpleFunction) {
+ withScopeCleanup {
simpleFunction.addTypeParametersScope()
transformDeclaration(simpleFunction, data).also {
unboundCyclesInTypeParametersSupertypes(it as FirTypeParametersOwner)
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt
index 7e15eb3..d19c691 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt
@@ -110,7 +110,7 @@
}
}
- override fun transformProperty(property: FirProperty, data: ResolutionMode): FirProperty {
+ override fun transformProperty(property: FirProperty, data: ResolutionMode): FirProperty = whileAnalysing(property) {
require(property !is FirSyntheticProperty) { "Synthetic properties should not be processed by body transformers" }
if (property.isLocal) {
@@ -119,24 +119,24 @@
property.getter?.let { it.transformStatus(this, it.resolveStatus(containingProperty = property).mode()) }
property.setter?.let { it.transformStatus(this, it.resolveStatus(containingProperty = property).mode()) }
property.backingField?.let { it.transformStatus(this, it.resolveStatus(containingProperty = property).mode()) }
- return transformLocalVariable(property)
+ return@whileAnalysing transformLocalVariable(property)
}
val returnTypeRefBeforeResolve = property.returnTypeRef
val bodyResolveState = property.bodyResolveState
- if (bodyResolveState == FirPropertyBodyResolveState.EVERYTHING_RESOLVED) return property
+ if (bodyResolveState == FirPropertyBodyResolveState.EVERYTHING_RESOLVED) return@whileAnalysing property
val canHaveDeepImplicitTypeRefs = property.hasExplicitBackingField
if (returnTypeRefBeforeResolve !is FirImplicitTypeRef && implicitTypeOnly && !canHaveDeepImplicitTypeRefs) {
- return property
+ return@whileAnalysing property
}
property.transformReceiverTypeRef(transformer, ResolutionMode.ContextIndependent)
dataFlowAnalyzer.enterProperty(property)
doTransformTypeParameters(property)
val shouldResolveEverything = !implicitTypeOnly
- return withFullBodyResolve {
+ withFullBodyResolve {
val initializerIsAlreadyResolved = bodyResolveState >= FirPropertyBodyResolveState.INITIALIZER_RESOLVED
var backingFieldIsAlreadyResolved = false
context.withProperty(property) {
@@ -366,7 +366,7 @@
return delegateExpression
}
- private fun transformLocalVariable(variable: FirProperty): FirProperty {
+ private fun transformLocalVariable(variable: FirProperty) = whileAnalysing(variable) {
assert(variable.isLocal)
val delegate = variable.delegate
@@ -392,7 +392,7 @@
variable.transformOtherChildren(transformer, ResolutionMode.ContextIndependent)
context.storeVariable(variable, session)
dataFlowAnalyzer.exitLocalVariableDeclaration(variable, hadExplicitType)
- return variable
+ variable
}
private fun FirProperty.transformChildrenWithoutComponents(returnTypeRef: FirTypeRef): FirProperty {
@@ -448,7 +448,7 @@
accessor: FirPropertyAccessor,
enhancedTypeRef: FirTypeRef,
owner: FirProperty
- ) {
+ ) = whileAnalysing(accessor) {
context.withPropertyAccessor(owner, accessor, components) {
if (accessor is FirDefaultPropertyAccessor || accessor.body == null) {
transformFunction(accessor, withExpectedType(enhancedTypeRef))
@@ -483,10 +483,10 @@
)
}
- override fun transformRegularClass(regularClass: FirRegularClass, data: ResolutionMode): FirStatement {
+ override fun transformRegularClass(regularClass: FirRegularClass, data: ResolutionMode): FirStatement = whileAnalysing(regularClass) {
context.withContainingClass(regularClass) {
if (regularClass.isLocal && regularClass !in context.targetedLocalClasses) {
- return regularClass.runAllPhasesForLocalClass(
+ return@whileAnalysing regularClass.runAllPhasesForLocalClass(
transformer,
components,
data,
@@ -496,13 +496,13 @@
}
doTransformTypeParameters(regularClass)
- return doTransformRegularClass(regularClass, data)
+ doTransformRegularClass(regularClass, data)
}
}
- override fun transformTypeAlias(typeAlias: FirTypeAlias, data: ResolutionMode): FirTypeAlias {
+ override fun transformTypeAlias(typeAlias: FirTypeAlias, data: ResolutionMode) = whileAnalysing(typeAlias) {
if (typeAlias.isLocal && typeAlias !in context.targetedLocalClasses) {
- return typeAlias.runAllPhasesForLocalClass(
+ return@whileAnalysing typeAlias.runAllPhasesForLocalClass(
transformer,
components,
data,
@@ -514,7 +514,7 @@
typeAlias.transformAnnotations(transformer, data)
transformer.firTowerDataContextCollector?.addDeclarationContext(typeAlias, context.towerDataContext)
typeAlias.transformExpandedTypeRef(transformer, data)
- return typeAlias
+ typeAlias
}
private fun doTransformRegularClass(
@@ -540,9 +540,9 @@
override fun transformAnonymousObject(
anonymousObject: FirAnonymousObject,
data: ResolutionMode
- ): FirStatement {
+ ): FirStatement = whileAnalysing(anonymousObject) {
if (anonymousObject !in context.targetedLocalClasses) {
- return anonymousObject.runAllPhasesForLocalClass(
+ return@whileAnalysing anonymousObject.runAllPhasesForLocalClass(
transformer,
components,
data,
@@ -564,7 +564,7 @@
} else {
dataFlowAnalyzer.exitClass()
}
- return result
+ result
}
private fun transformAnonymousFunctionWithLambdaResolution(
@@ -662,13 +662,13 @@
override fun transformFunction(
function: FirFunction,
data: ResolutionMode
- ): FirStatement {
+ ) = whileAnalysing(function) {
val functionIsNotAnalyzed = !function.bodyResolved
if (functionIsNotAnalyzed) {
dataFlowAnalyzer.enterFunction(function)
}
@Suppress("UNCHECKED_CAST")
- return transformDeclarationContent(function, data).also {
+ transformDeclarationContent(function, data).also {
if (functionIsNotAnalyzed) {
val result = it as FirFunction
val controlFlowGraphReference = dataFlowAnalyzer.exitFunction(result)
@@ -677,17 +677,17 @@
} as FirStatement
}
- override fun transformConstructor(constructor: FirConstructor, data: ResolutionMode): FirConstructor {
- if (implicitTypeOnly) return constructor
+ override fun transformConstructor(constructor: FirConstructor, data: ResolutionMode) = whileAnalysing(constructor) {
+ if (implicitTypeOnly) return@whileAnalysing constructor
val container = context.containerIfAny as? FirRegularClass
if (constructor.isPrimary && container?.classKind == ClassKind.ANNOTATION_CLASS) {
- return withFirArrayOfCallTransformer {
+ return@whileAnalysing withFirArrayOfCallTransformer {
@Suppress("UNCHECKED_CAST")
doTransformConstructor(constructor, data)
}
}
@Suppress("UNCHECKED_CAST")
- return doTransformConstructor(constructor, data)
+ doTransformConstructor(constructor, data)
}
private fun doTransformConstructor(constructor: FirConstructor, data: ResolutionMode): FirConstructor {
@@ -749,14 +749,14 @@
override fun transformAnonymousFunction(
anonymousFunction: FirAnonymousFunction,
data: ResolutionMode
- ): FirStatement {
+ ) = whileAnalysing(anonymousFunction) {
// Either ContextDependent, ContextIndependent or WithExpectedType could be here
if (data !is ResolutionMode.LambdaResolution) {
anonymousFunction.transformReturnTypeRef(transformer, ResolutionMode.ContextIndependent)
anonymousFunction.transformReceiverTypeRef(transformer, ResolutionMode.ContextIndependent)
anonymousFunction.valueParameters.forEach { it.transformReturnTypeRef(transformer, ResolutionMode.ContextIndependent) }
}
- return when (data) {
+ when (data) {
is ResolutionMode.ContextDependent, is ResolutionMode.ContextDependentDelegate -> {
context.withAnonymousFunction(anonymousFunction, components, data) {
anonymousFunction.addReturn()
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt
index 68886691..c8d699a 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt
@@ -354,7 +354,7 @@
return checkedSafeCallSubject
}
- override fun transformFunctionCall(functionCall: FirFunctionCall, data: ResolutionMode): FirStatement {
+ override fun transformFunctionCall(functionCall: FirFunctionCall, data: ResolutionMode) = whileAnalysing(functionCall) {
val calleeReference = functionCall.calleeReference
if (
(calleeReference is FirResolvedNamedReference || calleeReference is FirErrorNamedReference) &&
@@ -368,9 +368,9 @@
if (calleeReference !is FirResolvedNamedReference) {
functionCall.transformChildren(transformer, data)
}
- return functionCall
+ return@whileAnalysing functionCall
}
- if (calleeReference is FirNamedReferenceWithCandidate) return functionCall
+ if (calleeReference is FirNamedReferenceWithCandidate) return@whileAnalysing functionCall
dataFlowAnalyzer.enterCall()
functionCall.transformAnnotations(transformer, data)
functionCall.transformSingle(InvocationKindTransformer, null)
@@ -396,10 +396,10 @@
if (callCompleted) {
if (enableArrayOfCallTransformation) {
- return arrayOfCallTransformer.transformFunctionCall(result, null)
+ return@whileAnalysing arrayOfCallTransformer.transformFunctionCall(result, null)
}
}
- return result
+ result
}
@OptIn(PrivateForInline::class)
@@ -523,7 +523,7 @@
override fun transformAssignmentOperatorStatement(
assignmentOperatorStatement: FirAssignmentOperatorStatement,
data: ResolutionMode
- ): FirStatement {
+ ) = whileAnalysing(assignmentOperatorStatement) {
val operation = assignmentOperatorStatement.operation
require(operation != FirOperation.ASSIGN)
@@ -627,7 +627,7 @@
}
}
- return when {
+ when {
assignIsSuccessful && !lhsIsVar -> chooseAssign()
!assignIsSuccessful && !operatorIsSuccessful -> {
// If neither candidate is successful, choose whichever is resolved, prioritizing assign
@@ -1003,7 +1003,7 @@
override fun <T> transformConstExpression(
constExpression: FirConstExpression<T>,
data: ResolutionMode,
- ): FirStatement {
+ ) = whileAnalysing(constExpression) {
constExpression.transformAnnotations(transformer, ResolutionMode.ContextIndependent)
val type = when (val kind = constExpression.kind) {
@@ -1040,7 +1040,7 @@
dataFlowAnalyzer.exitConstExpression(constExpression as FirConstExpression<*>)
constExpression.resultType = constExpression.resultType.resolvedTypeFromPrototype(type)
- return constExpression
+ constExpression
}
override fun transformAnnotation(annotation: FirAnnotation, data: ResolutionMode): FirStatement {
@@ -1193,7 +1193,7 @@
override fun transformAugmentedArraySetCall(
augmentedArraySetCall: FirAugmentedArraySetCall,
data: ResolutionMode
- ): FirStatement {
+ ) = whileAnalysing(augmentedArraySetCall) {
/*
* a[b] += c can be desugared to:
*
@@ -1234,7 +1234,7 @@
// prefer a "simpler" variant for dynamics
if (transformedLhsCall.calleeReference.resolvedSymbol?.origin == FirDeclarationOrigin.DynamicScope) {
- return chooseAssign()
+ return@whileAnalysing chooseAssign()
}
// <array>.set(<index_i>, <array>.get(<index_i>).plus(c))
@@ -1245,7 +1245,7 @@
// if `plus` call already inapplicable then there is no need to try to resolve `set` call
if (assignIsSuccessful && !operatorIsSuccessful) {
- return chooseAssign()
+ return@whileAnalysing chooseAssign()
}
// a.set(b, a.get(b).plus(c))
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirCompilerRequiredAnnotationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirCompilerRequiredAnnotationsResolveTransformer.kt
index 67fbcd9..575f754 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirCompilerRequiredAnnotationsResolveTransformer.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirCompilerRequiredAnnotationsResolveTransformer.kt
@@ -19,6 +19,7 @@
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.extensions.*
+import org.jetbrains.kotlin.fir.forEachWrappingFileAnalysisException
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.fqName
@@ -47,13 +48,13 @@
val transformer = FirCompilerRequiredAnnotationsResolveTransformer(session, scopeSession)
val registeredPluginAnnotations = session.registeredPluginAnnotations
if (!registeredPluginAnnotations.hasRegisteredAnnotations) {
- files.forEach { it.transformSingle(transformer, Mode.RegularAnnotations) }
+ files.forEachWrappingFileAnalysisException { it.transformSingle(transformer, Mode.RegularAnnotations) }
return
}
if (registeredPluginAnnotations.metaAnnotations.isNotEmpty()) {
- files.forEach { it.transformSingle(transformer, Mode.MetaAnnotations) }
+ files.forEachWrappingFileAnalysisException { it.transformSingle(transformer, Mode.MetaAnnotations) }
}
- files.forEach { it.transformSingle(transformer, Mode.RegularAnnotations) }
+ files.forEachWrappingFileAnalysisException { it.transformSingle(transformer, Mode.RegularAnnotations) }
}
@OptIn(FirSymbolProviderInternals::class)
diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/Utils.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/Utils.kt
index 6bdb956..1aab476 100644
--- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/Utils.kt
+++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/Utils.kt
@@ -6,16 +6,10 @@
package org.jetbrains.kotlin.fir
import com.intellij.psi.PsiElement
-import org.jetbrains.kotlin.KtFakeSourceElementKind
-import org.jetbrains.kotlin.KtPsiSourceElement
-import org.jetbrains.kotlin.KtRealPsiSourceElement
+import org.jetbrains.kotlin.*
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibility
-import org.jetbrains.kotlin.fakeElement
-import org.jetbrains.kotlin.fir.declarations.FirContextReceiver
-import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus
-import org.jetbrains.kotlin.fir.declarations.FirFile
-import org.jetbrains.kotlin.fir.declarations.FirResolvedDeclarationStatus
+import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
import org.jetbrains.kotlin.fir.expressions.FirBlock
@@ -142,3 +136,18 @@
this.isFun = isFun
}
}
+
+inline fun <R> whileAnalysing(element: FirElement, block: () -> R) = whileAnalysing(element.source, block)
+
+inline fun <R> withFileAnalysisExceptionWrapping(file: FirFile, block: () -> R): R {
+ return withFileAnalysisExceptionWrapping(
+ file.sourceFile?.path,
+ file.source,
+ { file.sourceFileLinesMapping?.getLineAndColumnByOffset(it) },
+ block,
+ )
+}
+
+inline fun Collection<FirFile>.forEachWrappingFileAnalysisException(crossinline block: (FirFile) -> Unit) = forEach {
+ withFileAnalysisExceptionWrapping(it) { block(it) }
+}
diff --git a/compiler/frontend.common/src/org/jetbrains/kotlin/AnalysisExceptions.kt b/compiler/frontend.common/src/org/jetbrains/kotlin/AnalysisExceptions.kt
new file mode 100644
index 0000000..46366e4
--- /dev/null
+++ b/compiler/frontend.common/src/org/jetbrains/kotlin/AnalysisExceptions.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2010-2022 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
+
+val Throwable.classNameAndMessage get() = "${this::class.qualifiedName}: $message"
+
+class SourceCodeAnalysisException(val source: KtSourceElement, override val cause: Throwable) : Exception() {
+ override val message get() = cause.classNameAndMessage
+}
+
+inline fun <R> whileAnalysing(element: KtSourceElement?, block: () -> R): R {
+ return try {
+ block()
+ } catch (exception: SourceCodeAnalysisException) {
+ throw exception
+ } catch (exception: Exception) {
+ val source = element?.takeIf { it is KtRealPsiSourceElement } ?: throw exception
+ throw SourceCodeAnalysisException(source, exception)
+ } catch (error: StackOverflowError) {
+ val source = element?.takeIf { it is KtRealPsiSourceElement } ?: throw error
+ throw SourceCodeAnalysisException(source, error)
+ }
+}
+
+class FileAnalysisException(
+ private val path: String,
+ override val cause: Throwable,
+ private val lineAndOffset: Pair<Int, Int>? = null,
+) : Exception() {
+ override val message
+ get(): String {
+ val (line, offset) = lineAndOffset ?: return "Somewhere in file $path: ${cause.classNameAndMessage}"
+ return "While analysing $path:${line + 1}:${offset + 1}: ${cause.classNameAndMessage}"
+ }
+}
+
+inline fun <R> withFileAnalysisExceptionWrapping(
+ filePath: String?,
+ fileSource: AbstractKtSourceElement?,
+ linesMapping: (Int) -> Pair<Int, Int>?,
+ block: () -> R,
+): R {
+ return try {
+ block()
+ } catch (exception: SourceCodeAnalysisException) {
+ val path = filePath ?: throw exception
+
+ if (fileSource == exception.source) {
+ throw FileAnalysisException(path, exception.cause)
+ }
+
+ val lineAndOffset = linesMapping(exception.source.startOffset)
+ throw FileAnalysisException(path, exception.cause, lineAndOffset)
+ } catch (exception: Exception) {
+ val path = filePath ?: throw exception
+ throw FileAnalysisException(path, exception)
+ } catch (error: StackOverflowError) {
+ val path = filePath ?: throw error
+ throw FileAnalysisException(path, error)
+ }
+}
diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/Utils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/Utils.kt
index 2e1c6a8..d564d1d 100644
--- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/Utils.kt
+++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/Utils.kt
@@ -21,6 +21,7 @@
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrFile
+import org.jetbrains.kotlin.ir.declarations.path
fun CommonBackendContext.reportWarning(message: String, irFile: IrFile?, irElement: IrElement) {
report(irElement, irFile, message, false)
@@ -35,3 +36,12 @@
fun IrElement.sourceElement(): AbstractKtSourceElement? =
if (startOffset != UNDEFINED_OFFSET) KtOffsetsOnlySourceElement(this.startOffset, this.endOffset)
else null
+
+inline fun <R> withFileAnalysisExceptionWrapping(file: IrFile, block: () -> R): R {
+ return org.jetbrains.kotlin.withFileAnalysisExceptionWrapping(
+ file.path,
+ file.sourceElement(),
+ { file.fileEntry.getLineNumber(it) to file.fileEntry.getColumnNumber(it) },
+ block,
+ )
+}
diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/performByIrFile.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/performByIrFile.kt
index 9b8902b..6cd355a 100644
--- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/performByIrFile.kt
+++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/performByIrFile.kt
@@ -7,6 +7,7 @@
import org.jetbrains.kotlin.backend.common.CodegenUtil
import org.jetbrains.kotlin.backend.common.CommonBackendContext
+import org.jetbrains.kotlin.backend.common.withFileAnalysisExceptionWrapping
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrFile
@@ -62,7 +63,9 @@
try {
val filePhaserState = phaserState.changePhaserStateType<IrModuleFragment, IrFile>()
for (phase in lower) {
- phase.invoke(phaseConfig, filePhaserState, context, irFile)
+ withFileAnalysisExceptionWrapping(irFile) {
+ phase.invoke(phaseConfig, filePhaserState, context, irFile)
+ }
}
} catch (e: Throwable) {
CodegenUtil.reportBackendException(e, "IR lowering", irFile.fileEntry.name)
diff --git a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/fir/FirAnalyzerFacade.kt b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/fir/FirAnalyzerFacade.kt
index 77bd93d..c662b2e 100644
--- a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/fir/FirAnalyzerFacade.kt
+++ b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/fir/FirAnalyzerFacade.kt
@@ -92,10 +92,10 @@
if (collectedDiagnostics != null) return collectedDiagnostics!!
val collector = FirDiagnosticsCollector.create(session, scopeSession)
collectedDiagnostics = buildMap {
- for (file in firFiles!!) {
+ firFiles!!.forEachWrappingFileAnalysisException {
val reporter = DiagnosticReporterFactory.createPendingReporter()
- collector.collectDiagnostics(file, reporter)
- put(file, reporter.diagnostics)
+ collector.collectDiagnostics(it, reporter)
+ put(it, reporter.diagnostics)
}
}
return collectedDiagnostics!!