FIR checker: report JAVA_TYPE_MISMATCH

This commit is contained in:
Tianyu Geng
2021-05-21 12:01:25 -07:00
committed by TeamCityServer
parent eec5f99e35
commit 758859f198
26 changed files with 526 additions and 29 deletions
@@ -10,13 +10,14 @@ import org.jetbrains.kotlin.fir.analysis.CheckersComponentInternal
import org.jetbrains.kotlin.fir.analysis.checkers.*
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.ComposedDeclarationCheckers
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.DeclarationCheckers
import org.jetbrains.kotlin.fir.analysis.checkers.expression.ComposedExpressionCheckers
import org.jetbrains.kotlin.fir.analysis.checkers.expression.ExpressionCheckers
import org.jetbrains.kotlin.fir.analysis.checkers.type.TypeCheckers
import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollector
import org.jetbrains.kotlin.fir.analysis.collectors.components.*
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.jvm.checkers.JvmDeclarationCheckers
import org.jetbrains.kotlin.fir.checkers.*
import org.jetbrains.kotlin.fir.analysis.jvm.checkers.JvmExpressionCheckers
import org.jetbrains.kotlin.fir.moduleData
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.moduleSourceInfo
import org.jetbrains.kotlin.platform.SimplePlatform
@@ -42,7 +43,7 @@ private object CheckersFactory {
val moduleInfo = session.moduleData.moduleSourceInfo
val platform = moduleInfo.platform.componentPlatforms.first()
val declarationCheckers = createDeclarationCheckers(useExtendedCheckers, platform)
val expressionCheckers = createExpressionCheckers(useExtendedCheckers)
val expressionCheckers = createExpressionCheckers(useExtendedCheckers, platform)
val typeCheckers = createTypeCheckers(useExtendedCheckers)
@OptIn(ExperimentalStdlibApi::class)
@@ -71,8 +72,18 @@ private object CheckersFactory {
}
}
private fun createExpressionCheckers(useExtendedCheckers: Boolean): ExpressionCheckers =
if (useExtendedCheckers) ExtendedExpressionCheckers else CommonExpressionCheckers
private fun createExpressionCheckers(useExtendedCheckers: Boolean, platform: SimplePlatform): ExpressionCheckers {
return if (useExtendedCheckers) {
ExtendedExpressionCheckers
} else {
createExpressionCheckers {
add(CommonExpressionCheckers)
when (platform) {
is JvmPlatform -> add(JvmExpressionCheckers)
}
}
}
}
private fun createTypeCheckers(useExtendedCheckers: Boolean): TypeCheckers? =
if (useExtendedCheckers) null else CommonTypeCheckers
@@ -94,4 +105,19 @@ private object CheckersFactory {
}
}
}
@OptIn(ExperimentalStdlibApi::class)
private inline fun createExpressionCheckers(
createExpressionCheckers: MutableList<ExpressionCheckers>.() -> Unit
): ExpressionCheckers = createExpressionCheckers(buildList(createExpressionCheckers))
@OptIn(CheckersComponentInternal::class)
private fun createExpressionCheckers(expressionCheckers: List<ExpressionCheckers>): ExpressionCheckers {
return when (expressionCheckers.size) {
1 -> expressionCheckers.single()
else -> ComposedExpressionCheckers().apply {
expressionCheckers.forEach(::register)
}
}
}
}
@@ -21658,12 +21658,30 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("deepTypeHierarchy.kt")
public void testDeepTypeHierarchy() throws Exception {
runTest("compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/deepTypeHierarchy.kt");
}
@Test
@TestMetadata("inferenceFrom.kt")
public void testInferenceFrom() throws Exception {
runTest("compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/inferenceFrom.kt");
}
@Test
@TestMetadata("javaOutProjection.kt")
public void testJavaOutProjection() throws Exception {
runTest("compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/javaOutProjection.kt");
}
@Test
@TestMetadata("kotlinOutProjection.kt")
public void testKotlinOutProjection() throws Exception {
runTest("compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/kotlinOutProjection.kt");
}
@Test
@TestMetadata("listSuperType.kt")
public void testListSuperType() throws Exception {
@@ -3314,6 +3314,14 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.JAVA_TYPE_MISMATCH) { firDiagnostic ->
JavaTypeMismatchImpl(
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b),
firDiagnostic as FirPsiDiagnostic,
token,
)
}
add(FirJvmErrors.CONFLICTING_JVM_DECLARATIONS) { firDiagnostic ->
ConflictingJvmDeclarationsImpl(
firDiagnostic as FirPsiDiagnostic,
@@ -2311,6 +2311,12 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
override val diagnosticClass get() = ReturnForBuiltInSuspend::class
}
abstract class JavaTypeMismatch : KtFirDiagnostic<KtExpression>() {
override val diagnosticClass get() = JavaTypeMismatch::class
abstract val expectedType: KtType
abstract val actualType: KtType
}
abstract class ConflictingJvmDeclarations : KtFirDiagnostic<PsiElement>() {
override val diagnosticClass get() = ConflictingJvmDeclarations::class
}
@@ -3737,6 +3737,15 @@ internal class ReturnForBuiltInSuspendImpl(
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
}
internal class JavaTypeMismatchImpl(
override val expectedType: KtType,
override val actualType: KtType,
firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken,
) : KtFirDiagnostic.JavaTypeMismatch(), KtAbstractFirDiagnostic<KtExpression> {
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
}
internal class ConflictingJvmDeclarationsImpl(
firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken,