Highlighting visitor: refactoring
Do not call AnnotationHolder functions directly, only via HighlightingVisitor
This commit is contained in:
+7
-8
@@ -30,11 +30,10 @@ import org.jetbrains.kotlin.lexer.KtTokens
|
|||||||
import org.jetbrains.kotlin.psi.KtExpressionWithLabel
|
import org.jetbrains.kotlin.psi.KtExpressionWithLabel
|
||||||
import org.jetbrains.kotlin.psi.KtLambdaExpression
|
import org.jetbrains.kotlin.psi.KtLambdaExpression
|
||||||
import org.jetbrains.kotlin.psi.KtValueArgument
|
import org.jetbrains.kotlin.psi.KtValueArgument
|
||||||
import org.jetbrains.kotlin.psi.KtVisitorVoid
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
|
|
||||||
internal class BeforeResolveHighlightingVisitor(private val holder: AnnotationHolder) : KtVisitorVoid() {
|
internal class BeforeResolveHighlightingVisitor(holder: AnnotationHolder) : HighlightingVisitor(holder) {
|
||||||
|
|
||||||
override fun visitElement(element: PsiElement) {
|
override fun visitElement(element: PsiElement) {
|
||||||
val elementType = element.node.elementType
|
val elementType = element.node.elementType
|
||||||
@@ -51,7 +50,7 @@ internal class BeforeResolveHighlightingVisitor(private val holder: AnnotationHo
|
|||||||
else -> return
|
else -> return
|
||||||
}
|
}
|
||||||
|
|
||||||
holder.createInfoAnnotation(element, null).textAttributes = attributes
|
createInfoAnnotation(element, null).textAttributes = attributes
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun willApplyRainbowHighlight(element: KDocLink): Boolean {
|
private fun willApplyRainbowHighlight(element: KDocLink): Boolean {
|
||||||
@@ -66,29 +65,29 @@ internal class BeforeResolveHighlightingVisitor(private val holder: AnnotationHo
|
|||||||
if (ApplicationManager.getApplication().isUnitTestMode) return
|
if (ApplicationManager.getApplication().isUnitTestMode) return
|
||||||
|
|
||||||
val functionLiteral = lambdaExpression.functionLiteral
|
val functionLiteral = lambdaExpression.functionLiteral
|
||||||
holder.createInfoAnnotation(functionLiteral.lBrace, null).textAttributes = KotlinHighlightingColors.FUNCTION_LITERAL_BRACES_AND_ARROW
|
createInfoAnnotation(functionLiteral.lBrace, null).textAttributes = KotlinHighlightingColors.FUNCTION_LITERAL_BRACES_AND_ARROW
|
||||||
|
|
||||||
val closingBrace = functionLiteral.rBrace
|
val closingBrace = functionLiteral.rBrace
|
||||||
if (closingBrace != null) {
|
if (closingBrace != null) {
|
||||||
holder.createInfoAnnotation(closingBrace, null).textAttributes = KotlinHighlightingColors.FUNCTION_LITERAL_BRACES_AND_ARROW
|
createInfoAnnotation(closingBrace, null).textAttributes = KotlinHighlightingColors.FUNCTION_LITERAL_BRACES_AND_ARROW
|
||||||
}
|
}
|
||||||
|
|
||||||
val arrow = functionLiteral.arrow
|
val arrow = functionLiteral.arrow
|
||||||
if (arrow != null) {
|
if (arrow != null) {
|
||||||
holder.createInfoAnnotation(arrow, null).textAttributes = KotlinHighlightingColors.FUNCTION_LITERAL_BRACES_AND_ARROW
|
createInfoAnnotation(arrow, null).textAttributes = KotlinHighlightingColors.FUNCTION_LITERAL_BRACES_AND_ARROW
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitArgument(argument: KtValueArgument) {
|
override fun visitArgument(argument: KtValueArgument) {
|
||||||
val argumentName = argument.getArgumentName() ?: return
|
val argumentName = argument.getArgumentName() ?: return
|
||||||
val eq = argument.equalsToken ?: return
|
val eq = argument.equalsToken ?: return
|
||||||
holder.createInfoAnnotation(TextRange(argumentName.startOffset, eq.endOffset), null).textAttributes = KotlinHighlightingColors.NAMED_ARGUMENT
|
createInfoAnnotation(TextRange(argumentName.startOffset, eq.endOffset), null).textAttributes = KotlinHighlightingColors.NAMED_ARGUMENT
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitExpressionWithLabel(expression: KtExpressionWithLabel) {
|
override fun visitExpressionWithLabel(expression: KtExpressionWithLabel) {
|
||||||
val targetLabel = expression.getTargetLabel()
|
val targetLabel = expression.getTargetLabel()
|
||||||
if (targetLabel != null) {
|
if (targetLabel != null) {
|
||||||
holder.highlightName(targetLabel, KotlinHighlightingColors.LABEL)
|
highlightName(targetLabel, KotlinHighlightingColors.LABEL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -36,7 +36,7 @@ internal class FunctionsHighlightingVisitor(holder: AnnotationHolder, bindingCon
|
|||||||
AfterAnalysisHighlightingVisitor(holder, bindingContext) {
|
AfterAnalysisHighlightingVisitor(holder, bindingContext) {
|
||||||
|
|
||||||
override fun visitNamedFunction(function: KtNamedFunction) {
|
override fun visitNamedFunction(function: KtNamedFunction) {
|
||||||
function.nameIdentifier?.let { holder.highlightName(it, FUNCTION_DECLARATION) }
|
function.nameIdentifier?.let { highlightName(it, FUNCTION_DECLARATION) }
|
||||||
|
|
||||||
super.visitNamedFunction(function)
|
super.visitNamedFunction(function)
|
||||||
}
|
}
|
||||||
@@ -45,7 +45,7 @@ internal class FunctionsHighlightingVisitor(holder: AnnotationHolder, bindingCon
|
|||||||
val calleeExpression = call.calleeExpression
|
val calleeExpression = call.calleeExpression
|
||||||
val typeElement = calleeExpression.typeReference?.typeElement
|
val typeElement = calleeExpression.typeReference?.typeElement
|
||||||
if (typeElement is KtUserType) {
|
if (typeElement is KtUserType) {
|
||||||
typeElement.referenceExpression?.let { holder.highlightName(it, CONSTRUCTOR_CALL) }
|
typeElement.referenceExpression?.let { highlightName(it, CONSTRUCTOR_CALL) }
|
||||||
}
|
}
|
||||||
super.visitSuperTypeCallEntry(call)
|
super.visitSuperTypeCallEntry(call)
|
||||||
}
|
}
|
||||||
@@ -74,19 +74,19 @@ internal class FunctionsHighlightingVisitor(holder: AnnotationHolder, bindingCon
|
|||||||
val calleeDescriptor = resolvedCall.resultingDescriptor
|
val calleeDescriptor = resolvedCall.resultingDescriptor
|
||||||
|
|
||||||
if (calleeDescriptor.isDynamic()) {
|
if (calleeDescriptor.isDynamic()) {
|
||||||
holder.highlightName(callee, DYNAMIC_FUNCTION_CALL)
|
highlightName(callee, DYNAMIC_FUNCTION_CALL)
|
||||||
}
|
}
|
||||||
else if (resolvedCall is VariableAsFunctionResolvedCall) {
|
else if (resolvedCall is VariableAsFunctionResolvedCall) {
|
||||||
val container = calleeDescriptor.containingDeclaration
|
val container = calleeDescriptor.containingDeclaration
|
||||||
val containedInFunctionClassOrSubclass = container is ClassDescriptor && container.defaultType.isFunctionTypeOrSubtype
|
val containedInFunctionClassOrSubclass = container is ClassDescriptor && container.defaultType.isFunctionTypeOrSubtype
|
||||||
holder.highlightName(callee, if (containedInFunctionClassOrSubclass)
|
highlightName(callee, if (containedInFunctionClassOrSubclass)
|
||||||
VARIABLE_AS_FUNCTION_CALL
|
VARIABLE_AS_FUNCTION_CALL
|
||||||
else
|
else
|
||||||
VARIABLE_AS_FUNCTION_LIKE_CALL)
|
VARIABLE_AS_FUNCTION_LIKE_CALL)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (calleeDescriptor is ConstructorDescriptor) {
|
if (calleeDescriptor is ConstructorDescriptor) {
|
||||||
holder.highlightName(callee, CONSTRUCTOR_CALL)
|
highlightName(callee, CONSTRUCTOR_CALL)
|
||||||
}
|
}
|
||||||
else if (calleeDescriptor is FunctionDescriptor) {
|
else if (calleeDescriptor is FunctionDescriptor) {
|
||||||
val attributesKey = when {
|
val attributesKey = when {
|
||||||
@@ -100,7 +100,7 @@ internal class FunctionsHighlightingVisitor(holder: AnnotationHolder, bindingCon
|
|||||||
FUNCTION_CALL
|
FUNCTION_CALL
|
||||||
}
|
}
|
||||||
|
|
||||||
holder.highlightName(callee, attributesKey)
|
highlightName(callee, attributesKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-1
@@ -16,7 +16,30 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.highlighter
|
package org.jetbrains.kotlin.idea.highlighter
|
||||||
|
|
||||||
|
import com.intellij.lang.annotation.Annotation
|
||||||
import com.intellij.lang.annotation.AnnotationHolder
|
import com.intellij.lang.annotation.AnnotationHolder
|
||||||
|
import com.intellij.openapi.editor.colors.TextAttributesKey
|
||||||
|
import com.intellij.openapi.util.TextRange
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.psi.KtVisitorVoid
|
import org.jetbrains.kotlin.psi.KtVisitorVoid
|
||||||
|
|
||||||
abstract class HighlightingVisitor protected constructor(protected var holder: AnnotationHolder) : KtVisitorVoid()
|
abstract class HighlightingVisitor protected constructor(private var holder: AnnotationHolder) : KtVisitorVoid() {
|
||||||
|
|
||||||
|
protected fun createInfoAnnotation(element: PsiElement, message: String? = null): Annotation =
|
||||||
|
createInfoAnnotation(element.textRange, message)
|
||||||
|
|
||||||
|
protected fun createInfoAnnotation(textRange: TextRange, message: String? = null): Annotation =
|
||||||
|
holder.createInfoAnnotation(textRange, message)
|
||||||
|
|
||||||
|
protected fun highlightName(element: PsiElement, attributesKey: TextAttributesKey, message: String? = null) {
|
||||||
|
if (NameHighlighter.namesHighlightingEnabled) {
|
||||||
|
createInfoAnnotation(element, message).textAttributes = attributesKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun highlightName(textRange: TextRange, attributesKey: TextAttributesKey, message: String? = null) {
|
||||||
|
if (NameHighlighter.namesHighlightingEnabled) {
|
||||||
|
createInfoAnnotation(textRange, message).textAttributes = attributesKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,10 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.highlighter
|
package org.jetbrains.kotlin.idea.highlighter
|
||||||
|
|
||||||
import com.intellij.lang.annotation.AnnotationHolder
|
|
||||||
import com.intellij.openapi.editor.colors.TextAttributesKey
|
|
||||||
import com.intellij.openapi.util.TextRange
|
|
||||||
import com.intellij.psi.PsiElement
|
|
||||||
import org.jetbrains.annotations.TestOnly
|
import org.jetbrains.annotations.TestOnly
|
||||||
|
|
||||||
object NameHighlighter {
|
object NameHighlighter {
|
||||||
@@ -27,14 +23,3 @@ object NameHighlighter {
|
|||||||
@TestOnly set
|
@TestOnly set
|
||||||
}
|
}
|
||||||
|
|
||||||
fun AnnotationHolder.highlightName(element: PsiElement, attributesKey: TextAttributesKey) {
|
|
||||||
if (NameHighlighter.namesHighlightingEnabled) {
|
|
||||||
createInfoAnnotation(element, null).textAttributes = attributesKey
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun AnnotationHolder.highlightName(textRange: TextRange, attributesKey: TextAttributesKey) {
|
|
||||||
if (NameHighlighter.namesHighlightingEnabled) {
|
|
||||||
createInfoAnnotation(textRange, null).textAttributes = attributesKey
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+2
-2
@@ -38,7 +38,7 @@ internal class PropertiesHighlightingVisitor(holder: AnnotationHolder, bindingCo
|
|||||||
}
|
}
|
||||||
val target = bindingContext.get(BindingContext.REFERENCE_TARGET, expression)
|
val target = bindingContext.get(BindingContext.REFERENCE_TARGET, expression)
|
||||||
if (target is SyntheticFieldDescriptor) {
|
if (target is SyntheticFieldDescriptor) {
|
||||||
holder.highlightName(expression, BACKING_FIELD_VARIABLE)
|
highlightName(expression, BACKING_FIELD_VARIABLE)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (target !is PropertyDescriptor) {
|
if (target !is PropertyDescriptor) {
|
||||||
@@ -85,6 +85,6 @@ internal class PropertiesHighlightingVisitor(holder: AnnotationHolder, bindingCo
|
|||||||
else ->
|
else ->
|
||||||
INSTANCE_PROPERTY
|
INSTANCE_PROPERTY
|
||||||
}
|
}
|
||||||
holder.highlightName(elementToHighlight, attributesKey)
|
highlightName(elementToHighlight, attributesKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -51,11 +51,11 @@ internal class TypeKindHighlightingVisitor(holder: AnnotationHolder, bindingCont
|
|||||||
highlightAnnotation(expression)
|
highlightAnnotation(expression)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
holder.highlightName(expression, textAttributesKeyForClass(referenceTarget))
|
highlightName(expression, textAttributesKeyForClass(referenceTarget))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (referenceTarget is TypeParameterDescriptor) {
|
else if (referenceTarget is TypeParameterDescriptor) {
|
||||||
holder.highlightName(expression, TYPE_PARAMETER)
|
highlightName(expression, TYPE_PARAMETER)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,11 +74,11 @@ internal class TypeKindHighlightingVisitor(holder: AnnotationHolder, bindingCont
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
holder.highlightName(range, ANNOTATION)
|
highlightName(range, ANNOTATION)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitTypeParameter(parameter: KtTypeParameter) {
|
override fun visitTypeParameter(parameter: KtTypeParameter) {
|
||||||
parameter.nameIdentifier?.let { holder.highlightName(it, TYPE_PARAMETER) }
|
parameter.nameIdentifier?.let { highlightName(it, TYPE_PARAMETER) }
|
||||||
super.visitTypeParameter(parameter)
|
super.visitTypeParameter(parameter)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ internal class TypeKindHighlightingVisitor(holder: AnnotationHolder, bindingCont
|
|||||||
val identifier = classOrObject.nameIdentifier
|
val identifier = classOrObject.nameIdentifier
|
||||||
val classDescriptor = bindingContext.get(BindingContext.CLASS, classOrObject)
|
val classDescriptor = bindingContext.get(BindingContext.CLASS, classOrObject)
|
||||||
if (identifier != null && classDescriptor != null) {
|
if (identifier != null && classDescriptor != null) {
|
||||||
holder.highlightName(identifier, textAttributesKeyForClass(classDescriptor))
|
highlightName(identifier, textAttributesKeyForClass(classDescriptor))
|
||||||
}
|
}
|
||||||
super.visitClassOrObject(classOrObject)
|
super.visitClassOrObject(classOrObject)
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-13
@@ -42,7 +42,7 @@ internal class VariablesHighlightingVisitor(holder: AnnotationHolder, bindingCon
|
|||||||
val target = bindingContext.get(REFERENCE_TARGET, expression) ?: return
|
val target = bindingContext.get(REFERENCE_TARGET, expression) ?: return
|
||||||
if (target is ValueParameterDescriptor) {
|
if (target is ValueParameterDescriptor) {
|
||||||
if (bindingContext.get(AUTO_CREATED_IT, target) == true) {
|
if (bindingContext.get(AUTO_CREATED_IT, target) == true) {
|
||||||
holder.createInfoAnnotation(expression, "Automatically declared based on the expected type")
|
createInfoAnnotation(expression, "Automatically declared based on the expected type")
|
||||||
.textAttributes = FUNCTION_LITERAL_DEFAULT_PARAMETER
|
.textAttributes = FUNCTION_LITERAL_DEFAULT_PARAMETER
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -89,15 +89,15 @@ internal class VariablesHighlightingVisitor(holder: AnnotationHolder, bindingCon
|
|||||||
is ImplicitClassReceiver -> "Implicit receiver"
|
is ImplicitClassReceiver -> "Implicit receiver"
|
||||||
else -> "Unknown receiver"
|
else -> "Unknown receiver"
|
||||||
}
|
}
|
||||||
holder.createInfoAnnotation(expression,
|
createInfoAnnotation(expression,
|
||||||
"$receiverName smart cast to " + DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(type))
|
"$receiverName smart cast to " + DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(type))
|
||||||
.textAttributes = SMART_CAST_RECEIVER
|
.textAttributes = SMART_CAST_RECEIVER
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val nullSmartCast = bindingContext.get(SMARTCAST_NULL, expression) == true
|
val nullSmartCast = bindingContext.get(SMARTCAST_NULL, expression) == true
|
||||||
if (nullSmartCast) {
|
if (nullSmartCast) {
|
||||||
holder.createInfoAnnotation(expression, "Always null")
|
createInfoAnnotation(expression, "Always null")
|
||||||
.textAttributes = SMART_CONSTANT
|
.textAttributes = SMART_CONSTANT
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,14 +105,14 @@ internal class VariablesHighlightingVisitor(holder: AnnotationHolder, bindingCon
|
|||||||
if (smartCast != null) {
|
if (smartCast != null) {
|
||||||
val defaultType = smartCast.defaultType
|
val defaultType = smartCast.defaultType
|
||||||
if (defaultType != null) {
|
if (defaultType != null) {
|
||||||
holder.createInfoAnnotation(getSmartCastTarget(expression),
|
createInfoAnnotation(getSmartCastTarget(expression),
|
||||||
"Smart cast to " + DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(defaultType))
|
"Smart cast to " + DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(defaultType))
|
||||||
.textAttributes = SMART_CAST_VALUE
|
.textAttributes = SMART_CAST_VALUE
|
||||||
}
|
}
|
||||||
else if (smartCast is MultipleSmartCasts) {
|
else if (smartCast is MultipleSmartCasts) {
|
||||||
for ((call, type) in smartCast.map) {
|
for ((call, type) in smartCast.map) {
|
||||||
holder.createInfoAnnotation(getSmartCastTarget(expression),
|
createInfoAnnotation(getSmartCastTarget(expression),
|
||||||
"Smart cast to ${DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(type)} (for $call call)")
|
"Smart cast to ${DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(type)} (for $call call)")
|
||||||
.textAttributes = SMART_CAST_VALUE
|
.textAttributes = SMART_CAST_VALUE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,12 +133,12 @@ internal class VariablesHighlightingVisitor(holder: AnnotationHolder, bindingCon
|
|||||||
if (descriptor is VariableDescriptor) {
|
if (descriptor is VariableDescriptor) {
|
||||||
|
|
||||||
if (descriptor.isDynamic()) {
|
if (descriptor.isDynamic()) {
|
||||||
holder.highlightName(elementToHighlight, DYNAMIC_PROPERTY_CALL)
|
highlightName(elementToHighlight, DYNAMIC_PROPERTY_CALL)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (descriptor.isVar) {
|
if (descriptor.isVar) {
|
||||||
holder.highlightName(elementToHighlight, MUTABLE_VARIABLE)
|
highlightName(elementToHighlight, MUTABLE_VARIABLE)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bindingContext.get(CAPTURED_IN_CLOSURE, descriptor) == CaptureKind.NOT_INLINE) {
|
if (bindingContext.get(CAPTURED_IN_CLOSURE, descriptor) == CaptureKind.NOT_INLINE) {
|
||||||
@@ -149,16 +149,16 @@ internal class VariablesHighlightingVisitor(holder: AnnotationHolder, bindingCon
|
|||||||
|
|
||||||
val parent = elementToHighlight.parent
|
val parent = elementToHighlight.parent
|
||||||
if (!(parent is PsiNameIdentifierOwner && parent.nameIdentifier == elementToHighlight)) {
|
if (!(parent is PsiNameIdentifierOwner && parent.nameIdentifier == elementToHighlight)) {
|
||||||
holder.createInfoAnnotation(elementToHighlight, msg).textAttributes = WRAPPED_INTO_REF
|
createInfoAnnotation(elementToHighlight, msg).textAttributes = WRAPPED_INTO_REF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (descriptor is LocalVariableDescriptor && descriptor !is SyntheticFieldDescriptor) {
|
if (descriptor is LocalVariableDescriptor && descriptor !is SyntheticFieldDescriptor) {
|
||||||
holder.highlightName(elementToHighlight, LOCAL_VARIABLE)
|
highlightName(elementToHighlight, LOCAL_VARIABLE)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (descriptor is ValueParameterDescriptor) {
|
if (descriptor is ValueParameterDescriptor) {
|
||||||
holder.highlightName(elementToHighlight, PARAMETER)
|
highlightName(elementToHighlight, PARAMETER)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user