Refactor and simplify PlatformHeaderAnnotator
This commit is contained in:
+18
-33
@@ -23,8 +23,6 @@ import org.jetbrains.kotlin.analyzer.ModuleInfo
|
|||||||
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
|
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
|
||||||
import org.jetbrains.kotlin.descriptors.MemberDescriptor
|
import org.jetbrains.kotlin.descriptors.MemberDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.ModuleProductionSourceInfo
|
import org.jetbrains.kotlin.idea.caches.resolve.ModuleProductionSourceInfo
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.ModuleTestSourceInfo
|
import org.jetbrains.kotlin.idea.caches.resolve.ModuleTestSourceInfo
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
|
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
|
||||||
@@ -32,6 +30,7 @@ import org.jetbrains.kotlin.idea.core.toDescriptor
|
|||||||
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingTraceContext
|
||||||
import org.jetbrains.kotlin.resolve.TargetPlatform
|
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||||
import org.jetbrains.kotlin.resolve.checkers.HeaderImplDeclarationChecker
|
import org.jetbrains.kotlin.resolve.checkers.HeaderImplDeclarationChecker
|
||||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
||||||
@@ -47,50 +46,36 @@ val ModuleDescriptor.sourceKind: SourceKind
|
|||||||
enum class SourceKind { OTHER, PRODUCTION, TEST }
|
enum class SourceKind { OTHER, PRODUCTION, TEST }
|
||||||
|
|
||||||
val ModuleDescriptor.allImplementingCompatibleModules
|
val ModuleDescriptor.allImplementingCompatibleModules
|
||||||
get() = allImplementingModules.filter {
|
get() = allImplementingModules.filter { other ->
|
||||||
sourceKind == SourceKind.OTHER ||
|
this.sourceKind == SourceKind.OTHER ||
|
||||||
it.sourceKind == SourceKind.OTHER ||
|
other.sourceKind == SourceKind.OTHER ||
|
||||||
it.sourceKind == sourceKind
|
other.sourceKind == this.sourceKind
|
||||||
}
|
}
|
||||||
|
|
||||||
class PlatformHeaderAnnotator : Annotator {
|
class PlatformHeaderAnnotator : Annotator {
|
||||||
|
|
||||||
override fun annotate(element: PsiElement, holder: AnnotationHolder) {
|
override fun annotate(element: PsiElement, holder: AnnotationHolder) {
|
||||||
val declaration = element as? KtDeclaration ?: return
|
val declaration = element as? KtDeclaration ?: return
|
||||||
if (!declaration.hasModifier(KtTokens.HEADER_KEYWORD)) return
|
if (!declaration.hasModifier(KtTokens.HEADER_KEYWORD)) return
|
||||||
|
|
||||||
if (TargetPlatformDetector.getPlatform(declaration.containingKtFile) !is TargetPlatform.Default) return
|
if (TargetPlatformDetector.getPlatform(declaration.containingKtFile) !is TargetPlatform.Default) return
|
||||||
|
|
||||||
val defaultModuleDescriptor = declaration.findModuleDescriptor()
|
val implementingModules = declaration.findModuleDescriptor().allImplementingCompatibleModules
|
||||||
val dependentDescriptors = defaultModuleDescriptor.allImplementingCompatibleModules
|
if (implementingModules.isEmpty()) return
|
||||||
if (dependentDescriptors.isEmpty()) return
|
|
||||||
|
|
||||||
val diagnostics = validate(declaration, dependentDescriptors)
|
val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return
|
||||||
KotlinPsiChecker().annotateElement(declaration, holder, diagnostics)
|
if (!descriptor.isHeader) return
|
||||||
}
|
|
||||||
|
|
||||||
fun validate(declaration: KtDeclaration, modulesToCheck: Collection<ModuleDescriptor>): Diagnostics {
|
val trace = BindingTraceContext()
|
||||||
val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return Diagnostics.EMPTY
|
for (module in implementingModules) {
|
||||||
if (!descriptor.isHeader) return Diagnostics.EMPTY
|
HeaderImplDeclarationChecker.checkHeaderDeclarationHasImplementation(declaration, descriptor, trace, module, checkImpl = false)
|
||||||
|
|
||||||
val diagnosticList = mutableListOf<Diagnostic>()
|
|
||||||
val diagnosticSink = object : DiagnosticSink {
|
|
||||||
override fun report(diagnostic: Diagnostic) {
|
|
||||||
diagnosticList += diagnostic
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun wantsDiagnostics() = true
|
|
||||||
}
|
|
||||||
for (module in modulesToCheck) {
|
|
||||||
HeaderImplDeclarationChecker.checkHeaderDeclarationHasImplementation(
|
|
||||||
declaration, descriptor, diagnosticSink, module, checkImpl = false
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val suppressionCache = KotlinCacheService.getInstance(declaration.project).getSuppressionCache()
|
val suppressionCache = KotlinCacheService.getInstance(declaration.project).getSuppressionCache()
|
||||||
val filteredList = diagnosticList.filter {
|
val filteredList = trace.bindingContext.diagnostics.filter { diagnostic ->
|
||||||
!suppressionCache.isSuppressed(declaration, it.factory.name, it.severity)
|
!suppressionCache.isSuppressed(declaration, diagnostic.factory.name, diagnostic.severity)
|
||||||
}
|
}
|
||||||
return if (filteredList.isNotEmpty()) SimpleDiagnostics(filteredList) else Diagnostics.EMPTY
|
if (filteredList.isEmpty()) return
|
||||||
|
|
||||||
|
KotlinPsiChecker().annotateElement(declaration, holder, SimpleDiagnostics(filteredList))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user