[FIR] KT-44698: Print file:line:offset on K2 crash

^KT-44698 Fixed
This commit is contained in:
Nikolay Lunyak
2022-09-21 15:08:52 +03:00
committed by teamcity
parent bba5b87733
commit 2e9f9f987b
24 changed files with 363 additions and 147 deletions
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.analysis.api.fir.components package org.jetbrains.kotlin.analysis.api.fir.components
import org.jetbrains.kotlin.util.SourceCodeAnalysisException
import org.jetbrains.kotlin.analysis.api.calls.* import org.jetbrains.kotlin.analysis.api.calls.*
import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnostic import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.analysis.api.diagnostics.KtNonBoundToPsiErrorDiagnostic import org.jetbrains.kotlin.analysis.api.diagnostics.KtNonBoundToPsiErrorDiagnostic
@@ -1223,7 +1224,10 @@ internal class KtFirCallResolver(
action() action()
} catch (e: Throwable) { } catch (e: Throwable) {
if (shouldIjPlatformExceptionBeRethrown(e)) throw e if (shouldIjPlatformExceptionBeRethrown(e)) throw e
buildErrorWithAttachment("Error during resolving call ${element::class.java.name}", cause = e) { buildErrorWithAttachment(
"Error during resolving call ${element::class.java.name}",
cause = if (e is SourceCodeAnalysisException) e.cause else e,
) {
withPsiEntry("psi", element) withPsiEntry("psi", element)
element.getOrBuildFir(firResolveSession)?.let { withFirEntry("fir", it) } element.getOrBuildFir(firResolveSession)?.let { withFirEntry("fir", it) }
} }
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.analysis.collectors.DiagnosticCollectorComponent
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.SessionHolderImpl import org.jetbrains.kotlin.fir.resolve.SessionHolderImpl
import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.util.withSourceCodeAnalysisExceptionUnwrapping
internal abstract class FileStructureElementDiagnosticRetriever { internal abstract class FileStructureElementDiagnosticRetriever {
abstract fun retrieve( abstract fun retrieve(
@@ -36,8 +37,10 @@ internal class SingleNonLocalDeclarationDiagnosticRetriever(
val context = moduleComponents.globalResolveComponents.lockProvider.withWriteLock(firFile) { val context = moduleComponents.globalResolveComponents.lockProvider.withWriteLock(firFile) {
PersistenceContextCollector.collectContext(sessionHolder, firFile, structureElementDeclaration) PersistenceContextCollector.collectContext(sessionHolder, firFile, structureElementDeclaration)
} }
return collector.collectForStructureElement(structureElementDeclaration) { components -> return withSourceCodeAnalysisExceptionUnwrapping {
Visitor(structureElementDeclaration, context, components) collector.collectForStructureElement(structureElementDeclaration) { components ->
Visitor(structureElementDeclaration, context, components)
}
} }
} }
@@ -102,8 +105,10 @@ internal object FileDiagnosticRetriever : FileStructureElementDiagnosticRetrieve
collector: FileStructureElementDiagnosticsCollector, collector: FileStructureElementDiagnosticsCollector,
moduleComponents: LLFirModuleResolveComponents, moduleComponents: LLFirModuleResolveComponents,
): FileStructureElementDiagnosticList = ): FileStructureElementDiagnosticList =
collector.collectForStructureElement(firFile) { components -> withSourceCodeAnalysisExceptionUnwrapping {
Visitor(components, moduleComponents) collector.collectForStructureElement(firFile) { components ->
Visitor(components, moduleComponents)
}
} }
private class Visitor( private class Visitor(
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve package org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve
import org.jetbrains.kotlin.util.SourceCodeAnalysisException
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDeclarationDesignationWithFile import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDeclarationDesignationWithFile
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDesignationWithFile import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDesignationWithFile
@@ -443,7 +444,7 @@ private fun rethrowWithDetails(
appendLine("declaration KtModule: ${moduleData.ktModule::class}") appendLine("declaration KtModule: ${moduleData.ktModule::class}")
appendLine("declaration platform: ${moduleData.ktModule.platform}") appendLine("declaration platform: ${moduleData.ktModule.platform}")
}, },
cause = e, cause = if (e is SourceCodeAnalysisException) e.cause else e,
) { ) {
withEntry("KtModule", firDeclarationToResolve.llFirModuleData.ktModule) { it.moduleDescription } withEntry("KtModule", firDeclarationToResolve.llFirModuleData.ktModule) { it.moduleDescription }
withEntry("session", firDeclarationToResolve.llFirSession) { it.toString() } withEntry("session", firDeclarationToResolve.llFirSession) { it.toString() }
@@ -9,6 +9,7 @@ import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.progress.ProcessCanceledException import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.util.SourceCodeAnalysisException
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.diagnostics.DiagnosticSink import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Errors
@@ -233,13 +234,24 @@ object CodegenUtil {
} }
@JvmStatic @JvmStatic
fun reportBackendException(exception: Throwable, phase: String, location: String?, additionalMessage: String? = null): Nothing { fun reportBackendException(
exception: Throwable,
phase: String,
location: String?,
additionalMessage: String? = null,
linesMapping: (Int) -> Pair<Int, Int>? = { _ -> null },
): Nothing {
// CompilationException (the only KotlinExceptionWithAttachments possible here) is already supposed // CompilationException (the only KotlinExceptionWithAttachments possible here) is already supposed
// to have all information about the context. // to have all information about the context.
if (exception is KotlinExceptionWithAttachments) throw exception if (exception is KotlinExceptionWithAttachments) throw exception
if (exception is ProcessCanceledException) throw exception if (exception is ProcessCanceledException) throw exception
val locationWithLineAndOffset = location
?.let { exception as? SourceCodeAnalysisException }
?.let { linesMapping(it.source.startOffset) }
?.let { (line, offset) -> "$location:${line + 1}:${offset + 1}" }
?: location
throw BackendException( throw BackendException(
getExceptionMessage("Backend", "Exception during $phase", exception, location) + getExceptionMessage("Backend", "Exception during $phase", exception, locationWithLineAndOffset) +
additionalMessage?.let { "\n" + it }.orEmpty(), additionalMessage?.let { "\n" + it }.orEmpty(),
exception exception
) )
@@ -75,7 +75,9 @@ public class PackageCodegenImpl implements PackageCodegen {
} }
catch (Throwable e) { catch (Throwable e) {
VirtualFile vFile = file.getVirtualFile(); VirtualFile vFile = file.getVirtualFile();
CodegenUtil.reportBackendException(e, "file facade code generation", vFile == null ? null : vFile.getUrl(), null); CodegenUtil.reportBackendException(
e, "file facade code generation", vFile == null ? null : vFile.getUrl(), null, (it) -> null
);
} }
} }
} }
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.resolve.defaultType
import org.jetbrains.kotlin.fir.types.* 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.visitors.FirDefaultVisitor import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
import org.jetbrains.kotlin.fir.whileAnalysing
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
abstract class AbstractDiagnosticCollectorVisitor( abstract class AbstractDiagnosticCollectorVisitor(
@@ -270,7 +271,9 @@ abstract class AbstractDiagnosticCollectorVisitor(
val existingContext = context val existingContext = context
context = context.addQualifiedAccessOrAnnotationCall(qualifiedAccessOrAnnotationCall) context = context.addQualifiedAccessOrAnnotationCall(qualifiedAccessOrAnnotationCall)
try { try {
return block() return whileAnalysing(qualifiedAccessOrAnnotationCall) {
block()
}
} finally { } finally {
existingContext.dropQualifiedAccessOrAnnotationCall() existingContext.dropQualifiedAccessOrAnnotationCall()
context = existingContext context = existingContext
@@ -283,7 +286,9 @@ abstract class AbstractDiagnosticCollectorVisitor(
val existingContext = context val existingContext = context
context = context.addGetClassCall(getClassCall) context = context.addGetClassCall(getClassCall)
try { try {
return block() return whileAnalysing(getClassCall) {
block()
}
} finally { } finally {
existingContext.dropGetClassCall() existingContext.dropGetClassCall()
context = existingContext context = existingContext
@@ -296,7 +301,9 @@ abstract class AbstractDiagnosticCollectorVisitor(
val existingContext = context val existingContext = context
context = context.addDeclaration(declaration) context = context.addDeclaration(declaration)
try { try {
return block() return whileAnalysing(declaration) {
block()
}
} finally { } finally {
existingContext.dropDeclaration() existingContext.dropDeclaration()
context = existingContext context = existingContext
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.analysis.collectors.FirDiagnosticsCollector
import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveProcessor import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveProcessor
import org.jetbrains.kotlin.fir.withFileAnalysisExceptionWrapping
fun FirSession.runResolution(firFiles: List<FirFile>): Pair<ScopeSession, List<FirFile>> { fun FirSession.runResolution(firFiles: List<FirFile>): Pair<ScopeSession, List<FirFile>> {
val resolveProcessor = FirTotalResolveProcessor(this) val resolveProcessor = FirTotalResolveProcessor(this)
@@ -21,6 +22,8 @@ fun FirSession.runResolution(firFiles: List<FirFile>): Pair<ScopeSession, List<F
fun FirSession.runCheckers(scopeSession: ScopeSession, firFiles: List<FirFile>, reporter: DiagnosticReporter) { fun FirSession.runCheckers(scopeSession: ScopeSession, firFiles: List<FirFile>, reporter: DiagnosticReporter) {
val collector = FirDiagnosticsCollector.create(this, scopeSession) val collector = FirDiagnosticsCollector.create(this, scopeSession)
for (file in firFiles) { for (file in firFiles) {
collector.collectDiagnostics(file, reporter) withFileAnalysisExceptionWrapping(file) {
collector.collectDiagnostics(file, reporter)
}
} }
} }
@@ -87,7 +87,7 @@ class FirElementSerializer private constructor(
return builder return builder
} }
fun classProto(klass: FirClass): ProtoBuf.Class.Builder { fun classProto(klass: FirClass): ProtoBuf.Class.Builder = whileAnalysing(klass) {
val builder = ProtoBuf.Class.newBuilder() val builder = ProtoBuf.Class.newBuilder()
val regularClass = klass as? FirRegularClass val regularClass = klass as? FirRegularClass
@@ -248,7 +248,7 @@ class FirElementSerializer private constructor(
useSiteTarget == AnnotationUseSiteTarget.SETTER_PARAMETER && isSetter useSiteTarget == AnnotationUseSiteTarget.SETTER_PARAMETER && isSetter
} }
fun propertyProto(property: FirProperty): ProtoBuf.Property.Builder? { fun propertyProto(property: FirProperty): ProtoBuf.Property.Builder? = whileAnalysing(property) {
if (!extension.shouldSerializeProperty(property)) return null if (!extension.shouldSerializeProperty(property)) return null
val builder = ProtoBuf.Property.newBuilder() val builder = ProtoBuf.Property.newBuilder()
@@ -356,7 +356,7 @@ class FirElementSerializer private constructor(
return builder return builder
} }
fun functionProto(function: FirFunction): ProtoBuf.Function.Builder? { fun functionProto(function: FirFunction): ProtoBuf.Function.Builder? = whileAnalysing(function) {
if (!extension.shouldSerializeFunction(function)) return null if (!extension.shouldSerializeFunction(function)) return null
val builder = ProtoBuf.Function.newBuilder() val builder = ProtoBuf.Function.newBuilder()
@@ -450,7 +450,7 @@ class FirElementSerializer private constructor(
return builder return builder
} }
private fun typeAliasProto(typeAlias: FirTypeAlias): ProtoBuf.TypeAlias.Builder? { private fun typeAliasProto(typeAlias: FirTypeAlias): ProtoBuf.TypeAlias.Builder? = whileAnalysing(typeAlias) {
if (!extension.shouldSerializeTypeAlias(typeAlias)) return null if (!extension.shouldSerializeTypeAlias(typeAlias)) return null
val builder = ProtoBuf.TypeAlias.newBuilder() val builder = ProtoBuf.TypeAlias.newBuilder()
@@ -497,14 +497,14 @@ class FirElementSerializer private constructor(
return builder return builder
} }
private fun enumEntryProto(enumEntry: FirEnumEntry): ProtoBuf.EnumEntry.Builder { private fun enumEntryProto(enumEntry: FirEnumEntry): ProtoBuf.EnumEntry.Builder = whileAnalysing(enumEntry) {
val builder = ProtoBuf.EnumEntry.newBuilder() val builder = ProtoBuf.EnumEntry.newBuilder()
builder.name = getSimpleNameIndex(enumEntry.name) builder.name = getSimpleNameIndex(enumEntry.name)
extension.serializeEnumEntry(enumEntry, builder) extension.serializeEnumEntry(enumEntry, builder)
return builder return 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 builder = ProtoBuf.Constructor.newBuilder()
val local = createChildSerializer(constructor) val local = createChildSerializer(constructor)
@@ -543,7 +543,7 @@ class FirElementSerializer private constructor(
private fun valueParameterProto( private fun valueParameterProto(
parameter: FirValueParameter, parameter: FirValueParameter,
additionalAnnotations: List<FirAnnotation> = emptyList() additionalAnnotations: List<FirAnnotation> = emptyList()
): ProtoBuf.ValueParameter.Builder { ): ProtoBuf.ValueParameter.Builder = whileAnalysing(parameter) {
val builder = ProtoBuf.ValueParameter.newBuilder() val builder = ProtoBuf.ValueParameter.newBuilder()
val declaresDefaultValue = parameter.defaultValue != null // TODO: || parameter.isActualParameterWithAnyExpectedDefault val declaresDefaultValue = parameter.defaultValue != null // TODO: || parameter.isActualParameterWithAnyExpectedDefault
@@ -580,7 +580,7 @@ class FirElementSerializer private constructor(
return builder return builder
} }
private fun typeParameterProto(typeParameter: FirTypeParameter): ProtoBuf.TypeParameter.Builder { private fun typeParameterProto(typeParameter: FirTypeParameter): ProtoBuf.TypeParameter.Builder = whileAnalysing(typeParameter) {
val builder = ProtoBuf.TypeParameter.newBuilder() val builder = ProtoBuf.TypeParameter.newBuilder()
builder.id = getTypeParameterId(typeParameter) builder.id = getTypeParameterId(typeParameter)
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor 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.*
import org.jetbrains.kotlin.fir.backend.generators.DataClassMembersGenerator import org.jetbrains.kotlin.fir.backend.generators.DataClassMembersGenerator
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
@@ -29,9 +29,6 @@ import org.jetbrains.kotlin.fir.extensions.declarationGenerators
import org.jetbrains.kotlin.fir.extensions.extensionService import org.jetbrains.kotlin.fir.extensions.extensionService
import org.jetbrains.kotlin.fir.extensions.generatedMembers import org.jetbrains.kotlin.fir.extensions.generatedMembers
import org.jetbrains.kotlin.fir.extensions.generatedNestedClassifiers 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.resolve.ScopeSession
import org.jetbrains.kotlin.fir.signaturer.FirBasedSignatureComposer import org.jetbrains.kotlin.fir.signaturer.FirBasedSignatureComposer
import org.jetbrains.kotlin.fir.signaturer.FirMangler import org.jetbrains.kotlin.fir.signaturer.FirMangler
@@ -95,7 +92,9 @@ class Fir2IrConverter(
// If we encounter local class / anonymous object here, then we perform all (1)-(5) stages immediately // If we encounter local class / anonymous object here, then we perform all (1)-(5) stages immediately
delegatedMemberGenerator.generateBodies() delegatedMemberGenerator.generateBodies()
for (firFile in allFirFiles) { for (firFile in allFirFiles) {
firFile.accept(fir2irVisitor, null) withFileAnalysisExceptionWrapping(firFile) {
firFile.accept(fir2irVisitor, null)
}
} }
if (irGenerationExtensions.isNotEmpty()) { if (irGenerationExtensions.isNotEmpty()) {
@@ -77,7 +77,7 @@ class Fir2IrVisitor(
TODO("Should not be here: ${element::class} ${element.render()}") TODO("Should not be here: ${element::class} ${element.render()}")
} }
override fun visitField(field: FirField, data: Any?): IrField { override fun visitField(field: FirField, data: Any?): IrField = whileAnalysing(field) {
if (field.isSynthetic) { if (field.isSynthetic) {
return declarationStorage.getCachedIrDelegateOrBackingField(field)!!.apply { return declarationStorage.getCachedIrDelegateOrBackingField(field)!!.apply {
// If this is a property backing field, then it has no separate initializer, // If this is a property backing field, then it has no separate initializer,
@@ -106,13 +106,13 @@ class Fir2IrVisitor(
// ================================================================================== // ==================================================================================
override fun visitTypeAlias(typeAlias: FirTypeAlias, data: Any?): IrElement { override fun visitTypeAlias(typeAlias: FirTypeAlias, data: Any?): IrElement = whileAnalysing(typeAlias) {
val irTypeAlias = classifierStorage.getCachedTypeAlias(typeAlias)!! val irTypeAlias = classifierStorage.getCachedTypeAlias(typeAlias)!!
annotationGenerator.generate(irTypeAlias, typeAlias) annotationGenerator.generate(irTypeAlias, typeAlias)
return irTypeAlias return irTypeAlias
} }
override fun visitEnumEntry(enumEntry: FirEnumEntry, data: Any?): IrElement { override fun visitEnumEntry(enumEntry: FirEnumEntry, data: Any?): IrElement = whileAnalysing(enumEntry) {
val irEnumEntry = classifierStorage.getCachedIrEnumEntry(enumEntry)!! val irEnumEntry = classifierStorage.getCachedIrEnumEntry(enumEntry)!!
annotationGenerator.generate(irEnumEntry, enumEntry) annotationGenerator.generate(irEnumEntry, enumEntry)
val correspondingClass = irEnumEntry.correspondingClass val correspondingClass = irEnumEntry.correspondingClass
@@ -169,7 +169,7 @@ class Fir2IrVisitor(
return irEnumEntry return irEnumEntry
} }
override fun visitRegularClass(regularClass: FirRegularClass, data: Any?): IrElement { override fun visitRegularClass(regularClass: FirRegularClass, data: Any?): IrElement = whileAnalysing(regularClass) {
if (regularClass.visibility == Visibilities.Local) { if (regularClass.visibility == Visibilities.Local) {
val irParent = conversionScope.parentFromStack() val irParent = conversionScope.parentFromStack()
// NB: for implicit types it is possible that local class is already cached // NB: for implicit types it is possible that local class is already cached
@@ -215,7 +215,7 @@ class Fir2IrVisitor(
return visitAnonymousObject(anonymousObjectExpression.anonymousObject, data) return visitAnonymousObject(anonymousObjectExpression.anonymousObject, data)
} }
override fun visitAnonymousObject(anonymousObject: FirAnonymousObject, data: Any?): IrElement { override fun visitAnonymousObject(anonymousObject: FirAnonymousObject, data: Any?): IrElement = whileAnalysing(anonymousObject) {
val irParent = conversionScope.parentFromStack() val irParent = conversionScope.parentFromStack()
// NB: for implicit types it is possible that anonymous object is already cached // NB: for implicit types it is possible that anonymous object is already cached
val irAnonymousObject = classifierStorage.getCachedIrClass(anonymousObject)?.apply { this.parent = irParent } val irAnonymousObject = classifierStorage.getCachedIrClass(anonymousObject)?.apply { this.parent = irParent }
@@ -248,14 +248,17 @@ class Fir2IrVisitor(
// ================================================================================== // ==================================================================================
override fun visitConstructor(constructor: FirConstructor, data: Any?): IrElement { override fun visitConstructor(constructor: FirConstructor, data: Any?): IrElement = whileAnalysing(constructor) {
val irConstructor = declarationStorage.getCachedIrConstructor(constructor)!! val irConstructor = declarationStorage.getCachedIrConstructor(constructor)!!
return conversionScope.withFunction(irConstructor) { return conversionScope.withFunction(irConstructor) {
memberGenerator.convertFunctionContent(irConstructor, constructor, containingClass = conversionScope.containerFirClass()) memberGenerator.convertFunctionContent(irConstructor, constructor, containingClass = conversionScope.containerFirClass())
} }
} }
override fun visitAnonymousInitializer(anonymousInitializer: FirAnonymousInitializer, data: Any?): IrElement { override fun visitAnonymousInitializer(
anonymousInitializer: FirAnonymousInitializer,
data: Any?
): IrElement = whileAnalysing(anonymousInitializer) {
val irAnonymousInitializer = declarationStorage.getCachedIrAnonymousInitializer(anonymousInitializer)!! val irAnonymousInitializer = declarationStorage.getCachedIrAnonymousInitializer(anonymousInitializer)!!
declarationStorage.enterScope(irAnonymousInitializer) declarationStorage.enterScope(irAnonymousInitializer)
irAnonymousInitializer.body = convertToIrBlockBody(anonymousInitializer.body!!) irAnonymousInitializer.body = convertToIrBlockBody(anonymousInitializer.body!!)
@@ -263,7 +266,7 @@ class Fir2IrVisitor(
return irAnonymousInitializer 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) { val irFunction = if (simpleFunction.visibility == Visibilities.Local) {
declarationStorage.createIrFunction( declarationStorage.createIrFunction(
simpleFunction, irParent = conversionScope.parent(), predefinedOrigin = IrDeclarationOrigin.LOCAL_FUNCTION, isLocal = true simpleFunction, irParent = conversionScope.parent(), predefinedOrigin = IrDeclarationOrigin.LOCAL_FUNCTION, isLocal = true
@@ -282,7 +285,10 @@ class Fir2IrVisitor(
return visitAnonymousFunction(anonymousFunctionExpression.anonymousFunction, data) return visitAnonymousFunction(anonymousFunctionExpression.anonymousFunction, data)
} }
override fun visitAnonymousFunction(anonymousFunction: FirAnonymousFunction, data: Any?): IrElement { override fun visitAnonymousFunction(
anonymousFunction: FirAnonymousFunction,
data: Any?
): IrElement = whileAnalysing(anonymousFunction) {
return anonymousFunction.convertWithOffsets { startOffset, endOffset -> return anonymousFunction.convertWithOffsets { startOffset, endOffset ->
val irFunction = declarationStorage.createIrFunction( val irFunction = declarationStorage.createIrFunction(
anonymousFunction, anonymousFunction,
@@ -304,7 +310,7 @@ class Fir2IrVisitor(
} }
} }
private fun visitLocalVariable(variable: FirProperty): IrElement { private fun visitLocalVariable(variable: FirProperty): IrElement = whileAnalysing(variable) {
assert(variable.isLocal) assert(variable.isLocal)
val delegate = variable.delegate val delegate = variable.delegate
if (delegate != null) { if (delegate != null) {
@@ -354,7 +360,7 @@ class Fir2IrVisitor(
this@insertImplicitCast.cast(baseExpression, valueType, expectedType) 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) if (property.isLocal) return visitLocalVariable(property)
val irProperty = declarationStorage.getCachedIrProperty(property) val irProperty = declarationStorage.getCachedIrProperty(property)
?: return IrErrorExpressionImpl( ?: return IrErrorExpressionImpl(
@@ -462,11 +468,14 @@ class Fir2IrVisitor(
return result return result
} }
override fun visitFunctionCall(functionCall: FirFunctionCall, data: Any?): IrExpression { override fun visitFunctionCall(functionCall: FirFunctionCall, data: Any?): IrExpression = whileAnalysing(functionCall) {
return convertToIrCall(functionCall = functionCall, annotationMode = false) return convertToIrCall(functionCall = functionCall, annotationMode = false)
} }
override fun visitSafeCallExpression(safeCallExpression: FirSafeCallExpression, data: Any?): IrElement { override fun visitSafeCallExpression(
safeCallExpression: FirSafeCallExpression,
data: Any?
): IrElement = whileAnalysing(safeCallExpression) {
val explicitReceiverExpression = convertToIrExpression(safeCallExpression.receiver) val explicitReceiverExpression = convertToIrExpression(safeCallExpression.receiver)
val (receiverVariable, variableSymbol) = components.createTemporaryVariableForSafeCallConstruction( val (receiverVariable, variableSymbol) = components.createTemporaryVariableForSafeCallConstruction(
@@ -493,7 +502,7 @@ class Fir2IrVisitor(
return callGenerator.convertToIrConstructorCall(annotation) return callGenerator.convertToIrConstructorCall(annotation)
} }
override fun visitAnnotationCall(annotationCall: FirAnnotationCall, data: Any?): IrElement { override fun visitAnnotationCall(annotationCall: FirAnnotationCall, data: Any?): IrElement = whileAnalysing(annotationCall) {
return callGenerator.convertToIrConstructorCall(annotationCall) return callGenerator.convertToIrConstructorCall(annotationCall)
} }
@@ -508,7 +517,7 @@ class Fir2IrVisitor(
private fun convertQualifiedAccessExpression( private fun convertQualifiedAccessExpression(
qualifiedAccessExpression: FirQualifiedAccessExpression, qualifiedAccessExpression: FirQualifiedAccessExpression,
annotationMode: Boolean = false annotationMode: Boolean = false
) : IrExpression { ): IrExpression = whileAnalysing(qualifiedAccessExpression) {
val explicitReceiverExpression = convertToIrReceiverExpression( val explicitReceiverExpression = convertToIrReceiverExpression(
qualifiedAccessExpression.explicitReceiver, qualifiedAccessExpression.calleeReference qualifiedAccessExpression.explicitReceiver, qualifiedAccessExpression.calleeReference
) )
@@ -528,7 +537,10 @@ class Fir2IrVisitor(
return false return false
} }
override fun visitThisReceiverExpression(thisReceiverExpression: FirThisReceiverExpression, data: Any?): IrElement { override fun visitThisReceiverExpression(
thisReceiverExpression: FirThisReceiverExpression,
data: Any?
): IrElement = whileAnalysing(thisReceiverExpression) {
val calleeReference = thisReceiverExpression.calleeReference val calleeReference = thisReceiverExpression.calleeReference
val boundSymbol = calleeReference.boundSymbol val boundSymbol = calleeReference.boundSymbol
if (boundSymbol is FirClassSymbol) { if (boundSymbol is FirClassSymbol) {
@@ -611,7 +623,9 @@ class Fir2IrVisitor(
} }
override fun visitCallableReferenceAccess(callableReferenceAccess: FirCallableReferenceAccess, data: Any?): IrElement { override fun visitCallableReferenceAccess(callableReferenceAccess: FirCallableReferenceAccess, data: Any?): IrElement {
return convertCallableReferenceAccess(callableReferenceAccess, false) return whileAnalysing(callableReferenceAccess) {
convertCallableReferenceAccess(callableReferenceAccess, false)
}
} }
private fun convertCallableReferenceAccess(callableReferenceAccess: FirCallableReferenceAccess, isDelegate: Boolean): IrElement { private fun convertCallableReferenceAccess(callableReferenceAccess: FirCallableReferenceAccess, isDelegate: Boolean): IrElement {
@@ -625,15 +639,19 @@ class Fir2IrVisitor(
) )
} }
override fun visitVariableAssignment(variableAssignment: FirVariableAssignment, data: Any?): IrElement { override fun visitVariableAssignment(
variableAssignment: FirVariableAssignment,
data: Any?
): IrElement = whileAnalysing(variableAssignment) {
val explicitReceiverExpression = convertToIrReceiverExpression( val explicitReceiverExpression = convertToIrReceiverExpression(
variableAssignment.explicitReceiver, variableAssignment.calleeReference variableAssignment.explicitReceiver, variableAssignment.calleeReference
) )
return callGenerator.convertToIrSetCall(variableAssignment, explicitReceiverExpression) return callGenerator.convertToIrSetCall(variableAssignment, explicitReceiverExpression)
} }
override fun <T> visitConstExpression(constExpression: FirConstExpression<T>, data: Any?): IrElement = override fun <T> visitConstExpression(constExpression: FirConstExpression<T>, data: Any?): IrElement {
constExpression.toIrConst(constExpression.typeRef.toIrType()) return constExpression.toIrConst(constExpression.typeRef.toIrType())
}
// ================================================================================== // ==================================================================================
@@ -1210,7 +1228,10 @@ class Fir2IrVisitor(
override fun visitComparisonExpression(comparisonExpression: FirComparisonExpression, data: Any?): IrElement = override fun visitComparisonExpression(comparisonExpression: FirComparisonExpression, data: Any?): IrElement =
operatorGenerator.convertComparisonExpression(comparisonExpression) operatorGenerator.convertComparisonExpression(comparisonExpression)
override fun visitStringConcatenationCall(stringConcatenationCall: FirStringConcatenationCall, data: Any?): IrElement { override fun visitStringConcatenationCall(
stringConcatenationCall: FirStringConcatenationCall,
data: Any?
): IrElement = whileAnalysing(stringConcatenationCall) {
return stringConcatenationCall.convertWithOffsets { startOffset, endOffset -> return stringConcatenationCall.convertWithOffsets { startOffset, endOffset ->
val arguments = mutableListOf<IrExpression>() val arguments = mutableListOf<IrExpression>()
val sb = StringBuilder() val sb = StringBuilder()
@@ -1258,10 +1279,12 @@ class Fir2IrVisitor(
} }
override fun visitEqualityOperatorCall(equalityOperatorCall: FirEqualityOperatorCall, data: Any?): IrElement { override fun visitEqualityOperatorCall(equalityOperatorCall: FirEqualityOperatorCall, data: Any?): IrElement {
return operatorGenerator.convertEqualityOperatorCall(equalityOperatorCall) return whileAnalysing(equalityOperatorCall) {
operatorGenerator.convertEqualityOperatorCall(equalityOperatorCall)
}
} }
override fun visitCheckNotNullCall(checkNotNullCall: FirCheckNotNullCall, data: Any?): IrElement { override fun visitCheckNotNullCall(checkNotNullCall: FirCheckNotNullCall, data: Any?): IrElement = whileAnalysing(checkNotNullCall) {
return checkNotNullCall.convertWithOffsets { startOffset, endOffset -> return checkNotNullCall.convertWithOffsets { startOffset, endOffset ->
IrCallImpl( IrCallImpl(
startOffset, endOffset, startOffset, endOffset,
@@ -1277,7 +1300,7 @@ class Fir2IrVisitor(
} }
} }
override fun visitGetClassCall(getClassCall: FirGetClassCall, data: Any?): IrElement { override fun visitGetClassCall(getClassCall: FirGetClassCall, data: Any?): IrElement = whileAnalysing(getClassCall) {
val argument = getClassCall.argument val argument = getClassCall.argument
val irType = getClassCall.typeRef.toIrType() val irType = getClassCall.typeRef.toIrType()
val irClassType = val irClassType =
@@ -1342,11 +1365,14 @@ class Fir2IrVisitor(
} }
} }
override fun visitArrayOfCall(arrayOfCall: FirArrayOfCall, data: Any?): IrElement { override fun visitArrayOfCall(arrayOfCall: FirArrayOfCall, data: Any?): IrElement = whileAnalysing(arrayOfCall) {
return convertToArrayOfCall(arrayOfCall, annotationMode = false) return convertToArrayOfCall(arrayOfCall, annotationMode = false)
} }
override fun visitAugmentedArraySetCall(augmentedArraySetCall: FirAugmentedArraySetCall, data: Any?): IrElement { override fun visitAugmentedArraySetCall(
augmentedArraySetCall: FirAugmentedArraySetCall,
data: Any?
): IrElement = whileAnalysing(augmentedArraySetCall) {
return augmentedArraySetCall.convertWithOffsets { startOffset, endOffset -> return augmentedArraySetCall.convertWithOffsets { startOffset, endOffset ->
IrErrorCallExpressionImpl( IrErrorCallExpressionImpl(
startOffset, endOffset, irBuiltIns.unitType, startOffset, endOffset, irBuiltIns.unitType,
@@ -335,9 +335,10 @@ class FirCheckersRunnerTransformer(private val diagnosticCollector: AbstractDiag
return element return element
} }
override fun transformFile(file: FirFile, data: Nothing?): FirFile { override fun transformFile(file: FirFile, data: Nothing?): FirFile = file.also {
val reporter = DiagnosticReporterFactory.createPendingReporter() withFileAnalysisExceptionWrapping(file) {
diagnosticCollector.collectDiagnostics(file, reporter) val reporter = DiagnosticReporterFactory.createPendingReporter()
return file diagnosticCollector.collectDiagnostics(file, reporter)
}
} }
} }
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
import org.jetbrains.kotlin.fir.visitors.FirTransformer import org.jetbrains.kotlin.fir.visitors.FirTransformer
import org.jetbrains.kotlin.fir.visitors.transformSingle import org.jetbrains.kotlin.fir.visitors.transformSingle
import org.jetbrains.kotlin.fir.withFileAnalysisExceptionWrapping
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
class FirSealedClassInheritorsProcessor( class FirSealedClassInheritorsProcessor(
@@ -38,8 +39,16 @@ class FirSealedClassInheritorsProcessor(
override fun process(files: Collection<FirFile>) { override fun process(files: Collection<FirFile>) {
val sealedClassInheritorsMap = mutableMapOf<FirRegularClass, MutableList<ClassId>>() val sealedClassInheritorsMap = mutableMapOf<FirRegularClass, MutableList<ClassId>>()
val inheritorsCollector = InheritorsCollector(session) val inheritorsCollector = InheritorsCollector(session)
files.forEach { it.accept(inheritorsCollector, sealedClassInheritorsMap) } files.forEach {
files.forEach { it.transformSingle(InheritorsTransformer(sealedClassInheritorsMap), null) } withFileAnalysisExceptionWrapping(it) {
it.accept(inheritorsCollector, sealedClassInheritorsMap)
}
}
files.forEach {
withFileAnalysisExceptionWrapping(it) {
it.transformSingle(InheritorsTransformer(sealedClassInheritorsMap), null)
}
}
} }
class InheritorsCollector(val session: FirSession) : FirDefaultVisitor<Unit, MutableMap<FirRegularClass, MutableList<ClassId>>>() { class InheritorsCollector(val session: FirSession) : FirDefaultVisitor<Unit, MutableMap<FirRegularClass, MutableList<ClassId>>>() {
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.toSymbol import org.jetbrains.kotlin.fir.types.toSymbol
import org.jetbrains.kotlin.fir.visitors.transformSingle import org.jetbrains.kotlin.fir.visitors.transformSingle
import org.jetbrains.kotlin.fir.whileAnalysing
class FirStatusResolveProcessor( class FirStatusResolveProcessor(
session: FirSession, session: FirSession,
@@ -104,7 +105,7 @@ open class FirStatusResolveTransformer(
override fun transformRegularClass( override fun transformRegularClass(
regularClass: FirRegularClass, regularClass: FirRegularClass,
data: FirResolvedDeclarationStatus? data: FirResolvedDeclarationStatus?
): FirStatement { ): FirStatement = whileAnalysing(regularClass) {
val computationStatus = statusComputationSession.startComputing(regularClass) val computationStatus = statusComputationSession.startComputing(regularClass)
forceResolveStatusesOfSupertypes(regularClass) forceResolveStatusesOfSupertypes(regularClass)
/* /*
@@ -166,7 +167,7 @@ open class FirDesignatedStatusResolveTransformer(
override fun transformRegularClass( override fun transformRegularClass(
regularClass: FirRegularClass, regularClass: FirRegularClass,
data: FirResolvedDeclarationStatus? data: FirResolvedDeclarationStatus?
): FirStatement { ): FirStatement = whileAnalysing(regularClass) {
if (shouldSkipClass(regularClass)) return regularClass if (shouldSkipClass(regularClass)) return regularClass
regularClass.symbol.lazyResolveToPhase(FirResolvePhase.TYPES) regularClass.symbol.lazyResolveToPhase(FirResolvePhase.TYPES)
val classLocated = this.classLocated val classLocated = this.classLocated
@@ -290,7 +291,7 @@ abstract class AbstractFirStatusResolveTransformer(
override fun transformDeclaration( override fun transformDeclaration(
declaration: FirDeclaration, declaration: FirDeclaration,
data: FirResolvedDeclarationStatus? data: FirResolvedDeclarationStatus?
): FirDeclaration { ): FirDeclaration = whileAnalysing(declaration) {
return when (declaration) { return when (declaration) {
is FirCallableDeclaration -> { is FirCallableDeclaration -> {
if (declaration is FirFunction) { if (declaration is FirFunction) {
@@ -309,7 +310,7 @@ abstract class AbstractFirStatusResolveTransformer(
override fun transformTypeAlias( override fun transformTypeAlias(
typeAlias: FirTypeAlias, typeAlias: FirTypeAlias,
data: FirResolvedDeclarationStatus? data: FirResolvedDeclarationStatus?
): FirStatement { ): FirStatement = whileAnalysing(typeAlias) {
typeAlias.typeParameters.forEach { transformDeclaration(it, data) } typeAlias.typeParameters.forEach { transformDeclaration(it, data) }
typeAlias.transformStatus(this, statusResolver.resolveStatus(typeAlias, containingClass, isLocal = false)) typeAlias.transformStatus(this, statusResolver.resolveStatus(typeAlias, containingClass, isLocal = false))
return transformDeclaration(typeAlias, data) as FirTypeAlias return transformDeclaration(typeAlias, data) as FirTypeAlias
@@ -323,7 +324,7 @@ abstract class AbstractFirStatusResolveTransformer(
override fun transformAnonymousObject( override fun transformAnonymousObject(
anonymousObject: FirAnonymousObject, anonymousObject: FirAnonymousObject,
data: FirResolvedDeclarationStatus? data: FirResolvedDeclarationStatus?
): FirStatement { ): FirStatement = whileAnalysing(anonymousObject) {
anonymousObject.transformStatus( anonymousObject.transformStatus(
this, this,
FirResolvedDeclarationStatusImpl( FirResolvedDeclarationStatusImpl(
@@ -369,7 +370,7 @@ abstract class AbstractFirStatusResolveTransformer(
override fun transformClass( override fun transformClass(
klass: FirClass, klass: FirClass,
data: FirResolvedDeclarationStatus? data: FirResolvedDeclarationStatus?
): FirStatement { ): FirStatement = whileAnalysing(klass) {
return storeClass(klass) { return storeClass(klass) {
klass.typeParameters.forEach { it.transformSingle(this, data) } klass.typeParameters.forEach { it.transformSingle(this, data) }
transformDeclarationContent(klass, data) transformDeclarationContent(klass, data)
@@ -447,7 +448,7 @@ abstract class AbstractFirStatusResolveTransformer(
propertyAccessor: FirPropertyAccessor, propertyAccessor: FirPropertyAccessor,
containingProperty: FirProperty, containingProperty: FirProperty,
overriddenStatuses: List<FirResolvedDeclarationStatus> = emptyList(), overriddenStatuses: List<FirResolvedDeclarationStatus> = emptyList(),
) { ): Unit = whileAnalysing(propertyAccessor) {
propertyAccessor.transformStatus( propertyAccessor.transformStatus(
this, this,
statusResolver.resolveStatus( statusResolver.resolveStatus(
@@ -465,7 +466,7 @@ abstract class AbstractFirStatusResolveTransformer(
override fun transformConstructor( override fun transformConstructor(
constructor: FirConstructor, constructor: FirConstructor,
data: FirResolvedDeclarationStatus? data: FirResolvedDeclarationStatus?
): FirStatement { ): FirStatement = whileAnalysing(constructor) {
constructor.transformStatus(this, statusResolver.resolveStatus(constructor, containingClass, isLocal = false)) constructor.transformStatus(this, statusResolver.resolveStatus(constructor, containingClass, isLocal = false))
calculateDeprecations(constructor) calculateDeprecations(constructor)
return transformDeclaration(constructor, data) as FirStatement return transformDeclaration(constructor, data) as FirStatement
@@ -474,7 +475,7 @@ abstract class AbstractFirStatusResolveTransformer(
override fun transformSimpleFunction( override fun transformSimpleFunction(
simpleFunction: FirSimpleFunction, simpleFunction: FirSimpleFunction,
data: FirResolvedDeclarationStatus? data: FirResolvedDeclarationStatus?
): FirStatement { ): FirStatement = whileAnalysing(simpleFunction) {
val resolvedStatus = statusResolver.resolveStatus(simpleFunction, containingClass, isLocal = false) val resolvedStatus = statusResolver.resolveStatus(simpleFunction, containingClass, isLocal = false)
simpleFunction.transformStatus(this, resolvedStatus) simpleFunction.transformStatus(this, resolvedStatus)
calculateDeprecations(simpleFunction) calculateDeprecations(simpleFunction)
@@ -484,7 +485,7 @@ abstract class AbstractFirStatusResolveTransformer(
override fun transformProperty( override fun transformProperty(
property: FirProperty, property: FirProperty,
data: FirResolvedDeclarationStatus? data: FirResolvedDeclarationStatus?
): FirStatement { ): FirStatement = whileAnalysing(property) {
val overridden = statusResolver.getOverriddenProperties(property, containingClass) val overridden = statusResolver.getOverriddenProperties(property, containingClass)
val overriddenProperties = overridden.map { val overriddenProperties = overridden.map {
@@ -519,7 +520,7 @@ abstract class AbstractFirStatusResolveTransformer(
override fun transformField( override fun transformField(
field: FirField, field: FirField,
data: FirResolvedDeclarationStatus? data: FirResolvedDeclarationStatus?
): FirStatement { ): FirStatement = whileAnalysing(field) {
field.transformStatus(this, statusResolver.resolveStatus(field, containingClass, isLocal = false)) field.transformStatus(this, statusResolver.resolveStatus(field, containingClass, isLocal = false))
calculateDeprecations(field) calculateDeprecations(field)
return transformDeclaration(field, data) as FirField return transformDeclaration(field, data) as FirField
@@ -532,7 +533,7 @@ abstract class AbstractFirStatusResolveTransformer(
override fun transformEnumEntry( override fun transformEnumEntry(
enumEntry: FirEnumEntry, enumEntry: FirEnumEntry,
data: FirResolvedDeclarationStatus? data: FirResolvedDeclarationStatus?
): FirStatement { ): FirStatement = whileAnalysing(enumEntry) {
enumEntry.transformStatus(this, statusResolver.resolveStatus(enumEntry, containingClass, isLocal = false)) enumEntry.transformStatus(this, statusResolver.resolveStatus(enumEntry, containingClass, isLocal = false))
calculateDeprecations(enumEntry) calculateDeprecations(enumEntry)
return transformDeclaration(enumEntry, data) as FirEnumEntry return transformDeclaration(enumEntry, data) as FirEnumEntry
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirImplicitTyp
import org.jetbrains.kotlin.fir.resolve.transformers.contracts.FirContractResolveProcessor import org.jetbrains.kotlin.fir.resolve.transformers.contracts.FirContractResolveProcessor
import org.jetbrains.kotlin.fir.resolve.transformers.mpp.FirExpectActualMatcherProcessor import org.jetbrains.kotlin.fir.resolve.transformers.mpp.FirExpectActualMatcherProcessor
import org.jetbrains.kotlin.fir.resolve.transformers.plugin.* import org.jetbrains.kotlin.fir.resolve.transformers.plugin.*
import org.jetbrains.kotlin.fir.withFileAnalysisExceptionWrapping
class FirTotalResolveProcessor(session: FirSession) { class FirTotalResolveProcessor(session: FirSession) {
val scopeSession: ScopeSession = ScopeSession() val scopeSession: ScopeSession = ScopeSession()
@@ -30,7 +31,9 @@ class FirTotalResolveProcessor(session: FirSession) {
when (processor) { when (processor) {
is FirTransformerBasedResolveProcessor -> { is FirTransformerBasedResolveProcessor -> {
for (file in files) { for (file in files) {
processor.processFile(file) withFileAnalysisExceptionWrapping(file) {
processor.processFile(file)
}
} }
} }
is FirGlobalResolveProcessor -> { is FirGlobalResolveProcessor -> {
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.scopes.impl.nestedClassifierScope
import org.jetbrains.kotlin.fir.scopes.impl.wrapNestedClassifierScopeWithSubstitutionForSuperType import org.jetbrains.kotlin.fir.scopes.impl.wrapNestedClassifierScopeWithSubstitutionForSuperType
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
import org.jetbrains.kotlin.fir.whileAnalysing
class FirTypeResolveProcessor( class FirTypeResolveProcessor(
session: FirSession, session: FirSession,
@@ -74,16 +75,18 @@ open class FirTypeResolveTransformer(
} }
override fun transformRegularClass(regularClass: FirRegularClass, data: Any?): FirStatement { override fun transformRegularClass(regularClass: FirRegularClass, data: Any?): FirStatement {
withClassDeclarationCleanup(classDeclarationsStack, regularClass) { whileAnalysing(regularClass) {
withScopeCleanup { withClassDeclarationCleanup(classDeclarationsStack, regularClass) {
regularClass.addTypeParametersScope() withScopeCleanup {
regularClass.typeParameters.forEach { regularClass.addTypeParametersScope()
it.accept(this, data) regularClass.typeParameters.forEach {
it.accept(this, data)
}
unboundCyclesInTypeParametersSupertypes(regularClass)
} }
unboundCyclesInTypeParametersSupertypes(regularClass)
}
return resolveClassContent(regularClass, data) return resolveClassContent(regularClass, data)
}
} }
} }
@@ -93,21 +96,21 @@ open class FirTypeResolveTransformer(
} }
} }
override fun transformConstructor(constructor: FirConstructor, data: Any?): FirConstructor { override fun transformConstructor(constructor: FirConstructor, data: Any?): FirConstructor = whileAnalysing(constructor) {
return withScopeCleanup { return withScopeCleanup {
constructor.addTypeParametersScope() constructor.addTypeParametersScope()
transformDeclaration(constructor, data) transformDeclaration(constructor, data)
} as FirConstructor } as FirConstructor
} }
override fun transformTypeAlias(typeAlias: FirTypeAlias, data: Any?): FirTypeAlias { override fun transformTypeAlias(typeAlias: FirTypeAlias, data: Any?): FirTypeAlias = whileAnalysing(typeAlias) {
return withScopeCleanup { return withScopeCleanup {
typeAlias.addTypeParametersScope() typeAlias.addTypeParametersScope()
transformDeclaration(typeAlias, data) transformDeclaration(typeAlias, data)
} as FirTypeAlias } as FirTypeAlias
} }
override fun transformEnumEntry(enumEntry: FirEnumEntry, data: Any?): FirEnumEntry { override fun transformEnumEntry(enumEntry: FirEnumEntry, data: Any?): FirEnumEntry = whileAnalysing(enumEntry) {
enumEntry.transformReturnTypeRef(this, data) enumEntry.transformReturnTypeRef(this, data)
enumEntry.transformTypeParameters(this, data) enumEntry.transformTypeParameters(this, data)
enumEntry.transformAnnotations(this, data) enumEntry.transformAnnotations(this, data)
@@ -118,7 +121,7 @@ open class FirTypeResolveTransformer(
return receiverParameter.transformAnnotations(this, data).transformTypeRef(this, data) return receiverParameter.transformAnnotations(this, data).transformTypeRef(this, data)
} }
override fun transformProperty(property: FirProperty, data: Any?): FirProperty { override fun transformProperty(property: FirProperty, data: Any?): FirProperty = whileAnalysing(property) {
return withScopeCleanup { return withScopeCleanup {
property.addTypeParametersScope() property.addTypeParametersScope()
property.transformTypeParameters(this, data) property.transformTypeParameters(this, data)
@@ -150,14 +153,17 @@ open class FirTypeResolveTransformer(
property.setter?.valueParameters?.map { it.transformReturnTypeRef(StoreType, property.returnTypeRef) } property.setter?.valueParameters?.map { it.transformReturnTypeRef(StoreType, property.returnTypeRef) }
} }
override fun transformField(field: FirField, data: Any?): FirField { override fun transformField(field: FirField, data: Any?): FirField = whileAnalysing(field) {
return withScopeCleanup { return withScopeCleanup {
field.transformReturnTypeRef(this, data).transformAnnotations(this, data) field.transformReturnTypeRef(this, data).transformAnnotations(this, data)
field field
} }
} }
override fun transformSimpleFunction(simpleFunction: FirSimpleFunction, data: Any?): FirSimpleFunction { override fun transformSimpleFunction(
simpleFunction: FirSimpleFunction,
data: Any?
): FirSimpleFunction = whileAnalysing(simpleFunction) {
return withScopeCleanup { return withScopeCleanup {
simpleFunction.addTypeParametersScope() simpleFunction.addTypeParametersScope()
transformDeclaration(simpleFunction, data).also { transformDeclaration(simpleFunction, data).also {
@@ -208,7 +214,7 @@ open class FirTypeResolveTransformer(
} }
} }
override fun transformValueParameter(valueParameter: FirValueParameter, data: Any?): FirStatement { override fun transformValueParameter(valueParameter: FirValueParameter, data: Any?): FirStatement = whileAnalysing(valueParameter) {
valueParameter.transformReturnTypeRef(this, data) valueParameter.transformReturnTypeRef(this, data)
valueParameter.transformAnnotations(this, data) valueParameter.transformAnnotations(this, data)
valueParameter.transformVarargTypeToArrayType() valueParameter.transformVarargTypeToArrayType()
@@ -224,7 +230,7 @@ open class FirTypeResolveTransformer(
return annotation return annotation
} }
override fun transformAnnotationCall(annotationCall: FirAnnotationCall, data: Any?): FirStatement { override fun transformAnnotationCall(annotationCall: FirAnnotationCall, data: Any?): FirStatement = whileAnalysing(annotationCall) {
return transformAnnotation(annotationCall, data) return transformAnnotation(annotationCall, data)
} }
@@ -111,7 +111,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve
} }
} }
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" } require(property !is FirSyntheticProperty) { "Synthetic properties should not be processed by body transformers" }
if (property.isLocal) { if (property.isLocal) {
@@ -207,7 +207,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve
} }
} }
override fun transformField(field: FirField, data: ResolutionMode): FirField { override fun transformField(field: FirField, data: ResolutionMode): FirField = whileAnalysing(field) {
val returnTypeRef = field.returnTypeRef val returnTypeRef = field.returnTypeRef
if (implicitTypeOnly) return field if (implicitTypeOnly) return field
if (field.initializerResolved) return field if (field.initializerResolved) return field
@@ -373,7 +373,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve
return delegateExpression return delegateExpression
} }
private fun transformLocalVariable(variable: FirProperty): FirProperty { private fun transformLocalVariable(variable: FirProperty): FirProperty = whileAnalysing(variable) {
assert(variable.isLocal) assert(variable.isLocal)
val delegate = variable.delegate val delegate = variable.delegate
@@ -455,7 +455,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve
accessor: FirPropertyAccessor, accessor: FirPropertyAccessor,
enhancedTypeRef: FirTypeRef, enhancedTypeRef: FirTypeRef,
owner: FirProperty owner: FirProperty
) { ): Unit = whileAnalysing(accessor) {
context.withPropertyAccessor(owner, accessor, components) { context.withPropertyAccessor(owner, accessor, components) {
if (accessor is FirDefaultPropertyAccessor || accessor.body == null) { if (accessor is FirDefaultPropertyAccessor || accessor.body == null) {
transformFunction(accessor, withExpectedType(enhancedTypeRef)) transformFunction(accessor, withExpectedType(enhancedTypeRef))
@@ -490,8 +490,8 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve
) )
} }
override fun transformRegularClass(regularClass: FirRegularClass, data: ResolutionMode): FirStatement { override fun transformRegularClass(regularClass: FirRegularClass, data: ResolutionMode): FirStatement = whileAnalysing(regularClass) {
context.withContainingClass(regularClass) { return context.withContainingClass(regularClass) {
if (regularClass.isLocal && regularClass !in context.targetedLocalClasses) { if (regularClass.isLocal && regularClass !in context.targetedLocalClasses) {
return regularClass.runAllPhasesForLocalClass( return regularClass.runAllPhasesForLocalClass(
transformer, transformer,
@@ -503,7 +503,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve
} }
doTransformTypeParameters(regularClass) doTransformTypeParameters(regularClass)
return doTransformRegularClass(regularClass, data) doTransformRegularClass(regularClass, data)
} }
} }
@@ -519,7 +519,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve
return result return result
} }
override fun transformTypeAlias(typeAlias: FirTypeAlias, data: ResolutionMode): FirTypeAlias { override fun transformTypeAlias(typeAlias: FirTypeAlias, data: ResolutionMode): FirTypeAlias = whileAnalysing(typeAlias) {
if (typeAlias.isLocal && typeAlias !in context.targetedLocalClasses) { if (typeAlias.isLocal && typeAlias !in context.targetedLocalClasses) {
return typeAlias.runAllPhasesForLocalClass( return typeAlias.runAllPhasesForLocalClass(
transformer, transformer,
@@ -559,7 +559,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve
override fun transformAnonymousObject( override fun transformAnonymousObject(
anonymousObject: FirAnonymousObject, anonymousObject: FirAnonymousObject,
data: ResolutionMode data: ResolutionMode
): FirStatement { ): FirStatement = whileAnalysing(anonymousObject) {
if (anonymousObject !in context.targetedLocalClasses) { if (anonymousObject !in context.targetedLocalClasses) {
return anonymousObject.runAllPhasesForLocalClass( return anonymousObject.runAllPhasesForLocalClass(
transformer, transformer,
@@ -617,7 +617,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve
override fun transformSimpleFunction( override fun transformSimpleFunction(
simpleFunction: FirSimpleFunction, simpleFunction: FirSimpleFunction,
data: ResolutionMode data: ResolutionMode
): FirSimpleFunction { ): FirSimpleFunction = whileAnalysing(simpleFunction) {
if (simpleFunction.bodyResolved) { if (simpleFunction.bodyResolved) {
return simpleFunction return simpleFunction
} }
@@ -681,7 +681,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve
override fun transformFunction( override fun transformFunction(
function: FirFunction, function: FirFunction,
data: ResolutionMode data: ResolutionMode
): FirStatement { ): FirStatement = whileAnalysing(function) {
val functionIsNotAnalyzed = !function.bodyResolved val functionIsNotAnalyzed = !function.bodyResolved
if (functionIsNotAnalyzed) { if (functionIsNotAnalyzed) {
dataFlowAnalyzer.enterFunction(function) dataFlowAnalyzer.enterFunction(function)
@@ -696,7 +696,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve
} as FirStatement } as FirStatement
} }
override fun transformConstructor(constructor: FirConstructor, data: ResolutionMode): FirConstructor { override fun transformConstructor(constructor: FirConstructor, data: ResolutionMode): FirConstructor = whileAnalysing(constructor) {
if (implicitTypeOnly) return constructor if (implicitTypeOnly) return constructor
val container = context.containerIfAny as? FirRegularClass val container = context.containerIfAny as? FirRegularClass
if (constructor.isPrimary && container?.classKind == ClassKind.ANNOTATION_CLASS) { if (constructor.isPrimary && container?.classKind == ClassKind.ANNOTATION_CLASS) {
@@ -737,7 +737,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve
override fun transformAnonymousInitializer( override fun transformAnonymousInitializer(
anonymousInitializer: FirAnonymousInitializer, anonymousInitializer: FirAnonymousInitializer,
data: ResolutionMode data: ResolutionMode
): FirAnonymousInitializer { ): FirAnonymousInitializer = whileAnalysing(anonymousInitializer) {
if (implicitTypeOnly) return anonymousInitializer if (implicitTypeOnly) return anonymousInitializer
dataFlowAnalyzer.enterInitBlock(anonymousInitializer) dataFlowAnalyzer.enterInitBlock(anonymousInitializer)
return context.withAnonymousInitializer(anonymousInitializer, session) { return context.withAnonymousInitializer(anonymousInitializer, session) {
@@ -749,7 +749,10 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve
} }
} }
override fun transformValueParameter(valueParameter: FirValueParameter, data: ResolutionMode): FirStatement { override fun transformValueParameter(
valueParameter: FirValueParameter,
data: ResolutionMode
): FirStatement = whileAnalysing(valueParameter) {
dataFlowAnalyzer.enterValueParameter(valueParameter) dataFlowAnalyzer.enterValueParameter(valueParameter)
val result = context.withValueParameter(valueParameter, session) { val result = context.withValueParameter(valueParameter, session) {
transformDeclarationContent( transformDeclarationContent(
@@ -768,7 +771,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve
override fun transformAnonymousFunction( override fun transformAnonymousFunction(
anonymousFunction: FirAnonymousFunction, anonymousFunction: FirAnonymousFunction,
data: ResolutionMode data: ResolutionMode
): FirStatement { ): FirStatement = whileAnalysing(anonymousFunction) {
// Either ContextDependent, ContextIndependent or WithExpectedType could be here // Either ContextDependent, ContextIndependent or WithExpectedType could be here
if (data !is ResolutionMode.LambdaResolution) { if (data !is ResolutionMode.LambdaResolution) {
anonymousFunction.transformReturnTypeRef(transformer, ResolutionMode.ContextIndependent) anonymousFunction.transformReturnTypeRef(transformer, ResolutionMode.ContextIndependent)
@@ -1019,7 +1022,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve
override fun transformBackingField( override fun transformBackingField(
backingField: FirBackingField, backingField: FirBackingField,
data: ResolutionMode, data: ResolutionMode,
): FirStatement { ): FirStatement = whileAnalysing(backingField) {
val propertyType = data.expectedType val propertyType = data.expectedType
val initializerData = if (backingField.returnTypeRef is FirResolvedTypeRef) { val initializerData = if (backingField.returnTypeRef is FirResolvedTypeRef) {
withExpectedType(backingField.returnTypeRef) withExpectedType(backingField.returnTypeRef)
@@ -1123,7 +1126,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve
return element return element
} }
override fun transformValueParameter(valueParameter: FirValueParameter, data: Any?): FirStatement { override fun transformValueParameter(valueParameter: FirValueParameter, data: Any?): FirStatement = whileAnalysing(valueParameter) {
if (valueParameter.returnTypeRef is FirImplicitTypeRef) { if (valueParameter.returnTypeRef is FirImplicitTypeRef) {
valueParameter.transformReturnTypeRef( valueParameter.transformReturnTypeRef(
StoreType, StoreType,
@@ -84,7 +84,9 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
override fun transformQualifiedAccessExpression( override fun transformQualifiedAccessExpression(
qualifiedAccessExpression: FirQualifiedAccessExpression, qualifiedAccessExpression: FirQualifiedAccessExpression,
data: ResolutionMode, data: ResolutionMode,
): FirStatement = transformQualifiedAccessExpression(qualifiedAccessExpression, data, isUsedAsReceiver = false) ): FirStatement = whileAnalysing(qualifiedAccessExpression) {
transformQualifiedAccessExpression(qualifiedAccessExpression, data, isUsedAsReceiver = false)
}
fun transformQualifiedAccessExpression( fun transformQualifiedAccessExpression(
qualifiedAccessExpression: FirQualifiedAccessExpression, qualifiedAccessExpression: FirQualifiedAccessExpression,
@@ -317,23 +319,25 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
safeCallExpression: FirSafeCallExpression, safeCallExpression: FirSafeCallExpression,
data: ResolutionMode data: ResolutionMode
): FirStatement { ): FirStatement {
withContainingSafeCallExpression(safeCallExpression) { whileAnalysing(safeCallExpression) {
safeCallExpression.transformAnnotations(this, ResolutionMode.ContextIndependent) withContainingSafeCallExpression(safeCallExpression) {
safeCallExpression.transformReceiver(this, ResolutionMode.ContextIndependent) safeCallExpression.transformAnnotations(this, ResolutionMode.ContextIndependent)
safeCallExpression.transformReceiver(this, ResolutionMode.ContextIndependent)
val receiver = safeCallExpression.receiver val receiver = safeCallExpression.receiver
dataFlowAnalyzer.enterSafeCallAfterNullCheck(safeCallExpression) dataFlowAnalyzer.enterSafeCallAfterNullCheck(safeCallExpression)
safeCallExpression.apply { safeCallExpression.apply {
checkedSubjectRef.value.propagateTypeFromOriginalReceiver(receiver, components.session, components.file) checkedSubjectRef.value.propagateTypeFromOriginalReceiver(receiver, components.session, components.file)
transformSelector(this@FirExpressionsResolveTransformer, data) transformSelector(this@FirExpressionsResolveTransformer, data)
propagateTypeFromQualifiedAccessAfterNullCheck(receiver, session, context.file) propagateTypeFromQualifiedAccessAfterNullCheck(receiver, session, context.file)
}
dataFlowAnalyzer.exitSafeCall(safeCallExpression)
return safeCallExpression
} }
dataFlowAnalyzer.exitSafeCall(safeCallExpression)
return safeCallExpression
} }
} }
@@ -354,7 +358,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
return checkedSafeCallSubject return checkedSafeCallSubject
} }
override fun transformFunctionCall(functionCall: FirFunctionCall, data: ResolutionMode): FirStatement { override fun transformFunctionCall(functionCall: FirFunctionCall, data: ResolutionMode): FirStatement = whileAnalysing(functionCall) {
val calleeReference = functionCall.calleeReference val calleeReference = functionCall.calleeReference
if ( if (
(calleeReference is FirResolvedNamedReference || calleeReference is FirErrorNamedReference) && (calleeReference is FirResolvedNamedReference || calleeReference is FirErrorNamedReference) &&
@@ -513,7 +517,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
override fun transformComparisonExpression( override fun transformComparisonExpression(
comparisonExpression: FirComparisonExpression, comparisonExpression: FirComparisonExpression,
data: ResolutionMode data: ResolutionMode
): FirStatement { ): FirStatement = whileAnalysing(comparisonExpression) {
return (comparisonExpression.transformChildren(transformer, ResolutionMode.ContextIndependent) as FirComparisonExpression).also { return (comparisonExpression.transformChildren(transformer, ResolutionMode.ContextIndependent) as FirComparisonExpression).also {
it.resultType = comparisonExpression.typeRef.resolvedTypeFromPrototype(builtinTypes.booleanType.type) it.resultType = comparisonExpression.typeRef.resolvedTypeFromPrototype(builtinTypes.booleanType.type)
dataFlowAnalyzer.exitComparisonExpressionCall(it) dataFlowAnalyzer.exitComparisonExpressionCall(it)
@@ -523,7 +527,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
override fun transformAssignmentOperatorStatement( override fun transformAssignmentOperatorStatement(
assignmentOperatorStatement: FirAssignmentOperatorStatement, assignmentOperatorStatement: FirAssignmentOperatorStatement,
data: ResolutionMode data: ResolutionMode
): FirStatement { ): FirStatement = whileAnalysing(assignmentOperatorStatement) {
val operation = assignmentOperatorStatement.operation val operation = assignmentOperatorStatement.operation
require(operation != FirOperation.ASSIGN) require(operation != FirOperation.ASSIGN)
@@ -650,7 +654,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
override fun transformEqualityOperatorCall( override fun transformEqualityOperatorCall(
equalityOperatorCall: FirEqualityOperatorCall, equalityOperatorCall: FirEqualityOperatorCall,
data: ResolutionMode data: ResolutionMode
): FirStatement { ): FirStatement = whileAnalysing(equalityOperatorCall) {
// Currently, we use expectedType=Any? for both operands // Currently, we use expectedType=Any? for both operands
// In FE1.0, it's only used for the right // In FE1.0, it's only used for the right
// But it seems a bit inconsistent (see KT-47409) // But it seems a bit inconsistent (see KT-47409)
@@ -817,7 +821,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
override fun transformBinaryLogicExpression( override fun transformBinaryLogicExpression(
binaryLogicExpression: FirBinaryLogicExpression, binaryLogicExpression: FirBinaryLogicExpression,
data: ResolutionMode, data: ResolutionMode,
): FirStatement { ): FirStatement = whileAnalysing(binaryLogicExpression) {
val booleanType = binaryLogicExpression.typeRef.resolvedTypeFromPrototype(builtinTypes.booleanType.type) val booleanType = binaryLogicExpression.typeRef.resolvedTypeFromPrototype(builtinTypes.booleanType.type)
return when (binaryLogicExpression.kind) { return when (binaryLogicExpression.kind) {
LogicOperationKind.AND -> LogicOperationKind.AND ->
@@ -839,7 +843,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
override fun transformVariableAssignment( override fun transformVariableAssignment(
variableAssignment: FirVariableAssignment, variableAssignment: FirVariableAssignment,
data: ResolutionMode, data: ResolutionMode,
): FirStatement { ): FirStatement = whileAnalysing(variableAssignment) {
// val resolvedAssignment = transformCallee(variableAssignment) // val resolvedAssignment = transformCallee(variableAssignment)
variableAssignment.transformAnnotations(transformer, ResolutionMode.ContextIndependent) variableAssignment.transformAnnotations(transformer, ResolutionMode.ContextIndependent)
val resolvedAssignment = callResolver.resolveVariableAccessAndSelectCandidate(variableAssignment, isUsedAsReceiver = false) val resolvedAssignment = callResolver.resolveVariableAccessAndSelectCandidate(variableAssignment, isUsedAsReceiver = false)
@@ -884,7 +888,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
override fun transformCallableReferenceAccess( override fun transformCallableReferenceAccess(
callableReferenceAccess: FirCallableReferenceAccess, callableReferenceAccess: FirCallableReferenceAccess,
data: ResolutionMode, data: ResolutionMode,
): FirStatement { ): FirStatement = whileAnalysing(callableReferenceAccess) {
if (callableReferenceAccess.calleeReference is FirResolvedNamedReference) { if (callableReferenceAccess.calleeReference is FirResolvedNamedReference) {
return callableReferenceAccess return callableReferenceAccess
} }
@@ -922,7 +926,10 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
} }
} }
override fun transformGetClassCall(getClassCall: FirGetClassCall, data: ResolutionMode): FirStatement { override fun transformGetClassCall(
getClassCall: FirGetClassCall,
data: ResolutionMode
): FirStatement = whileAnalysing(getClassCall) {
getClassCall.transformAnnotations(transformer, ResolutionMode.ContextIndependent) getClassCall.transformAnnotations(transformer, ResolutionMode.ContextIndependent)
val arg = getClassCall.argument val arg = getClassCall.argument
val dataForLhs = if (arg is FirConstExpression<*>) { val dataForLhs = if (arg is FirConstExpression<*>) {
@@ -1062,7 +1069,10 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
return annotation return annotation
} }
override fun transformAnnotationCall(annotationCall: FirAnnotationCall, data: ResolutionMode): FirStatement { override fun transformAnnotationCall(
annotationCall: FirAnnotationCall,
data: ResolutionMode
): FirStatement = whileAnalysing(annotationCall) {
if (annotationCall.resolved) return annotationCall if (annotationCall.resolved) return annotationCall
annotationCall.transformAnnotationTypeRef(transformer, ResolutionMode.ContextIndependent) annotationCall.transformAnnotationTypeRef(transformer, ResolutionMode.ContextIndependent)
return context.forAnnotation { return context.forAnnotation {
@@ -1094,7 +1104,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
override fun transformDelegatedConstructorCall( override fun transformDelegatedConstructorCall(
delegatedConstructorCall: FirDelegatedConstructorCall, delegatedConstructorCall: FirDelegatedConstructorCall,
data: ResolutionMode, data: ResolutionMode,
): FirStatement { ): FirStatement = whileAnalysing(delegatedConstructorCall) {
if (transformer.implicitTypeOnly) return delegatedConstructorCall if (transformer.implicitTypeOnly) return delegatedConstructorCall
when (delegatedConstructorCall.calleeReference) { when (delegatedConstructorCall.calleeReference) {
is FirResolvedNamedReference, is FirErrorNamedReference -> return delegatedConstructorCall is FirResolvedNamedReference, is FirErrorNamedReference -> return delegatedConstructorCall
@@ -1209,7 +1219,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
override fun transformAugmentedArraySetCall( override fun transformAugmentedArraySetCall(
augmentedArraySetCall: FirAugmentedArraySetCall, augmentedArraySetCall: FirAugmentedArraySetCall,
data: ResolutionMode data: ResolutionMode
): FirStatement { ): FirStatement = whileAnalysing(augmentedArraySetCall) {
/* /*
* a[b] += c can be desugared to: * a[b] += c can be desugared to:
* *
@@ -1446,7 +1456,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
) )
} }
override fun transformArrayOfCall(arrayOfCall: FirArrayOfCall, data: ResolutionMode): FirStatement { override fun transformArrayOfCall(arrayOfCall: FirArrayOfCall, data: ResolutionMode): FirStatement = whileAnalysing(arrayOfCall) {
if (data is ResolutionMode.ContextDependent) { if (data is ResolutionMode.ContextDependent) {
arrayOfCall.transformChildren(transformer, data) arrayOfCall.transformChildren(transformer, data)
return arrayOfCall return arrayOfCall
@@ -1457,7 +1467,10 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
return arrayOfCall return arrayOfCall
} }
override fun transformStringConcatenationCall(stringConcatenationCall: FirStringConcatenationCall, data: ResolutionMode): FirStatement { override fun transformStringConcatenationCall(
stringConcatenationCall: FirStringConcatenationCall,
data: ResolutionMode
): FirStatement = whileAnalysing(stringConcatenationCall) {
dataFlowAnalyzer.enterCall() dataFlowAnalyzer.enterCall()
stringConcatenationCall.transformChildren(transformer, ResolutionMode.ContextIndependent) stringConcatenationCall.transformChildren(transformer, ResolutionMode.ContextIndependent)
dataFlowAnalyzer.exitStringConcatenationCall(stringConcatenationCall) dataFlowAnalyzer.exitStringConcatenationCall(stringConcatenationCall)
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.FirUserTypeRef import org.jetbrains.kotlin.fir.types.FirUserTypeRef
import org.jetbrains.kotlin.fir.types.coneTypeSafe import org.jetbrains.kotlin.fir.types.coneTypeSafe
import org.jetbrains.kotlin.fir.visitors.transformSingle import org.jetbrains.kotlin.fir.visitors.transformSingle
import org.jetbrains.kotlin.fir.withFileAnalysisExceptionWrapping
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -47,13 +48,25 @@ class FirCompilerRequiredAnnotationsResolveProcessor(
val transformer = FirCompilerRequiredAnnotationsResolveTransformer(session, scopeSession) val transformer = FirCompilerRequiredAnnotationsResolveTransformer(session, scopeSession)
val registeredPluginAnnotations = session.registeredPluginAnnotations val registeredPluginAnnotations = session.registeredPluginAnnotations
if (!registeredPluginAnnotations.hasRegisteredAnnotations) { if (!registeredPluginAnnotations.hasRegisteredAnnotations) {
files.forEach { it.transformSingle(transformer, Mode.RegularAnnotations) } files.forEach {
withFileAnalysisExceptionWrapping(it) {
it.transformSingle(transformer, Mode.RegularAnnotations)
}
}
return return
} }
if (registeredPluginAnnotations.metaAnnotations.isNotEmpty()) { if (registeredPluginAnnotations.metaAnnotations.isNotEmpty()) {
files.forEach { it.transformSingle(transformer, Mode.MetaAnnotations) } files.forEach {
withFileAnalysisExceptionWrapping(it) {
it.transformSingle(transformer, Mode.MetaAnnotations)
}
}
}
files.forEach {
withFileAnalysisExceptionWrapping(it) {
it.transformSingle(transformer, Mode.RegularAnnotations)
}
} }
files.forEach { it.transformSingle(transformer, Mode.RegularAnnotations) }
} }
@OptIn(FirSymbolProviderInternals::class) @OptIn(FirSymbolProviderInternals::class)
@@ -6,16 +6,10 @@
package org.jetbrains.kotlin.fir package org.jetbrains.kotlin.fir
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.KtFakeSourceElementKind import org.jetbrains.kotlin.*
import org.jetbrains.kotlin.KtPsiSourceElement
import org.jetbrains.kotlin.KtRealPsiSourceElement
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fakeElement import org.jetbrains.kotlin.fir.declarations.*
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.impl.FirDeclarationStatusImpl import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
import org.jetbrains.kotlin.fir.expressions.FirBlock import org.jetbrains.kotlin.fir.expressions.FirBlock
@@ -142,3 +136,14 @@ fun FirDeclarationStatus.copy(
this.isFun = isFun this.isFun = isFun
} }
} }
inline fun <R> whileAnalysing(element: FirElement, block: () -> R) = org.jetbrains.kotlin.util.whileAnalysing(element.source, block)
inline fun <R> withFileAnalysisExceptionWrapping(file: FirFile, block: () -> R): R {
return org.jetbrains.kotlin.util.withFileAnalysisExceptionWrapping(
file.sourceFile?.path,
file.source,
{ file.sourceFileLinesMapping?.getLineAndColumnByOffset(it) },
block,
)
}
@@ -0,0 +1,90 @@
/*
* 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.util
import com.intellij.openapi.diagnostic.ControlFlowException
import com.intellij.openapi.project.IndexNotReadyException
import org.jetbrains.kotlin.AbstractKtSourceElement
import org.jetbrains.kotlin.KtRealSourceElementKind
import org.jetbrains.kotlin.KtSourceElement
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 (throwable: Throwable) {
throw throwable.wrapIntoSourceCodeAnalysisExceptionIfNeeded(element)
}
}
@PublishedApi
internal fun Throwable.wrapIntoSourceCodeAnalysisExceptionIfNeeded(element: KtSourceElement?) = when (this) {
is SourceCodeAnalysisException -> this
is IndexNotReadyException -> this
is ControlFlowException -> this
is VirtualMachineError -> this
else -> when (element?.kind) {
is KtRealSourceElementKind -> SourceCodeAnalysisException(element, this)
else -> this
}
}
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?,
crossinline linesMapping: (Int) -> Pair<Int, Int>?,
block: () -> R,
): R {
return try {
block()
} catch (throwable: Throwable) {
throw throwable.wrapIntoFileAnalysisExceptionIfNeeded(filePath, fileSource) { linesMapping(it) }
}
}
@PublishedApi
internal fun Throwable.wrapIntoFileAnalysisExceptionIfNeeded(
filePath: String?,
fileSource: AbstractKtSourceElement?,
linesMapping: (Int) -> Pair<Int, Int>?,
) = when {
filePath == null -> this
this is SourceCodeAnalysisException -> when (fileSource) {
source -> FileAnalysisException(filePath, cause)
else -> FileAnalysisException(filePath, cause, linesMapping(source.startOffset))
}
this is IndexNotReadyException -> this
this is ControlFlowException -> this
this is VirtualMachineError -> this
else -> FileAnalysisException(filePath, this)
}
inline fun <R> withSourceCodeAnalysisExceptionUnwrapping(block: () -> R): R {
return try {
block()
} catch (throwable: Throwable) {
throw if (throwable is SourceCodeAnalysisException) throwable.cause else throwable
}
}
@@ -65,7 +65,11 @@ private class PerformByIrFilePhase<Context : CommonBackendContext>(
phase.invoke(phaseConfig, filePhaserState, context, irFile) phase.invoke(phaseConfig, filePhaserState, context, irFile)
} }
} catch (e: Throwable) { } catch (e: Throwable) {
CodegenUtil.reportBackendException(e, "IR lowering", irFile.fileEntry.name) CodegenUtil.reportBackendException(e, "IR lowering", irFile.fileEntry.name) { offset ->
irFile.fileEntry.takeIf { it.supportsDebugInfo }?.let {
it.getLineNumber(offset) to it.getColumnNumber(offset)
}
}
} }
} }
@@ -110,7 +114,11 @@ private class PerformByIrFilePhase<Context : CommonBackendContext>(
executor.awaitTermination(1, TimeUnit.DAYS) // Wait long enough executor.awaitTermination(1, TimeUnit.DAYS) // Wait long enough
thrownFromThread.get()?.let { (e, irFile) -> thrownFromThread.get()?.let { (e, irFile) ->
CodegenUtil.reportBackendException(e, "Experimental parallel IR backend", irFile.fileEntry.name) CodegenUtil.reportBackendException(e, "Experimental parallel IR backend", irFile.fileEntry.name) { offset ->
irFile.fileEntry.takeIf { it.supportsDebugInfo }?.let {
it.getLineNumber(offset) to it.getColumnNumber(offset)
}
}
} }
// Presumably each thread has run through the same list of phases. // Presumably each thread has run through the same list of phases.
@@ -24,6 +24,8 @@ class MultifileFacadeFileEntry(
override val maxOffset: Int override val maxOffset: Int
get() = UNDEFINED_OFFSET get() = UNDEFINED_OFFSET
override val supportsDebugInfo get() = false
override fun getSourceRangeInfo(beginOffset: Int, endOffset: Int): SourceRangeInfo = override fun getSourceRangeInfo(beginOffset: Int, endOffset: Int): SourceRangeInfo =
error("Multifile facade doesn't support debug info: $className") error("Multifile facade doesn't support debug info: $className")
@@ -20,6 +20,7 @@ data class SourceRangeInfo(
interface IrFileEntry { interface IrFileEntry {
val name: String val name: String
val maxOffset: Int val maxOffset: Int
val supportsDebugInfo: Boolean get() = true
fun getSourceRangeInfo(beginOffset: Int, endOffset: Int): SourceRangeInfo fun getSourceRangeInfo(beginOffset: Int, endOffset: Int): SourceRangeInfo
fun getLineNumber(offset: Int): Int fun getLineNumber(offset: Int): Int
fun getColumnNumber(offset: Int): Int fun getColumnNumber(offset: Int): Int
@@ -93,9 +93,11 @@ class FirAnalyzerFacade(
val collector = FirDiagnosticsCollector.create(session, scopeSession) val collector = FirDiagnosticsCollector.create(session, scopeSession)
collectedDiagnostics = buildMap { collectedDiagnostics = buildMap {
for (file in firFiles!!) { for (file in firFiles!!) {
val reporter = DiagnosticReporterFactory.createPendingReporter() withFileAnalysisExceptionWrapping(file) {
collector.collectDiagnostics(file, reporter) val reporter = DiagnosticReporterFactory.createPendingReporter()
put(file, reporter.diagnostics) collector.collectDiagnostics(file, reporter)
put(file, reporter.diagnostics)
}
} }
} }
return collectedDiagnostics!! return collectedDiagnostics!!