Add classifier usage checker for missing dependency classes
This has no effect for the original use case of mock class descriptors (unresolved classes used in libraries), but is necessary for pre-release classes in case the compiler is a release, because such classes end up in scope and can be the result of the resolution
This commit is contained in:
+3
-1
@@ -69,7 +69,9 @@ object JvmPlatformConfigurator : PlatformConfigurator(
|
||||
JavaTypeAccessibilityChecker()
|
||||
),
|
||||
|
||||
additionalClassifierUsageCheckers = listOf(),
|
||||
additionalClassifierUsageCheckers = listOf(
|
||||
MissingDependencyClassChecker.ClassifierUsage
|
||||
),
|
||||
|
||||
additionalAnnotationCheckers = listOf(
|
||||
RepeatableAnnotationChecker,
|
||||
|
||||
+33
-10
@@ -17,11 +17,14 @@
|
||||
package org.jetbrains.kotlin.resolve.checkers
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.MISSING_DEPENDENCY_CLASS
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.PRE_RELEASE_CLASS
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.isComputingDeferredType
|
||||
@@ -39,22 +42,29 @@ object MissingDependencyClassChecker : CallChecker {
|
||||
}
|
||||
}
|
||||
|
||||
private fun diagnosticFor(descriptor: ClassifierDescriptor, reportOn: PsiElement): Diagnostic? {
|
||||
if (descriptor is NotFoundClasses.MockClassDescriptor) {
|
||||
return MISSING_DEPENDENCY_CLASS.on(reportOn, descriptor.fqNameSafe)
|
||||
}
|
||||
|
||||
val source = descriptor.source
|
||||
if (source is DeserializedContainerSource && source.isPreReleaseInvisible) {
|
||||
// TODO: if at least one PRE_RELEASE_CLASS is reported, display a hint to disable the diagnostic
|
||||
return PRE_RELEASE_CLASS.on(reportOn, descriptor.fqNameSafe)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun collectDiagnostics(reportOn: PsiElement, descriptor: CallableDescriptor): Set<Diagnostic> {
|
||||
val result: MutableSet<Diagnostic> = newLinkedHashSetWithExpectedSize(1)
|
||||
|
||||
fun consider(classDescriptor: ClassDescriptor) {
|
||||
if (classDescriptor is NotFoundClasses.MockClassDescriptor) {
|
||||
result.add(MISSING_DEPENDENCY_CLASS.on(reportOn, classDescriptor.fqNameSafe))
|
||||
val diagnostic = diagnosticFor(classDescriptor, reportOn)
|
||||
if (diagnostic != null) {
|
||||
result.add(diagnostic)
|
||||
return
|
||||
}
|
||||
|
||||
val source = classDescriptor.source
|
||||
if (source is DeserializedContainerSource && source.isPreReleaseInvisible) {
|
||||
// TODO: if at least one PRE_RELEASE_CLASS is reported, display a hint to disable the diagnostic
|
||||
result.add(PRE_RELEASE_CLASS.on(reportOn, classDescriptor.fqNameSafe))
|
||||
return
|
||||
}
|
||||
|
||||
(classDescriptor.containingDeclaration as? ClassDescriptor)?.let(::consider)
|
||||
}
|
||||
|
||||
@@ -70,4 +80,17 @@ object MissingDependencyClassChecker : CallChecker {
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
object ClassifierUsage : ClassifierUsageChecker {
|
||||
override fun check(
|
||||
targetDescriptor: ClassifierDescriptor,
|
||||
trace: BindingTrace,
|
||||
element: PsiElement,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
) {
|
||||
diagnosticFor(targetDescriptor, element)?.let { diagnostic ->
|
||||
trace.report(diagnostic)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
@@ -1,3 +1,6 @@
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibrary/source.kt:5:16: error: class 'a.A' is compiled by a pre-release version of Kotlin and cannot be loaded by this version of the compiler
|
||||
fun baz(param: A) {
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibrary/source.kt:6:23: error: class 'a.A' is compiled by a pre-release version of Kotlin and cannot be loaded by this version of the compiler
|
||||
val constructor = A()
|
||||
^
|
||||
|
||||
Reference in New Issue
Block a user