VariablesHighlightingVisitor: J2K

This commit is contained in:
Dmitry Jemerov
2016-05-25 13:05:59 +02:00
parent 4ddbe9828a
commit 77a48c1d10
@@ -14,142 +14,120 @@
* limitations under the License. * limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.highlighter; package org.jetbrains.kotlin.idea.highlighter
import com.intellij.lang.annotation.AnnotationHolder; import com.intellij.lang.annotation.AnnotationHolder
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement
import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor; import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptor; import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor; import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.renderer.DescriptorRenderer; import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.BindingContext.*
import org.jetbrains.kotlin.resolve.calls.tasks.DynamicCallsKt; import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic
import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.expressions.CaptureKind
import org.jetbrains.kotlin.types.expressions.CaptureKind;
import static org.jetbrains.kotlin.resolve.BindingContext.*; internal class VariablesHighlightingVisitor(holder: AnnotationHolder, bindingContext: BindingContext)
: AfterAnalysisHighlightingVisitor(holder, bindingContext) {
class VariablesHighlightingVisitor extends AfterAnalysisHighlightingVisitor { override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) {
VariablesHighlightingVisitor(AnnotationHolder holder, BindingContext bindingContext) { val target = bindingContext.get(REFERENCE_TARGET, expression) ?: return
super(holder, bindingContext); if (target is ValueParameterDescriptor) {
} if (java.lang.Boolean.TRUE == bindingContext.get(AUTO_CREATED_IT, target)) {
holder.createInfoAnnotation(expression, "Automatically declared based on the expected type").textAttributes = KotlinHighlightingColors.FUNCTION_LITERAL_DEFAULT_PARAMETER
@Override
public void visitSimpleNameExpression(@NotNull KtSimpleNameExpression expression) {
DeclarationDescriptor target = bindingContext.get(REFERENCE_TARGET, expression);
if (target == null) {
return;
}
if (target instanceof ValueParameterDescriptor) {
ValueParameterDescriptor parameterDescriptor = (ValueParameterDescriptor) target;
if (Boolean.TRUE.equals(bindingContext.get(AUTO_CREATED_IT, parameterDescriptor))) {
holder.createInfoAnnotation(expression, "Automatically declared based on the expected type").setTextAttributes(
KotlinHighlightingColors.FUNCTION_LITERAL_DEFAULT_PARAMETER);
} }
} }
if (!(expression.getParent() instanceof KtValueArgumentName)) { // highlighted separately if (expression.parent !is KtValueArgumentName) { // highlighted separately
highlightVariable(expression, target); highlightVariable(expression, target)
} }
super.visitSimpleNameExpression(expression); super.visitSimpleNameExpression(expression)
} }
@Override override fun visitProperty(property: KtProperty) {
public void visitProperty(@NotNull KtProperty property) { visitVariableDeclaration(property)
visitVariableDeclaration(property); super.visitProperty(property)
super.visitProperty(property);
} }
@Override override fun visitParameter(parameter: KtParameter) {
public void visitParameter(@NotNull KtParameter parameter) { visitVariableDeclaration(parameter)
visitVariableDeclaration(parameter); super.visitParameter(parameter)
super.visitParameter(parameter);
} }
@NotNull private fun getSmartCastTarget(expression: KtExpression): PsiElement {
private static PsiElement getSmartCastTarget(@NotNull KtExpression expression) { var target: PsiElement = expression
PsiElement target = expression; if (target is KtParenthesizedExpression) {
if (target instanceof KtParenthesizedExpression) { target = KtPsiUtil.deparenthesize(target as KtParenthesizedExpression?) ?: expression
target = KtPsiUtil.deparenthesize((KtParenthesizedExpression) target);
if (target == null) {
target = expression;
}
} }
if (target instanceof KtIfExpression) { if (target is KtIfExpression) {
target = ((KtIfExpression) target).getIfKeyword(); target = target.ifKeyword
} }
else if (target instanceof KtWhenExpression) { else if (target is KtWhenExpression) {
target = ((KtWhenExpression) target).getWhenKeyword(); target = target.whenKeyword
} }
else if (target instanceof KtBinaryExpression) { else if (target is KtBinaryExpression) {
target = ((KtBinaryExpression) target).getOperationReference(); target = target.operationReference
} }
return target; return target
} }
@Override override fun visitExpression(expression: KtExpression) {
public void visitExpression(@NotNull KtExpression expression) { val implicitSmartCast = bindingContext.get(IMPLICIT_RECEIVER_SMARTCAST, expression)
KotlinType implicitSmartCast = bindingContext.get(IMPLICIT_RECEIVER_SMARTCAST, expression);
if (implicitSmartCast != null) { if (implicitSmartCast != null) {
holder.createInfoAnnotation(expression, "Implicit receiver smart cast to " + holder.createInfoAnnotation(expression, "Implicit receiver smart cast to " + DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(implicitSmartCast)).textAttributes = KotlinHighlightingColors.SMART_CAST_RECEIVER
DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(implicitSmartCast))
.setTextAttributes(KotlinHighlightingColors.SMART_CAST_RECEIVER);
} }
boolean nullSmartCast = bindingContext.get(SMARTCAST_NULL, expression) == Boolean.TRUE; val nullSmartCast = bindingContext.get(SMARTCAST_NULL, expression) === java.lang.Boolean.TRUE
if (nullSmartCast) { if (nullSmartCast) {
holder.createInfoAnnotation(expression, "Always null") holder.createInfoAnnotation(expression, "Always null").textAttributes = KotlinHighlightingColors.SMART_CONSTANT
.setTextAttributes(KotlinHighlightingColors.SMART_CONSTANT);
} }
KotlinType smartCast = bindingContext.get(SMARTCAST, expression); val smartCast = bindingContext.get(SMARTCAST, expression)
if (smartCast != null) { if (smartCast != null) {
holder.createInfoAnnotation(getSmartCastTarget(expression), holder.createInfoAnnotation(getSmartCastTarget(expression),
"Smart cast to " + DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(smartCast)) "Smart cast to " + DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(smartCast)).textAttributes = KotlinHighlightingColors.SMART_CAST_VALUE
.setTextAttributes(KotlinHighlightingColors.SMART_CAST_VALUE);
} }
super.visitExpression(expression); super.visitExpression(expression)
} }
private void visitVariableDeclaration(KtNamedDeclaration declaration) { private fun visitVariableDeclaration(declaration: KtNamedDeclaration) {
DeclarationDescriptor declarationDescriptor = bindingContext.get(DECLARATION_TO_DESCRIPTOR, declaration); val declarationDescriptor = bindingContext.get(DECLARATION_TO_DESCRIPTOR, declaration)
PsiElement nameIdentifier = declaration.getNameIdentifier(); val nameIdentifier = declaration.nameIdentifier
if (nameIdentifier != null && declarationDescriptor != null) { if (nameIdentifier != null && declarationDescriptor != null) {
highlightVariable(nameIdentifier, declarationDescriptor); highlightVariable(nameIdentifier, declarationDescriptor)
} }
} }
private void highlightVariable(@NotNull PsiElement elementToHighlight, @NotNull DeclarationDescriptor descriptor) { private fun highlightVariable(elementToHighlight: PsiElement, descriptor: DeclarationDescriptor) {
if (descriptor instanceof VariableDescriptor) { if (descriptor is VariableDescriptor) {
VariableDescriptor variableDescriptor = (VariableDescriptor) descriptor;
if (DynamicCallsKt.isDynamic(variableDescriptor)) { if (descriptor.isDynamic()) {
NameHighlighter.highlightName(holder, elementToHighlight, KotlinHighlightingColors.DYNAMIC_PROPERTY_CALL); NameHighlighter.highlightName(holder, elementToHighlight, KotlinHighlightingColors.DYNAMIC_PROPERTY_CALL)
return; return
} }
if (variableDescriptor.isVar()) { if (descriptor.isVar) {
NameHighlighter.highlightName(holder, elementToHighlight, KotlinHighlightingColors.MUTABLE_VARIABLE); NameHighlighter.highlightName(holder, elementToHighlight, KotlinHighlightingColors.MUTABLE_VARIABLE)
} }
if (bindingContext.get(CAPTURED_IN_CLOSURE, variableDescriptor) == CaptureKind.NOT_INLINE) { if (bindingContext.get(CAPTURED_IN_CLOSURE, descriptor) == CaptureKind.NOT_INLINE) {
String msg = ((VariableDescriptor) descriptor).isVar() val msg = if (descriptor.isVar)
? "Wrapped into a reference object to be modified when captured in a closure" "Wrapped into a reference object to be modified when captured in a closure"
: "Value captured in a closure"; else
holder.createInfoAnnotation(elementToHighlight, msg).setTextAttributes(KotlinHighlightingColors.WRAPPED_INTO_REF); "Value captured in a closure"
holder.createInfoAnnotation(elementToHighlight, msg).textAttributes = KotlinHighlightingColors.WRAPPED_INTO_REF
} }
if (descriptor instanceof LocalVariableDescriptor) { if (descriptor is LocalVariableDescriptor) {
NameHighlighter.highlightName(holder, elementToHighlight, KotlinHighlightingColors.LOCAL_VARIABLE); NameHighlighter.highlightName(holder, elementToHighlight, KotlinHighlightingColors.LOCAL_VARIABLE)
} }
if (descriptor instanceof ValueParameterDescriptor) { if (descriptor is ValueParameterDescriptor) {
NameHighlighter.highlightName(holder, elementToHighlight, KotlinHighlightingColors.PARAMETER); NameHighlighter.highlightName(holder, elementToHighlight, KotlinHighlightingColors.PARAMETER)
} }
} }
} }