Minor, refactor TypeKindHighlightingVisitor

This commit is contained in:
Pavel V. Talanov
2018-08-01 21:16:01 +02:00
parent 3d91d4b865
commit f80b85c282
@@ -26,8 +26,8 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
internal class TypeKindHighlightingVisitor(holder: AnnotationHolder, bindingContext: BindingContext) internal class TypeKindHighlightingVisitor(holder: AnnotationHolder, bindingContext: BindingContext) :
: AfterAnalysisHighlightingVisitor(holder, bindingContext) { AfterAnalysisHighlightingVisitor(holder, bindingContext) {
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) { override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) {
val parent = expression.parent val parent = expression.parent
@@ -36,48 +36,51 @@ internal class TypeKindHighlightingVisitor(holder: AnnotationHolder, bindingCont
return return
} }
if (NameHighlighter.namesHighlightingEnabled) { if (!NameHighlighter.namesHighlightingEnabled) return
var referenceTarget = bindingContext.get(BindingContext.REFERENCE_TARGET, expression)
if (referenceTarget is ConstructorDescriptor) {
val callElement = expression.getParentOfTypeAndBranch<KtCallExpression>(true) { calleeExpression }
?: expression.getParentOfTypeAndBranch<KtSuperTypeCallEntry>(true) { calleeExpression }
if (callElement == null) {
referenceTarget = referenceTarget.containingDeclaration
}
}
if (referenceTarget is ClassDescriptor) { val referenceTarget = computeReferencedDescriptor(expression) ?: return
if (referenceTarget.kind == ClassKind.ANNOTATION_CLASS) {
highlightAnnotation(expression) val key = when (referenceTarget) {
} is TypeParameterDescriptor -> TYPE_PARAMETER
else { is TypeAliasDescriptor -> TYPE_ALIAS
highlightName(expression, textAttributesKeyForClass(referenceTarget)) !is ClassDescriptor -> return
} else -> when (referenceTarget.kind) {
} ClassKind.ANNOTATION_CLASS -> ANNOTATION
else if (referenceTarget is TypeParameterDescriptor) { else -> textAttributesKeyForClassDeclaration(referenceTarget)
highlightName(expression, TYPE_PARAMETER)
}
else if (referenceTarget is TypeAliasDescriptor) {
highlightName(expression, TYPE_ALIAS)
} }
} }
highlightName(computeHighlightingRangeForUsage(expression, referenceTarget), key)
} }
private fun highlightAnnotation(expression: KtSimpleNameExpression) { private fun computeReferencedDescriptor(expression: KtSimpleNameExpression): DeclarationDescriptor? {
var range = expression.textRange val referenceTarget = bindingContext.get(BindingContext.REFERENCE_TARGET, expression)
if (referenceTarget !is ConstructorDescriptor) return referenceTarget
val callElement = expression.getParentOfTypeAndBranch<KtCallExpression>(true) { calleeExpression }
?: expression.getParentOfTypeAndBranch<KtSuperTypeCallEntry>(true) { calleeExpression }
if (callElement != null) {
return referenceTarget
}
return referenceTarget.containingDeclaration
}
private fun computeHighlightingRangeForUsage(expression: KtSimpleNameExpression, referenceTarget: DeclarationDescriptor): TextRange {
val expressionRange = expression.textRange
if (referenceTarget !is ClassDescriptor || referenceTarget.kind != ClassKind.ANNOTATION_CLASS) return expressionRange
// include '@' symbol if the reference is the first segment of KtAnnotationEntry // include '@' symbol if the reference is the first segment of KtAnnotationEntry
// if "Deprecated" is highlighted then '@' should be highlighted too in "@Deprecated" // if "Deprecated" is highlighted then '@' should be highlighted too in "@Deprecated"
val annotationEntry = PsiTreeUtil.getParentOfType( val annotationEntry = PsiTreeUtil.getParentOfType(
expression, KtAnnotationEntry::class.java, /* strict = */false, KtValueArgumentList::class.java) expression, KtAnnotationEntry::class.java, /* strict = */false, KtValueArgumentList::class.java
if (annotationEntry != null) { )
val atSymbol = annotationEntry.atSymbol val atSymbol = annotationEntry?.atSymbol ?: return expressionRange
if (atSymbol != null) { return TextRange(atSymbol.textRange.startOffset, expression.textRange.endOffset)
range = TextRange(atSymbol.textRange.startOffset, expression.textRange.endOffset)
}
}
highlightName(range, ANNOTATION)
} }
override fun visitTypeParameter(parameter: KtTypeParameter) { override fun visitTypeParameter(parameter: KtTypeParameter) {
@@ -92,7 +95,7 @@ internal class TypeKindHighlightingVisitor(holder: AnnotationHolder, bindingCont
highlightName( highlightName(
identifier, identifier,
attributeKeyForDeclarationFromExtensions(classOrObject, classDescriptor) attributeKeyForDeclarationFromExtensions(classOrObject, classDescriptor)
?: textAttributesKeyForClass(classDescriptor) ?: textAttributesKeyForClassDeclaration(classDescriptor)
) )
} }
super.visitClassOrObject(classOrObject) super.visitClassOrObject(classOrObject)
@@ -114,7 +117,7 @@ internal class TypeKindHighlightingVisitor(holder: AnnotationHolder, bindingCont
// Do nothing: 'dynamic' is highlighted as a keyword // Do nothing: 'dynamic' is highlighted as a keyword
} }
private fun textAttributesKeyForClass(descriptor: ClassDescriptor): TextAttributesKey = when (descriptor.kind) { private fun textAttributesKeyForClassDeclaration(descriptor: ClassDescriptor): TextAttributesKey = when (descriptor.kind) {
ClassKind.INTERFACE -> TRAIT ClassKind.INTERFACE -> TRAIT
ClassKind.ANNOTATION_CLASS -> ANNOTATION ClassKind.ANNOTATION_CLASS -> ANNOTATION
ClassKind.OBJECT -> OBJECT ClassKind.OBJECT -> OBJECT