[Jspecify] Move jspecify test runner under the new tests infrastructure
This commit is contained in:
+6
-2
@@ -111,8 +111,12 @@ class TestConfigurationBuilder {
|
|||||||
handlers += constructor
|
handlers += constructor
|
||||||
}
|
}
|
||||||
|
|
||||||
fun useSourcePreprocessor(vararg preprocessors: Constructor<SourceFilePreprocessor>) {
|
fun useSourcePreprocessor(vararg preprocessors: Constructor<SourceFilePreprocessor>, needToPrepend: Boolean = false) {
|
||||||
sourcePreprocessors += preprocessors
|
if (needToPrepend) {
|
||||||
|
sourcePreprocessors.addAll(0, preprocessors.toList())
|
||||||
|
} else {
|
||||||
|
sourcePreprocessors.addAll(preprocessors)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun useDirectives(vararg directives: DirectivesContainer) {
|
fun useDirectives(vararg directives: DirectivesContainer) {
|
||||||
|
|||||||
+6
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.test.directives
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.config.*
|
import org.jetbrains.kotlin.config.*
|
||||||
import org.jetbrains.kotlin.test.TestJdkKind
|
import org.jetbrains.kotlin.test.TestJdkKind
|
||||||
|
import org.jetbrains.kotlin.test.directives.model.DirectiveApplicability
|
||||||
import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer
|
import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer
|
||||||
|
|
||||||
object JvmEnvironmentConfigurationDirectives : SimpleDirectivesContainer() {
|
object JvmEnvironmentConfigurationDirectives : SimpleDirectivesContainer() {
|
||||||
@@ -34,6 +35,11 @@ object JvmEnvironmentConfigurationDirectives : SimpleDirectivesContainer() {
|
|||||||
val USE_JAVAC by directive("Enable javac integration")
|
val USE_JAVAC by directive("Enable javac integration")
|
||||||
val SKIP_JAVA_SOURCES by directive("Don't add java sources to compile classpath")
|
val SKIP_JAVA_SOURCES by directive("Don't add java sources to compile classpath")
|
||||||
|
|
||||||
|
val JSPECIFY_MUTE by directive(
|
||||||
|
"Skip jspecify checks for compliance Kotlin diagnostics to jspecify marks",
|
||||||
|
applicability = DirectiveApplicability.Global
|
||||||
|
)
|
||||||
|
|
||||||
@Suppress("RemoveExplicitTypeArguments")
|
@Suppress("RemoveExplicitTypeArguments")
|
||||||
val STRING_CONCAT by enumDirective<JvmStringConcat>(
|
val STRING_CONCAT by enumDirective<JvmStringConcat>(
|
||||||
description = "Configure mode of string concatenation",
|
description = "Configure mode of string concatenation",
|
||||||
|
|||||||
+163
@@ -0,0 +1,163 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 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.preprocessors
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.checkers.DiagnosedRange
|
||||||
|
import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil
|
||||||
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
||||||
|
import org.jetbrains.kotlin.test.KtAssert
|
||||||
|
import org.jetbrains.kotlin.test.directives.ForeignAnnotationsDirectives
|
||||||
|
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.JSPECIFY_MUTE
|
||||||
|
import org.jetbrains.kotlin.test.model.TestFile
|
||||||
|
import org.jetbrains.kotlin.test.services.*
|
||||||
|
import org.jetbrains.kotlin.utils.JavaTypeEnhancementState
|
||||||
|
import org.jetbrains.kotlin.utils.ReportLevel
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class JspecifyTestsPreprocessor(testServices: TestServices) : SourceFilePreprocessor(testServices) {
|
||||||
|
val shouldAutoApplyChanges = System.getProperty("autoApply") == "true"
|
||||||
|
|
||||||
|
private fun getJspecifyMarkRegex(jspecifyMark: String) = Regex("""^\s*// $jspecifyMark$""")
|
||||||
|
private fun checkIfAllJspecifyMarksByDiagnosticsArePresent(
|
||||||
|
diagnosedRanges: List<DiagnosedRange>,
|
||||||
|
lineIndexesByRanges: TreeMap<Int, Int>,
|
||||||
|
textLines: List<String>,
|
||||||
|
compilerDiagnosticsToJspecifyMarksMap: Map<String, String>
|
||||||
|
) {
|
||||||
|
for (diagnosticRange in diagnosedRanges) {
|
||||||
|
val lineIndex = lineIndexesByRanges.floorEntry(diagnosticRange.start).value
|
||||||
|
|
||||||
|
for (diagnostic in diagnosticRange.getDiagnostics()) {
|
||||||
|
val requiredJspecifyMark = compilerDiagnosticsToJspecifyMarksMap[diagnostic.name] ?: continue
|
||||||
|
|
||||||
|
fun getErrorMessage(lineIndex: Int) =
|
||||||
|
"Jspecify mark '$requiredJspecifyMark' not found for diagnostic '${diagnostic}' at ${lineIndex + 1} line.\n" +
|
||||||
|
"It should be located at the previous line as a comment."
|
||||||
|
|
||||||
|
assert(lineIndex != 0) { getErrorMessage(0) }
|
||||||
|
|
||||||
|
val previousLine = textLines[lineIndex - 1]
|
||||||
|
|
||||||
|
assert(getJspecifyMarkRegex(requiredJspecifyMark).matches(previousLine)) { getErrorMessage(lineIndex) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkIfAllDiagnosticsByJspecifyMarksArePresent(
|
||||||
|
diagnosedRanges: List<DiagnosedRange>,
|
||||||
|
lineIndexesByRanges: TreeMap<Int, Int>,
|
||||||
|
textLines: List<String>,
|
||||||
|
compilerDiagnosticsToJspecifyMarksMap: Map<String, List<String>>
|
||||||
|
) {
|
||||||
|
for ((jspecifyMark, possibleDiagnostics) in compilerDiagnosticsToJspecifyMarksMap) {
|
||||||
|
val diagnosticRanges = diagnosedRanges.mapNotNull {
|
||||||
|
val relevantDiagnostics = it.getDiagnostics().filter { it.name in possibleDiagnostics }
|
||||||
|
if (relevantDiagnostics.isEmpty()) return@mapNotNull null
|
||||||
|
it.start
|
||||||
|
}
|
||||||
|
|
||||||
|
val lineIndexesWithJspecifyMarks =
|
||||||
|
textLines.mapIndexedNotNull { index, it -> getJspecifyMarkRegex(jspecifyMark).find(it)?.let { index } }
|
||||||
|
|
||||||
|
if (diagnosticRanges.isEmpty()) {
|
||||||
|
if (lineIndexesWithJspecifyMarks.isEmpty()) {
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
KtAssert.fail(
|
||||||
|
"None of \"${possibleDiagnostics.joinToString(", ")}\" diagnostics not found " +
|
||||||
|
"for jspecify mark '$jspecifyMark' at lines: ${lineIndexesWithJspecifyMarks.map { it + 1 }.joinToString()}"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (lineIndex in lineIndexesWithJspecifyMarks) {
|
||||||
|
val lineStartPosition = lineIndexesByRanges.entries.find { (_, index) -> index == lineIndex + 1 }?.key
|
||||||
|
val errorMessage = "None of \"${possibleDiagnostics.joinToString()}\" diagnostics not found " +
|
||||||
|
"for jspecify mark '$jspecifyMark' at ${lineIndex + 1} line"
|
||||||
|
|
||||||
|
KtAssert.assertTrue(errorMessage, lineStartPosition != null)
|
||||||
|
|
||||||
|
val lineEndPosition = lineStartPosition!! + textLines[lineIndex + 1].length
|
||||||
|
val isCorrespondingDiagnosticPresent = diagnosticRanges.any { it in lineStartPosition..lineEndPosition }
|
||||||
|
|
||||||
|
KtAssert.assertTrue(errorMessage, isCorrespondingDiagnosticPresent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun process(file: TestFile, content: String): String {
|
||||||
|
if (!file.relativePath.endsWith(".kt")) return content
|
||||||
|
|
||||||
|
val textWithDiagnostics = content.substringAfter(MAIN_KT_FILE_DIRECTIVE).removeSuffix("\n")
|
||||||
|
val diagnosedRanges = mutableListOf<DiagnosedRange>()
|
||||||
|
val textWithoutDiagnostics = CheckerTestUtil.parseDiagnosedRanges(textWithDiagnostics, diagnosedRanges)
|
||||||
|
|
||||||
|
val textLines = textWithoutDiagnostics.lines()
|
||||||
|
val lineIndexesByRanges = TreeMap<Int, Int>().apply {
|
||||||
|
textLines.scanIndexed(0) { index, position, line ->
|
||||||
|
put(position, index)
|
||||||
|
position + line.length + 1 // + new line symbol
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val jspecifyMode = file.directives[ForeignAnnotationsDirectives.JSPECIFY_STATE].singleOrNull()
|
||||||
|
?: JavaTypeEnhancementState.DEFAULT_REPORT_LEVEL_FOR_JSPECIFY
|
||||||
|
val compilerDiagnosticsToJspecifyMarksMap = when (jspecifyMode) {
|
||||||
|
ReportLevel.STRICT -> diagnosticsToJspecifyMarksMapForStrictMode
|
||||||
|
ReportLevel.WARN -> diagnosticsToJspecifyMarksMapForWarnMode
|
||||||
|
ReportLevel.IGNORE -> mapOf()
|
||||||
|
}
|
||||||
|
val jspecifyMarksToCompilerDiagnosticsMap = when (jspecifyMode) {
|
||||||
|
ReportLevel.STRICT -> jspecifyMarksToPossibleDiagnosticsForStrictMode
|
||||||
|
ReportLevel.WARN -> jspecifyMarksToPossibleDiagnosticsForWarnMode
|
||||||
|
ReportLevel.IGNORE -> mapOf()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldAutoApplyChanges || JSPECIFY_MUTE in testServices.moduleStructure.allDirectives) {
|
||||||
|
return content
|
||||||
|
}
|
||||||
|
|
||||||
|
checkIfAllJspecifyMarksByDiagnosticsArePresent(
|
||||||
|
diagnosedRanges,
|
||||||
|
lineIndexesByRanges,
|
||||||
|
textLines,
|
||||||
|
compilerDiagnosticsToJspecifyMarksMap
|
||||||
|
)
|
||||||
|
checkIfAllDiagnosticsByJspecifyMarksArePresent(
|
||||||
|
diagnosedRanges,
|
||||||
|
lineIndexesByRanges,
|
||||||
|
textLines,
|
||||||
|
jspecifyMarksToCompilerDiagnosticsMap
|
||||||
|
)
|
||||||
|
|
||||||
|
return content
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val MAIN_KT_FILE_DIRECTIVE = "// FILE: main.kt\n"
|
||||||
|
|
||||||
|
val diagnosticsToJspecifyMarksMapForWarnMode = mapOf(
|
||||||
|
ErrorsJvm.NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS.name to "jspecify_nullness_mismatch",
|
||||||
|
Errors.TYPE_MISMATCH.name to "jspecify_nullness_mismatch",
|
||||||
|
Errors.NULL_FOR_NONNULL_TYPE.name to "jspecify_nullness_mismatch",
|
||||||
|
Errors.NOTHING_TO_OVERRIDE.name to "jspecify_nullness_mismatch",
|
||||||
|
Errors.RETURN_TYPE_MISMATCH_ON_OVERRIDE.name to "jspecify_nullness_mismatch",
|
||||||
|
Errors.UPPER_BOUND_VIOLATED.name to "jspecify_nullness_mismatch",
|
||||||
|
ErrorsJvm.NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS.name to "jspecify_nullness_mismatch",
|
||||||
|
ErrorsJvm.RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS.name to "jspecify_nullness_mismatch",
|
||||||
|
Errors.UNSAFE_CALL.name to "jspecify_nullness_mismatch",
|
||||||
|
)
|
||||||
|
|
||||||
|
val jspecifyMarksToPossibleDiagnosticsForWarnMode =
|
||||||
|
diagnosticsToJspecifyMarksMapForWarnMode.entries.groupBy({ it.value }, { it.key })
|
||||||
|
|
||||||
|
val diagnosticsToJspecifyMarksMapForStrictMode = diagnosticsToJspecifyMarksMapForWarnMode
|
||||||
|
|
||||||
|
val jspecifyMarksToPossibleDiagnosticsForStrictMode =
|
||||||
|
diagnosticsToJspecifyMarksMapForStrictMode.entries.groupBy({ it.value }, { it.key })
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
@@ -70,6 +70,10 @@ abstract class AbstractForeignAnnotationsTestBase : AbstractKotlinCompilerTest()
|
|||||||
ANNOTATIONS_PATH with JavaForeignAnnotationType.Java8Annotations
|
ANNOTATIONS_PATH with JavaForeignAnnotationType.Java8Annotations
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forTestsMatching("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/*") {
|
||||||
|
useSourcePreprocessor(::JspecifyTestsPreprocessor, needToPrepend = true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-173
@@ -1,173 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2020 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.checkers
|
|
||||||
|
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
|
||||||
import org.jetbrains.kotlin.ObsoleteTestInfrastructure
|
|
||||||
import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
|
||||||
import org.jetbrains.kotlin.test.MockLibraryUtilExt
|
|
||||||
import java.io.File
|
|
||||||
import java.util.*
|
|
||||||
import java.util.regex.Pattern
|
|
||||||
import kotlin.io.path.ExperimentalPathApi
|
|
||||||
import kotlin.io.path.createTempFile
|
|
||||||
import kotlin.io.path.writeText
|
|
||||||
|
|
||||||
const val JSPECIFY_NULLNESS_MISMATCH_MARK = "jspecify_nullness_mismatch"
|
|
||||||
|
|
||||||
const val JSPECIFY_NULLABLE_ANNOTATION = "@Nullable"
|
|
||||||
const val JSPECIFY_NULLNESS_UNSPECIFIED_ANNOTATION = "@NullnessUnspecified"
|
|
||||||
|
|
||||||
@OptIn(ObsoleteTestInfrastructure::class)
|
|
||||||
abstract class AbstractJspecifyAnnotationsTest : AbstractDiagnosticsTest() {
|
|
||||||
override fun doMultiFileTest(
|
|
||||||
wholeFile: File,
|
|
||||||
files: List<TestFile>
|
|
||||||
) {
|
|
||||||
super.doMultiFileTest(
|
|
||||||
wholeFile,
|
|
||||||
files,
|
|
||||||
MockLibraryUtilExt.compileJavaFilesLibraryToJar(FOREIGN_JDK8_ANNOTATIONS_SOURCES_PATH, "foreign-annotations"),
|
|
||||||
usePsiClassFilesReading = false,
|
|
||||||
excludeNonTypeUseJetbrainsAnnotations = true
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(ExperimentalPathApi::class)
|
|
||||||
override fun doTest(filePath: String) {
|
|
||||||
val ktSourceCode = File(filePath).readText()
|
|
||||||
val javaSourcesFilename = javaSourcesPathRegex.matcher(ktSourceCode).also { it.find() }.group(1)
|
|
||||||
?: throw Exception("Java sources' path not found")
|
|
||||||
val javaSourcesFile = File("$JSPECIFY_JAVA_SOURCES_PATH/$javaSourcesFilename")
|
|
||||||
val mergedSourceCode = buildString {
|
|
||||||
appendLine("// ORIGINAL_KT_FILE: $filePath")
|
|
||||||
|
|
||||||
if (javaSourcesFilename.endsWith(".java")) {
|
|
||||||
appendLine(makeJavaClassesPublicAndSeparatedByFiles(javaSourcesFile.readText()))
|
|
||||||
} else {
|
|
||||||
assert(javaSourcesFile.isDirectory) { "Specified Java sources should be a file with `java` extension or directory" }
|
|
||||||
|
|
||||||
for (javaFile in javaSourcesFile.walkTopDown().filter { it.isFile && it.extension == "java" }) {
|
|
||||||
appendLine("// FILE: ${javaFile.name}")
|
|
||||||
appendLine(makeJavaClassesPublicAndSeparatedByFiles(javaFile.readText()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
appendLine("// FILE: main.kt\n$ktSourceCode")
|
|
||||||
}
|
|
||||||
|
|
||||||
super.doTest(createTempFile().apply { writeText(mergedSourceCode) }.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun makeJavaClassesPublicAndSeparatedByFiles(javaCode: String): String {
|
|
||||||
val importSectionMatch = importSectionRegex.find(javaCode)
|
|
||||||
val importSection = if (importSectionMatch != null) "\n${importSectionMatch.groups[1]!!.value}\n" else ""
|
|
||||||
|
|
||||||
return javaCode.replace(importSectionRegex, "")
|
|
||||||
.replace(publicClassOrInterfaceRegex, "$1")
|
|
||||||
.replace(classOrInterfaceRegex, "public $1")
|
|
||||||
.replace(classShapeRegex, "\n// FILE: $3.java$importSection$1\npublic $2 $3$4")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getJspecifyMarkRegex(jspecifyMark: String) = Regex("""^\s*// $jspecifyMark$""")
|
|
||||||
|
|
||||||
private fun checkIfAllJspecifyMarksByDiagnosticsArePresent(
|
|
||||||
diagnosedRanges: List<DiagnosedRange>,
|
|
||||||
lineIndexesByRanges: TreeMap<Int, Int>,
|
|
||||||
textLines: List<String>
|
|
||||||
) {
|
|
||||||
for (diagnosticRange in diagnosedRanges) {
|
|
||||||
val lineIndex = lineIndexesByRanges.floorEntry(diagnosticRange.start).value
|
|
||||||
|
|
||||||
for (diagnostic in diagnosticRange.getDiagnostics()) {
|
|
||||||
val requiredJspecifyMark = diagnosticsToJspecifyMarksMap[diagnostic.name] ?: continue
|
|
||||||
|
|
||||||
fun getErrorMessage(lineIndex: Int) =
|
|
||||||
"Jspecify mark '$requiredJspecifyMark' not found for diagnostic '${diagnostic}' at ${lineIndex + 1} line.\n" +
|
|
||||||
"It should be located at the previous line as a comment."
|
|
||||||
|
|
||||||
assert(lineIndex != 0) { getErrorMessage(0) }
|
|
||||||
|
|
||||||
val previousLine = textLines[lineIndex - 1]
|
|
||||||
|
|
||||||
assert(getJspecifyMarkRegex(requiredJspecifyMark).matches(previousLine)) { getErrorMessage(lineIndex) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkIfAllDiagnosticsByJspecifyMarksArePresent(
|
|
||||||
diagnosedRanges: List<DiagnosedRange>,
|
|
||||||
lineIndexesByRanges: TreeMap<Int, Int>,
|
|
||||||
textLines: List<String>
|
|
||||||
) {
|
|
||||||
for ((diagnosticName, jspecifyMark) in diagnosticsToJspecifyMarksMap) {
|
|
||||||
val diagnosticRanges = diagnosedRanges.filter { diagnostics ->
|
|
||||||
diagnosticName in diagnostics.getDiagnostics().map { it.name }
|
|
||||||
}.map { it.start }
|
|
||||||
val lineIndexesWithJspecifyMarks =
|
|
||||||
textLines.mapIndexedNotNull { index, it -> getJspecifyMarkRegex(jspecifyMark).find(it)?.let { index } }
|
|
||||||
|
|
||||||
for (lineIndex in lineIndexesWithJspecifyMarks) {
|
|
||||||
val lineStartPosition = lineIndexesByRanges.entries.find { (_, index) -> index == lineIndex + 1 }?.key
|
|
||||||
val errorMessage = "Diagnostic '$diagnosticName' not found for jspecify mark '$jspecifyMark' at ${lineIndex + 1} line"
|
|
||||||
|
|
||||||
assertNotNull(errorMessage, lineStartPosition)
|
|
||||||
|
|
||||||
val lineEndPosition = lineStartPosition!! + textLines[lineIndex].length
|
|
||||||
val isCorrespondingDiagnosticPresent = diagnosticRanges.any { it in lineStartPosition..lineEndPosition }
|
|
||||||
|
|
||||||
assertTrue(errorMessage, isCorrespondingDiagnosticPresent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun checkDiagnostics(actualText: String, testDataFile: File) {
|
|
||||||
val mergedTestFilePath = originalKtFileRegex.matcher(actualText).also { it.find() }.group(1)
|
|
||||||
?: throw Exception("Path for original kt file in the merged file not found")
|
|
||||||
|
|
||||||
val textWithDiagnostics = actualText.substringAfter(MAIN_KT_FILE_DIRECTIVE).removeSuffix("\n")
|
|
||||||
val diagnosedRanges = mutableListOf<DiagnosedRange>()
|
|
||||||
val textWithoutDiagnostics = CheckerTestUtil.parseDiagnosedRanges(textWithDiagnostics, diagnosedRanges)
|
|
||||||
|
|
||||||
val textLines = textWithoutDiagnostics.lines()
|
|
||||||
val lineIndexesByRanges = TreeMap<Int, Int>().apply {
|
|
||||||
textLines.scanIndexed(0) { index, position, line ->
|
|
||||||
put(position, index)
|
|
||||||
position + line.length + 1 // + new line symbol
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
checkIfAllJspecifyMarksByDiagnosticsArePresent(diagnosedRanges, lineIndexesByRanges, textLines)
|
|
||||||
|
|
||||||
checkIfAllDiagnosticsByJspecifyMarksArePresent(diagnosedRanges, lineIndexesByRanges, textLines)
|
|
||||||
|
|
||||||
super.checkDiagnostics(textWithDiagnostics, File(mergedTestFilePath))
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getExpectedDescriptorFile(testDataFile: File, files: List<TestFile>): File {
|
|
||||||
val originalKtFilePath = originalKtFileRegex.matcher(testDataFile.readText()).also { it.find() }.group(1)
|
|
||||||
?: throw Exception("Path for original kt file in the merged file isn't found")
|
|
||||||
|
|
||||||
return File(FileUtil.getNameWithoutExtension(originalKtFilePath) + ".txt")
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
const val JSPECIFY_JAVA_SOURCES_PATH = "compiler/testData/foreignAnnotationsJava8/tests/jspecify/java"
|
|
||||||
const val MAIN_KT_FILE_DIRECTIVE = "// FILE: main.kt\n"
|
|
||||||
|
|
||||||
private val originalKtFileRegex = Pattern.compile("""// ORIGINAL_KT_FILE: (.*?\.kts?)\n""")
|
|
||||||
private val javaSourcesPathRegex = Pattern.compile("""// JAVA_SOURCES: (.*?(?:\.java)?)\n""")
|
|
||||||
|
|
||||||
val diagnosticsToJspecifyMarksMap = mapOf(
|
|
||||||
ErrorsJvm::NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS.name to JSPECIFY_NULLNESS_MISMATCH_MARK
|
|
||||||
)
|
|
||||||
|
|
||||||
private val importSectionRegex = Regex("""((?:import .*?;\n)+)""")
|
|
||||||
private val classOrInterfaceRegex = Regex("""(class|interface)""")
|
|
||||||
private val publicClassOrInterfaceRegex = Regex("""public (class|interface)""")
|
|
||||||
private val classShapeRegex = Regex("""(\n@NullMarked)?\npublic (class|interface) (\w+)(<[^>]+>)?""")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+3
-3
@@ -49,17 +49,17 @@ fun generateJUnit5CompilerTests(args: Array<String>) {
|
|||||||
|
|
||||||
testClass<AbstractForeignAnnotationsTest> {
|
testClass<AbstractForeignAnnotationsTest> {
|
||||||
model("diagnostics/foreignAnnotationsTests/tests")
|
model("diagnostics/foreignAnnotationsTests/tests")
|
||||||
model("diagnostics/foreignAnnotationsTests/java8Tests", excludeDirs = listOf("jspecify", "typeEnhancementOnCompiledJava"))
|
model("diagnostics/foreignAnnotationsTests/java8Tests", excludeDirs = listOf("typeEnhancementOnCompiledJava"))
|
||||||
}
|
}
|
||||||
|
|
||||||
testClass<AbstractForeignAnnotationsNoAnnotationInClasspathTest> {
|
testClass<AbstractForeignAnnotationsNoAnnotationInClasspathTest> {
|
||||||
model("diagnostics/foreignAnnotationsTests/tests")
|
model("diagnostics/foreignAnnotationsTests/tests")
|
||||||
model("diagnostics/foreignAnnotationsTests/java8Tests", excludeDirs = listOf("jspecify", "typeEnhancementOnCompiledJava"))
|
model("diagnostics/foreignAnnotationsTests/java8Tests", excludeDirs = listOf("typeEnhancementOnCompiledJava"))
|
||||||
}
|
}
|
||||||
|
|
||||||
testClass<AbstractForeignAnnotationsNoAnnotationInClasspathWithPsiClassReadingTest> {
|
testClass<AbstractForeignAnnotationsNoAnnotationInClasspathWithPsiClassReadingTest> {
|
||||||
model("diagnostics/foreignAnnotationsTests/tests")
|
model("diagnostics/foreignAnnotationsTests/tests")
|
||||||
model("diagnostics/foreignAnnotationsTests/java8Tests", excludeDirs = listOf("jspecify", "typeEnhancementOnCompiledJava"))
|
model("diagnostics/foreignAnnotationsTests/java8Tests", excludeDirs = listOf("typeEnhancementOnCompiledJava"))
|
||||||
}
|
}
|
||||||
|
|
||||||
testClass<AbstractBlackBoxCodegenTest> {
|
testClass<AbstractBlackBoxCodegenTest> {
|
||||||
|
|||||||
Generated
-157
@@ -1,157 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2021 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.checkers;
|
|
||||||
|
|
||||||
import com.intellij.testFramework.TestDataPath;
|
|
||||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
|
||||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
|
||||||
import org.jetbrains.kotlin.test.TestMetadata;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
@TestMetadata("compiler/testData/foreignAnnotations/java8Tests/jspecify/kotlin")
|
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
|
||||||
public class JspecifyAnnotationsTestGenerated extends AbstractJspecifyAnnotationsTest {
|
|
||||||
private void runTest(String testDataFilePath) throws Exception {
|
|
||||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAllFilesPresentInKotlin() throws Exception {
|
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/foreignAnnotations/java8Tests/jspecify/kotlin"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/foreignAnnotations/java8Tests/jspecify/kotlin/strictMode")
|
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
|
||||||
public static class StrictMode extends AbstractJspecifyAnnotationsTest {
|
|
||||||
private void runTest(String testDataFilePath) throws Exception {
|
|
||||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAllFilesPresentInStrictMode() throws Exception {
|
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/foreignAnnotations/java8Tests/jspecify/kotlin/strictMode"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("AnnotatedBoundsOfWildcard.kt")
|
|
||||||
public void testAnnotatedBoundsOfWildcard() throws Exception {
|
|
||||||
runTest("compiler/testData/foreignAnnotations/java8Tests/jspecify/kotlin/strictMode/AnnotatedBoundsOfWildcard.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("Defaults.kt")
|
|
||||||
public void testDefaults() throws Exception {
|
|
||||||
runTest("compiler/testData/foreignAnnotations/java8Tests/jspecify/kotlin/strictMode/Defaults.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("IgnoreAnnotations.kt")
|
|
||||||
public void testIgnoreAnnotations() throws Exception {
|
|
||||||
runTest("compiler/testData/foreignAnnotations/java8Tests/jspecify/kotlin/strictMode/IgnoreAnnotations.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("NonPlatformTypeParameter.kt")
|
|
||||||
public void testNonPlatformTypeParameter() throws Exception {
|
|
||||||
runTest("compiler/testData/foreignAnnotations/java8Tests/jspecify/kotlin/strictMode/NonPlatformTypeParameter.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("NullnessUnspecifiedTypeParameter.kt")
|
|
||||||
public void testNullnessUnspecifiedTypeParameter() throws Exception {
|
|
||||||
runTest("compiler/testData/foreignAnnotations/java8Tests/jspecify/kotlin/strictMode/NullnessUnspecifiedTypeParameter.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("SelfType.kt")
|
|
||||||
public void testSelfType() throws Exception {
|
|
||||||
runTest("compiler/testData/foreignAnnotations/java8Tests/jspecify/kotlin/strictMode/SelfType.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("Simple.kt")
|
|
||||||
public void testSimple() throws Exception {
|
|
||||||
runTest("compiler/testData/foreignAnnotations/java8Tests/jspecify/kotlin/strictMode/Simple.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("TypeArgumentsFromParameterBounds.kt")
|
|
||||||
public void testTypeArgumentsFromParameterBounds() throws Exception {
|
|
||||||
runTest("compiler/testData/foreignAnnotations/java8Tests/jspecify/kotlin/strictMode/TypeArgumentsFromParameterBounds.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("TypeParameterBounds.kt")
|
|
||||||
public void testTypeParameterBounds() throws Exception {
|
|
||||||
runTest("compiler/testData/foreignAnnotations/java8Tests/jspecify/kotlin/strictMode/TypeParameterBounds.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("WildcardsWithDefault.kt")
|
|
||||||
public void testWildcardsWithDefault() throws Exception {
|
|
||||||
runTest("compiler/testData/foreignAnnotations/java8Tests/jspecify/kotlin/strictMode/WildcardsWithDefault.kt");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/foreignAnnotations/java8Tests/jspecify/kotlin/warnMode")
|
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
|
||||||
public static class WarnMode extends AbstractJspecifyAnnotationsTest {
|
|
||||||
private void runTest(String testDataFilePath) throws Exception {
|
|
||||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAllFilesPresentInWarnMode() throws Exception {
|
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/foreignAnnotations/java8Tests/jspecify/kotlin/warnMode"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("AnnotatedBoundsOfWildcard.kt")
|
|
||||||
public void testAnnotatedBoundsOfWildcard() throws Exception {
|
|
||||||
runTest("compiler/testData/foreignAnnotations/java8Tests/jspecify/kotlin/warnMode/AnnotatedBoundsOfWildcard.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("Defaults.kt")
|
|
||||||
public void testDefaults() throws Exception {
|
|
||||||
runTest("compiler/testData/foreignAnnotations/java8Tests/jspecify/kotlin/warnMode/Defaults.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("IgnoreAnnotations.kt")
|
|
||||||
public void testIgnoreAnnotations() throws Exception {
|
|
||||||
runTest("compiler/testData/foreignAnnotations/java8Tests/jspecify/kotlin/warnMode/IgnoreAnnotations.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("NonPlatformTypeParameter.kt")
|
|
||||||
public void testNonPlatformTypeParameter() throws Exception {
|
|
||||||
runTest("compiler/testData/foreignAnnotations/java8Tests/jspecify/kotlin/warnMode/NonPlatformTypeParameter.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("NullnessUnspecifiedTypeParameter.kt")
|
|
||||||
public void testNullnessUnspecifiedTypeParameter() throws Exception {
|
|
||||||
runTest("compiler/testData/foreignAnnotations/java8Tests/jspecify/kotlin/warnMode/NullnessUnspecifiedTypeParameter.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("SelfType.kt")
|
|
||||||
public void testSelfType() throws Exception {
|
|
||||||
runTest("compiler/testData/foreignAnnotations/java8Tests/jspecify/kotlin/warnMode/SelfType.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("Simple.kt")
|
|
||||||
public void testSimple() throws Exception {
|
|
||||||
runTest("compiler/testData/foreignAnnotations/java8Tests/jspecify/kotlin/warnMode/Simple.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("TypeArgumentsFromParameterBounds.kt")
|
|
||||||
public void testTypeArgumentsFromParameterBounds() throws Exception {
|
|
||||||
runTest("compiler/testData/foreignAnnotations/java8Tests/jspecify/kotlin/warnMode/TypeArgumentsFromParameterBounds.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("TypeParameterBounds.kt")
|
|
||||||
public void testTypeParameterBounds() throws Exception {
|
|
||||||
runTest("compiler/testData/foreignAnnotations/java8Tests/jspecify/kotlin/warnMode/TypeParameterBounds.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("WildcardsWithDefault.kt")
|
|
||||||
public void testWildcardsWithDefault() throws Exception {
|
|
||||||
runTest("compiler/testData/foreignAnnotations/java8Tests/jspecify/kotlin/warnMode/WildcardsWithDefault.kt");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -28,10 +28,6 @@ fun main(args: Array<String>) {
|
|||||||
|
|
||||||
generateTestGroupSuite(args) {
|
generateTestGroupSuite(args) {
|
||||||
testGroup("compiler/tests-java8/tests", "compiler/testData") {
|
testGroup("compiler/tests-java8/tests", "compiler/testData") {
|
||||||
testClass<AbstractJspecifyAnnotationsTest> {
|
|
||||||
model("foreignAnnotations/java8Tests/jspecify/kotlin")
|
|
||||||
}
|
|
||||||
|
|
||||||
testClass<AbstractForeignAnnotationsCompiledJavaDiagnosticTest> {
|
testClass<AbstractForeignAnnotationsCompiledJavaDiagnosticTest> {
|
||||||
model("foreignAnnotations/java8Tests/typeEnhancementOnCompiledJava")
|
model("foreignAnnotations/java8Tests/typeEnhancementOnCompiledJava")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user