Use highlight visitor instead of custom general like highlighting pass
#KTIJ-1760 Fixed #KT-45254 Fixed
This commit is contained in:
committed by
Space
parent
5e173c9f83
commit
cb92474af9
+126
-97
@@ -1,64 +1,66 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.highlighter
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.Divider
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightVisitor
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightInfoHolder
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.codeInsight.problems.ProblemImpl
|
||||
import com.intellij.lang.annotation.Annotation
|
||||
import com.intellij.lang.annotation.AnnotationHolder
|
||||
import com.intellij.lang.annotation.Annotator
|
||||
import com.intellij.lang.annotation.HighlightSeverity
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.editor.Document
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.problems.Problem
|
||||
import com.intellij.problems.WolfTheProblemSolver
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiRecursiveElementVisitor
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.util.CommonProcessors
|
||||
import com.intellij.util.containers.MultiMap
|
||||
import org.jetbrains.kotlin.asJava.getJvmSignatureDiagnostics
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.RenderingContext
|
||||
import org.jetbrains.kotlin.idea.caches.project.getModuleInfo
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithAllCompilerChecks
|
||||
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||
import org.jetbrains.kotlin.idea.quickfix.QuickFixes
|
||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import java.lang.reflect.*
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
abstract class AbstractKotlinHighlightingPass(file: KtFile, document: Document) :
|
||||
AbstractBindingContextAwareHighlightingPassBase(file, document) {
|
||||
override val annotator: Annotator
|
||||
get() = KotlinAfterAnalysisAnnotator()
|
||||
abstract class AbstractKotlinHighlightVisitor : HighlightVisitor {
|
||||
private var afterAnalysisVisitor: Array<AfterAnalysisHighlightingVisitor>? = null
|
||||
|
||||
private inner class KotlinAfterAnalysisAnnotator : Annotator {
|
||||
override fun annotate(element: PsiElement, holder: AnnotationHolder) {
|
||||
val bindingContext = bindingContext()
|
||||
getAfterAnalysisVisitor(holder, bindingContext).forEach { visitor -> element.accept(visitor) }
|
||||
override fun suitableForFile(file: PsiFile) = file is KtFile
|
||||
|
||||
override fun visit(element: PsiElement) {
|
||||
afterAnalysisVisitor?.forEach(element::accept)
|
||||
}
|
||||
|
||||
override fun analyze(psiFile: PsiFile, updateWholeFile: Boolean, holder: HighlightInfoHolder, action: Runnable): Boolean {
|
||||
val file = psiFile as? KtFile ?: return false
|
||||
|
||||
try {
|
||||
analyze(file, holder)
|
||||
|
||||
action.run()
|
||||
} finally {
|
||||
afterAnalysisVisitor = null
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun doApplyInformationToEditor() {
|
||||
super.doApplyInformationToEditor()
|
||||
|
||||
reportErrorsToWolf()
|
||||
}
|
||||
|
||||
override fun buildBindingContext(holder: AnnotationHolder): BindingContext {
|
||||
private fun analyze(file: KtFile, holder: HighlightInfoHolder) {
|
||||
val dividedElements: List<Divider.DividedElements> = ArrayList()
|
||||
Divider.divideInsideAndOutsideAllRoots(
|
||||
file, file.textRange, file.textRange, { true },
|
||||
@@ -71,8 +73,8 @@ abstract class AbstractKotlinHighlightingPass(file: KtFile, document: Document)
|
||||
|
||||
// annotate diagnostics on fly: show diagnostics as soon as front-end reports them
|
||||
// don't create quick fixes as it could require some resolve
|
||||
val annotationByDiagnostic = mutableMapOf<Diagnostic, Annotation>()
|
||||
val annotationByTextRange = mutableMapOf<TextRange, Annotation>()
|
||||
val highlightInfoByDiagnostic = mutableMapOf<Diagnostic, HighlightInfo>()
|
||||
val highlightInfoByTextRange = mutableMapOf<TextRange, HighlightInfo>()
|
||||
|
||||
// render of on-fly diagnostics with descriptors could lead to recursion
|
||||
fun checkIfDescriptor(candidate: Any?): Boolean =
|
||||
@@ -82,61 +84,84 @@ abstract class AbstractKotlinHighlightingPass(file: KtFile, document: Document)
|
||||
file.analyzeWithAllCompilerChecks({
|
||||
val element = it.psiElement
|
||||
if (element in elements &&
|
||||
it !in annotationByDiagnostic &&
|
||||
it !in highlightInfoByDiagnostic &&
|
||||
!RenderingContext.parameters(it).any(::checkIfDescriptor)
|
||||
) {
|
||||
annotateDiagnostic(element, holder, it, annotationByDiagnostic, annotationByTextRange)
|
||||
annotateDiagnostic(
|
||||
file,
|
||||
element,
|
||||
holder,
|
||||
it,
|
||||
highlightInfoByDiagnostic,
|
||||
highlightInfoByTextRange
|
||||
)
|
||||
}
|
||||
}).also { it.throwIfError() }
|
||||
}
|
||||
).also { it.throwIfError() }
|
||||
// resolve is done!
|
||||
|
||||
val bindingContext = analysisResult.bindingContext
|
||||
|
||||
cleanUpCalculatingAnnotations(annotationByTextRange)
|
||||
// TODO: for some reasons it could be duplicated diagnostics for the same factory
|
||||
// see [PsiCheckerTestGenerated$Checker.testRedeclaration]
|
||||
val diagnostics = bindingContext.diagnostics.asSequence().filter { it.psiElement in elements }.toSet()
|
||||
afterAnalysisVisitor = getAfterAnalysisVisitor(holder, bindingContext)
|
||||
|
||||
if (diagnostics.isNotEmpty()) {
|
||||
// annotate diagnostics those were not possible to render on fly
|
||||
diagnostics.asSequence().filterNot { it in annotationByDiagnostic }.forEach {
|
||||
annotateDiagnostic(it.psiElement, holder, it, annotationByDiagnostic, calculatingInProgress = false)
|
||||
}
|
||||
// apply quick fixes for all diagnostics grouping by element
|
||||
diagnostics.groupBy(Diagnostic::psiElement).forEach {
|
||||
annotateQuickFixes(it.key, it.value, annotationByDiagnostic)
|
||||
}
|
||||
cleanUpCalculatingAnnotations(highlightInfoByTextRange)
|
||||
|
||||
annotateDuplicateJvmSignature(file, holder, bindingContext.diagnostics)
|
||||
|
||||
for (diagnostic in bindingContext.diagnostics) {
|
||||
val psiElement = diagnostic.psiElement
|
||||
if (psiElement !in elements) continue
|
||||
// has been processed earlier e.g. on-fly or for some reasons it could be duplicated diagnostics for the same factory
|
||||
// see [PsiCheckerTestGenerated$Checker.testRedeclaration]
|
||||
if (diagnostic in highlightInfoByDiagnostic) continue
|
||||
|
||||
// annotate diagnostics those were not possible to report (and therefore render) on fly
|
||||
annotateDiagnostic(file, psiElement, holder, diagnostic, highlightInfoByDiagnostic, calculatingInProgress = false)
|
||||
}
|
||||
return bindingContext
|
||||
|
||||
// apply quick fixes for all diagnostics grouping by element
|
||||
highlightInfoByDiagnostic.keys.groupBy { it.psiElement }.forEach {
|
||||
annotateQuickFixes(file, it.key, it.value, highlightInfoByDiagnostic)
|
||||
}
|
||||
}
|
||||
|
||||
private fun annotateDuplicateJvmSignature(file: KtFile, holder: HighlightInfoHolder, otherDiagnostics: Diagnostics) {
|
||||
if (!(ProjectRootsUtil.isInProjectSource(file) && TargetPlatformDetector.getPlatform(file).isJvm())) return
|
||||
|
||||
val duplicateJvmSignatureAnnotator =
|
||||
DuplicateJvmSignatureAnnotator(file, holder, otherDiagnostics, file.getModuleInfo().contentScope())
|
||||
duplicateJvmSignatureAnnotator.visit()
|
||||
}
|
||||
|
||||
private fun annotateDiagnostic(
|
||||
file: KtFile,
|
||||
element: PsiElement,
|
||||
holder: AnnotationHolder,
|
||||
holder: HighlightInfoHolder,
|
||||
diagnostic: Diagnostic,
|
||||
annotationByDiagnostic: MutableMap<Diagnostic, Annotation>? = null,
|
||||
annotationByTextRange: MutableMap<TextRange, Annotation>? = null,
|
||||
highlightInfoByDiagnostic: MutableMap<Diagnostic, HighlightInfo>? = null,
|
||||
highlightInfoByTextRange: MutableMap<TextRange, HighlightInfo>? = null,
|
||||
calculatingInProgress: Boolean = true
|
||||
) = annotateDiagnostics(element, holder, listOf(diagnostic), annotationByDiagnostic, annotationByTextRange, true, calculatingInProgress)
|
||||
) = annotateDiagnostics(file, element, holder, listOf(diagnostic), highlightInfoByDiagnostic, highlightInfoByTextRange, true, calculatingInProgress)
|
||||
|
||||
private fun cleanUpCalculatingAnnotations(annotationByTextRange: Map<TextRange, Annotation>) {
|
||||
annotationByTextRange.values.forEach { annotation ->
|
||||
annotation.quickFixes?.removeIf {
|
||||
it.quickFix is CalculatingIntentionAction
|
||||
private fun cleanUpCalculatingAnnotations(highlightInfoByTextRange: Map<TextRange, HighlightInfo>) {
|
||||
highlightInfoByTextRange.values.forEach { annotation ->
|
||||
annotation.unregisterQuickFix {
|
||||
it is CalculatingIntentionAction
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun annotateDiagnostics(
|
||||
file: KtFile,
|
||||
element: PsiElement,
|
||||
holder: AnnotationHolder,
|
||||
holder: HighlightInfoHolder,
|
||||
diagnostics: List<Diagnostic>,
|
||||
annotationByDiagnostic: MutableMap<Diagnostic, Annotation>? = null,
|
||||
annotationByTextRange: MutableMap<TextRange, Annotation>? = null,
|
||||
highlightInfoByDiagnostic: MutableMap<Diagnostic, HighlightInfo>? = null,
|
||||
highlightInfoByTextRange: MutableMap<TextRange, HighlightInfo>? = null,
|
||||
noFixes: Boolean = false,
|
||||
calculatingInProgress: Boolean = false
|
||||
) = annotateDiagnostics(
|
||||
file, element, holder, diagnostics, annotationByDiagnostic, annotationByTextRange,
|
||||
file, element, holder, diagnostics, highlightInfoByDiagnostic, highlightInfoByTextRange,
|
||||
::shouldSuppressUnusedParameter,
|
||||
noFixes = noFixes, calculatingInProgress = calculatingInProgress
|
||||
)
|
||||
@@ -145,9 +170,10 @@ abstract class AbstractKotlinHighlightingPass(file: KtFile, document: Document)
|
||||
* [diagnostics] has to belong to the same element
|
||||
*/
|
||||
private fun annotateQuickFixes(
|
||||
file: KtFile,
|
||||
element: PsiElement,
|
||||
diagnostics: List<Diagnostic>,
|
||||
annotationByDiagnostic: MutableMap<Diagnostic, Annotation>
|
||||
highlightInfoByDiagnostic: MutableMap<Diagnostic, HighlightInfo>
|
||||
) {
|
||||
if (diagnostics.isEmpty()) return
|
||||
|
||||
@@ -161,63 +187,64 @@ abstract class AbstractKotlinHighlightingPass(file: KtFile, document: Document)
|
||||
if (shouldHighlightErrors) {
|
||||
ElementAnnotator(element) { param ->
|
||||
shouldSuppressUnusedParameter(param)
|
||||
}.registerDiagnosticsQuickFixes(diagnostics, annotationByDiagnostic)
|
||||
}.registerDiagnosticsQuickFixes(diagnostics, highlightInfoByDiagnostic)
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun shouldSuppressUnusedParameter(parameter: KtParameter): Boolean = false
|
||||
|
||||
private fun reportErrorsToWolf() {
|
||||
if (!file.viewProvider.isPhysical) return // e.g. errors in evaluate expression
|
||||
val project: Project = file.project
|
||||
if (!PsiManager.getInstance(project).isInProject(file)) return // do not report problems in libraries
|
||||
val file: VirtualFile = file.virtualFile ?: return
|
||||
private inner class DuplicateJvmSignatureAnnotator(
|
||||
private val file: KtFile,
|
||||
private val holder: HighlightInfoHolder,
|
||||
private val otherDiagnostics: Diagnostics,
|
||||
private val moduleScope: GlobalSearchScope
|
||||
) {
|
||||
fun visit() {
|
||||
file.accept(object : PsiRecursiveElementVisitor() {
|
||||
override fun visitElement(element: PsiElement) {
|
||||
annotate(element)
|
||||
super.visitElement(element)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
val wolf = WolfTheProblemSolver.getInstance(project)
|
||||
private fun annotate(element: PsiElement) {
|
||||
if (element !is KtFile && element !is KtDeclaration) return
|
||||
|
||||
val hasSyntaxErrors = wolf.hasSyntaxErrors(file)
|
||||
val problemFile = wolf.isProblemFile(file)
|
||||
val diagnostics = getJvmSignatureDiagnostics(element, otherDiagnostics, moduleScope) ?: return
|
||||
|
||||
// do nothing if file has already problems
|
||||
if (hasSyntaxErrors || problemFile) return
|
||||
val diagnosticsForElement = diagnostics.forElement(element).toSet()
|
||||
|
||||
val problems = convertToProblems(infos, file)
|
||||
wolf.reportProblems(file, problems)
|
||||
annotateDiagnostics(file, element, holder, diagnosticsForElement)
|
||||
}
|
||||
}
|
||||
|
||||
private fun convertToProblems(
|
||||
infos: Collection<HighlightInfo>,
|
||||
file: VirtualFile,
|
||||
hasErrorElement: Boolean = true
|
||||
): List<Problem> =
|
||||
infos.filter { it.severity == HighlightSeverity.ERROR }.map { ProblemImpl(file, it, hasErrorElement) }
|
||||
|
||||
companion object {
|
||||
fun createQuickFixes(diagnostic: Diagnostic): Collection<IntentionAction> =
|
||||
createQuickFixes(listOfNotNull(diagnostic))[diagnostic]
|
||||
private val UNRESOLVED_KEY = Key<Unit>("KotlinHighlightVisitor.UNRESOLVED_KEY")
|
||||
|
||||
private val UNRESOLVED_KEY = Key<Unit>("KotlinHighlightingPass.UNRESOLVED_KEY")
|
||||
|
||||
fun wasUnresolved(element: KtNameReferenceExpression) = element.getUserData(UNRESOLVED_KEY) != null
|
||||
|
||||
fun getAfterAnalysisVisitor(holder: AnnotationHolder, bindingContext: BindingContext) = arrayOf(
|
||||
fun getAfterAnalysisVisitor(holder: HighlightInfoHolder, bindingContext: BindingContext) = arrayOf(
|
||||
PropertiesHighlightingVisitor(holder, bindingContext),
|
||||
FunctionsHighlightingVisitor(holder, bindingContext),
|
||||
VariablesHighlightingVisitor(holder, bindingContext),
|
||||
TypeKindHighlightingVisitor(holder, bindingContext)
|
||||
)
|
||||
|
||||
private fun assertBelongsToTheSameElement(element: PsiElement, diagnostics: Collection<Diagnostic>) {
|
||||
fun createQuickFixes(diagnostic: Diagnostic): Collection<IntentionAction> =
|
||||
createQuickFixes(listOfNotNull(diagnostic))[diagnostic]
|
||||
|
||||
fun wasUnresolved(element: KtNameReferenceExpression) = element.getUserData(UNRESOLVED_KEY) != null
|
||||
|
||||
internal fun assertBelongsToTheSameElement(element: PsiElement, diagnostics: Collection<Diagnostic>) {
|
||||
assert(diagnostics.all { it.psiElement == element })
|
||||
}
|
||||
|
||||
fun annotateDiagnostics(
|
||||
file: KtFile,
|
||||
element: PsiElement,
|
||||
holder: AnnotationHolder,
|
||||
holder: HighlightInfoHolder,
|
||||
diagnostics: Collection<Diagnostic>,
|
||||
annotationByDiagnostic: MutableMap<Diagnostic, Annotation>? = null,
|
||||
annotationByTextRange: MutableMap<TextRange, Annotation>? = null,
|
||||
highlightInfoByDiagnostic: MutableMap<Diagnostic, HighlightInfo>? = null,
|
||||
highlightInfoByTextRange: MutableMap<TextRange, HighlightInfo>? = null,
|
||||
shouldSuppressUnusedParameter: (KtParameter) -> Boolean = { false },
|
||||
noFixes: Boolean = false,
|
||||
calculatingInProgress: Boolean = false
|
||||
@@ -241,16 +268,16 @@ abstract class AbstractKotlinHighlightingPass(file: KtFile, document: Document)
|
||||
shouldSuppressUnusedParameter(param)
|
||||
}
|
||||
elementAnnotator.registerDiagnosticsAnnotations(
|
||||
holder, diagnostics, annotationByDiagnostic,
|
||||
annotationByTextRange,
|
||||
holder, diagnostics, highlightInfoByDiagnostic,
|
||||
highlightInfoByTextRange,
|
||||
noFixes = noFixes, calculatingInProgress = calculatingInProgress
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal fun createQuickFixes(similarDiagnostics: Collection<Diagnostic>): MultiMap<Diagnostic, IntentionAction> {
|
||||
val first = similarDiagnostics.minByOrNull { it.toString() }
|
||||
val factory = similarDiagnostics.first().getRealDiagnosticFactory()
|
||||
@@ -278,6 +305,7 @@ internal fun createQuickFixes(similarDiagnostics: Collection<Diagnostic>): Multi
|
||||
return actions
|
||||
}
|
||||
|
||||
|
||||
private fun Diagnostic.getRealDiagnosticFactory(): DiagnosticFactory<*> =
|
||||
when (factory) {
|
||||
Errors.PLUGIN_ERROR -> Errors.PLUGIN_ERROR.cast(this).a.factory
|
||||
@@ -330,3 +358,4 @@ private object NoDeclarationDescriptorsChecker {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -16,7 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.highlighter
|
||||
|
||||
import com.intellij.lang.annotation.AnnotationHolder
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightInfoHolder
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
import com.intellij.psi.PsiElement
|
||||
@@ -28,8 +28,8 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||
|
||||
abstract class AfterAnalysisHighlightingVisitor protected constructor(
|
||||
holder: AnnotationHolder, protected var bindingContext: BindingContext
|
||||
) : HighlightingVisitor(holder) {
|
||||
holder: HighlightInfoHolder, protected var bindingContext: BindingContext
|
||||
) : AbstractHighlightInfoHolderHighlightingVisitor(holder) {
|
||||
|
||||
protected fun attributeKeyForDeclarationFromExtensions(element: PsiElement, descriptor: DeclarationDescriptor): TextAttributesKey? {
|
||||
@Suppress("DEPRECATION")
|
||||
|
||||
+65
-43
@@ -5,12 +5,14 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.highlighter
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfoType
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightInfoHolder
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction
|
||||
import com.intellij.codeInsight.intention.EmptyIntentionAction
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.codeInspection.ProblemHighlightType
|
||||
import com.intellij.lang.annotation.Annotation
|
||||
import com.intellij.lang.annotation.AnnotationHolder
|
||||
import com.intellij.lang.annotation.HighlightSeverity
|
||||
import com.intellij.openapi.editor.colors.CodeInsightColors
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.util.containers.MultiMap
|
||||
@@ -30,23 +32,24 @@ class AnnotationPresentationInfo(
|
||||
) {
|
||||
|
||||
fun processDiagnostics(
|
||||
holder: AnnotationHolder,
|
||||
holder: HighlightInfoHolder,
|
||||
diagnostics: Collection<Diagnostic>,
|
||||
annotationBuilderByDiagnostic: MutableMap<Diagnostic, Annotation>? = null,
|
||||
annotationByTextRange: MutableMap<TextRange, Annotation>?,
|
||||
highlightInfoBuilderByDiagnostic: MutableMap<Diagnostic, HighlightInfo>? = null,
|
||||
highlightInfoByTextRange: MutableMap<TextRange, HighlightInfo>?,
|
||||
fixesMap: MultiMap<Diagnostic, IntentionAction>?,
|
||||
calculatingInProgress: Boolean
|
||||
) {
|
||||
for (range in ranges) {
|
||||
for (diagnostic in diagnostics) {
|
||||
create(diagnostic, range, holder) { annotation ->
|
||||
annotationBuilderByDiagnostic?.put(diagnostic, annotation)
|
||||
create(diagnostic, range) { info ->
|
||||
holder.add(info)
|
||||
highlightInfoBuilderByDiagnostic?.put(diagnostic, info)
|
||||
if (fixesMap != null) {
|
||||
applyFixes(fixesMap, diagnostic, annotation)
|
||||
applyFixes(fixesMap, diagnostic, info)
|
||||
}
|
||||
if (calculatingInProgress && annotationByTextRange?.containsKey(range) == false) {
|
||||
annotationByTextRange[range] = annotation
|
||||
annotation.registerFix(CalculatingIntentionAction(), range)
|
||||
if (calculatingInProgress && highlightInfoByTextRange?.containsKey(range) == false) {
|
||||
highlightInfoByTextRange[range] = info
|
||||
QuickFixAction.registerQuickFixAction(info, CalculatingIntentionAction())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,55 +59,36 @@ class AnnotationPresentationInfo(
|
||||
internal fun applyFixes(
|
||||
fixesMap: MultiMap<Diagnostic, IntentionAction>,
|
||||
diagnostic: Diagnostic,
|
||||
annotation: Annotation
|
||||
info: HighlightInfo
|
||||
) {
|
||||
val fixes = fixesMap[diagnostic]
|
||||
val textRange = TextRange(annotation.startOffset, annotation.endOffset)
|
||||
fixes.forEach {
|
||||
when (it) {
|
||||
is KotlinUniversalQuickFix -> {
|
||||
annotation.registerBatchFix(it, textRange, null)
|
||||
annotation.registerFix(it, textRange)
|
||||
}
|
||||
is IntentionAction -> {
|
||||
annotation.registerFix(it, textRange)
|
||||
}
|
||||
}
|
||||
fixes.filter { it is IntentionAction || it is KotlinUniversalQuickFix }.forEach {
|
||||
QuickFixAction.registerQuickFixAction(info, it)
|
||||
}
|
||||
|
||||
if (diagnostic.severity == Severity.WARNING) {
|
||||
if (fixes.isEmpty()) {
|
||||
// if there are no quick fixes we need to register an EmptyIntentionAction to enable 'suppress' actions
|
||||
//annotation.newFix(EmptyIntentionAction(diagnostic.factory.name)).registerFix()
|
||||
annotation.registerFix(EmptyIntentionAction(diagnostic.factory.name), textRange)
|
||||
QuickFixAction.registerQuickFixAction(info, EmptyIntentionAction(diagnostic.factory.name))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun create(diagnostic: Diagnostic, range: TextRange, holder: AnnotationHolder, consumer: (Annotation) -> Unit) {
|
||||
val severity = when (diagnostic.severity) {
|
||||
Severity.ERROR -> HighlightSeverity.ERROR
|
||||
Severity.WARNING -> if (highlightType == ProblemHighlightType.WEAK_WARNING) {
|
||||
HighlightSeverity.WEAK_WARNING
|
||||
} else HighlightSeverity.WARNING
|
||||
Severity.INFO -> HighlightSeverity.WEAK_WARNING
|
||||
}
|
||||
|
||||
|
||||
private fun create(diagnostic: Diagnostic, range: TextRange, consumer: (HighlightInfo) -> Unit) {
|
||||
val message = nonDefaultMessage ?: getDefaultMessage(diagnostic)
|
||||
holder.newAnnotation(severity, message)
|
||||
HighlightInfo
|
||||
.newHighlightInfo(toHighlightInfoType(highlightType, diagnostic.severity))
|
||||
.range(range)
|
||||
.tooltip(getMessage(diagnostic))
|
||||
.also { builder -> highlightType?.let { builder.highlightType(it) } }
|
||||
.also { builder -> textAttributes?.let { builder.textAttributes(it) } }
|
||||
.description(message)
|
||||
.escapedToolTip(getMessage(diagnostic))
|
||||
.also { builder -> textAttributes?.let(builder::textAttributes) ?: convertSeverityTextAttributes(highlightType, diagnostic.severity)?.let(builder::textAttributes) }
|
||||
.also {
|
||||
if (diagnostic.severity == Severity.WARNING) {
|
||||
it.problemGroup(KotlinSuppressableWarningProblemGroup(diagnostic.factory))
|
||||
}
|
||||
}
|
||||
.create()
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
(holder as? List<Annotation>)?.last()?.let(consumer::invoke)
|
||||
.createUnconditionally()
|
||||
.also(consumer)
|
||||
}
|
||||
|
||||
private fun getMessage(diagnostic: Diagnostic): String {
|
||||
@@ -132,4 +116,42 @@ class AnnotationPresentationInfo(
|
||||
}
|
||||
}
|
||||
|
||||
private fun toHighlightInfoType(highlightType: ProblemHighlightType?, severity: Severity): HighlightInfoType =
|
||||
when (highlightType) {
|
||||
ProblemHighlightType.LIKE_UNUSED_SYMBOL -> HighlightInfoType.UNUSED_SYMBOL
|
||||
ProblemHighlightType.LIKE_UNKNOWN_SYMBOL -> HighlightInfoType.WRONG_REF
|
||||
ProblemHighlightType.LIKE_DEPRECATED -> HighlightInfoType.DEPRECATED
|
||||
ProblemHighlightType.LIKE_MARKED_FOR_REMOVAL -> HighlightInfoType.MARKED_FOR_REMOVAL
|
||||
else -> convertSeverity(highlightType, severity)
|
||||
}
|
||||
|
||||
private fun convertSeverity(highlightType: ProblemHighlightType?, severity: Severity): HighlightInfoType =
|
||||
when (severity) {
|
||||
Severity.ERROR -> HighlightInfoType.ERROR
|
||||
Severity.WARNING -> {
|
||||
if (highlightType == ProblemHighlightType.WEAK_WARNING) {
|
||||
HighlightInfoType.WEAK_WARNING
|
||||
} else HighlightInfoType.WARNING
|
||||
}
|
||||
Severity.INFO -> HighlightInfoType.WEAK_WARNING
|
||||
else -> HighlightInfoType.INFORMATION
|
||||
}
|
||||
|
||||
private fun convertSeverityTextAttributes(highlightType: ProblemHighlightType?, severity: Severity): TextAttributesKey? =
|
||||
when (highlightType) {
|
||||
null, ProblemHighlightType.GENERIC_ERROR_OR_WARNING ->
|
||||
when (severity) {
|
||||
Severity.ERROR -> CodeInsightColors.ERRORS_ATTRIBUTES
|
||||
Severity.WARNING -> {
|
||||
if (highlightType == ProblemHighlightType.WEAK_WARNING) {
|
||||
CodeInsightColors.WEAK_WARNING_ATTRIBUTES
|
||||
} else CodeInsightColors.WARNINGS_ATTRIBUTES
|
||||
}
|
||||
Severity.INFO -> CodeInsightColors.WARNINGS_ATTRIBUTES
|
||||
else -> null
|
||||
}
|
||||
ProblemHighlightType.GENERIC_ERROR -> CodeInsightColors.ERRORS_ATTRIBUTES
|
||||
else -> null
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-74
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.highlighter
|
||||
|
||||
import com.intellij.codeHighlighting.*
|
||||
import com.intellij.lang.annotation.AnnotationHolder
|
||||
import com.intellij.lang.annotation.Annotator
|
||||
import com.intellij.openapi.editor.Document
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.asJava.getJvmSignatureDiagnostics
|
||||
import org.jetbrains.kotlin.idea.caches.project.getModuleInfo
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithContent
|
||||
import org.jetbrains.kotlin.idea.highlighter.AbstractKotlinHighlightingPass.Companion.annotateDiagnostics
|
||||
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
class DuplicateJvmSignatureHighlightPass(file: KtFile, document: Document) :
|
||||
AbstractBindingContextAwareHighlightingPassBase(file, document) {
|
||||
override val annotator: Annotator
|
||||
get() = DuplicateJvmSignatureAnnotator()
|
||||
|
||||
inner class DuplicateJvmSignatureAnnotator : Annotator {
|
||||
override fun annotate(element: PsiElement, holder: AnnotationHolder) {
|
||||
if (element !is KtFile && element !is KtDeclaration) return
|
||||
|
||||
val otherDiagnostics = when (element) {
|
||||
is KtDeclaration -> element.analyzeWithContent()
|
||||
is KtFile -> element.analyzeWithContent()
|
||||
else -> throw AssertionError("DuplicateJvmSignatureAnnotator: should not get here! Element: ${element.text}")
|
||||
}.diagnostics
|
||||
|
||||
val moduleScope = element.getModuleInfo().contentScope()
|
||||
val diagnostics = getJvmSignatureDiagnostics(element, otherDiagnostics, moduleScope) ?: return
|
||||
|
||||
val diagnosticsForElement = diagnostics.forElement(element).toSet()
|
||||
|
||||
annotateDiagnostics(file, element, holder, diagnosticsForElement)
|
||||
}
|
||||
}
|
||||
|
||||
class Factory : TextEditorHighlightingPassFactory {
|
||||
override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass? {
|
||||
return if (file is KtFile &&
|
||||
ProjectRootsUtil.isInProjectSource(file) &&
|
||||
TargetPlatformDetector.getPlatform(file).isJvm()
|
||||
) {
|
||||
DuplicateJvmSignatureHighlightPass(file, editor.document)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Registrar : TextEditorHighlightingPassFactoryRegistrar {
|
||||
override fun registerHighlightingPassFactory(registrar: TextEditorHighlightingPassRegistrar, project: Project) {
|
||||
registrar.registerTextEditorHighlightingPass(
|
||||
Factory(),
|
||||
/* runAfterCompletionOf = */ intArrayOf(Pass.UPDATE_ALL),
|
||||
/* runAfterStartingOf = */ null,
|
||||
/* runIntentionsPassAfter = */ false,
|
||||
/* forcedPassId = */ -1
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,10 +5,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.highlighter
|
||||
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightInfoHolder
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.codeInspection.ProblemHighlightType
|
||||
import com.intellij.lang.annotation.Annotation
|
||||
import com.intellij.lang.annotation.AnnotationHolder
|
||||
import com.intellij.openapi.diagnostic.ControlFlowException
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.editor.colors.CodeInsightColors
|
||||
@@ -31,10 +32,10 @@ internal class ElementAnnotator(
|
||||
private val shouldSuppressUnusedParameter: (KtParameter) -> Boolean
|
||||
) {
|
||||
fun registerDiagnosticsAnnotations(
|
||||
holder: AnnotationHolder,
|
||||
holder: HighlightInfoHolder,
|
||||
diagnostics: Collection<Diagnostic>,
|
||||
annotationByDiagnostic: MutableMap<Diagnostic, Annotation>?,
|
||||
annotationByTextRange: MutableMap<TextRange, Annotation>?,
|
||||
highlightInfoByDiagnostic: MutableMap<Diagnostic, HighlightInfo>?,
|
||||
highlightInfoByTextRange: MutableMap<TextRange, HighlightInfo>?,
|
||||
noFixes: Boolean,
|
||||
calculatingInProgress: Boolean
|
||||
) = diagnostics.groupBy { it.factory }
|
||||
@@ -42,18 +43,18 @@ internal class ElementAnnotator(
|
||||
registerSameFactoryDiagnosticsAnnotations(
|
||||
holder,
|
||||
it.value,
|
||||
annotationByDiagnostic,
|
||||
annotationByTextRange,
|
||||
highlightInfoByDiagnostic,
|
||||
highlightInfoByTextRange,
|
||||
noFixes,
|
||||
calculatingInProgress
|
||||
)
|
||||
}
|
||||
|
||||
private fun registerSameFactoryDiagnosticsAnnotations(
|
||||
holder: AnnotationHolder,
|
||||
holder: HighlightInfoHolder,
|
||||
diagnostics: Collection<Diagnostic>,
|
||||
annotationByDiagnostic: MutableMap<Diagnostic, Annotation>?,
|
||||
annotationByTextRange: MutableMap<TextRange, Annotation>?,
|
||||
highlightInfoByDiagnostic: MutableMap<Diagnostic, HighlightInfo>?,
|
||||
highlightInfoByTextRange: MutableMap<TextRange, HighlightInfo>?,
|
||||
noFixes: Boolean,
|
||||
calculatingInProgress: Boolean
|
||||
) {
|
||||
@@ -62,8 +63,8 @@ internal class ElementAnnotator(
|
||||
holder,
|
||||
diagnostics,
|
||||
presentationInfo,
|
||||
annotationByDiagnostic,
|
||||
annotationByTextRange,
|
||||
highlightInfoByDiagnostic,
|
||||
highlightInfoByTextRange,
|
||||
noFixes,
|
||||
calculatingInProgress
|
||||
)
|
||||
@@ -71,21 +72,21 @@ internal class ElementAnnotator(
|
||||
|
||||
fun registerDiagnosticsQuickFixes(
|
||||
diagnostics: List<Diagnostic>,
|
||||
annotationByDiagnostic: MutableMap<Diagnostic, Annotation>
|
||||
highlightInfoByDiagnostic: MutableMap<Diagnostic, HighlightInfo>
|
||||
) = diagnostics.groupBy { it.factory }
|
||||
.forEach { registerDiagnosticsSameFactoryQuickFixes(it.value, annotationByDiagnostic) }
|
||||
.forEach { registerDiagnosticsSameFactoryQuickFixes(it.value, highlightInfoByDiagnostic) }
|
||||
|
||||
private fun registerDiagnosticsSameFactoryQuickFixes(
|
||||
diagnostics: List<Diagnostic>,
|
||||
annotationByDiagnostic: MutableMap<Diagnostic, Annotation>
|
||||
highlightInfoByDiagnostic: MutableMap<Diagnostic, HighlightInfo>
|
||||
) {
|
||||
val presentationInfo = presentationInfo(diagnostics) ?: return
|
||||
val fixesMap = createFixesMap(diagnostics) ?: return
|
||||
|
||||
diagnostics.forEach {
|
||||
val annotation = annotationByDiagnostic[it] ?: return
|
||||
val highlightInfo = highlightInfoByDiagnostic[it] ?: return
|
||||
|
||||
presentationInfo.applyFixes(fixesMap, it, annotation)
|
||||
presentationInfo.applyFixes(fixesMap, it, highlightInfo)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,18 +162,18 @@ internal class ElementAnnotator(
|
||||
}
|
||||
|
||||
private fun setUpAnnotations(
|
||||
holder: AnnotationHolder,
|
||||
holder: HighlightInfoHolder,
|
||||
diagnostics: Collection<Diagnostic>,
|
||||
data: AnnotationPresentationInfo,
|
||||
annotationByDiagnostic: MutableMap<Diagnostic, Annotation>?,
|
||||
annotationByTextRange: MutableMap<TextRange, Annotation>?,
|
||||
highlightInfoByDiagnostic: MutableMap<Diagnostic, HighlightInfo>?,
|
||||
highlightInfoByTextRange: MutableMap<TextRange, HighlightInfo>?,
|
||||
noFixes: Boolean,
|
||||
calculatingInProgress: Boolean
|
||||
) {
|
||||
val fixesMap =
|
||||
createFixesMap(diagnostics, noFixes)
|
||||
|
||||
data.processDiagnostics(holder, diagnostics, annotationByDiagnostic, annotationByTextRange, fixesMap, calculatingInProgress)
|
||||
data.processDiagnostics(holder, diagnostics, highlightInfoByDiagnostic, highlightInfoByTextRange, fixesMap, calculatingInProgress)
|
||||
}
|
||||
|
||||
private fun createFixesMap(
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.highlighter
|
||||
|
||||
import com.intellij.lang.annotation.AnnotationHolder
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightInfoHolder
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
|
||||
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
|
||||
import org.jetbrains.kotlin.serialization.deserialization.KOTLIN_SUSPEND_BUILT_IN_FUNCTION_FQ_NAME
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||
|
||||
internal class FunctionsHighlightingVisitor(holder: AnnotationHolder, bindingContext: BindingContext) :
|
||||
internal class FunctionsHighlightingVisitor(holder: HighlightInfoHolder, bindingContext: BindingContext) :
|
||||
AfterAnalysisHighlightingVisitor(holder, bindingContext) {
|
||||
|
||||
override fun visitBinaryExpression(expression: KtBinaryExpression) {
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.highlighter
|
||||
|
||||
import com.intellij.lang.annotation.AnnotationHolder
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightInfoHolder
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
import com.intellij.psi.PsiElement
|
||||
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.isSynthesized
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||
|
||||
internal class PropertiesHighlightingVisitor(holder: AnnotationHolder, bindingContext: BindingContext) :
|
||||
internal class PropertiesHighlightingVisitor(holder: HighlightInfoHolder, bindingContext: BindingContext) :
|
||||
AfterAnalysisHighlightingVisitor(holder, bindingContext) {
|
||||
|
||||
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) {
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.highlighter
|
||||
|
||||
import com.intellij.lang.annotation.AnnotationHolder
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightInfoHolder
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
|
||||
|
||||
internal class TypeKindHighlightingVisitor(holder: AnnotationHolder, bindingContext: BindingContext) :
|
||||
internal class TypeKindHighlightingVisitor(holder: HighlightInfoHolder, bindingContext: BindingContext) :
|
||||
AfterAnalysisHighlightingVisitor(holder, bindingContext) {
|
||||
|
||||
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) {
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.highlighter
|
||||
|
||||
import com.intellij.lang.annotation.AnnotationHolder
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightInfoHolder
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiNameIdentifierOwner
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
|
||||
import org.jetbrains.kotlin.types.expressions.CaptureKind
|
||||
|
||||
internal class VariablesHighlightingVisitor(holder: AnnotationHolder, bindingContext: BindingContext) :
|
||||
internal class VariablesHighlightingVisitor(holder: HighlightInfoHolder, bindingContext: BindingContext) :
|
||||
AfterAnalysisHighlightingVisitor(holder, bindingContext) {
|
||||
|
||||
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) {
|
||||
|
||||
+2
-3
@@ -9,8 +9,7 @@ import com.intellij.codeInsight.completion.PrefixMatcher
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.idea.highlighter.AbstractKotlinHighlightingPass
|
||||
import org.jetbrains.kotlin.idea.highlighter.KotlinHighlightingPass
|
||||
import org.jetbrains.kotlin.idea.highlighter.AbstractKotlinHighlightVisitor
|
||||
import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
|
||||
import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
@@ -29,7 +28,7 @@ class FromUnresolvedNamesCompletion(
|
||||
scope.forEachDescendantOfType<KtNameReferenceExpression> { refExpr ->
|
||||
ProgressManager.checkCanceled()
|
||||
|
||||
if (AbstractKotlinHighlightingPass.wasUnresolved(refExpr)) {
|
||||
if (AbstractKotlinHighlightVisitor.wasUnresolved(refExpr)) {
|
||||
val callTypeAndReceiver = CallTypeAndReceiver.detect(refExpr)
|
||||
if (callTypeAndReceiver.receiver != null) return@forEachDescendantOfType
|
||||
if (sampleDescriptor != null) {
|
||||
|
||||
+2
-2
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.idea.highlighter.KotlinHighlightingColors as Colors
|
||||
|
||||
internal class DeclarationHighlightingVisitor(holder: AnnotationHolder) : HighlightingVisitor(holder) {
|
||||
internal class DeclarationHighlightingVisitor(holder: AnnotationHolder) : AbstractAnnotationHolderHighlightingVisitor(holder) {
|
||||
override fun visitTypeAlias(typeAlias: KtTypeAlias) {
|
||||
highlightNamedDeclaration(typeAlias, Colors.TYPE_ALIAS)
|
||||
super.visitTypeAlias(typeAlias)
|
||||
@@ -56,6 +56,6 @@ internal class DeclarationHighlightingVisitor(holder: AnnotationHolder) : Highli
|
||||
}
|
||||
|
||||
class DeclarationHighlightingExtension : BeforeResolveHighlightingExtension {
|
||||
override fun createVisitor(holder: AnnotationHolder): HighlightingVisitor =
|
||||
override fun createVisitor(holder: AnnotationHolder): AbstractHighlightingVisitor =
|
||||
DeclarationHighlightingVisitor(holder)
|
||||
}
|
||||
+2
-2
@@ -9,12 +9,12 @@ import com.intellij.lang.annotation.AnnotationHolder
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.idea.highlighter.HighlightingVisitor
|
||||
import org.jetbrains.kotlin.idea.highlighter.AbstractAnnotationHolderHighlightingVisitor
|
||||
|
||||
abstract class FirAfterResolveHighlightingVisitor(
|
||||
protected val analysisSession: KtAnalysisSession,
|
||||
protected val holder: AnnotationHolder
|
||||
) : HighlightingVisitor(holder) {
|
||||
) : AbstractAnnotationHolderHighlightingVisitor(holder) {
|
||||
|
||||
override fun createInfoAnnotation(textRange: TextRange, message: String?, textAttributes: TextAttributesKey?) {
|
||||
// TODO: Temporary use deprecated for FIR plugin as it is supposes to be rewritten fully
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.highlighter
|
||||
|
||||
import com.intellij.lang.annotation.AnnotationHolder
|
||||
import com.intellij.lang.annotation.HighlightSeverity
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey
|
||||
import com.intellij.openapi.util.TextRange
|
||||
|
||||
abstract class AbstractAnnotationHolderHighlightingVisitor protected constructor(private val holder: AnnotationHolder): AbstractHighlightingVisitor() {
|
||||
override fun createInfoAnnotation(textRange: TextRange, message: String?, textAttributes: TextAttributesKey?) {
|
||||
(message?.let { holder.newAnnotation(HighlightSeverity.INFORMATION, it) }
|
||||
?: holder.newSilentAnnotation(HighlightSeverity.INFORMATION))
|
||||
.range(textRange)
|
||||
.also { builder -> textAttributes?.let { builder.textAttributes(it) } }
|
||||
.create()
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.highlighter
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfoType
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightInfoHolder
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey
|
||||
import com.intellij.openapi.util.TextRange
|
||||
|
||||
abstract class AbstractHighlightInfoHolderHighlightingVisitor protected constructor(private val holder: HighlightInfoHolder) :
|
||||
AbstractHighlightingVisitor() {
|
||||
override fun createInfoAnnotation(textRange: TextRange, message: String?, textAttributes: TextAttributesKey?) {
|
||||
HighlightInfo.newHighlightInfo(HighlightInfoType.INFORMATION)
|
||||
.range(textRange)
|
||||
.also { builder -> message?.let { builder.description(it) } }
|
||||
.also { builder ->
|
||||
textAttributes?.let {
|
||||
builder.textAttributes(it)
|
||||
}
|
||||
}
|
||||
.create()
|
||||
.also { holder.add(it) }
|
||||
}
|
||||
}
|
||||
+2
-16
@@ -5,17 +5,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.highlighter
|
||||
|
||||
import com.intellij.lang.annotation.AnnotationHolder
|
||||
import com.intellij.lang.annotation.HighlightSeverity
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtVisitorVoid
|
||||
|
||||
abstract class HighlightingVisitor protected constructor(
|
||||
private val holder: AnnotationHolder
|
||||
) : KtVisitorVoid() {
|
||||
abstract class AbstractHighlightingVisitor : KtVisitorVoid() {
|
||||
|
||||
protected fun createInfoAnnotation(element: PsiElement, message: String? = null, textAttributes: TextAttributesKey) {
|
||||
createInfoAnnotation(element.textRange, message, textAttributes)
|
||||
@@ -24,17 +20,7 @@ abstract class HighlightingVisitor protected constructor(
|
||||
protected fun createInfoAnnotation(element: PsiElement, message: String? = null) =
|
||||
createInfoAnnotation(element.textRange, message)
|
||||
|
||||
protected open fun createInfoAnnotation(textRange: TextRange, message: String? = null, textAttributes: TextAttributesKey? = null) {
|
||||
(message?.let { holder.newAnnotation(HighlightSeverity.INFORMATION, it) }
|
||||
?: holder.newSilentAnnotation(HighlightSeverity.INFORMATION))
|
||||
.range(textRange)
|
||||
.also { builder ->
|
||||
textAttributes?.let {
|
||||
builder.textAttributes(it)
|
||||
}
|
||||
}
|
||||
.create()
|
||||
}
|
||||
protected abstract fun createInfoAnnotation(textRange: TextRange, message: String? = null, textAttributes: TextAttributesKey? = null)
|
||||
|
||||
protected fun highlightName(element: PsiElement, attributesKey: TextAttributesKey, message: String? = null) {
|
||||
if (NameHighlighter.namesHighlightingEnabled && !element.textRange.isEmpty) {
|
||||
+1
-1
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
|
||||
internal class BeforeResolveHighlightingVisitor(holder: AnnotationHolder) : HighlightingVisitor(holder) {
|
||||
internal class BeforeResolveHighlightingVisitor(holder: AnnotationHolder) : AbstractAnnotationHolderHighlightingVisitor(holder) {
|
||||
|
||||
override fun visitElement(element: PsiElement) {
|
||||
val elementType = element.node.elementType
|
||||
|
||||
+1
-1
@@ -56,5 +56,5 @@ class KotlinBeforeResolveHighlightingPass(file: KtFile, document: Document) : Ab
|
||||
}
|
||||
|
||||
interface BeforeResolveHighlightingExtension {
|
||||
fun createVisitor(holder: AnnotationHolder): HighlightingVisitor
|
||||
fun createVisitor(holder: AnnotationHolder): AbstractHighlightingVisitor
|
||||
}
|
||||
+14
-30
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.idea.perf
|
||||
|
||||
import com.intellij.codeHighlighting.*
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightInfoHolder
|
||||
import com.intellij.openapi.editor.Document
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
@@ -15,7 +16,7 @@ import com.intellij.psi.PsiFile
|
||||
import com.intellij.testFramework.RunAll
|
||||
import com.intellij.util.ThrowableRunnable
|
||||
import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
|
||||
import org.jetbrains.kotlin.idea.highlighter.KotlinHighlightingPass
|
||||
import org.jetbrains.kotlin.idea.highlighter.KotlinHighlightVisitor
|
||||
import org.jetbrains.kotlin.idea.perf.Stats.Companion.TEST_KEY
|
||||
import org.jetbrains.kotlin.idea.perf.Stats.Companion.runAndMeasure
|
||||
import org.jetbrains.kotlin.idea.perf.util.Metric
|
||||
@@ -379,8 +380,8 @@ class PerformanceProjectsTest : AbstractPerformanceProjectsTest() {
|
||||
private fun replaceWithCustomHighlighter() {
|
||||
org.jetbrains.kotlin.idea.testFramework.replaceWithCustomHighlighter(
|
||||
testRootDisposable,
|
||||
KotlinHighlightingPass.Registrar::class.java.name,
|
||||
TestKotlinHighlightingPass.Registrar::class.java.name
|
||||
KotlinHighlightVisitor::class.java.name,
|
||||
TestKotlinHighlightVisitor::class.java.name
|
||||
)
|
||||
}
|
||||
|
||||
@@ -434,38 +435,21 @@ class PerformanceProjectsTest : AbstractPerformanceProjectsTest() {
|
||||
}
|
||||
|
||||
|
||||
class TestKotlinHighlightingPass(file: KtFile, document: Document) : KotlinHighlightingPass(file, document) {
|
||||
override fun doCollectInformation(progress: ProgressIndicator) {
|
||||
annotationCallback {
|
||||
val nowNs = System.nanoTime()
|
||||
diagnosticTimer.addAndGet(nowNs)
|
||||
resetAnnotationCallback()
|
||||
}
|
||||
class TestKotlinHighlightVisitor : KotlinHighlightVisitor() {
|
||||
override fun analyze(psiFile: PsiFile, updateWholeFile: Boolean, holder: HighlightInfoHolder, action: Runnable): Boolean {
|
||||
// TODO:
|
||||
//annotationCallback {
|
||||
// val nowNs = System.nanoTime()
|
||||
// diagnosticTimer.addAndGet(nowNs)
|
||||
// resetAnnotationCallback()
|
||||
//}
|
||||
try {
|
||||
super.doCollectInformation(progress)
|
||||
return super.analyze(psiFile, updateWholeFile, holder, action)
|
||||
} finally {
|
||||
resetAnnotationCallback()
|
||||
//resetAnnotationCallback()
|
||||
markTimestamp()
|
||||
}
|
||||
}
|
||||
|
||||
class Factory : TextEditorHighlightingPassFactory {
|
||||
override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass? {
|
||||
if (file !is KtFile) return null
|
||||
return TestKotlinHighlightingPass(file, editor.document)
|
||||
}
|
||||
}
|
||||
|
||||
class Registrar : TextEditorHighlightingPassFactoryRegistrar {
|
||||
override fun registerHighlightingPassFactory(registrar: TextEditorHighlightingPassRegistrar, project: Project) {
|
||||
registrar.registerTextEditorHighlightingPass(
|
||||
Factory(),
|
||||
null,
|
||||
intArrayOf(Pass.UPDATE_ALL),
|
||||
false,
|
||||
-1
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,10 +134,9 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
|
||||
<projectService serviceImplementation="org.jetbrains.kotlin.idea.completion.LookupCancelService"/>
|
||||
<projectService serviceImplementation="org.jetbrains.kotlin.idea.configuration.KotlinMigrationProjectService"/>
|
||||
|
||||
<highlightVisitor implementation="org.jetbrains.kotlin.idea.highlighter.KotlinHighlightVisitor"/>
|
||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Registrar"/>
|
||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinHighlightingPass$Registrar"/>
|
||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.DebugInfoHighlightingPass$Registrar"/>
|
||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.DuplicateJvmSignatureHighlightPass$Registrar"/>
|
||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.ScriptExternalHighlightingPass$Registrar"/>
|
||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.refactoring.cutPaste.MoveDeclarationsPassFactory$Registrar"/>
|
||||
|
||||
|
||||
@@ -134,10 +134,9 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
|
||||
<projectService serviceImplementation="org.jetbrains.kotlin.idea.completion.LookupCancelService"/>
|
||||
<projectService serviceImplementation="org.jetbrains.kotlin.idea.configuration.KotlinMigrationProjectService"/>
|
||||
|
||||
<highlightVisitor implementation="org.jetbrains.kotlin.idea.highlighter.KotlinHighlightVisitor"/>
|
||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Registrar"/>
|
||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinHighlightingPass$Registrar"/>
|
||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.DebugInfoHighlightingPass$Registrar"/>
|
||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.DuplicateJvmSignatureHighlightPass$Registrar"/>
|
||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.ScriptExternalHighlightingPass$Registrar"/>
|
||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.refactoring.cutPaste.MoveDeclarationsPassFactory$Registrar"/>
|
||||
|
||||
|
||||
@@ -133,10 +133,9 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
|
||||
<projectService serviceImplementation="org.jetbrains.kotlin.idea.completion.LookupCancelService"/>
|
||||
<projectService serviceImplementation="org.jetbrains.kotlin.idea.configuration.KotlinMigrationProjectService"/>
|
||||
|
||||
<highlightVisitor implementation="org.jetbrains.kotlin.idea.highlighter.KotlinHighlightVisitor"/>
|
||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Registrar"/>
|
||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinHighlightingPass$Registrar"/>
|
||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.DebugInfoHighlightingPass$Registrar"/>
|
||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.DuplicateJvmSignatureHighlightPass$Registrar"/>
|
||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.ScriptExternalHighlightingPass$Registrar"/>
|
||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.refactoring.cutPaste.MoveDeclarationsPassFactory$Registrar"/>
|
||||
|
||||
|
||||
@@ -114,10 +114,9 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
|
||||
<projectService serviceImplementation="org.jetbrains.kotlin.idea.completion.LookupCancelService"/>
|
||||
<projectService serviceImplementation="org.jetbrains.kotlin.idea.configuration.KotlinMigrationProjectService"/>
|
||||
|
||||
<highlightVisitor implementation="org.jetbrains.kotlin.idea.highlighter.KotlinHighlightVisitor"/>
|
||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Registrar"/>
|
||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinHighlightingPass$Registrar"/>
|
||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.DebugInfoHighlightingPass$Registrar"/>
|
||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.DuplicateJvmSignatureHighlightPass$Registrar"/>
|
||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.ScriptExternalHighlightingPass$Registrar"/>
|
||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.refactoring.cutPaste.MoveDeclarationsPassFactory$Registrar"/>
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.highlighter
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightVisitor
|
||||
import org.jetbrains.kotlin.idea.inspections.UnusedSymbolInspection
|
||||
import org.jetbrains.kotlin.idea.isMainFunction
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
|
||||
open class KotlinHighlightVisitor : AbstractKotlinHighlightVisitor() {
|
||||
|
||||
override fun shouldSuppressUnusedParameter(parameter: KtParameter): Boolean {
|
||||
val grandParent = parameter.parent.parent as? KtNamedFunction ?: return false
|
||||
if (!UnusedSymbolInspection.isEntryPoint(grandParent)) return false
|
||||
return !grandParent.isMainFunction()
|
||||
}
|
||||
|
||||
override fun clone(): HighlightVisitor = KotlinHighlightVisitor()
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.highlighter
|
||||
|
||||
import com.intellij.codeHighlighting.*
|
||||
import com.intellij.openapi.editor.Document
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.idea.inspections.UnusedSymbolInspection
|
||||
import org.jetbrains.kotlin.idea.isMainFunction
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
|
||||
open class KotlinHighlightingPass(file: KtFile, document: Document) : AbstractKotlinHighlightingPass(file, document) {
|
||||
|
||||
override fun shouldSuppressUnusedParameter(parameter: KtParameter): Boolean {
|
||||
val grandParent = parameter.parent.parent as? KtNamedFunction ?: return false
|
||||
if (!UnusedSymbolInspection.isEntryPoint(grandParent)) return false
|
||||
return !grandParent.isMainFunction()
|
||||
}
|
||||
|
||||
class Factory : TextEditorHighlightingPassFactory {
|
||||
override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass? {
|
||||
if (file !is KtFile) return null
|
||||
return KotlinHighlightingPass(file, editor.document)
|
||||
}
|
||||
}
|
||||
|
||||
class Registrar : TextEditorHighlightingPassFactoryRegistrar {
|
||||
override fun registerHighlightingPassFactory(registrar: TextEditorHighlightingPassRegistrar, project: Project) {
|
||||
registrar.registerTextEditorHighlightingPass(
|
||||
Factory(),
|
||||
/* runAfterCompletionOf = */ null,
|
||||
/* runAfterStartingOf = */ intArrayOf(Pass.UPDATE_ALL),
|
||||
/* runIntentionsPassAfter = */false,
|
||||
/* forcedPassId = */-1
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
|
||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithAllCompilerChecks
|
||||
import org.jetbrains.kotlin.idea.highlighter.AbstractKotlinHighlightingPass
|
||||
import org.jetbrains.kotlin.idea.highlighter.AbstractKotlinHighlightVisitor
|
||||
import org.jetbrains.kotlin.idea.quickfix.CleanupFix
|
||||
import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction
|
||||
import org.jetbrains.kotlin.idea.quickfix.ReplaceObsoleteLabelSyntaxFix
|
||||
@@ -99,7 +99,7 @@ class KotlinCleanupInspection : LocalInspectionTool(), CleanupLocalInspectionToo
|
||||
}
|
||||
|
||||
private fun Diagnostic.toCleanupFixes(): Collection<CleanupFix> {
|
||||
return AbstractKotlinHighlightingPass.createQuickFixes(this).filterIsInstance<CleanupFix>()
|
||||
return AbstractKotlinHighlightVisitor.createQuickFixes(this).filterIsInstance<CleanupFix>()
|
||||
}
|
||||
|
||||
private class Wrapper(val intention: IntentionAction, file: KtFile) : IntentionWrapper(intention, file) {
|
||||
|
||||
@@ -89,12 +89,12 @@ abstract class AbstractKotlinHighlightWolfPassTest : KotlinLightCodeInsightFixtu
|
||||
// TODO: [VD] HAS TO BE UNCOMMENTED with 211
|
||||
// val hasWolfErrors = hasWolfErrors(myFixture)
|
||||
// assertEquals(hasWolfErrors, wolf.isProblemFile(virtualFile) || wolf.hasSyntaxErrors(virtualFile))
|
||||
// if (hasWolfErrors) {
|
||||
// if (hasWolfErrors && !initialWolfErrors) {
|
||||
// TestCase.assertTrue(problemsAppeared > 0)
|
||||
// } else {
|
||||
// assertEquals(0, problemsAppeared)
|
||||
// }
|
||||
// assertEquals(if (initialWolfErrors) 1 else 0, problemsDisappeared)
|
||||
// assertEquals(0, problemsDisappeared)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.highlighter
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.AnnotationHolderImpl
|
||||
import com.intellij.lang.annotation.AnnotationSession
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightInfoHolder
|
||||
import com.intellij.psi.PsiComment
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithAllCompilerChecks
|
||||
import org.jetbrains.kotlin.idea.highlighter.dsl.DslHighlighterExtension
|
||||
@@ -33,15 +32,14 @@ abstract class AbstractDslHighlighterTest : KotlinLightCodeInsightFixtureTestCas
|
||||
val styleIdByComment = commentText?.replace("//", "")?.trim()?.toInt()?.let { DslHighlighterExtension.externalKeyName(it) }
|
||||
val styleIdByCall = extension.highlightCall(element, call)?.externalName
|
||||
if (styleIdByCall != null && styleIdByCall == styleIdByComment) {
|
||||
val annotationHolder = AnnotationHolderImpl(AnnotationSession(psiFile))
|
||||
annotationHolder.runAnnotatorWithContext(file) { _, _ ->
|
||||
val checkers = AbstractKotlinHighlightingPass.getAfterAnalysisVisitor(annotationHolder, bindingContext)
|
||||
checkers.forEach { call.call.callElement.accept(it) }
|
||||
}
|
||||
val holder = HighlightInfoHolder(psiFile)
|
||||
val checkers = AbstractKotlinHighlightVisitor.getAfterAnalysisVisitor(holder, bindingContext)
|
||||
checkers.forEach { call.call.callElement.accept(it) }
|
||||
|
||||
assertTrue(
|
||||
"KotlinHighlightingPass did not contribute an Annotation containing the correct text attribute key at line ${lineNumber + 1}",
|
||||
annotationHolder.any {
|
||||
it.textAttributes.externalName == styleIdByComment
|
||||
(0 until holder.size()).map { holder[it] }.any {
|
||||
it.forcedTextAttributesKey.externalName == styleIdByComment
|
||||
}
|
||||
)
|
||||
} else if (styleIdByCall != styleIdByComment) {
|
||||
|
||||
Reference in New Issue
Block a user