highlight infix function calls

#KT-6540 Fixed
This commit is contained in:
Dmitry Jemerov
2016-05-25 15:15:10 +02:00
parent a448af5d17
commit 49335fa6eb
2 changed files with 54 additions and 32 deletions
@@ -17,7 +17,9 @@
package org.jetbrains.kotlin.idea.highlighter
import com.intellij.lang.annotation.AnnotationHolder
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
@@ -26,6 +28,7 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic
@@ -47,44 +50,58 @@ internal class FunctionsHighlightingVisitor(holder: AnnotationHolder, bindingCon
super.visitSuperTypeCallEntry(call)
}
override fun visitBinaryExpression(expression: KtBinaryExpression) {
if (expression.operationReference.getIdentifier() != null) {
val resolvedCall = expression.getResolvedCall(bindingContext)
if (resolvedCall != null) {
highlightCall(expression.operationReference, resolvedCall)
}
}
super.visitBinaryExpression(expression)
}
override fun visitCallExpression(expression: KtCallExpression) {
val callee = expression.calleeExpression
val resolvedCall = expression.getResolvedCall(bindingContext)
if (callee is KtReferenceExpression && resolvedCall != null) {
val calleeDescriptor = resolvedCall.resultingDescriptor
if (calleeDescriptor.isDynamic()) {
holder.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)
VARIABLE_AS_FUNCTION_CALL
else
VARIABLE_AS_FUNCTION_LIKE_CALL)
}
else {
if (calleeDescriptor is ConstructorDescriptor) {
holder.highlightName(callee, CONSTRUCTOR_CALL)
}
else if (calleeDescriptor is FunctionDescriptor) {
val color = when {
calleeDescriptor.extensionReceiverParameter != null ->
EXTENSION_FUNCTION_CALL
DescriptorUtils.isTopLevelDeclaration(calleeDescriptor) ->
PACKAGE_FUNCTION_CALL
else ->
FUNCTION_CALL
}
holder.highlightName(callee, color)
}
}
highlightCall(callee, resolvedCall)
}
super.visitCallExpression(expression)
}
private fun highlightCall(callee: PsiElement, resolvedCall: ResolvedCall<out CallableDescriptor>) {
val calleeDescriptor = resolvedCall.resultingDescriptor
if (calleeDescriptor.isDynamic()) {
holder.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)
VARIABLE_AS_FUNCTION_CALL
else
VARIABLE_AS_FUNCTION_LIKE_CALL)
}
else {
if (calleeDescriptor is ConstructorDescriptor) {
holder.highlightName(callee, CONSTRUCTOR_CALL)
}
else if (calleeDescriptor is FunctionDescriptor) {
val color = when {
calleeDescriptor.extensionReceiverParameter != null ->
EXTENSION_FUNCTION_CALL
DescriptorUtils.isTopLevelDeclaration(calleeDescriptor) ->
PACKAGE_FUNCTION_CALL
else ->
FUNCTION_CALL
}
holder.highlightName(callee, color)
}
}
}
}