From 3cdcdbf6a88df6b5c590041c537a4eed591328ab Mon Sep 17 00:00:00 2001 From: Vladimir Dolzhenko Date: Wed, 18 Mar 2020 14:40:03 +0100 Subject: [PATCH] Register Kotlin specific highlight passes via highlightingPassFactory in 193+ --- .../KotlinBeforeResolveHighlightingPass.kt | 25 ++- ...KotlinBeforeResolveHighlightingPass.kt.192 | 71 +++++++++ .../ScriptExternalHighlightingPass.kt | 16 +- .../ScriptExternalHighlightingPass.kt.192 | 148 ++++++++++++++++++ idea/resources/META-INF/plugin-common.xml | 18 +-- .../custom/KotlinCodeHintsPass.kt | 34 ++-- .../custom/KotlinCodeHintsPass.kt.192 | 103 ++++++++++++ .../cutPaste/MoveDeclarationsPassFactory.kt | 27 ++-- .../MoveDeclarationsPassFactory.kt.192 | 74 +++++++++ 9 files changed, 452 insertions(+), 64 deletions(-) create mode 100644 idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/KotlinBeforeResolveHighlightingPass.kt.192 create mode 100644 idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/ScriptExternalHighlightingPass.kt.192 create mode 100644 idea/src/org/jetbrains/kotlin/idea/parameterInfo/custom/KotlinCodeHintsPass.kt.192 create mode 100644 idea/src/org/jetbrains/kotlin/idea/refactoring/cutPaste/MoveDeclarationsPassFactory.kt.192 diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/KotlinBeforeResolveHighlightingPass.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/KotlinBeforeResolveHighlightingPass.kt index ffa13718fe9..a4c3c879c21 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/KotlinBeforeResolveHighlightingPass.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/KotlinBeforeResolveHighlightingPass.kt @@ -5,19 +5,16 @@ 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.codeHighlighting.* 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.openapi.project.Project import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile import com.intellij.psi.PsiRecursiveElementVisitor @@ -52,20 +49,22 @@ class KotlinBeforeResolveHighlightingPass( annotationHolder = null } - class Factory(registrar: TextEditorHighlightingPassRegistrar) : ProjectComponent, TextEditorHighlightingPassFactory { - init { + class Factory : TextEditorHighlightingPassFactory { + 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( - this, + Factory(), 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) - } } } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/KotlinBeforeResolveHighlightingPass.kt.192 b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/KotlinBeforeResolveHighlightingPass.kt.192 new file mode 100644 index 00000000000..ffa13718fe9 --- /dev/null +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/KotlinBeforeResolveHighlightingPass.kt.192 @@ -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) + } + } +} diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/ScriptExternalHighlightingPass.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/ScriptExternalHighlightingPass.kt index d137df5dbb9..76f909df438 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/ScriptExternalHighlightingPass.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/ScriptExternalHighlightingPass.kt @@ -16,21 +16,18 @@ 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.codeHighlighting.* 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.project.Project import com.intellij.openapi.ui.MessageType import com.intellij.openapi.wm.WindowManager import com.intellij.openapi.wm.ex.StatusBarEx @@ -128,18 +125,19 @@ class ScriptExternalHighlightingPass( } } - class Factory(registrar: TextEditorHighlightingPassRegistrar) : ProjectComponent, - TextEditorHighlightingPassFactory { - init { + class Registrar : TextEditorHighlightingPassFactoryRegistrar { + override fun registerHighlightingPassFactory(registrar: TextEditorHighlightingPassRegistrar, project: Project) { registrar.registerTextEditorHighlightingPass( - this, + Factory(), TextEditorHighlightingPassRegistrar.Anchor.BEFORE, Pass.UPDATE_FOLDING, false, false ) } + } + class Factory : TextEditorHighlightingPassFactory { override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass? { if (file !is KtFile) return null return ScriptExternalHighlightingPass(file, editor.document) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/ScriptExternalHighlightingPass.kt.192 b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/ScriptExternalHighlightingPass.kt.192 new file mode 100644 index 00000000000..d137df5dbb9 --- /dev/null +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/ScriptExternalHighlightingPass.kt.192 @@ -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 { + 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) + } + } +} diff --git a/idea/resources/META-INF/plugin-common.xml b/idea/resources/META-INF/plugin-common.xml index ca7628e9522..a54b73b8702 100644 --- a/idea/resources/META-INF/plugin-common.xml +++ b/idea/resources/META-INF/plugin-common.xml @@ -1,18 +1,5 @@ - - org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Factory - - - org.jetbrains.kotlin.idea.parameterInfo.custom.KotlinCodeHintsPass$Companion$Factory - - - org.jetbrains.kotlin.idea.refactoring.cutPaste.MoveDeclarationsPassFactory - - - - org.jetbrains.kotlin.idea.highlighter.ScriptExternalHighlightingPass$Factory - org.jetbrains.kotlin.idea.completion.LookupCancelWatcher @@ -232,6 +219,11 @@ + + + + + diff --git a/idea/src/org/jetbrains/kotlin/idea/parameterInfo/custom/KotlinCodeHintsPass.kt b/idea/src/org/jetbrains/kotlin/idea/parameterInfo/custom/KotlinCodeHintsPass.kt index 37194d8026f..e6b706cdca4 100644 --- a/idea/src/org/jetbrains/kotlin/idea/parameterInfo/custom/KotlinCodeHintsPass.kt +++ b/idea/src/org/jetbrains/kotlin/idea/parameterInfo/custom/KotlinCodeHintsPass.kt @@ -5,16 +5,13 @@ 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.codeHighlighting.* 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.openapi.project.Project import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile import com.intellij.psi.SyntaxTraverser @@ -84,18 +81,27 @@ class KotlinCodeHintsPass(private val myRootElement: PsiElement, editor: Editor) 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) - } + class Registrar : TextEditorHighlightingPassFactoryRegistrar { + override fun registerHighlightingPassFactory(registrar: TextEditorHighlightingPassRegistrar, project: Project) { + 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 get() = EditorSettingsExternalizable.getInstance().isShowParameterNameHints diff --git a/idea/src/org/jetbrains/kotlin/idea/parameterInfo/custom/KotlinCodeHintsPass.kt.192 b/idea/src/org/jetbrains/kotlin/idea/parameterInfo/custom/KotlinCodeHintsPass.kt.192 new file mode 100644 index 00000000000..37194d8026f --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/parameterInfo/custom/KotlinCodeHintsPass.kt.192 @@ -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 = 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() + myTraverser.forEach { element -> processLambdaReturnHints(element, actualHints) } + + kotlinCodeHintsModel.update(myDocument, actualHints) + } else { + kotlinCodeHintsModel.removeAll(myDocument) + } + } + + private fun processLambdaReturnHints(element: PsiElement, actualElements: MutableMap) { + 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 + } +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/cutPaste/MoveDeclarationsPassFactory.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/cutPaste/MoveDeclarationsPassFactory.kt index 8a12a75343c..ba2a4530855 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/cutPaste/MoveDeclarationsPassFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/cutPaste/MoveDeclarationsPassFactory.kt @@ -5,15 +5,11 @@ 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.codeHighlighting.* 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 @@ -21,17 +17,18 @@ 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 { +class MoveDeclarationsPassFactory : TextEditorHighlightingPassFactory { - init { - highlightingPassRegistrar.registerTextEditorHighlightingPass( - this, - TextEditorHighlightingPassRegistrar.Anchor.BEFORE, - Pass.POPUP_HINTS, - true, - true - ) + class Registrar : TextEditorHighlightingPassFactoryRegistrar { + override fun registerHighlightingPassFactory(registrar: TextEditorHighlightingPassRegistrar, project: Project) { + registrar.registerTextEditorHighlightingPass( + MoveDeclarationsPassFactory(), + TextEditorHighlightingPassRegistrar.Anchor.BEFORE, + Pass.POPUP_HINTS, + true, + true + ) + } } override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass? { diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/cutPaste/MoveDeclarationsPassFactory.kt.192 b/idea/src/org/jetbrains/kotlin/idea/refactoring/cutPaste/MoveDeclarationsPassFactory.kt.192 new file mode 100644 index 00000000000..8a12a75343c --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/cutPaste/MoveDeclarationsPassFactory.kt.192 @@ -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 + } + } +}