Added separate highlighting keys for variables invoked as function and function-like.
This commit is contained in:
@@ -116,6 +116,7 @@ options.jet.attribute.descriptor.namespace.fun.call=Package-level function call
|
||||
options.jet.attribute.descriptor.extension.fun.call=Extension function call
|
||||
options.jet.attribute.descriptor.constructor.call=Constructor call
|
||||
options.jet.attribute.descriptor.variable.as.function.call=Variable as function call
|
||||
options.jet.attribute.descriptor.variable.as.function.like.call=Variable as function-like call
|
||||
options.jet.attribute.descriptor.auto.casted=Smart-cast value
|
||||
options.jet.attribute.descriptor.label=Label
|
||||
change.to.function.invocation=Change to function invocation
|
||||
|
||||
@@ -22,6 +22,11 @@ import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.VariableAsFunctionResolvedCall;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
|
||||
public class FunctionsHighlightingVisitor extends AfterAnalysisHighlightingVisitor {
|
||||
public FunctionsHighlightingVisitor(AnnotationHolder holder, BindingContext bindingContext) {
|
||||
@@ -58,33 +63,72 @@ public class FunctionsHighlightingVisitor extends AfterAnalysisHighlightingVisit
|
||||
public void visitCallExpression(JetCallExpression expression) {
|
||||
JetExpression callee = expression.getCalleeExpression();
|
||||
if (callee instanceof JetReferenceExpression) {
|
||||
DeclarationDescriptor calleeDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, (JetReferenceExpression)callee);
|
||||
if (calleeDescriptor != null) {
|
||||
if (calleeDescriptor instanceof ConstructorDescriptor) {
|
||||
JetPsiChecker.highlightName(holder, callee, JetHighlightingColors.CONSTRUCTOR_CALL);
|
||||
ResolvedCall<? extends CallableDescriptor> resolvedCall =
|
||||
bindingContext.get(BindingContext.RESOLVED_CALL, (JetReferenceExpression) callee);
|
||||
if (resolvedCall != null) {
|
||||
if (resolvedCall instanceof VariableAsFunctionResolvedCall) {
|
||||
highlightVariableAsFunctionCall(callee, (VariableAsFunctionResolvedCall) resolvedCall);
|
||||
}
|
||||
else if (calleeDescriptor instanceof FunctionDescriptor) {
|
||||
FunctionDescriptor fun = (FunctionDescriptor)calleeDescriptor;
|
||||
JetPsiChecker.highlightName(holder, callee, JetHighlightingColors.FUNCTION_CALL);
|
||||
if (DescriptorUtils.isTopLevelDeclaration(fun)) {
|
||||
JetPsiChecker.highlightName(holder, callee, JetHighlightingColors.NAMESPACE_FUNCTION_CALL);
|
||||
else {
|
||||
DeclarationDescriptor calleeDescriptor = resolvedCall.getResultingDescriptor();
|
||||
if (calleeDescriptor instanceof ConstructorDescriptor) {
|
||||
JetPsiChecker.highlightName(holder, callee, JetHighlightingColors.CONSTRUCTOR_CALL);
|
||||
}
|
||||
if (fun.getReceiverParameter() != null) {
|
||||
JetPsiChecker.highlightName(holder, callee, JetHighlightingColors.EXTENSION_FUNCTION_CALL);
|
||||
else if (calleeDescriptor instanceof FunctionDescriptor) {
|
||||
FunctionDescriptor fun = (FunctionDescriptor) calleeDescriptor;
|
||||
JetPsiChecker.highlightName(holder, callee, JetHighlightingColors.FUNCTION_CALL);
|
||||
if (DescriptorUtils.isTopLevelDeclaration(fun)) {
|
||||
JetPsiChecker.highlightName(holder, callee, JetHighlightingColors.NAMESPACE_FUNCTION_CALL);
|
||||
}
|
||||
if (fun.getReceiverParameter() != null) {
|
||||
JetPsiChecker.highlightName(holder, callee, JetHighlightingColors.EXTENSION_FUNCTION_CALL);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (calleeDescriptor instanceof VariableDescriptor) {
|
||||
String kind = calleeDescriptor instanceof ValueParameterDescriptor
|
||||
? "parameter"
|
||||
: calleeDescriptor instanceof PropertyDescriptor
|
||||
? "property"
|
||||
: "variable";
|
||||
holder.createInfoAnnotation(callee, "Calling " + kind + " as function").setTextAttributes(
|
||||
JetHighlightingColors.VARIABLE_AS_FUNCTION_CALL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.visitCallExpression(expression);
|
||||
}
|
||||
|
||||
private void highlightVariableAsFunctionCall(JetExpression callee, VariableAsFunctionResolvedCall resolvedCall) {
|
||||
VariableDescriptor variableDescriptor = resolvedCall.getVariableCall().getResultingDescriptor();
|
||||
|
||||
String kind = variableDescriptor instanceof ValueParameterDescriptor
|
||||
? "parameter"
|
||||
: variableDescriptor instanceof PropertyDescriptor
|
||||
? "property"
|
||||
: "variable";
|
||||
|
||||
if (containedInFunctionClassOrSubclass(resolvedCall.getFunctionCall().getResultingDescriptor())) {
|
||||
holder.createInfoAnnotation(callee, "Calling " + kind + " as function").setTextAttributes(
|
||||
JetHighlightingColors.VARIABLE_AS_FUNCTION_CALL);
|
||||
}
|
||||
else {
|
||||
holder.createInfoAnnotation(callee, "Calling " + kind + " as function-like").setTextAttributes(
|
||||
JetHighlightingColors.VARIABLE_AS_FUNCTION_LIKE_CALL);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean containedInFunctionClassOrSubclass(DeclarationDescriptor calleeDescriptor) {
|
||||
DeclarationDescriptor parent = calleeDescriptor.getContainingDeclaration();
|
||||
if (!(parent instanceof ClassDescriptor)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance();
|
||||
JetType defaultType = ((ClassDescriptor) parent).getDefaultType();
|
||||
|
||||
if (builtIns.isFunctionOrExtensionFunctionType(defaultType)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (JetType supertype : TypeUtils.getAllSupertypes(defaultType)) {
|
||||
if (builtIns.isFunctionOrExtensionFunctionType(supertype)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,10 +58,10 @@ public class JetColorSettingsPage implements ColorSettingsPage {
|
||||
" */\n" +
|
||||
"[<ANNOTATION>Deprecated</ANNOTATION>]\n" +
|
||||
"<BUILTIN_ANNOTATION>public</BUILTIN_ANNOTATION> class <CLASS>MyClass</CLASS><<BUILTIN_ANNOTATION>out</BUILTIN_ANNOTATION> <TYPE_PARAMETER>T</TYPE_PARAMETER> : <TRAIT>Iterable</TRAIT><<TYPE_PARAMETER>T</TYPE_PARAMETER>>>(var <INSTANCE_PROPERTY><MUTABLE_VARIABLE>prop1</MUTABLE_VARIABLE></INSTANCE_PROPERTY> : Int) {\n" +
|
||||
" fun <FUNCTION_DECLARATION>foo</FUNCTION_DECLARATION>(<PARAMETER>nullable</PARAMETER> : String?, <PARAMETER>r</PARAMETER> : <TRAIT>Runnable</TRAIT>, <PARAMETER>f</PARAMETER> : () -> Int) {\n" +
|
||||
" fun <FUNCTION_DECLARATION>foo</FUNCTION_DECLARATION>(<PARAMETER>nullable</PARAMETER> : String?, <PARAMETER>r</PARAMETER> : <TRAIT>Runnable</TRAIT>, <PARAMETER>f</PARAMETER> : () -> Int, <PARAMETER>fl</PARAMETER> : <TRAIT>FunctionLike</TRAIT>) {\n" +
|
||||
" <FUNCTION_CALL><NAMESPACE_FUNCTION_CALL>println</NAMESPACE_FUNCTION_CALL></FUNCTION_CALL>(\"length\\nis ${<PARAMETER>nullable</PARAMETER><SAFE_ACCESS>?.</SAFE_ACCESS><INSTANCE_PROPERTY>length</INSTANCE_PROPERTY>} <INVALID_STRING_ESCAPE><STRING_ESCAPE>\\e</STRING_ESCAPE></INVALID_STRING_ESCAPE>\")\n" +
|
||||
" val <LOCAL_VARIABLE>ints</LOCAL_VARIABLE> = java.util.<CONSTRUCTOR_CALL>ArrayList</CONSTRUCTOR_CALL><Int?>(2)\n" +
|
||||
" <LOCAL_VARIABLE>ints</LOCAL_VARIABLE>[0] = 102 + <PARAMETER><VARIABLE_AS_FUNCTION_CALL>f</VARIABLE_AS_FUNCTION_CALL></PARAMETER>()\n" +
|
||||
" <LOCAL_VARIABLE>ints</LOCAL_VARIABLE>[0] = 102 + <PARAMETER><VARIABLE_AS_FUNCTION_CALL>f</VARIABLE_AS_FUNCTION_CALL></PARAMETER>() + <PARAMETER><VARIABLE_AS_FUNCTION_LIKE_CALL>fl</VARIABLE_AS_FUNCTION_LIKE_CALL></PARAMETER>()\n" +
|
||||
" val <LOCAL_VARIABLE>myFun</LOCAL_VARIABLE> = <FUNCTION_LITERAL_BRACES_AND_ARROW>{</FUNCTION_LITERAL_BRACES_AND_ARROW> <FUNCTION_LITERAL_BRACES_AND_ARROW>-></FUNCTION_LITERAL_BRACES_AND_ARROW> \"\" <FUNCTION_LITERAL_BRACES_AND_ARROW>}</FUNCTION_LITERAL_BRACES_AND_ARROW>;\n" +
|
||||
" var <LOCAL_VARIABLE><MUTABLE_VARIABLE><WRAPPED_INTO_REF>ref</WRAPPED_INTO_REF></MUTABLE_VARIABLE></LOCAL_VARIABLE> = <LOCAL_VARIABLE>ints</LOCAL_VARIABLE>.<FUNCTION_CALL>size</FUNCTION_CALL>()\n" +
|
||||
" if (!<LOCAL_VARIABLE>ints</LOCAL_VARIABLE>.<EXTENSION_PROPERTY><NAMESPACE_PROPERTY>empty</NAMESPACE_PROPERTY></EXTENSION_PROPERTY>) {\n" +
|
||||
@@ -156,6 +156,7 @@ public class JetColorSettingsPage implements ColorSettingsPage {
|
||||
new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.extension.fun.call"), JetHighlightingColors.EXTENSION_FUNCTION_CALL),
|
||||
new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.constructor.call"), JetHighlightingColors.CONSTRUCTOR_CALL),
|
||||
new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.variable.as.function.call"), JetHighlightingColors.VARIABLE_AS_FUNCTION_CALL),
|
||||
new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.variable.as.function.like.call"), JetHighlightingColors.VARIABLE_AS_FUNCTION_LIKE_CALL),
|
||||
|
||||
new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.bad.character"), JetHighlightingColors.BAD_CHARACTER),
|
||||
|
||||
|
||||
@@ -241,6 +241,11 @@ public class JetHighlightingColors {
|
||||
new TextAttributes()
|
||||
);
|
||||
|
||||
public static final TextAttributesKey VARIABLE_AS_FUNCTION_LIKE_CALL = TextAttributesKey.createTextAttributesKey(
|
||||
"KOTLIN_VARIABLE_AS_FUNCTION_LIKE",
|
||||
new TextAttributes()
|
||||
);
|
||||
|
||||
public static final TextAttributesKey BAD_CHARACTER = TextAttributesKey.createTextAttributesKey(
|
||||
"KOTLIN_BAD_CHARACTER",
|
||||
HighlighterColors.BAD_CHARACTER.getDefaultAttributes()
|
||||
|
||||
@@ -7,7 +7,7 @@ val <info>property</info> = {}
|
||||
|
||||
fun foo(param: (Int) -> Int, functionLike: FunctionLike) {
|
||||
<info descr="Calling parameter as function">param</info>(1)
|
||||
<info descr="Calling parameter as function">functionLike</info>()
|
||||
<info descr="Calling parameter as function-like">functionLike</info>()
|
||||
|
||||
val v1 = param
|
||||
var v2 = param
|
||||
@@ -15,5 +15,7 @@ fun foo(param: (Int) -> Int, functionLike: FunctionLike) {
|
||||
<info descr="Calling variable as function">v1</info>(1)
|
||||
<info descr="Calling variable as function">v2</info>(1)
|
||||
|
||||
<info descr="Calling property as function">property</info>()
|
||||
<info descr="Calling property as function">property</info>();
|
||||
|
||||
{}() //should not be highlighted as "calling variable as function"
|
||||
}
|
||||
Reference in New Issue
Block a user