KT-32368 Rework Inline hints settings // remove outdated KotlinCodeHintsPass
Some time ago platform couldn't place hints at the end of a line. This is how KotlinCodeHintsPass appeared. Class was responsible for lambda related hints. Now that platform evolved functionality was moved to KotlinLambdasHintsProvider.
This commit is contained in:
@@ -89,7 +89,6 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
|
|||||||
|
|
||||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Registrar"/>
|
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Registrar"/>
|
||||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.ScriptExternalHighlightingPass$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"/>
|
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.refactoring.cutPaste.MoveDeclarationsPassFactory$Registrar"/>
|
||||||
|
|
||||||
<projectService serviceImplementation="org.jetbrains.kotlin.idea.caches.trackers.KotlinCodeBlockModificationListener"/>
|
<projectService serviceImplementation="org.jetbrains.kotlin.idea.caches.trackers.KotlinCodeBlockModificationListener"/>
|
||||||
|
|||||||
@@ -78,9 +78,6 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
|
|||||||
<component>
|
<component>
|
||||||
<implementation-class>org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Factory</implementation-class>
|
<implementation-class>org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Factory</implementation-class>
|
||||||
</component>
|
</component>
|
||||||
<component>
|
|
||||||
<implementation-class>org.jetbrains.kotlin.idea.parameterInfo.custom.KotlinCodeHintsPass$Companion$Factory</implementation-class>
|
|
||||||
</component>
|
|
||||||
<component>
|
<component>
|
||||||
<implementation-class>org.jetbrains.kotlin.idea.refactoring.cutPaste.MoveDeclarationsPassFactory</implementation-class>
|
<implementation-class>org.jetbrains.kotlin.idea.refactoring.cutPaste.MoveDeclarationsPassFactory</implementation-class>
|
||||||
<skipForDefaultProject/>
|
<skipForDefaultProject/>
|
||||||
|
|||||||
@@ -95,7 +95,6 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
|
|||||||
|
|
||||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Registrar"/>
|
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Registrar"/>
|
||||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.ScriptExternalHighlightingPass$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"/>
|
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.refactoring.cutPaste.MoveDeclarationsPassFactory$Registrar"/>
|
||||||
|
|
||||||
<statistics.counterUsagesCollector groupId="kotlin.gradle.target" version="2"/>
|
<statistics.counterUsagesCollector groupId="kotlin.gradle.target" version="2"/>
|
||||||
|
|||||||
@@ -89,7 +89,6 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
|
|||||||
|
|
||||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Registrar"/>
|
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Registrar"/>
|
||||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.ScriptExternalHighlightingPass$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"/>
|
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.refactoring.cutPaste.MoveDeclarationsPassFactory$Registrar"/>
|
||||||
|
|
||||||
<projectService serviceImplementation="org.jetbrains.kotlin.idea.caches.trackers.KotlinCodeBlockModificationListener"/>
|
<projectService serviceImplementation="org.jetbrains.kotlin.idea.caches.trackers.KotlinCodeBlockModificationListener"/>
|
||||||
|
|||||||
@@ -79,9 +79,6 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
|
|||||||
<component>
|
<component>
|
||||||
<implementation-class>org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Factory</implementation-class>
|
<implementation-class>org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Factory</implementation-class>
|
||||||
</component>
|
</component>
|
||||||
<component>
|
|
||||||
<implementation-class>org.jetbrains.kotlin.idea.parameterInfo.custom.KotlinCodeHintsPass$Companion$Factory</implementation-class>
|
|
||||||
</component>
|
|
||||||
<component>
|
<component>
|
||||||
<implementation-class>org.jetbrains.kotlin.idea.refactoring.cutPaste.MoveDeclarationsPassFactory</implementation-class>
|
<implementation-class>org.jetbrains.kotlin.idea.refactoring.cutPaste.MoveDeclarationsPassFactory</implementation-class>
|
||||||
<skipForDefaultProject/>
|
<skipForDefaultProject/>
|
||||||
|
|||||||
@@ -94,7 +94,6 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
|
|||||||
|
|
||||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Registrar"/>
|
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Registrar"/>
|
||||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.ScriptExternalHighlightingPass$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"/>
|
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.refactoring.cutPaste.MoveDeclarationsPassFactory$Registrar"/>
|
||||||
|
|
||||||
<fileTypeUsageSchemaDescriptor schema="Gradle Script" implementationClass="org.jetbrains.kotlin.idea.core.script.KotlinGradleScriptFileTypeSchemaDetector"/>
|
<fileTypeUsageSchemaDescriptor schema="Gradle Script" implementationClass="org.jetbrains.kotlin.idea.core.script.KotlinGradleScriptFileTypeSchemaDetector"/>
|
||||||
|
|||||||
@@ -88,7 +88,6 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
|
|||||||
|
|
||||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Registrar"/>
|
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Registrar"/>
|
||||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.ScriptExternalHighlightingPass$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"/>
|
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.refactoring.cutPaste.MoveDeclarationsPassFactory$Registrar"/>
|
||||||
|
|
||||||
<projectService serviceImplementation="org.jetbrains.kotlin.idea.caches.trackers.KotlinCodeBlockModificationListener"/>
|
<projectService serviceImplementation="org.jetbrains.kotlin.idea.caches.trackers.KotlinCodeBlockModificationListener"/>
|
||||||
|
|||||||
@@ -228,8 +228,6 @@
|
|||||||
|
|
||||||
<projectService serviceImplementation="org.jetbrains.kotlin.idea.compiler.configuration.KotlinCompilerSettings"/>
|
<projectService serviceImplementation="org.jetbrains.kotlin.idea.compiler.configuration.KotlinCompilerSettings"/>
|
||||||
|
|
||||||
<projectService serviceImplementation="org.jetbrains.kotlin.idea.parameterInfo.custom.KotlinCodeHintsModel"/>
|
|
||||||
|
|
||||||
<projectService serviceImplementation="org.jetbrains.kotlin.idea.compiler.configuration.KotlinCompilerWorkspaceSettings"/>
|
<projectService serviceImplementation="org.jetbrains.kotlin.idea.compiler.configuration.KotlinCompilerWorkspaceSettings"/>
|
||||||
|
|
||||||
<projectService serviceImplementation="org.jetbrains.kotlin.asJava.classes.FacadeCache"/>
|
<projectService serviceImplementation="org.jetbrains.kotlin.asJava.classes.FacadeCache"/>
|
||||||
|
|||||||
-44
@@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.codeInsight.hints.InlayParameterHintsExtension
|
|
||||||
import com.intellij.codeInsight.intention.IntentionAction
|
|
||||||
import com.intellij.codeInsight.intention.LowPriorityAction
|
|
||||||
import com.intellij.openapi.editor.Editor
|
|
||||||
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable
|
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import com.intellij.psi.PsiFile
|
|
||||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.hints.HintType
|
|
||||||
import org.jetbrains.kotlin.idea.util.refreshAllOpenEditors
|
|
||||||
|
|
||||||
class DisableReturnLambdaHintOptionAction : IntentionAction, LowPriorityAction {
|
|
||||||
override fun getText(): String {
|
|
||||||
return HintType.LAMBDA_RETURN_EXPRESSION.doNotShowDesc
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getFamilyName(): String = text
|
|
||||||
|
|
||||||
override fun isAvailable(project: Project, editor: Editor, file: PsiFile): Boolean {
|
|
||||||
if (file.language != KotlinLanguage.INSTANCE) return false
|
|
||||||
|
|
||||||
InlayParameterHintsExtension.forLanguage(file.language) ?: return false
|
|
||||||
|
|
||||||
if (!EditorSettingsExternalizable.getInstance().isShowParameterNameHints || !HintType.LAMBDA_RETURN_EXPRESSION.enabled) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return KotlinCodeHintsModel.getInstance(project).getExtensionInfoAtOffset(editor) != null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun invoke(project: Project, editor: Editor, file: PsiFile) {
|
|
||||||
HintType.LAMBDA_RETURN_EXPRESSION.option.set(false)
|
|
||||||
refreshAllOpenEditors()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun startInWriteAction(): Boolean = false
|
|
||||||
}
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.openapi.application.ApplicationManager
|
|
||||||
import com.intellij.openapi.editor.Document
|
|
||||||
import com.intellij.openapi.editor.Editor
|
|
||||||
import com.intellij.openapi.editor.EditorFactory
|
|
||||||
import com.intellij.openapi.editor.RangeMarker
|
|
||||||
import com.intellij.openapi.editor.event.EditorFactoryEvent
|
|
||||||
import com.intellij.openapi.editor.event.EditorFactoryListener
|
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import com.intellij.psi.PsiElement
|
|
||||||
import com.intellij.util.containers.ContainerUtil
|
|
||||||
import org.jetbrains.kotlin.idea.core.util.end
|
|
||||||
import org.jetbrains.kotlin.idea.core.util.range
|
|
||||||
import org.jetbrains.kotlin.idea.util.application.getServiceSafe
|
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
|
||||||
|
|
||||||
class KotlinCodeHintsModel(val project: Project) : EditorFactoryListener {
|
|
||||||
companion object {
|
|
||||||
fun getInstance(project: Project): KotlinCodeHintsModel = project.getServiceSafe()
|
|
||||||
}
|
|
||||||
|
|
||||||
private class DocumentExtensionInfoModel(val document: Document) {
|
|
||||||
private val lineEndMarkers = ConcurrentHashMap<RangeMarker, String>()
|
|
||||||
|
|
||||||
fun markEndOfLine(lineEndOffset: Int, hint: String) {
|
|
||||||
val endLineMarker = document.createRangeMarker(lineEndOffset, lineEndOffset)
|
|
||||||
endLineMarker.isGreedyToRight = true
|
|
||||||
|
|
||||||
lineEndMarkers[endLineMarker] = hint
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getExtensionAtOffset(offset: Int): String? {
|
|
||||||
return runReadAction {
|
|
||||||
// Protect operations working with the document offsets
|
|
||||||
|
|
||||||
lineEndMarkers
|
|
||||||
.entries
|
|
||||||
.firstOrNull { (marker, _) ->
|
|
||||||
val textRange = marker.range
|
|
||||||
if (textRange == null || !(textRange.startOffset <= offset && offset <= textRange.endOffset)) {
|
|
||||||
return@firstOrNull false
|
|
||||||
}
|
|
||||||
if (textRange.end > document.textLength) {
|
|
||||||
return@firstOrNull false
|
|
||||||
}
|
|
||||||
|
|
||||||
val document = marker.document
|
|
||||||
val hasNewLine = document.getText(textRange).contains('\n')
|
|
||||||
if (!hasNewLine) {
|
|
||||||
textRange.endOffset == offset
|
|
||||||
} else {
|
|
||||||
// New line may appear after session of fast typing with one or several enter hitting.
|
|
||||||
// We can't believe startOffset too because typing session may had started with
|
|
||||||
// typing adding several chars at the original line.
|
|
||||||
val originalLineNumber = document.getLineNumber(textRange.startOffset)
|
|
||||||
val currentOriginalLineEnd = document.getLineEndOffset(originalLineNumber)
|
|
||||||
|
|
||||||
currentOriginalLineEnd == offset
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun dispose() {
|
|
||||||
val keys = lineEndMarkers.keys()
|
|
||||||
ApplicationManager.getApplication().invokeLater {
|
|
||||||
for (marker in keys) {
|
|
||||||
marker.dispose()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val documentModels =
|
|
||||||
ContainerUtil.createConcurrentSoftMap<Document, DocumentExtensionInfoModel>()
|
|
||||||
|
|
||||||
init {
|
|
||||||
val editorFactory = EditorFactory.getInstance()
|
|
||||||
editorFactory.addEditorFactoryListener(this, project)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun editorReleased(event: EditorFactoryEvent) {
|
|
||||||
// Pass for other editor with the same document if present should re-add needed hints
|
|
||||||
removeAll(event.editor.document)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getExtensionInfoAtOffset(editor: Editor): String? {
|
|
||||||
return getExtensionInfo(editor.document, editor.caretModel.offset)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getExtensionInfo(document: Document, offset: Int): String? {
|
|
||||||
return documentModels[document]?.getExtensionAtOffset(offset)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun removeAll(document: Document) {
|
|
||||||
documentModels.remove(document)?.dispose()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun update(document: Document, actualHints: Map<PsiElement, String>) {
|
|
||||||
if (actualHints.isEmpty()) {
|
|
||||||
removeAll(document)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val updatedModel = runReadAction {
|
|
||||||
val model = DocumentExtensionInfoModel(document)
|
|
||||||
for ((element, hint) in actualHints) {
|
|
||||||
val lineNumber = document.getLineNumber(element.endOffset)
|
|
||||||
val lineEndOffset = document.getLineEndOffset(lineNumber)
|
|
||||||
|
|
||||||
model.markEndOfLine(lineEndOffset, hint)
|
|
||||||
}
|
|
||||||
|
|
||||||
model
|
|
||||||
}
|
|
||||||
|
|
||||||
documentModels.put(document, updatedModel)?.dispose()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.*
|
|
||||||
import com.intellij.codeInsight.hints.InlayParameterHintsExtension
|
|
||||||
import com.intellij.diff.util.DiffUtil
|
|
||||||
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
|
|
||||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.hints.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
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.codeInsight.hints.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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.openapi.editor.DefaultLanguageHighlighterColors
|
|
||||||
import com.intellij.openapi.editor.EditorLinePainter
|
|
||||||
import com.intellij.openapi.editor.LineExtensionInfo
|
|
||||||
import com.intellij.openapi.editor.colors.EditorColorsManager
|
|
||||||
import com.intellij.openapi.editor.markup.TextAttributes
|
|
||||||
import com.intellij.openapi.fileEditor.FileDocumentManager
|
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
|
||||||
import com.intellij.psi.PsiManager
|
|
||||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
|
||||||
|
|
||||||
class ReturnHintLinePainter : EditorLinePainter() {
|
|
||||||
companion object {
|
|
||||||
val SPACE_LINE_EXTENSION_INFO = LineExtensionInfo(" ", TextAttributes())
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getLineExtensions(project: Project, file: VirtualFile, lineNumber: Int): List<LineExtensionInfo>? {
|
|
||||||
if (!file.isValid) return null
|
|
||||||
|
|
||||||
val psiFile = PsiManager.getInstance(project).findFile(file) ?: return null
|
|
||||||
if (psiFile.language != KotlinLanguage.INSTANCE) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
val hint = getLineHint(project, file, lineNumber)
|
|
||||||
?: return null
|
|
||||||
|
|
||||||
val textAttributes =
|
|
||||||
EditorColorsManager.getInstance().globalScheme.getAttributes(DefaultLanguageHighlighterColors.INLINE_PARAMETER_HINT)
|
|
||||||
val hintLineInfo = LineExtensionInfo(hint, textAttributes)
|
|
||||||
|
|
||||||
return listOf(SPACE_LINE_EXTENSION_INFO, hintLineInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getLineHint(project: Project, file: VirtualFile, lineNumber: Int): String? {
|
|
||||||
val doc = FileDocumentManager.getInstance().getDocument(file) ?: return null
|
|
||||||
if (lineNumber >= doc.lineCount) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
val lineEndOffset = doc.getLineEndOffset(lineNumber)
|
|
||||||
|
|
||||||
return KotlinCodeHintsModel.getInstance(project).getExtensionInfo(doc, lineEndOffset)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.util
|
|
||||||
|
|
||||||
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer
|
|
||||||
import com.intellij.codeInsight.hints.ParameterHintsPassFactory
|
|
||||||
import com.intellij.openapi.fileEditor.FileEditorManager
|
|
||||||
import com.intellij.openapi.project.ProjectManager
|
|
||||||
import com.intellij.psi.PsiManager
|
|
||||||
|
|
||||||
fun refreshAllOpenEditors() {
|
|
||||||
ParameterHintsPassFactory.forceHintsUpdateOnNextPass();
|
|
||||||
ProjectManager.getInstance().openProjects.forEach { project ->
|
|
||||||
val psiManager = PsiManager.getInstance(project)
|
|
||||||
val daemonCodeAnalyzer = DaemonCodeAnalyzer.getInstance(project)
|
|
||||||
val fileEditorManager = FileEditorManager.getInstance(project)
|
|
||||||
|
|
||||||
DaemonCodeAnalyzer.getInstance(project).restart()
|
|
||||||
|
|
||||||
fileEditorManager.selectedFiles.forEach {
|
|
||||||
psiManager.findFile(it)?.let { daemonCodeAnalyzer.restart(it) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user