!RENDER_DIAGNOSTICS_FULL_TEXT directive
Compares diagnostics rendered as text with corresponding .diag.txt file
This commit is contained in:
+44
-1
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.TestsCompilerError
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
||||
import org.jetbrains.kotlin.analyzer.common.CommonResolverForModuleFactory
|
||||
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns
|
||||
import org.jetbrains.kotlin.cli.common.messages.*
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.NoScopeRecordCliBindingTrace
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
|
||||
import org.jetbrains.kotlin.config.*
|
||||
@@ -61,7 +62,9 @@ import org.jetbrains.kotlin.test.util.RecursiveDescriptorComparator.RECURSIVE
|
||||
import org.jetbrains.kotlin.test.util.RecursiveDescriptorComparator.RECURSIVE_ALL
|
||||
import org.jetbrains.kotlin.utils.keysToMap
|
||||
import org.junit.Assert
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.File
|
||||
import java.io.PrintStream
|
||||
import java.util.*
|
||||
import java.util.function.Predicate
|
||||
import java.util.regex.Pattern
|
||||
@@ -169,6 +172,15 @@ abstract class AbstractDiagnosticsTest : BaseDiagnosticsTest() {
|
||||
// main checks
|
||||
var ok = true
|
||||
|
||||
val diagnosticsFullTextByteArrayStream = ByteArrayOutputStream()
|
||||
val diagnosticsFullTextPrintStream = PrintStream(diagnosticsFullTextByteArrayStream)
|
||||
var shouldCheckDiagnosticsFullText = false
|
||||
val diagnosticsFullTextCollector =
|
||||
GroupingMessageCollector(
|
||||
PrintingMessageCollector(diagnosticsFullTextPrintStream, MessageRenderer.SYSTEM_INDEPENDENT_RELATIVE_PATHS, true),
|
||||
false
|
||||
)
|
||||
|
||||
val actualText = StringBuilder()
|
||||
for (testFile in files) {
|
||||
val module = testFile.module
|
||||
@@ -183,14 +195,20 @@ abstract class AbstractDiagnosticsTest : BaseDiagnosticsTest() {
|
||||
}
|
||||
val moduleDescriptor = modules[module]!!
|
||||
|
||||
val moduleBindingContext = moduleBindings[module]!!
|
||||
ok = ok and testFile.getActualText(
|
||||
moduleBindings[module]!!,
|
||||
moduleBindingContext,
|
||||
implementingModulesBindings,
|
||||
actualText,
|
||||
shouldSkipJvmSignatureDiagnostics(groupedByModule) || isCommonModule,
|
||||
languageVersionSettingsByModule[module]!!,
|
||||
moduleDescriptor
|
||||
)
|
||||
|
||||
if (testFile.renderDiagnosticsFullText) {
|
||||
shouldCheckDiagnosticsFullText = true
|
||||
AnalyzerWithCompilerReport.reportDiagnostics(moduleBindingContext.diagnostics, diagnosticsFullTextCollector)
|
||||
}
|
||||
}
|
||||
|
||||
var exceptionFromDynamicCallDescriptorsValidation: Throwable? = null
|
||||
@@ -201,6 +219,15 @@ abstract class AbstractDiagnosticsTest : BaseDiagnosticsTest() {
|
||||
exceptionFromDynamicCallDescriptorsValidation = e
|
||||
}
|
||||
|
||||
if (shouldCheckDiagnosticsFullText) {
|
||||
diagnosticsFullTextCollector.flush()
|
||||
diagnosticsFullTextPrintStream.flush()
|
||||
KotlinTestUtils.assertEqualsToFile(
|
||||
File(FileUtil.getNameWithoutExtension(testDataFile.absolutePath) + ".diag.txt"),
|
||||
String(diagnosticsFullTextByteArrayStream.toByteArray())
|
||||
)
|
||||
}
|
||||
|
||||
KotlinTestUtils.assertEqualsToFile(getExpectedDiagnosticsFile(testDataFile), actualText.cleanupInferenceDiagnostics()) { s ->
|
||||
s.replace("COROUTINES_PACKAGE", coroutinesPackage)
|
||||
}
|
||||
@@ -218,6 +245,22 @@ abstract class AbstractDiagnosticsTest : BaseDiagnosticsTest() {
|
||||
checkOriginalAndFirTestdataIdentity(testDataFile)
|
||||
}
|
||||
|
||||
private class DiagnosticsFullTextMessageCollector : MessageCollector {
|
||||
|
||||
|
||||
override fun clear() {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation?) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun hasErrors(): Boolean {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkOriginalAndFirTestdataIdentity(testDataFile: File) {
|
||||
val firTestDataFile = File(testDataFile.absolutePath.replace(".kt", ".fir.kt"))
|
||||
if (!firTestDataFile.exists()) return
|
||||
|
||||
@@ -157,6 +157,7 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
||||
val withNewInferenceDirective: Boolean
|
||||
val newInferenceEnabled: Boolean
|
||||
val renderDiagnosticMessages: Boolean
|
||||
val renderDiagnosticsFullText: Boolean
|
||||
|
||||
init {
|
||||
this.whatDiagnosticsToConsider = parseDiagnosticFilterDirective(directives, declareCheckType)
|
||||
@@ -166,8 +167,8 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
||||
this.declareFlexibleType = EXPLICIT_FLEXIBLE_TYPES_DIRECTIVE in directives
|
||||
this.markDynamicCalls = MARK_DYNAMIC_CALLS_DIRECTIVE in directives
|
||||
this.withNewInferenceDirective = WITH_NEW_INFERENCE_DIRECTIVE in directives
|
||||
this.newInferenceEnabled = customLanguageVersionSettings?.supportsFeature(LanguageFeature.NewInference) ?:
|
||||
shouldUseNewInferenceForTests()
|
||||
this.newInferenceEnabled =
|
||||
customLanguageVersionSettings?.supportsFeature(LanguageFeature.NewInference) ?: shouldUseNewInferenceForTests()
|
||||
if (fileName.endsWith(".java")) {
|
||||
// TODO: check there are no syntax errors in .java sources
|
||||
this.createKtFile = lazyOf(null)
|
||||
@@ -175,10 +176,12 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
||||
this.expectedText = this.clearText
|
||||
} else {
|
||||
this.expectedText = textWithMarkers
|
||||
this.clearText = CheckerTestUtil.parseDiagnosedRanges(addExtras(expectedText), diagnosedRanges, diagnosedRangesToDiagnosticNames)
|
||||
this.clearText =
|
||||
CheckerTestUtil.parseDiagnosedRanges(addExtras(expectedText), diagnosedRanges, diagnosedRangesToDiagnosticNames)
|
||||
this.createKtFile = lazy { TestCheckerUtil.createCheckAndReturnPsiFile(fileName, clearText, project) }
|
||||
}
|
||||
this.renderDiagnosticMessages = RENDER_DIAGNOSTICS_MESSAGES in directives
|
||||
this.renderDiagnosticsFullText = RENDER_DIAGNOSTICS_FULL_TEXT in directives
|
||||
}
|
||||
|
||||
val ktFile: KtFile? by createKtFile
|
||||
@@ -210,14 +213,14 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
||||
|
||||
private fun addImports(text: String, imports: String): String {
|
||||
var result = text
|
||||
val pattern = Pattern.compile("^package [\\.\\w\\d]*\n", Pattern.MULTILINE)
|
||||
val pattern = Pattern.compile("^package [.\\w\\d]*\n", Pattern.MULTILINE)
|
||||
val matcher = pattern.matcher(result)
|
||||
if (matcher.find()) {
|
||||
result = if (matcher.find()) {
|
||||
// add imports after the package directive
|
||||
result = result.substring(0, matcher.end()) + imports + result.substring(matcher.end())
|
||||
result.substring(0, matcher.end()) + imports + result.substring(matcher.end())
|
||||
} else {
|
||||
// add imports at the beginning
|
||||
result = imports + result
|
||||
imports + result
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -264,10 +267,9 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
||||
moduleDescriptor,
|
||||
this.diagnosedRangesToDiagnosticNames
|
||||
)
|
||||
val filteredDiagnostics = ContainerUtil.filter(
|
||||
diagnostics + jvmSignatureDiagnostics,
|
||||
{ whatDiagnosticsToConsider.value(it.diagnostic) }
|
||||
)
|
||||
val filteredDiagnostics = ContainerUtil.filter(diagnostics + jvmSignatureDiagnostics) {
|
||||
whatDiagnosticsToConsider.value(it.diagnostic)
|
||||
}
|
||||
|
||||
actualDiagnostics.addAll(filteredDiagnostics)
|
||||
|
||||
@@ -320,11 +322,9 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
||||
|
||||
fun updateUncheckedDiagnostics(diagnostic: TextDiagnostic, start: Int, end: Int) {
|
||||
diagnostic.enhanceInferenceCompatibility(invertedInferenceCompatibilityOfTest)
|
||||
uncheckedDiagnostics.add(PositionalTextDiagnostic(diagnostic, start, end
|
||||
)
|
||||
)
|
||||
}
|
||||
})
|
||||
uncheckedDiagnostics.add(PositionalTextDiagnostic(diagnostic, start, end))
|
||||
}
|
||||
})
|
||||
|
||||
actualText.append(
|
||||
CheckerTestUtil.addDiagnosticMarkersToText(
|
||||
@@ -370,7 +370,7 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
||||
companion object {
|
||||
private const val HELPERS_PATH = "./compiler/testData/diagnostics/helpers"
|
||||
val DIAGNOSTICS_DIRECTIVE = "DIAGNOSTICS"
|
||||
val DIAGNOSTICS_PATTERN: Pattern = Pattern.compile("([\\+\\-!])(\\w+)\\s*")
|
||||
val DIAGNOSTICS_PATTERN: Pattern = Pattern.compile("([+\\-!])(\\w+)\\s*")
|
||||
val DIAGNOSTICS_TO_INCLUDE_ANYWAY: Set<DiagnosticFactory<*>> = setOf(
|
||||
Errors.UNRESOLVED_REFERENCE,
|
||||
Errors.UNRESOLVED_REFERENCE_WRONG_RECEIVER,
|
||||
@@ -406,6 +406,8 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
||||
|
||||
val RENDER_DIAGNOSTICS_MESSAGES = "RENDER_DIAGNOSTICS_MESSAGES"
|
||||
|
||||
val RENDER_DIAGNOSTICS_FULL_TEXT = "RENDER_DIAGNOSTICS_FULL_TEXT"
|
||||
|
||||
val DIAGNOSTIC_IN_TESTDATA_PATTERN = Regex("<!>|<!(.*?(\\(\".*?\"\\)|\\(\\))??)+(?<!<)!>")
|
||||
|
||||
fun parseDiagnosticFilterDirective(
|
||||
@@ -435,12 +437,12 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
||||
if (!matcher.find()) {
|
||||
Assert.fail(
|
||||
"Wrong syntax in the '// !$DIAGNOSTICS_DIRECTIVE: ...' directive:\n" +
|
||||
"found: '$directives'\n" +
|
||||
"Must be '([+-!]DIAGNOSTIC_FACTORY_NAME|ERROR|WARNING|INFO)+'\n" +
|
||||
"where '+' means 'include'\n" +
|
||||
" '-' means 'exclude'\n" +
|
||||
" '!' means 'exclude everything but this'\n" +
|
||||
"directives are applied in the order of appearance, i.e. !FOO +BAR means include only FOO and BAR"
|
||||
"found: '$directives'\n" +
|
||||
"Must be '([+-!]DIAGNOSTIC_FACTORY_NAME|ERROR|WARNING|INFO)+'\n" +
|
||||
"where '+' means 'include'\n" +
|
||||
" '-' means 'exclude'\n" +
|
||||
" '!' means 'exclude everything but this'\n" +
|
||||
"directives are applied in the order of appearance, i.e. !FOO +BAR means include only FOO and BAR"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -461,7 +463,7 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
||||
if (!first) {
|
||||
Assert.fail(
|
||||
"'$operation$name' appears in a position rather than the first one, " +
|
||||
"which effectively cancels all the previous filters in this directive"
|
||||
"which effectively cancels all the previous filters in this directive"
|
||||
)
|
||||
}
|
||||
condition = newCondition
|
||||
|
||||
Reference in New Issue
Block a user