诊断测试是 Kotlin 编译器测试基础设施的关键组成部分,旨在验证编译器是否能正确识别和报告错误、警告和其他诊断消息。本文档介绍了诊断测试框架、诊断测试的组织和执行方式,以及它们如何帮助确保编译器的前端组件正常工作。
有关验证编译器后端正确性的代码生成测试,请参阅代码生成测试。
诊断测试可验证编译器在分析 Kotlin 代码时检测错误并生成适当诊断消息的能力。这些测试确保:
诊断测试框架同时支持经典的 Kotlin 编译器前端 (K1) 和新的前端 IR (FIR) 实现,以及各种解析器实现 (PSI 和 Light Tree)。
来源:compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java18-25 compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsWithLatestLanguageVersionTestGenerated.java18-25 compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/PhasedJvmDiagnosticPsiTestGenerated.java18-25
诊断测试系统由几个关键组件组成:
来源:compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsWithLatestLanguageVersionTestGenerated.java compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/PhasedJvmDiagnosticPsiTestGenerated.java analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLDiagnosticsFirTestGenerated.java compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithLightTreeWithLatestLanguageVersionTestGenerated.java
诊断测试由测试生成器自动生成,该生成器:
生成的测试类继承自提供核心测试功能的抽象基类。
当诊断测试执行时,它会经历以下阶段:
Kotlin 编译器测试基础设施包含几种不同实现细节的诊断测试:
这种测试类型矩阵会产生特定的测试运行器,例如:
| 测试类型 | 目的 |
|---|---|
DiagnosticTest | 使用 K1 前端的基础诊断测试 |
FirLightTreeDiagnosticsTest | 使用 FIR 和 Light Tree 表示的测试 |
PhasedJvmDiagnosticPsiTest | 使用 PSI 的分阶段诊断 |
LLDiagnosticsFirTest | 使用 FIR 的低级 API 诊断 |
FirOldFrontendMPPDiagnosticsWithLightTree | 使用 FIR 和 Light Tree 的多平台项目测试 |
来源:compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsWithLatestLanguageVersionTestGenerated.java analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLDiagnosticsFe10TestGenerated.java
诊断测试文件是带有注释中特殊指令的 Kotlin 源代码文件。这些文件位于 /compiler/testData/diagnostics/tests/ 目录及其子目录中。
典型的诊断测试文件结构如下:
| 指令 | 目的 |
|---|---|
RUN_PIPELINE_TILL | 指定要运行的编译器阶段(例如,FRONTEND) |
DIAGNOSTICS | 启用 (+) 或禁用 (-) 特定诊断检查 |
LANGUAGE | 启用 (+) 或禁用 (-) 特定语言功能 |
WITH_EXTRA_CHECKERS | 启用额外的诊断检查器 |
FILE | 在多文件测试中定义一个文件 |
TARGET_BACKEND | 为代码生成测试指定目标后端 |
预期诊断使用 <!DIAGNOSTIC_TYPE!> 语法在测试文件中进行内联标记。
对于需要检查同一代码片段的多个诊断的测试,它们可以用逗号分隔。
来源:compiler/testData/diagnostics/tests/inline/exposingPrivateTypeInInternal.fir.kt1-14 compiler/testData/diagnostics/tests/inline/exposingPrivateTypeInPublic.fir.kt1-14
诊断测试按功能领域和语言结构组织在 /compiler/testData/diagnostics/tests/ 目录中。这种结构有助于查找相关测试并确保全面覆盖。
测试文件遵循指示其用途的命名约定:
Casts.kt、DiamondFunction.kt)kt41984.kt)invalidAnnotation.kt)对于特定于 FIR 的变体,测试文件可能具有 .fir.kt 扩展名以指示特定于 FIR 的行为。
诊断测试系统与 JUnit 测试框架集成,允许使用标准的测试运行器执行测试。
可以通过以下方式直接从 IDE 运行诊断测试:
DiagnosticTestGenerated)在开发新语言功能或修复 bug 时,添加新的诊断测试对于验证编译器行为至关重要。
/compiler/testData/diagnostics/tests/ 的适当子目录中创建新的 .kt 文件。<!DIAGNOSTIC_TYPE!> 语法标记预期诊断。来源:compiler/testData/diagnostics/tests/inline/exposingPrivateTypeInInternal.fir.kt compiler/testData/diagnostics/tests/inline/exposingPrivateTypeInPublic.fir.kt
诊断测试系统与 Kotlin 编译器的诊断基础设施紧密集成。
这种集成确保诊断测试能够准确地反映编译器的行为,同时在测试和生产环境中使用相同的诊断基础设施。
来源:compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsWithLatestLanguageVersionTestGenerated.java
诊断测试系统是 Kotlin 编译器质量保证基础设施的关键组成部分。它确保:
通过维护一套全面的诊断测试,Kotlin 团队可以自信地发展语言,同时确保编译器保持可靠和用户友好。