Dsl highlighting: Provide gutter for marker annotation definition

Allows to jump to corresponding page in 'color and font' settings
This commit is contained in:
Pavel V. Talanov
2018-02-01 17:14:22 +01:00
parent 0d5d826bc5
commit 7b8d501670
3 changed files with 70 additions and 12 deletions
@@ -11,8 +11,6 @@ import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.idea.highlighter.HighlighterExtension
import org.jetbrains.kotlin.idea.highlighter.KotlinHighlightingColors
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
@@ -24,16 +22,12 @@ class DslHighlighterExtension : HighlighterExtension() {
}
override fun highlightCall(elementToHighlight: PsiElement, resolvedCall: ResolvedCall<*>): TextAttributesKey? {
val markerAnnotationFqName = markerAnnotationFqName(resolvedCall) ?: return null
return styleForDsl(markerAnnotationFqName)
}
private fun markerAnnotationFqName(resolvedCall: ResolvedCall<*>): FqName? {
val markerAnnotation = resolvedCall.resultingDescriptor.annotations.find { annotation ->
annotation.annotationClass?.isDslHighlightingMarker() ?: false
}
}?.annotationClass ?: return null
return markerAnnotation?.fqName
val styleId = styleIdByMarkerAnnotation(markerAnnotation) ?: return null
return styles[styleId - 1]
}
companion object {
@@ -51,11 +45,15 @@ class DslHighlighterExtension : HighlighterExtension() {
}
val descriptionsToStyles = (1..numStyles).associate { index ->
"Dsl//Style$index" to styles[index - 1]
"Dsl//${styleOptionDisplayName(index)}" to styles[index - 1]
}
private fun styleForDsl(markerAnnotationFqName: FqName) =
styles[(markerAnnotationFqName.asString().hashCode() % numStyles).absoluteValue]
fun styleOptionDisplayName(index: Int) = "Style$index"
fun styleIdByMarkerAnnotation(markerAnnotation: ClassDescriptor): Int? {
val markerAnnotationFqName = markerAnnotation.fqNameSafe
return (markerAnnotationFqName.asString().hashCode() % numStyles).absoluteValue + 1
}
}
}
@@ -0,0 +1,59 @@
/*
* 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/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.highlighter.markers
import com.intellij.application.options.colors.ColorAndFontOptions
import com.intellij.codeHighlighting.Pass
import com.intellij.codeInsight.daemon.GutterIconNavigationHandler
import com.intellij.codeInsight.daemon.LineMarkerInfo
import com.intellij.icons.AllIcons
import com.intellij.ide.DataManager
import com.intellij.openapi.editor.markup.GutterIconRenderer
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.idea.core.toDescriptor
import org.jetbrains.kotlin.idea.highlighter.dsl.DslHighlighterExtension
import org.jetbrains.kotlin.idea.highlighter.dsl.isDslHighlightingMarker
import org.jetbrains.kotlin.psi.KtClass
import javax.swing.JComponent
private val navHandler = GutterIconNavigationHandler<PsiElement> { event, element ->
val dataContext = (event.component as? JComponent)?.let { DataManager.getInstance().getDataContext(it) }
?: return@GutterIconNavigationHandler
val ktClass = element?.parent as? KtClass ?: return@GutterIconNavigationHandler
val styleId = ktClass.styleIdForMarkerAnnotation() ?: return@GutterIconNavigationHandler
ColorAndFontOptions.selectOrEditColor(dataContext, DslHighlighterExtension.styleOptionDisplayName(styleId), KotlinLanguage.NAME)
}
fun collectHighlightingColorsMarkers(
ktClass: KtClass,
result: MutableCollection<LineMarkerInfo<*>>
) {
if (ktClass.styleIdForMarkerAnnotation() == null) return
val anchor = ktClass.nameIdentifier ?: return
result.add(
LineMarkerInfo<PsiElement>(
anchor,
anchor.textRange,
AllIcons.Gutter.Colors,
Pass.LINE_MARKERS,
null, navHandler,
GutterIconRenderer.Alignment.RIGHT
)
)
}
private fun KtClass.styleIdForMarkerAnnotation(): Int? {
val classDescriptor = toDescriptor() as? ClassDescriptor ?: return null
if (classDescriptor.kind != ClassKind.ANNOTATION_CLASS) return null
if (!classDescriptor.isDslHighlightingMarker()) return null
return DslHighlighterExtension.styleIdByMarkerAnnotation(classDescriptor)
}
@@ -96,6 +96,7 @@ class KotlinLineMarkerProvider : LineMarkerProvider {
when (element) {
is KtClass -> {
collectInheritedClassMarker(element, result)
collectHighlightingColorsMarkers(element, result)
}
is KtNamedFunction -> {
functions.add(element)