[K2, MPP] implement IR errors reporting and test infrastructure
Fix test data ^KT-56344 Fixed
This commit is contained in:
committed by
Space Team
parent
3b1071b42b
commit
59b88f33b2
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.backend.common
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactoryToRendererMap
|
||||
import org.jetbrains.kotlin.diagnostics.error1
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.BaseDiagnosticRendererFactory
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.CommonRenderers.STRING
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.Renderers.MODULE_WITH_PLATFORM
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.RootDiagnosticRendererFactory
|
||||
|
||||
object CommonBackendErrors {
|
||||
val NO_ACTUAL_FOR_EXPECT by error1<PsiElement, ModuleDescriptor>()
|
||||
val MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED by error1<PsiElement, String>()
|
||||
|
||||
init {
|
||||
RootDiagnosticRendererFactory.registerFactory(KtDefaultCommonBackendErrorMessages)
|
||||
}
|
||||
}
|
||||
|
||||
object KtDefaultCommonBackendErrorMessages : BaseDiagnosticRendererFactory() {
|
||||
override val MAP = KtDiagnosticFactoryToRendererMap("KT").also { map ->
|
||||
map.put(CommonBackendErrors.NO_ACTUAL_FOR_EXPECT, "Expected {0} has no actual declaration in module {1}", MODULE_WITH_PLATFORM)
|
||||
map.put(CommonBackendErrors.MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED, "{0} must override {1} because it inherits multiple interface methods of it", STRING)
|
||||
}
|
||||
}
|
||||
+15
-8
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.common.actualizer
|
||||
|
||||
import org.jetbrains.kotlin.KtDiagnosticReporterWithImplicitIrBasedContext
|
||||
import org.jetbrains.kotlin.backend.common.ir.isExpect
|
||||
import org.jetbrains.kotlin.backend.common.ir.isProperExpect
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
@@ -18,7 +19,11 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
internal class ExpectActualCollector(private val mainFragment: IrModuleFragment, private val dependentFragments: List<IrModuleFragment>) {
|
||||
internal class ExpectActualCollector(
|
||||
private val mainFragment: IrModuleFragment,
|
||||
private val dependentFragments: List<IrModuleFragment>,
|
||||
private val diagnosticsReporter: KtDiagnosticReporterWithImplicitIrBasedContext
|
||||
) {
|
||||
fun collect(): Pair<Map<IrSymbol, IrSymbol>, Map<FqName, FqName>> {
|
||||
val result = mutableMapOf<IrSymbol, IrSymbol>()
|
||||
// Collect and link classifiers at first to make it possible to expand type aliases on the callables linking
|
||||
@@ -38,7 +43,7 @@ internal class ExpectActualCollector(private val mainFragment: IrModuleFragment,
|
||||
ActualClassifiersCollector(actualClassifiers, allActualDeclarations, typeAliasMap).visitModuleFragment(fragment, false)
|
||||
}
|
||||
|
||||
val linkCollector = ClassifiersLinkCollector(this, actualClassifiers)
|
||||
val linkCollector = ClassifiersLinkCollector(this, actualClassifiers, diagnosticsReporter)
|
||||
dependentFragments.forEach { linkCollector.visitModuleFragment(it) }
|
||||
|
||||
return allActualDeclarations to typeAliasMap
|
||||
@@ -51,7 +56,7 @@ internal class ExpectActualCollector(private val mainFragment: IrModuleFragment,
|
||||
val actualMembers = mutableMapOf<String, IrDeclarationBase>()
|
||||
|
||||
collectActualCallables(this, actualMembers, allActualDeclarations)
|
||||
val collector = CallablesLinkCollector(this, actualMembers, typeAliasMap)
|
||||
val collector = CallablesLinkCollector(this, actualMembers, typeAliasMap, diagnosticsReporter)
|
||||
dependentFragments.forEach { collector.visitModuleFragment(it) }
|
||||
}
|
||||
}
|
||||
@@ -106,14 +111,15 @@ private class ActualClassifiersCollector(
|
||||
|
||||
private class ClassifiersLinkCollector(
|
||||
private val expectActualMap: MutableMap<IrSymbol, IrSymbol>,
|
||||
private val actualClassifiers: Map<FqName, IrSymbol>
|
||||
private val actualClassifiers: Map<FqName, IrSymbol>,
|
||||
private val diagnosticsReporter: KtDiagnosticReporterWithImplicitIrBasedContext
|
||||
) : IrElementVisitorVoid {
|
||||
private fun addLinkOrReportMissing(expectElement: IrSymbolOwner, actualTypeId: FqName) {
|
||||
private fun addLinkOrReportMissing(expectElement: IrDeclaration, actualTypeId: FqName) {
|
||||
val actualClassifier = actualClassifiers[actualTypeId]
|
||||
if (actualClassifier != null) {
|
||||
expectActualMap[expectElement.symbol] = actualClassifier
|
||||
} else if (!expectElement.containsOptionalExpectation()) {
|
||||
reportMissingActual(expectElement)
|
||||
diagnosticsReporter.reportMissingActual(expectElement)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,7 +171,8 @@ private fun collectActualCallables(
|
||||
private class CallablesLinkCollector(
|
||||
private val expectActualMap: MutableMap<IrSymbol, IrSymbol>,
|
||||
private val actualMembers: Map<String, IrDeclarationBase>,
|
||||
private val typeAliasMap: Map<FqName, FqName>
|
||||
private val typeAliasMap: Map<FqName, FqName>,
|
||||
private val diagnosticsReporter: KtDiagnosticReporterWithImplicitIrBasedContext
|
||||
) : IrElementVisitorVoid {
|
||||
override fun visitFunction(declaration: IrFunction) = addLink(declaration)
|
||||
|
||||
@@ -182,7 +189,7 @@ private class CallablesLinkCollector(
|
||||
declaration.setter?.symbol?.let { expectActualMap[it] = actualProperty.setter!!.symbol }
|
||||
}
|
||||
} else if (!declaration.parent.containsOptionalExpectation()) {
|
||||
reportMissingActual(declaration)
|
||||
diagnosticsReporter.reportMissingActual(declaration)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+15
-6
@@ -5,17 +5,25 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.common.actualizer
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.ir.isProperExpect
|
||||
import org.jetbrains.kotlin.KtDiagnosticReporterWithImplicitIrBasedContext
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
object IrActualizer {
|
||||
fun actualize(mainFragment: IrModuleFragment, dependentFragments: List<IrModuleFragment>) {
|
||||
val (expectActualMap, typeAliasMap) = ExpectActualCollector(mainFragment, dependentFragments).collect()
|
||||
fun actualize(
|
||||
mainFragment: IrModuleFragment,
|
||||
dependentFragments: List<IrModuleFragment>,
|
||||
diagnosticReporter: DiagnosticReporter,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
) {
|
||||
val ktDiagnosticReporter = KtDiagnosticReporterWithImplicitIrBasedContext(diagnosticReporter, languageVersionSettings)
|
||||
val (expectActualMap, typeAliasMap) = ExpectActualCollector(mainFragment, dependentFragments, ktDiagnosticReporter).collect()
|
||||
FunctionDefaultParametersActualizer(expectActualMap).actualize()
|
||||
removeExpectDeclarations(dependentFragments, expectActualMap)
|
||||
addMissingFakeOverrides(expectActualMap, dependentFragments, typeAliasMap)
|
||||
addMissingFakeOverrides(expectActualMap, dependentFragments, typeAliasMap, ktDiagnosticReporter)
|
||||
linkExpectToActual(expectActualMap, dependentFragments)
|
||||
mergeIrFragments(mainFragment, dependentFragments)
|
||||
}
|
||||
@@ -40,9 +48,10 @@ object IrActualizer {
|
||||
private fun addMissingFakeOverrides(
|
||||
expectActualMap: Map<IrSymbol, IrSymbol>,
|
||||
dependentFragments: List<IrModuleFragment>,
|
||||
typeAliasMap: Map<FqName, FqName>
|
||||
typeAliasMap: Map<FqName, FqName>,
|
||||
diagnosticsReporter: KtDiagnosticReporterWithImplicitIrBasedContext
|
||||
) {
|
||||
MissingFakeOverridesAdder(expectActualMap, typeAliasMap).apply { dependentFragments.forEach { visitModuleFragment(it) } }
|
||||
MissingFakeOverridesAdder(expectActualMap, typeAliasMap, diagnosticsReporter).apply { dependentFragments.forEach { visitModuleFragment(it) } }
|
||||
}
|
||||
|
||||
private fun linkExpectToActual(expectActualMap: Map<IrSymbol, IrSymbol>, dependentFragments: List<IrModuleFragment>) {
|
||||
|
||||
+10
-11
@@ -5,18 +5,18 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.common.actualizer
|
||||
|
||||
import org.jetbrains.kotlin.KtDiagnosticReporterWithImplicitIrBasedContext
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendErrors
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationBase
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithName
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||
import org.jetbrains.kotlin.ir.util.hasAnnotation
|
||||
import org.jetbrains.kotlin.ir.util.kotlinFqName
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.ir.util.module
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.OptionalAnnotationUtil
|
||||
|
||||
@@ -71,14 +71,13 @@ private fun appendElementFullName(
|
||||
}
|
||||
}
|
||||
|
||||
fun reportMissingActual(irElement: IrElement) {
|
||||
// TODO: setup diagnostics reporting
|
||||
throw AssertionError("Missing actual for ${irElement.render()}")
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
fun KtDiagnosticReporterWithImplicitIrBasedContext.reportMissingActual(irDeclaration: IrDeclaration) {
|
||||
at(irDeclaration).report(CommonBackendErrors.NO_ACTUAL_FOR_EXPECT, irDeclaration.module)
|
||||
}
|
||||
|
||||
fun reportManyInterfacesMembersNotImplemented(declaration: IrClass, actualMember: IrDeclarationWithName) {
|
||||
// TODO: setup diagnostics reporting
|
||||
throw AssertionError("${declaration.name} must override ${actualMember.name} because it inherits multiple interface methods of it")
|
||||
fun KtDiagnosticReporterWithImplicitIrBasedContext.reportManyInterfacesMembersNotImplemented(declaration: IrClass, actualMember: IrDeclarationWithName) {
|
||||
at(declaration).report(CommonBackendErrors.MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED, actualMember.name.asString())
|
||||
}
|
||||
|
||||
internal fun IrElement.containsOptionalExpectation(): Boolean {
|
||||
|
||||
+4
-2
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.common.actualizer
|
||||
|
||||
import org.jetbrains.kotlin.KtDiagnosticReporterWithImplicitIrBasedContext
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildProperty
|
||||
@@ -22,7 +23,8 @@ import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
class MissingFakeOverridesAdder(
|
||||
private val expectActualMap: Map<IrSymbol, IrSymbol>,
|
||||
private val typeAliasMap: Map<FqName, FqName>
|
||||
private val typeAliasMap: Map<FqName, FqName>,
|
||||
private val diagnosticsReporter: KtDiagnosticReporterWithImplicitIrBasedContext
|
||||
) : IrElementVisitorVoid {
|
||||
override fun visitClass(declaration: IrClass) {
|
||||
if (!declaration.isExpect) {
|
||||
@@ -75,7 +77,7 @@ class MissingFakeOverridesAdder(
|
||||
is IrFunctionImpl,
|
||||
is IrPropertyImpl -> {
|
||||
if (members[generateIrElementFullName(actualMember, expectActualMap, typeAliasMap)] != null) {
|
||||
reportManyInterfacesMembersNotImplemented(declaration, actualMember as IrDeclarationWithName)
|
||||
diagnosticsReporter.reportManyInterfacesMembersNotImplemented(declaration, actualMember as IrDeclarationWithName)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user