From 7b8d5016704b0b9fd6b2e68bb98888e5117d6ecd Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Thu, 1 Feb 2018 17:14:22 +0100 Subject: [PATCH] Dsl highlighting: Provide gutter for marker annotation definition Allows to jump to corresponding page in 'color and font' settings --- .../dsl/DslHighlighterExtension.kt | 22 ++++--- .../markers/DslHighlightingMarker.kt | 59 +++++++++++++++++++ .../markers/KotlinLineMarkerProvider.kt | 1 + 3 files changed, 70 insertions(+), 12 deletions(-) create mode 100644 idea/src/org/jetbrains/kotlin/idea/highlighter/markers/DslHighlightingMarker.kt diff --git a/idea/src/org/jetbrains/kotlin/idea/highlighter/dsl/DslHighlighterExtension.kt b/idea/src/org/jetbrains/kotlin/idea/highlighter/dsl/DslHighlighterExtension.kt index 0068c39a1d1..ca6373d8120 100644 --- a/idea/src/org/jetbrains/kotlin/idea/highlighter/dsl/DslHighlighterExtension.kt +++ b/idea/src/org/jetbrains/kotlin/idea/highlighter/dsl/DslHighlighterExtension.kt @@ -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 + } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/DslHighlightingMarker.kt b/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/DslHighlightingMarker.kt new file mode 100644 index 00000000000..25518811c29 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/DslHighlightingMarker.kt @@ -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 { 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> +) { + if (ktClass.styleIdForMarkerAnnotation() == null) return + + val anchor = ktClass.nameIdentifier ?: return + + result.add( + LineMarkerInfo( + 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) +} + diff --git a/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/KotlinLineMarkerProvider.kt b/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/KotlinLineMarkerProvider.kt index 3f81cccc61d..a0502f9e972 100644 --- a/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/KotlinLineMarkerProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/KotlinLineMarkerProvider.kt @@ -96,6 +96,7 @@ class KotlinLineMarkerProvider : LineMarkerProvider { when (element) { is KtClass -> { collectInheritedClassMarker(element, result) + collectHighlightingColorsMarkers(element, result) } is KtNamedFunction -> { functions.add(element)