Refactor and simplify PlatformHeaderAnnotator

This commit is contained in:
Alexander Udalov
2017-07-21 15:36:42 +03:00
parent 59c49675b0
commit 6cb4916dee
@@ -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))
} }
} }