diff --git a/compiler/testData/diagnostics/firTestWithJvmBackend/exceptionFromInterpreter_ir.diag.txt b/compiler/testData/diagnostics/firTestWithJvmBackend/exceptionFromInterpreter_ir.diag.txt new file mode 100644 index 00000000000..16e4a928ecb --- /dev/null +++ b/compiler/testData/diagnostics/firTestWithJvmBackend/exceptionFromInterpreter_ir.diag.txt @@ -0,0 +1,11 @@ +/exceptionFromInterpreter_ir.kt:7:26: error: An exception occur while evaluating const value initializer: +Exception java.lang.ArithmeticException: / by zero + at ExceptionFromInterpreter_irKt.(exceptionFromInterpreter_ir.kt:7) + +/exceptionFromInterpreter_ir.kt:8:39: error: An exception occur while evaluating const value initializer: +Exception java.lang.IllegalArgumentException: marginPrefix must be non-blank string. + at ExceptionFromInterpreter_irKt.(exceptionFromInterpreter_ir.kt:8) + +/exceptionFromInterpreter_ir.kt:12:4: error: An exception occur while evaluating const value initializer: +Exception java.lang.ArithmeticException: / by zero + at ExceptionFromInterpreter_irKt.(exceptionFromInterpreter_ir.kt:12) \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithJvmBackend/scripts/enumCapturesProperty.diag.txt b/compiler/testData/diagnostics/testsWithJvmBackend/scripts/enumCapturesProperty.diag.txt new file mode 100644 index 00000000000..62735a9a13a --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJvmBackend/scripts/enumCapturesProperty.diag.txt @@ -0,0 +1 @@ +/enumCapturesProperty.kts:7:1: error: Enum class Bar captures the script class instance. Try to use class or anonymous object instead diff --git a/compiler/testData/diagnostics/testsWithJvmBackend/scripts/enumEntryCapturesProperty.diag.txt b/compiler/testData/diagnostics/testsWithJvmBackend/scripts/enumEntryCapturesProperty.diag.txt new file mode 100644 index 00000000000..084a60c4588 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJvmBackend/scripts/enumEntryCapturesProperty.diag.txt @@ -0,0 +1 @@ +/enumEntryCapturesProperty.kts:7:1: error: Enum class Bar captures the script class instance. Try to use class or anonymous object instead diff --git a/compiler/testData/diagnostics/testsWithJvmBackend/scripts/interfaceCapturesProperty.diag.txt b/compiler/testData/diagnostics/testsWithJvmBackend/scripts/interfaceCapturesProperty.diag.txt new file mode 100644 index 00000000000..e5bd3ca0c2c --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJvmBackend/scripts/interfaceCapturesProperty.diag.txt @@ -0,0 +1 @@ +/interfaceCapturesProperty.kts:8:1: error: Interface A captures the script class instance. Try to use class instead diff --git a/compiler/testData/diagnostics/testsWithJvmBackend/scripts/nestedAndOuterClassesCaptureProperty.diag.txt b/compiler/testData/diagnostics/testsWithJvmBackend/scripts/nestedAndOuterClassesCaptureProperty.diag.txt new file mode 100644 index 00000000000..26f82e3052b --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJvmBackend/scripts/nestedAndOuterClassesCaptureProperty.diag.txt @@ -0,0 +1 @@ +/nestedAndOuterClassesCaptureProperty.kts:9:5: error: Nested class User captures the script class instance. Try to use explicit inner modifier for both nested User and outer Outer diff --git a/compiler/testData/diagnostics/testsWithJvmBackend/scripts/nestedClassCapturesProperty.diag.txt b/compiler/testData/diagnostics/testsWithJvmBackend/scripts/nestedClassCapturesProperty.diag.txt new file mode 100644 index 00000000000..5eefdf6b03b --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJvmBackend/scripts/nestedClassCapturesProperty.diag.txt @@ -0,0 +1 @@ +/nestedClassCapturesProperty.kts:8:5: error: Nested class User captures the script class instance. Try to use explicit inner modifier for both nested User and outer Outer diff --git a/compiler/testData/diagnostics/testsWithJvmBackend/scripts/nestedToObjectClassCapturesProperty.diag.txt b/compiler/testData/diagnostics/testsWithJvmBackend/scripts/nestedToObjectClassCapturesProperty.diag.txt new file mode 100644 index 00000000000..415fa44ef51 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJvmBackend/scripts/nestedToObjectClassCapturesProperty.diag.txt @@ -0,0 +1 @@ +/nestedToObjectClassCapturesProperty.kts:8:5: error: Nested class User captures the script class instance. Try to use explicit inner modifier for both nested User and outer Outer diff --git a/compiler/testData/diagnostics/testsWithJvmBackend/scripts/objectCapturesProperty.diag.txt b/compiler/testData/diagnostics/testsWithJvmBackend/scripts/objectCapturesProperty.diag.txt new file mode 100644 index 00000000000..da82bc68610 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJvmBackend/scripts/objectCapturesProperty.diag.txt @@ -0,0 +1 @@ +/objectCapturesProperty.kts:8:1: error: Object B captures the script class instance. Try to use class or anonymous object instead diff --git a/compiler/testData/diagnostics/testsWithJvmBackend/scripts/objectCapturesPropertyIndirect.diag.txt b/compiler/testData/diagnostics/testsWithJvmBackend/scripts/objectCapturesPropertyIndirect.diag.txt new file mode 100644 index 00000000000..3fda0034626 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJvmBackend/scripts/objectCapturesPropertyIndirect.diag.txt @@ -0,0 +1 @@ +/objectCapturesPropertyIndirect.kts:12:1: error: Object B captures the script class instance. Try to use class or anonymous object instead diff --git a/compiler/testData/diagnostics/testsWithJvmBackend/scripts/objectCapturesPropertyViaExtension1.diag.txt b/compiler/testData/diagnostics/testsWithJvmBackend/scripts/objectCapturesPropertyViaExtension1.diag.txt new file mode 100644 index 00000000000..c1b74c09fd6 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJvmBackend/scripts/objectCapturesPropertyViaExtension1.diag.txt @@ -0,0 +1 @@ +/objectCapturesPropertyViaExtension1.kts:11:1: error: Object ZipHelper captures the script class instance. Try to use class or anonymous object instead diff --git a/compiler/testData/diagnostics/testsWithJvmBackend/scripts/objectCapturesPropertyViaExtension2.diag.txt b/compiler/testData/diagnostics/testsWithJvmBackend/scripts/objectCapturesPropertyViaExtension2.diag.txt new file mode 100644 index 00000000000..29baa7d88c0 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJvmBackend/scripts/objectCapturesPropertyViaExtension2.diag.txt @@ -0,0 +1 @@ +/objectCapturesPropertyViaExtension2.kts:17:1: error: Object ZipHelper captures the script class instance. Try to use class or anonymous object instead diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/JvmBackendDiagnosticsHandler.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/JvmBackendDiagnosticsHandler.kt index a87571c38b2..789fc3651b7 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/JvmBackendDiagnosticsHandler.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/JvmBackendDiagnosticsHandler.kt @@ -5,9 +5,16 @@ package org.jetbrains.kotlin.test.backend.handlers +import com.intellij.openapi.util.io.FileUtil +import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport +import org.jetbrains.kotlin.diagnostics.DiagnosticUtils +import org.jetbrains.kotlin.diagnostics.KtDiagnostic +import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.resolve.jvm.diagnostics.KtDefaultJvmErrorMessages +import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives import org.jetbrains.kotlin.test.frontend.classic.handlers.ClassicDiagnosticReporter import org.jetbrains.kotlin.test.frontend.classic.handlers.withNewInferenceModeEnabled import org.jetbrains.kotlin.test.frontend.fir.handlers.toMetaInfos @@ -19,32 +26,16 @@ import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.assertions import org.jetbrains.kotlin.test.services.dependencyProvider import org.jetbrains.kotlin.test.services.globalMetadataInfoHandler +import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly +import java.io.File class JvmBackendDiagnosticsHandler(testServices: TestServices) : JvmBinaryArtifactHandler(testServices) { private val reporter = ClassicDiagnosticReporter(testServices) override fun processModule(module: TestModule, info: BinaryArtifacts.Jvm) { - val testFileToKtFileMap = getKtFiles(module) - val ktFileToTestFileMap = testFileToKtFileMap.entries.associate { it.value to it.key } - val generationState = info.classFileFactory.generationState - val diagnostics = generationState.collectedExtraJvmDiagnostics.all() - val configuration = reporter.createConfiguration(module) - val withNewInferenceModeEnabled = testServices.withNewInferenceModeEnabled() - for (diagnostic in diagnostics) { - val ktFile = diagnostic.psiFile as? KtFile ?: continue - val testFile = ktFileToTestFileMap[ktFile] ?: continue - reporter.reportDiagnostic(diagnostic, module, testFile, configuration, withNewInferenceModeEnabled) - } - val ktDiagnosticReporter = generationState.diagnosticReporter as BaseDiagnosticsCollector - val globalMetadataInfoHandler = testServices.globalMetadataInfoHandler - for ((testFile, ktFile) in testFileToKtFileMap.entries) { - val ktDiagnostics = ktDiagnosticReporter.diagnosticsByFilePath[ktFile.virtualFilePath] ?: continue - ktDiagnostics.forEach { - val metaInfos = - it.toMetaInfos(testFile, globalMetadataInfoHandler, false, false) - globalMetadataInfoHandler.addMetadataInfosForFile(testFile, metaInfos) - } - } + reportDiagnostics(module, info) + reportKtDiagnostics(module, info) + checkFullDiagnosticRender(module, info) } private fun getKtFiles(module: TestModule): Map { @@ -57,4 +48,67 @@ class JvmBackendDiagnosticsHandler(testServices: TestServices) : JvmBinaryArtifa } override fun processAfterAllModules(someAssertionWasFailed: Boolean) {} + + private fun getLineAndColumnRange(diagnostic: KtDiagnostic): PsiDiagnosticUtils.LineAndColumnRange { + val file = diagnostic.psiElement.containingFile + val textRanges = diagnostic.textRanges + return DiagnosticUtils.getLineAndColumnRange(file, textRanges) + } + + private fun reportDiagnostics(module: TestModule, info: BinaryArtifacts.Jvm) { + val testFileToKtFileMap = getKtFiles(module) + val ktFileToTestFileMap = testFileToKtFileMap.entries.associate { it.value to it.key } + val generationState = info.classFileFactory.generationState + val configuration = reporter.createConfiguration(module) + val withNewInferenceModeEnabled = testServices.withNewInferenceModeEnabled() + + val diagnostics = generationState.collectedExtraJvmDiagnostics.all() + for (diagnostic in diagnostics) { + val ktFile = diagnostic.psiFile as? KtFile ?: continue + val testFile = ktFileToTestFileMap[ktFile] ?: continue + reporter.reportDiagnostic(diagnostic, module, testFile, configuration, withNewInferenceModeEnabled) + } + } + + private fun reportKtDiagnostics(module: TestModule, info: BinaryArtifacts.Jvm) { + val testFileToKtFileMap = getKtFiles(module) + val generationState = info.classFileFactory.generationState + + val ktDiagnosticReporter = generationState.diagnosticReporter as BaseDiagnosticsCollector + val globalMetadataInfoHandler = testServices.globalMetadataInfoHandler + for ((testFile, ktFile) in testFileToKtFileMap.entries) { + val ktDiagnostics = ktDiagnosticReporter.diagnosticsByFilePath[ktFile.virtualFilePath] ?: continue + ktDiagnostics.forEach { + val metaInfos = + it.toMetaInfos(testFile, globalMetadataInfoHandler, false, false) + globalMetadataInfoHandler.addMetadataInfosForFile(testFile, metaInfos) + } + } + } + + private fun checkFullDiagnosticRender(module: TestModule, info: BinaryArtifacts.Jvm) { + if (DiagnosticsDirectives.RENDER_DIAGNOSTICS_FULL_TEXT !in module.directives) return + + val testFileToKtFileMap = getKtFiles(module) + val generationState = info.classFileFactory.generationState + + val ktDiagnosticReporter = generationState.diagnosticReporter as BaseDiagnosticsCollector + val reportedDiagnostics = mutableListOf() + for (ktFile in testFileToKtFileMap.values) { + val ktDiagnostics = ktDiagnosticReporter.diagnosticsByFilePath[ktFile.virtualFilePath] ?: continue + ktDiagnostics.forEach { + val severity = AnalyzerWithCompilerReport.convertSeverity(it.severity).toString().toLowerCaseAsciiOnly() + val message = KtDefaultJvmErrorMessages.MAP[it.factory]?.render(it) + val position = getLineAndColumnRange(it).start + reportedDiagnostics += "/${ktFile.name}:${position.line}:${position.column}: $severity: $message" + } + } + + if (reportedDiagnostics.isNotEmpty()) { + testServices.assertions.assertEqualsToFile( + File(FileUtil.getNameWithoutExtension(testFileToKtFileMap.keys.first().originalFile.absolutePath) + ".diag.txt"), + reportedDiagnostics.joinToString(separator = "\n\n") + ) + } + } }