IDEA-238791/IDEA-241748: use RangeHighlighterEx instead of HighlightInfo to create HighlightingProblem

GitOrigin-RevId: 7df56318c4e772c9215fce4a18bb728289185f6f
This commit is contained in:
Sergey Malenkov
2020-06-09 01:05:17 +03:00
committed by intellij-monorepo-bot
parent 29c146ecf4
commit db35ecd64b
7 changed files with 51 additions and 25 deletions
@@ -1,8 +1,8 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.analysis.problemsView.toolWindow
import com.intellij.codeInsight.daemon.impl.HighlightInfo
import com.intellij.lang.annotation.HighlightSeverity.INFORMATION
import com.intellij.openapi.editor.ex.RangeHighlighterEx
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.vfs.VirtualFile
@@ -23,8 +23,8 @@ internal class HighlightingFileRoot(panel: ProblemsViewPanel, val file: VirtualF
return synchronized(problems) { problems.getProblemNodes() }
}
fun findProblemNode(info: HighlightInfo?): ProblemNode? {
val problem = watcher.getProblem(info) ?: return null
fun findProblemNode(highlighter: RangeHighlighterEx): ProblemNode? {
val problem = watcher.findProblem(highlighter) ?: return null
return synchronized(problems) { problems.findProblemNode(problem) }
}
@@ -42,6 +42,10 @@ internal class HighlightingFileRoot(panel: ProblemsViewPanel, val file: VirtualF
structureChanged()
}
override fun updateProblem(file: VirtualFile, problem: Problem) {
synchronized(problems) { problems.findProblemNode(problem) }?.let { structureChanged() }
}
override fun updateProblems(file: VirtualFile, collection: Collection<Problem>) {
synchronized(problems) { problems.update(collection) }
structureChanged()
@@ -1,11 +1,11 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.analysis.problemsView.toolWindow
import com.intellij.codeInsight.daemon.impl.HighlightInfo
import com.intellij.codeInsight.daemon.impl.SeverityRegistrar.getSeverityRegistrar
import com.intellij.ide.TreeExpander
import com.intellij.lang.annotation.HighlightSeverity
import com.intellij.openapi.actionSystem.ToggleOptionAction.Option
import com.intellij.openapi.editor.ex.RangeHighlighterEx
import com.intellij.openapi.fileEditor.*
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
@@ -30,9 +30,9 @@ internal class HighlightingPanel(project: Project, state: ProblemsViewState)
if (selected) updateCurrentFile()
}
fun selectHighlightInfo(info: HighlightInfo) {
fun selectHighlighter(highlighter: RangeHighlighterEx) {
val root = treeModel.root as? HighlightingFileRoot
root?.findProblemNode(info)?.let { select(it) }
root?.findProblemNode(highlighter)?.let { select(it) }
}
override fun fileOpened(manager: FileEditorManager, file: VirtualFile) = updateCurrentFile()
@@ -12,40 +12,44 @@ import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.RangeMarker
import com.intellij.openapi.editor.ex.RangeHighlighterEx
import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.PsiFile
import javax.swing.Icon
internal class HighlightingProblem(val info: HighlightInfo) : Problem {
internal class HighlightingProblem(private val highlighter: RangeHighlighterEx) : Problem {
private fun getIcon(level: HighlightDisplayLevel) = if (severity >= level.severity.myVal) level.icon else null
private val info: HighlightInfo?
get() = HighlightInfo.fromRangeHighlighter(highlighter)
override val icon: Icon
get() = HighlightDisplayLevel.find(info.severity)?.icon
get() = HighlightDisplayLevel.find(info?.severity)?.icon
?: getIcon(HighlightDisplayLevel.ERROR)
?: getIcon(HighlightDisplayLevel.WARNING)
?: HighlightDisplayLevel.WEAK_WARNING.icon
override val description: String
get() = info.description
get() = info?.description ?: "Invalid"
override val severity: Int
get() = info.severity.myVal
get() = info?.severity?.myVal ?: -1
override val offset: Int
get() = info.actualStartOffset
get() = info?.actualStartOffset ?: -1
override fun hashCode() = info.hashCode()
override fun hashCode() = highlighter.hashCode()
override fun equals(other: Any?) = other is HighlightingProblem && other.info == info
override fun equals(other: Any?) = other is HighlightingProblem && other.highlighter == highlighter
override fun hasQuickFixActions(): Boolean {
val markers = info.quickFixActionMarkers ?: return false
val markers = info?.quickFixActionMarkers ?: return false
return markers.any { it.second.isValid }
}
override fun getQuickFixActions(): Collection<AnAction> {
val markers = info.quickFixActionMarkers ?: return emptyList()
val markers = info?.quickFixActionMarkers ?: return emptyList()
return markers.filter { it.second.isValid }.map { QuickFixAction(it.first.action, it.second) }
}
}
@@ -17,6 +17,7 @@ internal class HighlightingWatcher(
private val level: Int = ERROR.myVal)
: MarkupModelListener, Disposable {
private val problems = mutableMapOf<RangeHighlighterEx, Problem>()
private var reference: WeakReference<MarkupModelEx>? = null
init {
@@ -33,6 +34,10 @@ internal class HighlightingWatcher(
getProblem(highlighter)?.let { root.removeProblem(file, it) }
}
override fun attributesChanged(highlighter: RangeHighlighterEx, renderersChanged: Boolean, fontStyleOrColorChanged: Boolean) {
findProblem(highlighter)?.let { root.updateProblem(file, it) }
}
fun update() {
val model = reference?.get() ?: getMarkupModel() ?: return
val problems = mutableSetOf<Problem>()
@@ -43,13 +48,18 @@ internal class HighlightingWatcher(
root.updateProblems(file, problems)
}
fun getProblem(info: HighlightInfo?): Problem? {
return if (null == info?.description || info.severity.myVal < level) null else HighlightingProblem(info)
fun findProblem(highlighter: RangeHighlighterEx) = synchronized(problems) { problems[highlighter] }
private fun getProblem(highlighter: RangeHighlighterEx) = when {
!isValid(highlighter) -> null
else -> synchronized(problems) {
problems.computeIfAbsent(highlighter) { HighlightingProblem(highlighter) }
}
}
private fun getProblem(highlighter: RangeHighlighterEx): Problem? {
val info = highlighter.errorStripeTooltip as? HighlightInfo ?: return null
return getProblem(info)
private fun isValid(highlighter: RangeHighlighterEx): Boolean {
val info = highlighter.errorStripeTooltip as? HighlightInfo ?: return false
return info.description != null && info.severity.myVal >= level
}
private fun getMarkupModel(): MarkupModelEx? {
@@ -1,10 +1,10 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.analysis.problemsView.toolWindow;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.application.Experiments;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.ex.RangeHighlighterEx;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
@@ -42,9 +42,9 @@ public final class ProblemsView implements DumbAware, ToolWindowFactory {
window.activate(null, true);
}
public static void selectHighlightInfoIfVisible(@NotNull Project project, @NotNull HighlightInfo info) {
public static void selectHighlighterIfVisible(@NotNull Project project, @NotNull RangeHighlighterEx highlighter) {
HighlightingPanel panel = get(HighlightingPanel.class, getSelectedContent(project));
if (panel != null && panel.isShowing()) panel.selectHighlightInfo(info);
if (panel != null && panel.isShowing()) panel.selectHighlighter(highlighter);
}
static @Nullable Document getDocument(@Nullable Project project, @NotNull VirtualFile file) {
@@ -44,6 +44,12 @@ internal open class Root(val panel: ProblemsViewPanel) : Node(panel.project), Di
synchronized(allProblems) { remove(file, problem) }?.let { structureChanged(it) }
}
open fun updateProblem(file: VirtualFile, problem: Problem) {
val node = synchronized(allProblems) { allProblems[file]?.findProblemNode(problem) } ?: return
node.update()
structureChanged(node)
}
open fun removeProblems(file: VirtualFile) {
synchronized(allProblems) { removeAll(file) }?.let { structureChanged(it) }
}
@@ -9,6 +9,7 @@ import com.intellij.codeInsight.hint.HintManager;
import com.intellij.codeInspection.InspectionsBundle;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.ex.RangeHighlighterEx;
import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.registry.Registry;
@@ -16,7 +17,7 @@ import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import static com.intellij.analysis.problemsView.toolWindow.ProblemsView.selectHighlightInfoIfVisible;
import static com.intellij.analysis.problemsView.toolWindow.ProblemsView.selectHighlighterIfVisible;
public class GotoNextErrorHandler implements CodeInsightActionHandler {
private final boolean myGoForward;
@@ -140,7 +141,8 @@ public class GotoNextErrorHandler implements CodeInsightActionHandler {
);
IdeDocumentHistory.getInstance(project).includeCurrentCommandAsNavigation();
selectHighlightInfoIfVisible(project, info);
RangeHighlighterEx highlighter = info.getHighlighter();
if (highlighter != null) selectHighlighterIfVisible(project, highlighter);
}
private static int getNavigationPositionFor(HighlightInfo info, Document document) {