Register Kotlin specific highlight passes via highlightingPassFactory in 193+

This commit is contained in:
Vladimir Dolzhenko
2020-03-18 14:40:03 +01:00
parent 2e20cdf2e6
commit 3cdcdbf6a8
9 changed files with 452 additions and 64 deletions
@@ -5,19 +5,16 @@
package org.jetbrains.kotlin.idea.highlighter package org.jetbrains.kotlin.idea.highlighter
import com.intellij.codeHighlighting.Pass import com.intellij.codeHighlighting.*
import com.intellij.codeHighlighting.TextEditorHighlightingPass
import com.intellij.codeHighlighting.TextEditorHighlightingPassFactory
import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar
import com.intellij.codeInsight.daemon.impl.AnnotationHolderImpl import com.intellij.codeInsight.daemon.impl.AnnotationHolderImpl
import com.intellij.codeInsight.daemon.impl.HighlightInfo import com.intellij.codeInsight.daemon.impl.HighlightInfo
import com.intellij.codeInsight.daemon.impl.UpdateHighlightersUtil import com.intellij.codeInsight.daemon.impl.UpdateHighlightersUtil
import com.intellij.lang.annotation.AnnotationSession import com.intellij.lang.annotation.AnnotationSession
import com.intellij.openapi.components.ProjectComponent
import com.intellij.openapi.editor.Document import com.intellij.openapi.editor.Document
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import com.intellij.openapi.progress.ProgressIndicator import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.project.DumbAware import com.intellij.openapi.project.DumbAware
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile import com.intellij.psi.PsiFile
import com.intellij.psi.PsiRecursiveElementVisitor import com.intellij.psi.PsiRecursiveElementVisitor
@@ -52,20 +49,22 @@ class KotlinBeforeResolveHighlightingPass(
annotationHolder = null annotationHolder = null
} }
class Factory(registrar: TextEditorHighlightingPassRegistrar) : ProjectComponent, TextEditorHighlightingPassFactory { class Factory : TextEditorHighlightingPassFactory {
init { override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass? {
if (file !is KtFile) return null
return KotlinBeforeResolveHighlightingPass(file, editor.document)
}
}
class Registrar : TextEditorHighlightingPassFactoryRegistrar {
override fun registerHighlightingPassFactory(registrar: TextEditorHighlightingPassRegistrar, project: Project) {
registrar.registerTextEditorHighlightingPass( registrar.registerTextEditorHighlightingPass(
this, Factory(),
TextEditorHighlightingPassRegistrar.Anchor.BEFORE, TextEditorHighlightingPassRegistrar.Anchor.BEFORE,
Pass.UPDATE_FOLDING, Pass.UPDATE_FOLDING,
false, false,
false false
) )
} }
override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass? {
if (file !is KtFile) return null
return KotlinBeforeResolveHighlightingPass(file, editor.document)
}
} }
} }
@@ -0,0 +1,71 @@
/*
* Copyright 2010-2019 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.Pass
import com.intellij.codeHighlighting.TextEditorHighlightingPass
import com.intellij.codeHighlighting.TextEditorHighlightingPassFactory
import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar
import com.intellij.codeInsight.daemon.impl.AnnotationHolderImpl
import com.intellij.codeInsight.daemon.impl.HighlightInfo
import com.intellij.codeInsight.daemon.impl.UpdateHighlightersUtil
import com.intellij.lang.annotation.AnnotationSession
import com.intellij.openapi.components.ProjectComponent
import com.intellij.openapi.editor.Document
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.project.DumbAware
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiRecursiveElementVisitor
import org.jetbrains.kotlin.psi.KtFile
class KotlinBeforeResolveHighlightingPass(
private val file: KtFile,
document: Document
) : TextEditorHighlightingPass(file.project, document), DumbAware {
@Volatile
private var annotationHolder: AnnotationHolderImpl? = null
override fun doCollectInformation(progress: ProgressIndicator) {
val annotationHolder = AnnotationHolderImpl(AnnotationSession(file))
val visitor = BeforeResolveHighlightingVisitor(annotationHolder)
file.accept(object : PsiRecursiveElementVisitor() {
override fun visitElement(element: PsiElement) {
super.visitElement(element)
element.accept(visitor)
}
})
this.annotationHolder = annotationHolder
}
override fun doApplyInformationToEditor() {
if (annotationHolder == null) return
val infos = annotationHolder!!.map { HighlightInfo.fromAnnotation(it) }
UpdateHighlightersUtil.setHighlightersToEditor(myProject, myDocument!!, 0, file.textLength, infos, colorsScheme, id)
annotationHolder = null
}
class Factory(registrar: TextEditorHighlightingPassRegistrar) : ProjectComponent, TextEditorHighlightingPassFactory {
init {
registrar.registerTextEditorHighlightingPass(
this,
TextEditorHighlightingPassRegistrar.Anchor.BEFORE,
Pass.UPDATE_FOLDING,
false,
false
)
}
override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass? {
if (file !is KtFile) return null
return KotlinBeforeResolveHighlightingPass(file, editor.document)
}
}
}
@@ -16,21 +16,18 @@
package org.jetbrains.kotlin.idea.highlighter package org.jetbrains.kotlin.idea.highlighter
import com.intellij.codeHighlighting.Pass import com.intellij.codeHighlighting.*
import com.intellij.codeHighlighting.TextEditorHighlightingPass
import com.intellij.codeHighlighting.TextEditorHighlightingPassFactory
import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar
import com.intellij.codeInsight.daemon.impl.HighlightInfo import com.intellij.codeInsight.daemon.impl.HighlightInfo
import com.intellij.codeInsight.daemon.impl.UpdateHighlightersUtil import com.intellij.codeInsight.daemon.impl.UpdateHighlightersUtil
import com.intellij.lang.annotation.Annotation import com.intellij.lang.annotation.Annotation
import com.intellij.lang.annotation.HighlightSeverity import com.intellij.lang.annotation.HighlightSeverity
import com.intellij.lang.annotation.HighlightSeverity.* import com.intellij.lang.annotation.HighlightSeverity.*
import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.ProjectComponent
import com.intellij.openapi.editor.Document import com.intellij.openapi.editor.Document
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import com.intellij.openapi.progress.ProgressIndicator import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.project.DumbAware import com.intellij.openapi.project.DumbAware
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.MessageType import com.intellij.openapi.ui.MessageType
import com.intellij.openapi.wm.WindowManager import com.intellij.openapi.wm.WindowManager
import com.intellij.openapi.wm.ex.StatusBarEx import com.intellij.openapi.wm.ex.StatusBarEx
@@ -128,18 +125,19 @@ class ScriptExternalHighlightingPass(
} }
} }
class Factory(registrar: TextEditorHighlightingPassRegistrar) : ProjectComponent, class Registrar : TextEditorHighlightingPassFactoryRegistrar {
TextEditorHighlightingPassFactory { override fun registerHighlightingPassFactory(registrar: TextEditorHighlightingPassRegistrar, project: Project) {
init {
registrar.registerTextEditorHighlightingPass( registrar.registerTextEditorHighlightingPass(
this, Factory(),
TextEditorHighlightingPassRegistrar.Anchor.BEFORE, TextEditorHighlightingPassRegistrar.Anchor.BEFORE,
Pass.UPDATE_FOLDING, Pass.UPDATE_FOLDING,
false, false,
false false
) )
} }
}
class Factory : TextEditorHighlightingPassFactory {
override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass? { override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass? {
if (file !is KtFile) return null if (file !is KtFile) return null
return ScriptExternalHighlightingPass(file, editor.document) return ScriptExternalHighlightingPass(file, editor.document)
@@ -0,0 +1,148 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.highlighter
import com.intellij.codeHighlighting.Pass
import com.intellij.codeHighlighting.TextEditorHighlightingPass
import com.intellij.codeHighlighting.TextEditorHighlightingPassFactory
import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar
import com.intellij.codeInsight.daemon.impl.HighlightInfo
import com.intellij.codeInsight.daemon.impl.UpdateHighlightersUtil
import com.intellij.lang.annotation.Annotation
import com.intellij.lang.annotation.HighlightSeverity
import com.intellij.lang.annotation.HighlightSeverity.*
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.ProjectComponent
import com.intellij.openapi.editor.Document
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.project.DumbAware
import com.intellij.openapi.ui.MessageType
import com.intellij.openapi.wm.WindowManager
import com.intellij.openapi.wm.ex.StatusBarEx
import com.intellij.psi.PsiFile
import com.intellij.util.ui.UIUtil
import org.jetbrains.kotlin.idea.core.script.IdeScriptReportSink
import org.jetbrains.kotlin.idea.script.ScriptDiagnosticFixProvider
import org.jetbrains.kotlin.psi.KtFile
import kotlin.script.experimental.api.ScriptDiagnostic
import kotlin.script.experimental.api.SourceCode
class ScriptExternalHighlightingPass(
private val file: KtFile,
document: Document
) : TextEditorHighlightingPass(file.project, document), DumbAware {
override fun doCollectInformation(progress: ProgressIndicator) = Unit
override fun doApplyInformationToEditor() {
val document = document ?: return
if (!file.isScript()) return
val reports = IdeScriptReportSink.getReports(file)
val annotations = reports.mapNotNull { scriptDiagnostic ->
val (startOffset, endOffset) = scriptDiagnostic.location?.let { computeOffsets(document, it) } ?: 0 to 0
val exception = scriptDiagnostic.exception
val exceptionMessage = if (exception != null) " ($exception)" else ""
val message = scriptDiagnostic.message + exceptionMessage
val annotation = Annotation(
startOffset,
endOffset,
scriptDiagnostic.severity.convertSeverity() ?: return@mapNotNull null,
message,
message
)
// if range is empty, show notification panel in editor
annotation.isFileLevelAnnotation = startOffset == endOffset
for (provider in ScriptDiagnosticFixProvider.EP_NAME.extensions) {
provider.provideFixes(scriptDiagnostic).forEach {
annotation.registerFix(it)
}
}
annotation
}
val infos = annotations.map { HighlightInfo.fromAnnotation(it) }
UpdateHighlightersUtil.setHighlightersToEditor(myProject, myDocument!!, 0, file.textLength, infos, colorsScheme, id)
}
private fun computeOffsets(document: Document, position: SourceCode.Location): Pair<Int, Int> {
val startLine = position.start.line.coerceLineIn(document)
val startOffset = document.offsetBy(startLine, position.start.col)
val endLine = position.end?.line?.coerceAtLeast(startLine)?.coerceLineIn(document) ?: startLine
val endOffset = document.offsetBy(
endLine,
position.end?.col ?: document.getLineEndOffset(endLine)
).coerceAtLeast(startOffset)
return startOffset to endOffset
}
private fun Int.coerceLineIn(document: Document) = coerceIn(0, document.lineCount - 1)
private fun Document.offsetBy(line: Int, col: Int): Int {
return (getLineStartOffset(line) + col).coerceIn(getLineStartOffset(line), getLineEndOffset(line))
}
private fun ScriptDiagnostic.Severity.convertSeverity(): HighlightSeverity? {
return when (this) {
ScriptDiagnostic.Severity.FATAL -> ERROR
ScriptDiagnostic.Severity.ERROR -> ERROR
ScriptDiagnostic.Severity.WARNING -> WARNING
ScriptDiagnostic.Severity.INFO -> INFORMATION
ScriptDiagnostic.Severity.DEBUG -> if (ApplicationManager.getApplication().isInternal) INFORMATION else null
}
}
private fun showNotification(file: KtFile, message: String) {
UIUtil.invokeLaterIfNeeded {
val ideFrame = WindowManager.getInstance().getIdeFrame(file.project)
if (ideFrame != null) {
val statusBar = ideFrame.statusBar as StatusBarEx
statusBar.notifyProgressByBalloon(
MessageType.WARNING,
message,
null,
null
)
}
}
}
class Factory(registrar: TextEditorHighlightingPassRegistrar) : ProjectComponent,
TextEditorHighlightingPassFactory {
init {
registrar.registerTextEditorHighlightingPass(
this,
TextEditorHighlightingPassRegistrar.Anchor.BEFORE,
Pass.UPDATE_FOLDING,
false,
false
)
}
override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass? {
if (file !is KtFile) return null
return ScriptExternalHighlightingPass(file, editor.document)
}
}
}
+5 -13
View File
@@ -1,18 +1,5 @@
<idea-plugin> <idea-plugin>
<project-components> <project-components>
<component>
<implementation-class>org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Factory</implementation-class>
</component>
<component>
<implementation-class>org.jetbrains.kotlin.idea.parameterInfo.custom.KotlinCodeHintsPass$Companion$Factory</implementation-class>
</component>
<component>
<implementation-class>org.jetbrains.kotlin.idea.refactoring.cutPaste.MoveDeclarationsPassFactory</implementation-class>
<skipForDefaultProject/>
</component>
<component>
<implementation-class>org.jetbrains.kotlin.idea.highlighter.ScriptExternalHighlightingPass$Factory</implementation-class>
</component>
<component> <component>
<implementation-class>org.jetbrains.kotlin.idea.completion.LookupCancelWatcher</implementation-class> <implementation-class>org.jetbrains.kotlin.idea.completion.LookupCancelWatcher</implementation-class>
</component> </component>
@@ -232,6 +219,11 @@
<applicationService serviceImplementation="org.jetbrains.kotlin.idea.PluginStartupService" /> <applicationService serviceImplementation="org.jetbrains.kotlin.idea.PluginStartupService" />
<postStartupActivity implementation="org.jetbrains.kotlin.idea.PluginStartupActivity"/> <postStartupActivity implementation="org.jetbrains.kotlin.idea.PluginStartupActivity"/>
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Registrar"/>
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.ScriptExternalHighlightingPass$Registrar"/>
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.parameterInfo.custom.KotlinCodeHintsPass$Registrar"/>
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.refactoring.cutPaste.MoveDeclarationsPassFactory$Registrar"/>
<applicationService serviceInterface="org.jetbrains.kotlin.idea.KotlinIconProviderService" <applicationService serviceInterface="org.jetbrains.kotlin.idea.KotlinIconProviderService"
serviceImplementation="org.jetbrains.kotlin.idea.KotlinIdeFileIconProviderService"/> serviceImplementation="org.jetbrains.kotlin.idea.KotlinIdeFileIconProviderService"/>
@@ -5,16 +5,13 @@
package org.jetbrains.kotlin.idea.parameterInfo.custom package org.jetbrains.kotlin.idea.parameterInfo.custom
import com.intellij.codeHighlighting.EditorBoundHighlightingPass import com.intellij.codeHighlighting.*
import com.intellij.codeHighlighting.TextEditorHighlightingPass
import com.intellij.codeHighlighting.TextEditorHighlightingPassFactory
import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar
import com.intellij.codeInsight.hints.InlayParameterHintsExtension import com.intellij.codeInsight.hints.InlayParameterHintsExtension
import com.intellij.diff.util.DiffUtil import com.intellij.diff.util.DiffUtil
import com.intellij.openapi.components.ProjectComponent
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable import com.intellij.openapi.editor.ex.EditorSettingsExternalizable
import com.intellij.openapi.progress.ProgressIndicator import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile import com.intellij.psi.PsiFile
import com.intellij.psi.SyntaxTraverser import com.intellij.psi.SyntaxTraverser
@@ -84,18 +81,27 @@ class KotlinCodeHintsPass(private val myRootElement: PsiElement, editor: Editor)
return myDocument != null && myDocument.textLength == rootRange.length return myDocument != null && myDocument.textLength == rootRange.length
} }
companion object {
class Factory(registrar: TextEditorHighlightingPassRegistrar) : ProjectComponent, TextEditorHighlightingPassFactory {
init {
registrar.registerTextEditorHighlightingPass(this, null, null, false, -1)
}
override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass? { class Registrar : TextEditorHighlightingPassFactoryRegistrar {
if (file.language != KotlinLanguage.INSTANCE) return null override fun registerHighlightingPassFactory(registrar: TextEditorHighlightingPassRegistrar, project: Project) {
return KotlinCodeHintsPass(file, editor) registrar.registerTextEditorHighlightingPass(
} Factory(),
null,
null,
false,
-1
)
} }
}
class Factory : TextEditorHighlightingPassFactory {
override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass? {
if (file.language != KotlinLanguage.INSTANCE) return null
return KotlinCodeHintsPass(file, editor)
}
}
companion object {
private val isEnabled: Boolean private val isEnabled: Boolean
get() = get() =
EditorSettingsExternalizable.getInstance().isShowParameterNameHints EditorSettingsExternalizable.getInstance().isShowParameterNameHints
@@ -0,0 +1,103 @@
/*
* Copyright 2010-2019 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.parameterInfo.custom
import com.intellij.codeHighlighting.EditorBoundHighlightingPass
import com.intellij.codeHighlighting.TextEditorHighlightingPass
import com.intellij.codeHighlighting.TextEditorHighlightingPassFactory
import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar
import com.intellij.codeInsight.hints.InlayParameterHintsExtension
import com.intellij.diff.util.DiffUtil
import com.intellij.openapi.components.ProjectComponent
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.SyntaxTraverser
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.idea.parameterInfo.HintType
import org.jetbrains.kotlin.idea.parameterInfo.TYPE_INFO_PREFIX
import org.jetbrains.kotlin.idea.parameterInfo.provideLambdaReturnValueHints
import org.jetbrains.kotlin.psi.KtExpression
import java.util.*
class KotlinCodeHintsPass(private val myRootElement: PsiElement, editor: Editor) :
EditorBoundHighlightingPass(editor, myRootElement.containingFile, true) {
private val myTraverser: SyntaxTraverser<PsiElement> = SyntaxTraverser.psiTraverser(myRootElement)
override fun doCollectInformation(progress: ProgressIndicator) {
if (myFile.language != KotlinLanguage.INSTANCE) return
if (myDocument == null) return
val kotlinCodeHintsModel = KotlinCodeHintsModel.getInstance(myRootElement.project)
val provider = InlayParameterHintsExtension.forLanguage(KotlinLanguage.INSTANCE)
if (provider == null || !provider.canShowHintsWhenDisabled() && !isEnabled || DiffUtil.isDiffEditor(myEditor)) {
kotlinCodeHintsModel.removeAll(myDocument)
return
}
if (HintType.LAMBDA_RETURN_EXPRESSION.enabled) {
val actualHints = HashMap<PsiElement, String>()
myTraverser.forEach { element -> processLambdaReturnHints(element, actualHints) }
kotlinCodeHintsModel.update(myDocument, actualHints)
} else {
kotlinCodeHintsModel.removeAll(myDocument)
}
}
private fun processLambdaReturnHints(element: PsiElement, actualElements: MutableMap<PsiElement, String>) {
if (element !is KtExpression) return
for (returnHint in provideLambdaReturnValueHints(element)) {
val offset = returnHint.offset
if (!canShowHintsAtOffset(offset)) continue
actualElements[element] = returnHint.text.substringAfter(TYPE_INFO_PREFIX)
}
}
override fun doApplyInformationToEditor() {
// Information will be painted with org.jetbrains.kotlin.idea.parameterInfo.custom.ReturnHintLinePainter
}
/**
* Adding hints on the borders of root element (at startOffset or endOffset)
* is allowed only in the case when root element is a document
*
* @return true iff a given offset can be used for hint rendering
*/
private fun canShowHintsAtOffset(offset: Int): Boolean {
val rootRange = myRootElement.textRange
if (rootRange.startOffset < offset && offset < rootRange.endOffset) {
return true
}
return myDocument != null && myDocument.textLength == rootRange.length
}
companion object {
class Factory(registrar: TextEditorHighlightingPassRegistrar) : ProjectComponent, TextEditorHighlightingPassFactory {
init {
registrar.registerTextEditorHighlightingPass(this, null, null, false, -1)
}
override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass? {
if (file.language != KotlinLanguage.INSTANCE) return null
return KotlinCodeHintsPass(file, editor)
}
}
private val isEnabled: Boolean
get() =
EditorSettingsExternalizable.getInstance().isShowParameterNameHints
}
}
@@ -5,15 +5,11 @@
package org.jetbrains.kotlin.idea.refactoring.cutPaste package org.jetbrains.kotlin.idea.refactoring.cutPaste
import com.intellij.codeHighlighting.Pass import com.intellij.codeHighlighting.*
import com.intellij.codeHighlighting.TextEditorHighlightingPass
import com.intellij.codeHighlighting.TextEditorHighlightingPassFactory
import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar
import com.intellij.codeInsight.daemon.impl.HighlightInfo import com.intellij.codeInsight.daemon.impl.HighlightInfo
import com.intellij.codeInsight.daemon.impl.HighlightInfoType import com.intellij.codeInsight.daemon.impl.HighlightInfoType
import com.intellij.codeInsight.daemon.impl.UpdateHighlightersUtil import com.intellij.codeInsight.daemon.impl.UpdateHighlightersUtil
import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction
import com.intellij.openapi.components.ProjectComponent
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import com.intellij.openapi.progress.ProgressIndicator import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
@@ -21,17 +17,18 @@ import com.intellij.psi.PsiFile
import com.intellij.psi.util.PsiModificationTracker import com.intellij.psi.util.PsiModificationTracker
import org.jetbrains.kotlin.idea.core.util.range import org.jetbrains.kotlin.idea.core.util.range
class MoveDeclarationsPassFactory(highlightingPassRegistrar: TextEditorHighlightingPassRegistrar) : ProjectComponent, class MoveDeclarationsPassFactory : TextEditorHighlightingPassFactory {
TextEditorHighlightingPassFactory {
init { class Registrar : TextEditorHighlightingPassFactoryRegistrar {
highlightingPassRegistrar.registerTextEditorHighlightingPass( override fun registerHighlightingPassFactory(registrar: TextEditorHighlightingPassRegistrar, project: Project) {
this, registrar.registerTextEditorHighlightingPass(
TextEditorHighlightingPassRegistrar.Anchor.BEFORE, MoveDeclarationsPassFactory(),
Pass.POPUP_HINTS, TextEditorHighlightingPassRegistrar.Anchor.BEFORE,
true, Pass.POPUP_HINTS,
true true,
) true
)
}
} }
override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass? { override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass? {
@@ -0,0 +1,74 @@
/*
* Copyright 2010-2019 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.refactoring.cutPaste
import com.intellij.codeHighlighting.Pass
import com.intellij.codeHighlighting.TextEditorHighlightingPass
import com.intellij.codeHighlighting.TextEditorHighlightingPassFactory
import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar
import com.intellij.codeInsight.daemon.impl.HighlightInfo
import com.intellij.codeInsight.daemon.impl.HighlightInfoType
import com.intellij.codeInsight.daemon.impl.UpdateHighlightersUtil
import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction
import com.intellij.openapi.components.ProjectComponent
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiFile
import com.intellij.psi.util.PsiModificationTracker
import org.jetbrains.kotlin.idea.core.util.range
class MoveDeclarationsPassFactory(highlightingPassRegistrar: TextEditorHighlightingPassRegistrar) : ProjectComponent,
TextEditorHighlightingPassFactory {
init {
highlightingPassRegistrar.registerTextEditorHighlightingPass(
this,
TextEditorHighlightingPassRegistrar.Anchor.BEFORE,
Pass.POPUP_HINTS,
true,
true
)
}
override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass? {
return MyPass(file.project, file, editor)
}
private class MyPass(
private val project: Project,
private val file: PsiFile,
private val editor: Editor
) : TextEditorHighlightingPass(project, editor.document, true) {
override fun doCollectInformation(progress: ProgressIndicator) {}
override fun doApplyInformationToEditor() {
val info = buildHighlightingInfo()
UpdateHighlightersUtil.setHighlightersToEditor(project, myDocument!!, 0, file.textLength, listOfNotNull(info), colorsScheme, id)
}
private fun buildHighlightingInfo(): HighlightInfo? {
val cookie = editor.getUserData(MoveDeclarationsEditorCookie.KEY) ?: return null
if (cookie.modificationCount != PsiModificationTracker.SERVICE.getInstance(project).modificationCount) return null
val processor = MoveDeclarationsProcessor.build(editor, cookie)
if (processor == null) {
editor.putUserData(MoveDeclarationsEditorCookie.KEY, null)
return null
}
val info = HighlightInfo.newHighlightInfo(HighlightInfoType.INFORMATION)
.range(cookie.bounds.range!!)
.createUnconditionally()
QuickFixAction.registerQuickFixAction(info, MoveDeclarationsIntentionAction(processor, cookie.bounds, cookie.modificationCount))
return info
}
}
}