[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
+1
-1
@@ -80,7 +80,7 @@ class JvmBackendDiagnosticsHandler(testServices: TestServices) : JvmBinaryArtifa
|
||||
val ktDiagnostics = ktDiagnosticReporter.diagnosticsByFilePath[ktFile.virtualFilePath] ?: continue
|
||||
ktDiagnostics.forEach {
|
||||
val metaInfos =
|
||||
it.toMetaInfos(testFile, globalMetadataInfoHandler, false, false)
|
||||
it.toMetaInfos(module, testFile, globalMetadataInfoHandler, false, false)
|
||||
globalMetadataInfoHandler.addMetadataInfosForFile(testFile, metaInfos)
|
||||
}
|
||||
}
|
||||
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.test.backend.ir
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.actualizer.IrActualizer
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.test.model.*
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
|
||||
|
||||
class ActualizerOnlyFacade(
|
||||
val testServices: TestServices,
|
||||
) : AbstractTestFacade<IrBackendInput, IrBackendInput>() {
|
||||
override fun transform(module: TestModule, inputArtifact: IrBackendInput): IrBackendInput {
|
||||
if (module.useIrActualizer()) {
|
||||
when (inputArtifact) {
|
||||
is IrBackendInput.JvmIrBackendInput ->
|
||||
IrActualizer.actualize(
|
||||
inputArtifact.backendInput.irModuleFragment,
|
||||
inputArtifact.dependentInputs.map { it.irModuleFragment },
|
||||
inputArtifact.state.diagnosticReporter,
|
||||
inputArtifact.state.languageVersionSettings
|
||||
)
|
||||
is IrBackendInput.JsIrBackendInput ->
|
||||
IrActualizer.actualize(
|
||||
inputArtifact.mainModuleFragment,
|
||||
inputArtifact.dependentModuleFragments,
|
||||
inputArtifact.diagnosticsCollector,
|
||||
testServices.compilerConfigurationProvider.getCompilerConfiguration(module).languageVersionSettings
|
||||
)
|
||||
}
|
||||
}
|
||||
return inputArtifact
|
||||
}
|
||||
|
||||
private fun TestModule.useIrActualizer(): Boolean {
|
||||
return frontendKind == FrontendKinds.FIR && languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)
|
||||
}
|
||||
|
||||
override val inputKind: TestArtifactKind<IrBackendInput> = BackendKinds.IrBackend
|
||||
override val outputKind: TestArtifactKind<IrBackendInput> = BackendKinds.IrBackend
|
||||
|
||||
override fun shouldRunAnalysis(module: TestModule): Boolean = true
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector
|
||||
import org.jetbrains.kotlin.ir.backend.js.KotlinFileSerializedData
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
@@ -36,6 +37,7 @@ sealed class IrBackendInput : ResultingArtifact.BackendInput<IrBackendInput>() {
|
||||
val sourceFiles: List<KtSourceFile>,
|
||||
val icData: List<KotlinFileSerializedData>,
|
||||
val expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>, // TODO: abstract from descriptors
|
||||
val diagnosticsCollector: BaseDiagnosticsCollector,
|
||||
val hasErrors: Boolean,
|
||||
val serializeSingleFile: (KtSourceFile) -> ProtoBuf.PackageFragment
|
||||
) : IrBackendInput() {
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.test.backend.ir
|
||||
|
||||
import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector
|
||||
import org.jetbrains.kotlin.test.FirParser
|
||||
import org.jetbrains.kotlin.test.backend.handlers.AbstractIrHandler
|
||||
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives
|
||||
import org.jetbrains.kotlin.test.directives.model.singleOrZeroValue
|
||||
import org.jetbrains.kotlin.test.frontend.fir.handlers.diagnosticCodeMetaInfos
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.*
|
||||
|
||||
class IrDiagnosticsHandler(testServices: TestServices) : AbstractIrHandler(testServices) {
|
||||
private val globalMetadataInfoHandler: GlobalMetadataInfoHandler
|
||||
get() = testServices.globalMetadataInfoHandler
|
||||
|
||||
private val diagnosticsService: DiagnosticsService
|
||||
get() = testServices.diagnosticsService
|
||||
|
||||
override fun processModule(module: TestModule, info: IrBackendInput) {
|
||||
val diagnosticsByFilePath = when (info) {
|
||||
is IrBackendInput.JvmIrBackendInput -> (info.state.diagnosticReporter as BaseDiagnosticsCollector).diagnosticsByFilePath
|
||||
is IrBackendInput.JsIrBackendInput -> info.diagnosticsCollector.diagnosticsByFilePath
|
||||
}
|
||||
for (currentModule in testServices.moduleStructure.modules) {
|
||||
val lightTreeComparingModeEnabled = FirDiagnosticsDirectives.COMPARE_WITH_LIGHT_TREE in currentModule.directives
|
||||
val lightTreeEnabled = currentModule.directives.singleOrZeroValue(FirDiagnosticsDirectives.FIR_PARSER) == FirParser.LightTree
|
||||
for (file in currentModule.files) {
|
||||
val diagnostics = diagnosticsByFilePath["/" + file.relativePath]
|
||||
if (diagnostics != null && diagnostics.isNotEmpty()) {
|
||||
val diagnosticsMetadataInfos =
|
||||
diagnostics.diagnosticCodeMetaInfos(
|
||||
module, file, diagnosticsService, globalMetadataInfoHandler,
|
||||
lightTreeEnabled, lightTreeComparingModeEnabled
|
||||
)
|
||||
globalMetadataInfoHandler.addMetadataInfosForFile(file, diagnosticsMetadataInfos)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun processAfterAllModules(someAssertionWasFailed: Boolean) {}
|
||||
}
|
||||
+6
-1
@@ -36,7 +36,12 @@ class JvmIrBackendFacade(
|
||||
}
|
||||
|
||||
if (module.useIrActualizer()) {
|
||||
IrActualizer.actualize(inputArtifact.backendInput.irModuleFragment, inputArtifact.dependentInputs.map { it.irModuleFragment })
|
||||
IrActualizer.actualize(
|
||||
inputArtifact.backendInput.irModuleFragment,
|
||||
inputArtifact.dependentInputs.map { it.irModuleFragment },
|
||||
inputArtifact.state.diagnosticReporter,
|
||||
inputArtifact.state.languageVersionSettings
|
||||
)
|
||||
}
|
||||
|
||||
val state = inputArtifact.state
|
||||
|
||||
+1
@@ -110,6 +110,7 @@ class ClassicFrontend2IrConverter(
|
||||
sourceFiles.map(::KtPsiSourceFile),
|
||||
icData,
|
||||
expectDescriptorToSymbol = expectDescriptorToSymbol,
|
||||
diagnosticsCollector = DiagnosticReporterFactory.createReporter(),
|
||||
hasErrors
|
||||
) { file ->
|
||||
metadataSerializer.serializeScope(file, analysisResult.bindingContext, moduleFragment.descriptor)
|
||||
|
||||
+2
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
|
||||
import org.jetbrains.kotlin.diagnostics.KtDiagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.Severity
|
||||
import org.jetbrains.kotlin.fir.AbstractFirAnalyzerFacade
|
||||
@@ -114,6 +115,7 @@ class Fir2IrJsResultsConverter(
|
||||
sourceFiles,
|
||||
configuration.incrementalDataProvider?.getSerializedData(sourceFiles) ?: emptyList(),
|
||||
expectDescriptorToSymbol = mutableMapOf(),
|
||||
diagnosticsCollector = DiagnosticReporterFactory.createReporter(),
|
||||
hasErrors = hasErrors
|
||||
) { file ->
|
||||
val (firFile, components) = firFilesAndComponentsBySourceFile[file]
|
||||
|
||||
+55
-24
@@ -15,14 +15,11 @@ import org.jetbrains.kotlin.diagnostics.rendering.Renderers
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.builder.FirSyntaxErrors
|
||||
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.references.*
|
||||
import org.jetbrains.kotlin.fir.renderForDebugInfo
|
||||
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
@@ -31,6 +28,10 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitorVoid
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
import org.jetbrains.kotlin.platform.isCommon
|
||||
import org.jetbrains.kotlin.platform.isJs
|
||||
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||
import org.jetbrains.kotlin.platform.konan.isNative
|
||||
import org.jetbrains.kotlin.psi.KtBinaryExpression
|
||||
import org.jetbrains.kotlin.psi.KtQualifiedExpression
|
||||
import org.jetbrains.kotlin.resolve.AnalyzingUtils
|
||||
@@ -79,25 +80,14 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
|
||||
if (LanguageSettingsDirectives.API_VERSION in currentModule.directives) {
|
||||
diagnostics = diagnostics.filter { it.factory.name != FirErrors.NEWER_VERSION_IN_SINCE_KOTLIN.name }
|
||||
}
|
||||
val diagnosticsMetadataInfos = diagnostics.flatMap { diagnostic ->
|
||||
if (!diagnosticsService.shouldRenderDiagnostic(
|
||||
currentModule,
|
||||
diagnostic.factory.name,
|
||||
diagnostic.severity
|
||||
)
|
||||
) return@flatMap emptyList()
|
||||
// SYNTAX errors will be reported later
|
||||
if (diagnostic.factory == FirSyntaxErrors.SYNTAX) return@flatMap emptyList()
|
||||
if (!diagnostic.isValid) return@flatMap emptyList()
|
||||
diagnostic.toMetaInfos(
|
||||
file,
|
||||
globalMetadataInfoHandler,
|
||||
lightTreeEnabled,
|
||||
lightTreeComparingModeEnabled
|
||||
val diagnosticsMetadataInfos =
|
||||
diagnostics.diagnosticCodeMetaInfos(
|
||||
currentModule, file,
|
||||
diagnosticsService, globalMetadataInfoHandler,
|
||||
lightTreeEnabled, lightTreeComparingModeEnabled
|
||||
)
|
||||
}
|
||||
globalMetadataInfoHandler.addMetadataInfosForFile(file, diagnosticsMetadataInfos)
|
||||
collectSyntaxDiagnostics(file, firFile, lightTreeEnabled, lightTreeComparingModeEnabled)
|
||||
collectSyntaxDiagnostics(currentModule, file, firFile, lightTreeEnabled, lightTreeComparingModeEnabled)
|
||||
collectDebugInfoDiagnostics(currentModule, file, firFile, lightTreeEnabled, lightTreeComparingModeEnabled)
|
||||
}
|
||||
}
|
||||
@@ -105,6 +95,7 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
|
||||
|
||||
@OptIn(InternalDiagnosticFactoryMethod::class)
|
||||
private fun collectSyntaxDiagnostics(
|
||||
module: TestModule,
|
||||
testFile: TestFile,
|
||||
firFile: FirFile,
|
||||
lightTreeEnabled: Boolean,
|
||||
@@ -114,6 +105,7 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
|
||||
AnalyzingUtils.getSyntaxErrorRanges(firFile.psi!!).flatMap {
|
||||
FirSyntaxErrors.SYNTAX.on(KtRealPsiSourceElement(it), positioningStrategy = null)
|
||||
.toMetaInfos(
|
||||
module,
|
||||
testFile,
|
||||
globalMetadataInfoHandler1 = globalMetadataInfoHandler,
|
||||
lightTreeEnabled,
|
||||
@@ -124,6 +116,7 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
|
||||
collectLightTreeSyntaxErrors(firFile).flatMap { sourceElement ->
|
||||
FirSyntaxErrors.SYNTAX.on(sourceElement, positioningStrategy = null)
|
||||
.toMetaInfos(
|
||||
module,
|
||||
testFile,
|
||||
globalMetadataInfoHandler1 = globalMetadataInfoHandler,
|
||||
lightTreeEnabled,
|
||||
@@ -237,6 +230,7 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
|
||||
|
||||
val codeMetaInfos = result.flatMap { diagnostic ->
|
||||
diagnostic.toMetaInfos(
|
||||
module,
|
||||
testFile,
|
||||
globalMetadataInfoHandler,
|
||||
lightTreeEnabled,
|
||||
@@ -323,6 +317,32 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
|
||||
override fun processAfterAllModules(someAssertionWasFailed: Boolean) {}
|
||||
}
|
||||
|
||||
fun List<KtDiagnostic>.diagnosticCodeMetaInfos(
|
||||
module: TestModule,
|
||||
file: TestFile,
|
||||
diagnosticsService: DiagnosticsService,
|
||||
globalMetadataInfoHandler: GlobalMetadataInfoHandler,
|
||||
lightTreeEnabled: Boolean,
|
||||
lightTreeComparingModeEnabled: Boolean
|
||||
): List<FirDiagnosticCodeMetaInfo> = flatMap { diagnostic ->
|
||||
if (!diagnosticsService.shouldRenderDiagnostic(
|
||||
module,
|
||||
diagnostic.factory.name,
|
||||
diagnostic.severity
|
||||
)
|
||||
) return@flatMap emptyList()
|
||||
// SYNTAX errors will be reported later
|
||||
if (diagnostic.factory == FirSyntaxErrors.SYNTAX) return@flatMap emptyList()
|
||||
if (!diagnostic.isValid) return@flatMap emptyList()
|
||||
diagnostic.toMetaInfos(
|
||||
module,
|
||||
file,
|
||||
globalMetadataInfoHandler,
|
||||
lightTreeEnabled,
|
||||
lightTreeComparingModeEnabled
|
||||
)
|
||||
}
|
||||
|
||||
private fun FirTypeRef.isFunctionTypeWithDynamicReceiver(session: FirSession) =
|
||||
coneTypeSafe<ConeKotlinType>()?.isFunctionTypeWithDynamicReceiver(session) == true
|
||||
|
||||
@@ -498,6 +518,7 @@ class PsiLightTreeMetaInfoProcessor(testServices: TestServices) : AbstractTwoAtt
|
||||
}
|
||||
|
||||
fun KtDiagnostic.toMetaInfos(
|
||||
module: TestModule,
|
||||
file: TestFile,
|
||||
globalMetadataInfoHandler1: GlobalMetadataInfoHandler,
|
||||
lightTreeEnabled: Boolean,
|
||||
@@ -513,6 +534,16 @@ fun KtDiagnostic.toMetaInfos(
|
||||
if (lightTreeComparingModeEnabled) {
|
||||
metaInfo.attributes += if (lightTreeEnabled) PsiLightTreeMetaInfoProcessor.LT else PsiLightTreeMetaInfoProcessor.PSI
|
||||
}
|
||||
if (file !in module.files) {
|
||||
val targetPlatform = module.targetPlatform
|
||||
metaInfo.attributes += when {
|
||||
targetPlatform.isJvm() -> "JVM"
|
||||
targetPlatform.isJs() -> "JS"
|
||||
targetPlatform.isNative() -> "NATIVE"
|
||||
targetPlatform.isCommon() -> "COMMON"
|
||||
else -> error("Should not be here")
|
||||
}
|
||||
}
|
||||
metaInfo
|
||||
}
|
||||
|
||||
|
||||
+23
-5
@@ -9,17 +9,16 @@ import org.jetbrains.kotlin.config.ExplicitApiMode
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.symbols.FirLazyDeclarationResolver
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||
import org.jetbrains.kotlin.test.Constructor
|
||||
import org.jetbrains.kotlin.test.TestJdkKind
|
||||
import org.jetbrains.kotlin.test.bind
|
||||
import org.jetbrains.kotlin.test.*
|
||||
import org.jetbrains.kotlin.test.backend.ir.ActualizerOnlyFacade
|
||||
import org.jetbrains.kotlin.test.backend.ir.IrDiagnosticsHandler
|
||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||
import org.jetbrains.kotlin.test.builders.configureFirHandlersStep
|
||||
import org.jetbrains.kotlin.test.builders.firHandlersStep
|
||||
import org.jetbrains.kotlin.test.coerce
|
||||
import org.jetbrains.kotlin.test.builders.irHandlersStep
|
||||
import org.jetbrains.kotlin.test.directives.ConfigurationDirectives.WITH_STDLIB
|
||||
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives.FIR_DUMP
|
||||
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives.WITH_EXTENDED_CHECKERS
|
||||
import org.jetbrains.kotlin.test.FirParser
|
||||
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.JDK_KIND
|
||||
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.WITH_REFLECT
|
||||
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives
|
||||
@@ -49,6 +48,25 @@ abstract class AbstractFirDiagnosticTestBase(val parser: FirParser) : AbstractKo
|
||||
abstract class AbstractFirPsiDiagnosticTest : AbstractFirDiagnosticTestBase(FirParser.Psi)
|
||||
abstract class AbstractFirLightTreeDiagnosticsTest : AbstractFirDiagnosticTestBase(FirParser.LightTree)
|
||||
|
||||
abstract class AbstractFirWithActualizerDiagnosticsTest(val parser: FirParser) : AbstractKotlinCompilerWithTargetBackendTest(TargetBackend.JVM_IR) {
|
||||
override fun TestConfigurationBuilder.configuration() {
|
||||
configureFirParser(parser)
|
||||
baseFirDiagnosticTestConfiguration()
|
||||
|
||||
facadeStep(::Fir2IrResultsConverter)
|
||||
facadeStep(::ActualizerOnlyFacade)
|
||||
irHandlersStep {
|
||||
useHandlers(
|
||||
::IrDiagnosticsHandler
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open class AbstractFirPsiWithActualizerDiagnosticsTest : AbstractFirWithActualizerDiagnosticsTest(FirParser.Psi)
|
||||
|
||||
open class AbstractFirLightTreeWithActualizerDiagnosticsTest : AbstractFirWithActualizerDiagnosticsTest(FirParser.LightTree)
|
||||
|
||||
fun TestConfigurationBuilder.configurationForClassicAndFirTestsAlongside() {
|
||||
useAfterAnalysisCheckers(
|
||||
::FirIdenticalChecker,
|
||||
|
||||
Reference in New Issue
Block a user