Highlighting visitor: refactoring

Do not call AnnotationHolder functions directly,
only via HighlightingVisitor
This commit is contained in:
Mikhail Glukhikh
2017-06-08 19:13:36 +03:00
parent f225d8dea5
commit aa3589004e
7 changed files with 57 additions and 50 deletions
@@ -30,11 +30,10 @@ import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtExpressionWithLabel
import org.jetbrains.kotlin.psi.KtLambdaExpression
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.startOffset
internal class BeforeResolveHighlightingVisitor(private val holder: AnnotationHolder) : KtVisitorVoid() {
internal class BeforeResolveHighlightingVisitor(holder: AnnotationHolder) : HighlightingVisitor(holder) {
override fun visitElement(element: PsiElement) {
val elementType = element.node.elementType
@@ -51,7 +50,7 @@ internal class BeforeResolveHighlightingVisitor(private val holder: AnnotationHo
else -> return
}
holder.createInfoAnnotation(element, null).textAttributes = attributes
createInfoAnnotation(element, null).textAttributes = attributes
}
private fun willApplyRainbowHighlight(element: KDocLink): Boolean {
@@ -66,29 +65,29 @@ internal class BeforeResolveHighlightingVisitor(private val holder: AnnotationHo
if (ApplicationManager.getApplication().isUnitTestMode) return
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
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
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) {
val argumentName = argument.getArgumentName() ?: 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) {
val targetLabel = expression.getTargetLabel()
if (targetLabel != null) {
holder.highlightName(targetLabel, KotlinHighlightingColors.LABEL)
highlightName(targetLabel, KotlinHighlightingColors.LABEL)
}
}
}
@@ -36,7 +36,7 @@ internal class FunctionsHighlightingVisitor(holder: AnnotationHolder, bindingCon
AfterAnalysisHighlightingVisitor(holder, bindingContext) {
override fun visitNamedFunction(function: KtNamedFunction) {
function.nameIdentifier?.let { holder.highlightName(it, FUNCTION_DECLARATION) }
function.nameIdentifier?.let { highlightName(it, FUNCTION_DECLARATION) }
super.visitNamedFunction(function)
}
@@ -45,7 +45,7 @@ internal class FunctionsHighlightingVisitor(holder: AnnotationHolder, bindingCon
val calleeExpression = call.calleeExpression
val typeElement = calleeExpression.typeReference?.typeElement
if (typeElement is KtUserType) {
typeElement.referenceExpression?.let { holder.highlightName(it, CONSTRUCTOR_CALL) }
typeElement.referenceExpression?.let { highlightName(it, CONSTRUCTOR_CALL) }
}
super.visitSuperTypeCallEntry(call)
}
@@ -74,19 +74,19 @@ internal class FunctionsHighlightingVisitor(holder: AnnotationHolder, bindingCon
val calleeDescriptor = resolvedCall.resultingDescriptor
if (calleeDescriptor.isDynamic()) {
holder.highlightName(callee, DYNAMIC_FUNCTION_CALL)
highlightName(callee, DYNAMIC_FUNCTION_CALL)
}
else if (resolvedCall is VariableAsFunctionResolvedCall) {
val container = calleeDescriptor.containingDeclaration
val containedInFunctionClassOrSubclass = container is ClassDescriptor && container.defaultType.isFunctionTypeOrSubtype
holder.highlightName(callee, if (containedInFunctionClassOrSubclass)
highlightName(callee, if (containedInFunctionClassOrSubclass)
VARIABLE_AS_FUNCTION_CALL
else
VARIABLE_AS_FUNCTION_LIKE_CALL)
}
else {
if (calleeDescriptor is ConstructorDescriptor) {
holder.highlightName(callee, CONSTRUCTOR_CALL)
highlightName(callee, CONSTRUCTOR_CALL)
}
else if (calleeDescriptor is FunctionDescriptor) {
val attributesKey = when {
@@ -100,7 +100,7 @@ internal class FunctionsHighlightingVisitor(holder: AnnotationHolder, bindingCon
FUNCTION_CALL
}
holder.highlightName(callee, attributesKey)
highlightName(callee, attributesKey)
}
}
}
@@ -16,7 +16,30 @@
package org.jetbrains.kotlin.idea.highlighter
import com.intellij.lang.annotation.Annotation
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
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
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
object NameHighlighter {
@@ -27,14 +23,3 @@ object NameHighlighter {
@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
}
}
@@ -38,7 +38,7 @@ internal class PropertiesHighlightingVisitor(holder: AnnotationHolder, bindingCo
}
val target = bindingContext.get(BindingContext.REFERENCE_TARGET, expression)
if (target is SyntheticFieldDescriptor) {
holder.highlightName(expression, BACKING_FIELD_VARIABLE)
highlightName(expression, BACKING_FIELD_VARIABLE)
return
}
if (target !is PropertyDescriptor) {
@@ -85,6 +85,6 @@ internal class PropertiesHighlightingVisitor(holder: AnnotationHolder, bindingCo
else ->
INSTANCE_PROPERTY
}
holder.highlightName(elementToHighlight, attributesKey)
highlightName(elementToHighlight, attributesKey)
}
}
@@ -51,11 +51,11 @@ internal class TypeKindHighlightingVisitor(holder: AnnotationHolder, bindingCont
highlightAnnotation(expression)
}
else {
holder.highlightName(expression, textAttributesKeyForClass(referenceTarget))
highlightName(expression, textAttributesKeyForClass(referenceTarget))
}
}
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) {
parameter.nameIdentifier?.let { holder.highlightName(it, TYPE_PARAMETER) }
parameter.nameIdentifier?.let { highlightName(it, TYPE_PARAMETER) }
super.visitTypeParameter(parameter)
}
@@ -86,7 +86,7 @@ internal class TypeKindHighlightingVisitor(holder: AnnotationHolder, bindingCont
val identifier = classOrObject.nameIdentifier
val classDescriptor = bindingContext.get(BindingContext.CLASS, classOrObject)
if (identifier != null && classDescriptor != null) {
holder.highlightName(identifier, textAttributesKeyForClass(classDescriptor))
highlightName(identifier, textAttributesKeyForClass(classDescriptor))
}
super.visitClassOrObject(classOrObject)
}
@@ -42,7 +42,7 @@ internal class VariablesHighlightingVisitor(holder: AnnotationHolder, bindingCon
val target = bindingContext.get(REFERENCE_TARGET, expression) ?: return
if (target is ValueParameterDescriptor) {
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
}
}
@@ -89,15 +89,15 @@ internal class VariablesHighlightingVisitor(holder: AnnotationHolder, bindingCon
is ImplicitClassReceiver -> "Implicit receiver"
else -> "Unknown receiver"
}
holder.createInfoAnnotation(expression,
"$receiverName smart cast to " + DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(type))
createInfoAnnotation(expression,
"$receiverName smart cast to " + DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(type))
.textAttributes = SMART_CAST_RECEIVER
}
}
val nullSmartCast = bindingContext.get(SMARTCAST_NULL, expression) == true
if (nullSmartCast) {
holder.createInfoAnnotation(expression, "Always null")
createInfoAnnotation(expression, "Always null")
.textAttributes = SMART_CONSTANT
}
@@ -105,14 +105,14 @@ internal class VariablesHighlightingVisitor(holder: AnnotationHolder, bindingCon
if (smartCast != null) {
val defaultType = smartCast.defaultType
if (defaultType != null) {
holder.createInfoAnnotation(getSmartCastTarget(expression),
"Smart cast to " + DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(defaultType))
createInfoAnnotation(getSmartCastTarget(expression),
"Smart cast to " + DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(defaultType))
.textAttributes = SMART_CAST_VALUE
}
else if (smartCast is MultipleSmartCasts) {
for ((call, type) in smartCast.map) {
holder.createInfoAnnotation(getSmartCastTarget(expression),
"Smart cast to ${DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(type)} (for $call call)")
createInfoAnnotation(getSmartCastTarget(expression),
"Smart cast to ${DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(type)} (for $call call)")
.textAttributes = SMART_CAST_VALUE
}
}
@@ -133,12 +133,12 @@ internal class VariablesHighlightingVisitor(holder: AnnotationHolder, bindingCon
if (descriptor is VariableDescriptor) {
if (descriptor.isDynamic()) {
holder.highlightName(elementToHighlight, DYNAMIC_PROPERTY_CALL)
highlightName(elementToHighlight, DYNAMIC_PROPERTY_CALL)
return
}
if (descriptor.isVar) {
holder.highlightName(elementToHighlight, MUTABLE_VARIABLE)
highlightName(elementToHighlight, MUTABLE_VARIABLE)
}
if (bindingContext.get(CAPTURED_IN_CLOSURE, descriptor) == CaptureKind.NOT_INLINE) {
@@ -149,16 +149,16 @@ internal class VariablesHighlightingVisitor(holder: AnnotationHolder, bindingCon
val parent = elementToHighlight.parent
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) {
holder.highlightName(elementToHighlight, LOCAL_VARIABLE)
highlightName(elementToHighlight, LOCAL_VARIABLE)
}
if (descriptor is ValueParameterDescriptor) {
holder.highlightName(elementToHighlight, PARAMETER)
highlightName(elementToHighlight, PARAMETER)
}
}
}