MethodChainHintsPass: extract class for element processing

This commit is contained in:
Roman.Ivanov
2018-03-30 12:28:49 +07:00
parent dbb6ff2b56
commit 0835528f5a
5 changed files with 95 additions and 31 deletions
@@ -0,0 +1,67 @@
// Copyright 2000-2018 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.codeInsight.hints
import com.intellij.codeHighlighting.EditorBoundHighlightingPass
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.EditorFactory
import com.intellij.openapi.editor.ex.util.CaretVisualPositionKeeper
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.util.Key
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.SyntaxTraverser
abstract class ElementProcessingHintPass(
val rootElement: PsiElement,
val editor: Editor
) : EditorBoundHighlightingPass(editor, rootElement.containingFile, true) {
private val traverser: SyntaxTraverser<PsiElement> = SyntaxTraverser.psiTraverser(rootElement)
override fun doCollectInformation(progress: ProgressIndicator) {
assert(myDocument != null)
clearCollected()
val virtualFile = rootElement.containingFile?.originalFile?.virtualFile ?: return
if (isAvailable(virtualFile)) {
traverser.forEach { collectElementHints(it) }
}
}
override fun doApplyInformationToEditor() {
val keeper = CaretVisualPositionKeeper(myEditor)
applyHintsToEditor()
keeper.restoreOriginalLocation(false)
if (rootElement === myFile) {
modificationStampHolder.putCurrentModificationStamp(myEditor, myFile)
}
}
abstract fun isAvailable(virtualFile: VirtualFile): Boolean
abstract fun collectElementHints(element: PsiElement)
abstract fun applyHintsToEditor()
abstract fun clearCollected()
abstract val modificationStampHolder: ModificationStampHolder
}
class ModificationStampHolder (val key: Key<Long>) {
fun putCurrentModificationStamp(editor: Editor, file: PsiFile) {
editor.putUserData<Long>(key, ParameterHintsPassFactory.getCurrentModificationStamp(file))
}
private fun forceHintsUpdateOnNextPass(editor: Editor) {
editor.putUserData<Long>(key, null)
}
fun forceHintsUpdateOnNextPass() {
EditorFactory.getInstance().allEditors.forEach { forceHintsUpdateOnNextPass(it) }
}
}
@@ -17,6 +17,6 @@ class MethodChainHintsConfigurable : BeanConfigurable<CodeInsightSettings>(CodeI
override fun apply() {
super.apply()
AnnotationHintsPassFactory.forceHintsUpdateOnNextPass()
MethodChainHintsPassFactory.modificationStampHolder.forceHintsUpdateOnNextPass()
}
}
@@ -1,36 +1,31 @@
// Copyright 2000-2018 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.codeInsight.hints
import com.intellij.codeHighlighting.EditorBoundHighlightingPass
import com.intellij.codeInsight.CodeInsightSettings
import com.intellij.codeInsight.daemon.impl.HintRenderer
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.ex.util.CaretVisualPositionKeeper
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.Key
import com.intellij.psi.*
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.PsiType
import com.intellij.psi.PsiWhiteSpace
import com.intellij.util.DocumentUtil
import com.siyeh.ig.psiutils.ExpressionUtils
import gnu.trove.TIntObjectHashMap
class MethodChainHintsPass(private val rootElement: PsiElement, editor: Editor) : EditorBoundHighlightingPass(editor,
rootElement.containingFile,
true) {
class MethodChainHintsPass(
override val modificationStampHolder: ModificationStampHolder,
rootElement: PsiElement,
editor: Editor
) : ElementProcessingHintPass(rootElement, editor) {
private val hints = TIntObjectHashMap<String>()
private val traverser: SyntaxTraverser<PsiElement> = SyntaxTraverser.psiTraverser(rootElement)
override fun doCollectInformation(progress: ProgressIndicator) {
assert(myDocument != null)
hints.clear()
override fun isAvailable(virtualFile: VirtualFile) = CodeInsightSettings.getInstance().SHOW_METHOD_CHAIN_TYPES_INLINE
val virtualFile = rootElement.containingFile?.originalFile?.virtualFile
if (virtualFile != null && CodeInsightSettings.getInstance().SHOW_METHOD_CHAIN_TYPES_INLINE) {
traverser.forEach { process(it) }
}
}
private fun process(element: PsiElement) {
override fun collectElementHints(element: PsiElement) {
val call = element as? PsiMethodCallExpression ?: return
val qualifier = call.methodExpression.qualifierExpression
if (qualifier != null && qualifier is PsiMethodCallExpression) {
@@ -71,9 +66,7 @@ class MethodChainHintsPass(private val rootElement: PsiElement, editor: Editor)
return chain
}
override fun doApplyInformationToEditor() {
val keeper = CaretVisualPositionKeeper(myEditor)
override fun applyHintsToEditor() {
val inlayModel = myEditor.inlayModel
val toRemove = inlayModel.getInlineElementsInRange(rootElement.textRange.startOffset + 1, rootElement.textRange.endOffset - 1)
@@ -92,19 +85,18 @@ class MethodChainHintsPass(private val rootElement: PsiElement, editor: Editor)
true
}
}
}
keeper.restoreOriginalLocation(false)
private class MethodChainHintRenderer(text: String) : HintRenderer(text) {
override fun getContextMenuGroupId() = "MethodChainHintsContextMenu"
}
if (rootElement === myFile) {
AnnotationHintsPassFactory.putCurrentModificationStamp(myEditor, myFile)
}
override fun clearCollected() {
hints.clear()
}
companion object {
private val METHOD_CHAIN_INLAY_KEY = Key.create<Boolean>("METHOD_CHAIN_INLAY_KEY")
}
private class MethodChainHintRenderer(text: String) : HintRenderer(text) {
override fun getContextMenuGroupId() = "MethodChainHintsContextMenu"
}
}
@@ -7,6 +7,7 @@ import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar
import com.intellij.openapi.components.AbstractProjectComponent
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Key
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiJavaFile
@@ -21,7 +22,11 @@ class MethodChainHintsPassFactory(project: Project, registrar: TextEditorHighlig
if (editor.isOneLineMode
|| file !is PsiJavaFile
|| AnnotationHintsPassFactory.LAST_PASS_MODIFICATION_TIMESTAMP.get(editor, 0) == ParameterHintsPassFactory.getCurrentModificationStamp(file)) return null
return MethodChainHintsPass(file, editor)
return MethodChainHintsPass(modificationStampHolder, file, editor)
}
companion object {
val modificationStampHolder = ModificationStampHolder(Key.create("METHOD_CHAIN_PASS_LAST_MODIFICATION_TIMESTAMP"))
}
}
+1 -1
View File
@@ -496,7 +496,7 @@
<group id="MethodChainHintsContextMenu" popup="true">
<action id="MethodChainHintAction"
class="com.intellij.codeInsight.hints.MethodChainHintTurningAction"
text="Toggle method chain hints"/>
text="Show Method chain hints"/>
<separator/>
<reference ref="EditorPopupMenu"/>
</group>