!RENDER_DIAGNOSTICS_FULL_TEXT directive
Compares diagnostics rendered as text with corresponding .diag.txt file
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.cli.common.messages;
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.utils.fileUtils.FileUtilsKt;
|
||||
@@ -69,6 +70,23 @@ public interface MessageRenderer {
|
||||
}
|
||||
};
|
||||
|
||||
MessageRenderer SYSTEM_INDEPENDENT_RELATIVE_PATHS = new PlainTextMessageRenderer() {
|
||||
private final File cwd = new File(".").getAbsoluteFile();
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected String getPath(@NotNull CompilerMessageLocation location) {
|
||||
return FileUtil.toSystemIndependentName(
|
||||
FileUtilsKt.descendantRelativeTo(new File(location.getPath()), cwd).getPath()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "SystemIndependentRelativePath";
|
||||
}
|
||||
};
|
||||
|
||||
MessageRenderer GRADLE_STYLE = new GradleStyleMessageRenderer();
|
||||
|
||||
String renderPreamble();
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
/inlineCycle.kt:8:5: error: the 'inlineFun2' invocation is a part of inline cycle
|
||||
inlineFun2(p)
|
||||
^
|
||||
/inlineCycle.kt:13:5: error: the 'inlineFun1' invocation is a part of inline cycle
|
||||
inlineFun1(p)
|
||||
^
|
||||
@@ -1,3 +1,5 @@
|
||||
// !RENDER_DIAGNOSTICS_FULL_TEXT
|
||||
|
||||
inline fun inlineFun1(p: () -> Unit) {
|
||||
p()
|
||||
<!INLINE_CALL_CYCLE, INLINE_CALL_CYCLE!>inlineFun2(p)<!>
|
||||
|
||||
+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
|
||||
|
||||
@@ -59,7 +59,7 @@ import org.jetbrains.kotlin.types.AbstractTypeBindingTest
|
||||
import org.jetbrains.kotlin.visualizer.fir.AbstractFirVisualizer
|
||||
import org.jetbrains.kotlin.visualizer.psi.AbstractPsiVisualizer
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
fun main() {
|
||||
System.setProperty("java.awt.headless", "true")
|
||||
|
||||
val excludedFirTestdataPattern = "^(.+)\\.fir\\.kts?\$"
|
||||
@@ -127,11 +127,11 @@ fun main(args: Array<String>) {
|
||||
}
|
||||
|
||||
testClass<AbstractDiagnosticsTestWithOldJvmBackend> {
|
||||
model("diagnostics/testsWithJvmBackend")
|
||||
model("diagnostics/testsWithJvmBackend", targetBackend = TargetBackend.JVM)
|
||||
}
|
||||
|
||||
testClass<AbstractDiagnosticsTestWithJvmIrBackend> {
|
||||
model("diagnostics/testsWithJvmBackend")
|
||||
model("diagnostics/testsWithJvmBackend", targetBackend = TargetBackend.JVM_IR)
|
||||
}
|
||||
|
||||
testClass<AbstractMultiPlatformIntegrationTest> {
|
||||
|
||||
Reference in New Issue
Block a user