From 06cae390e7685bd121760d1cbc519af5aca3910c Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Fri, 30 Mar 2012 19:00:01 +0400 Subject: [PATCH] Added highlighting for properties depending on their container and presence of backing field. --- .../BackingFieldHighlightingVisitor.java | 68 ------------- .../highlighter/JetColorSettingsPage.java | 5 + .../plugin/highlighter/JetHighlighter.java | 1 - .../highlighter/JetHighlightingColors.java | 28 +++++- .../jet/plugin/highlighter/JetPsiChecker.java | 2 +- .../PropertiesHighlightingVisitor.java | 95 +++++++++++++++++++ 6 files changed, 127 insertions(+), 72 deletions(-) delete mode 100644 idea/src/org/jetbrains/jet/plugin/highlighter/BackingFieldHighlightingVisitor.java create mode 100644 idea/src/org/jetbrains/jet/plugin/highlighter/PropertiesHighlightingVisitor.java diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/BackingFieldHighlightingVisitor.java b/idea/src/org/jetbrains/jet/plugin/highlighter/BackingFieldHighlightingVisitor.java deleted file mode 100644 index 903fadd93b5..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/highlighter/BackingFieldHighlightingVisitor.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2010-2012 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.plugin.highlighter; - -import com.intellij.lang.annotation.AnnotationHolder; -import com.intellij.psi.PsiElement; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; -import org.jetbrains.jet.lang.descriptors.VariableDescriptor; -import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.lang.resolve.BindingContext; - -class BackingFieldHighlightingVisitor extends AfterAnalysisHighlightingVisitor { - BackingFieldHighlightingVisitor(AnnotationHolder holder, BindingContext bindingContext) { - super(holder, bindingContext); - } - - @Override - public void visitProperty(@NotNull JetProperty property) { - VariableDescriptor propertyDescriptor = bindingContext.get(BindingContext.VARIABLE, property); - if (propertyDescriptor instanceof PropertyDescriptor) { - Boolean backingFieldRequired = bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, (PropertyDescriptor)propertyDescriptor); - if (Boolean.TRUE.equals(backingFieldRequired)) { - putBackingFieldAnnotation(holder, property); - } - } - } - - @Override - public void visitParameter(@NotNull JetParameter parameter) { - PropertyDescriptor propertyDescriptor = bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter); - if (propertyDescriptor != null) { - Boolean backingFieldRequired = bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor); - if (Boolean.TRUE.equals(backingFieldRequired)) { - putBackingFieldAnnotation(holder, parameter); - } - } - } - - @Override - public void visitJetElement(@NotNull JetElement element) { - element.acceptChildren(this); - } - - private static void putBackingFieldAnnotation(@NotNull AnnotationHolder holder, @NotNull JetNamedDeclaration element) { - PsiElement nameIdentifier = element.getNameIdentifier(); - if (nameIdentifier != null) { - holder.createInfoAnnotation( - nameIdentifier, - "This property has a backing field") - .setTextAttributes(JetHighlightingColors.INSTANCE_PROPERTY_WITH_BACKING_FIELD); - } - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/JetColorSettingsPage.java b/idea/src/org/jetbrains/jet/plugin/highlighter/JetColorSettingsPage.java index b62dba85a99..a04b165ff4f 100644 --- a/idea/src/org/jetbrains/jet/plugin/highlighter/JetColorSettingsPage.java +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/JetColorSettingsPage.java @@ -133,9 +133,14 @@ public class JetColorSettingsPage implements ColorSettingsPage { new AttributesDescriptor("Read-only local variable (val)", JetHighlightingColors.LOCAL_VAL), new AttributesDescriptor("Mutable local variable (var)", JetHighlightingColors.LOCAL_VAR), + new AttributesDescriptor("Instance property", JetHighlightingColors.INSTANCE_PROPERTY), new AttributesDescriptor("Instance property with backing field", JetHighlightingColors.INSTANCE_PROPERTY_WITH_BACKING_FIELD), new AttributesDescriptor("Instance property backing field access", JetHighlightingColors.INSTANCE_BACKING_FIELD_ACCESS), + new AttributesDescriptor("Namespace property", JetHighlightingColors.NAMESPACE_PROPERTY), + new AttributesDescriptor("Namespace property with backing field", JetHighlightingColors.NAMESPACE_PROPERTY_WITH_BACKING_FIELD), + new AttributesDescriptor("Namespace property backing field access", JetHighlightingColors.NAMESPACE_BACKING_FIELD_ACCESS), + new AttributesDescriptor("Function literal default parameter", JetHighlightingColors.FUNCTION_LITERAL_DEFAULT_PARAMETER), new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.bad.character"), JetHighlightingColors.BAD_CHARACTER), diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlighter.java b/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlighter.java index cfdfa989d44..be74e14d5ea 100644 --- a/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlighter.java +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlighter.java @@ -56,7 +56,6 @@ public class JetHighlighter extends SyntaxHighlighterBase { keys1.put(JetTokens.AS_SAFE, JetHighlightingColors.KEYWORD); keys1.put(JetTokens.LABEL_IDENTIFIER, JetHighlightingColors.LABEL); keys1.put(JetTokens.ATAT, JetHighlightingColors.LABEL); - keys1.put(JetTokens.FIELD_IDENTIFIER, JetHighlightingColors.INSTANCE_BACKING_FIELD_ACCESS); keys1.put(JetTokens.INTEGER_LITERAL, JetHighlightingColors.NUMBER); keys1.put(JetTokens.FLOAT_LITERAL, JetHighlightingColors.NUMBER); diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlightingColors.java b/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlightingColors.java index 8d51c8c4c5d..cd36eec9c19 100644 --- a/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlightingColors.java +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlightingColors.java @@ -176,9 +176,17 @@ public class JetHighlightingColors { CodeInsightColors.IMPLICIT_ANONYMOUS_CLASS_PARAMETER_ATTRIBUTES.getDefaultAttributes() ); + public static final TextAttributesKey INSTANCE_PROPERTY = TextAttributesKey.createTextAttributesKey( + "KOTLIN_INSTANCE_PROPERTY", + CodeInsightColors.INSTANCE_FIELD_ATTRIBUTES.getDefaultAttributes() + ); + public static final TextAttributesKey INSTANCE_PROPERTY_WITH_BACKING_FIELD = TextAttributesKey.createTextAttributesKey( "KOTLIN_INSTANCE_PROPERTY_WITH_BACKING_FIELD", - CodeInsightColors.INSTANCE_FIELD_ATTRIBUTES.getDefaultAttributes() + TextAttributes + .fromFlyweight(CodeInsightColors.INSTANCE_FIELD_ATTRIBUTES.getDefaultAttributes() + .getFlyweight().withEffectType(EffectType.BOLD_DOTTED_LINE).withEffectColor( + CodeInsightColors.INSTANCE_FIELD_ATTRIBUTES.getDefaultAttributes().getForegroundColor())) ); public static final TextAttributesKey INSTANCE_BACKING_FIELD_ACCESS = TextAttributesKey.createTextAttributesKey( @@ -186,6 +194,22 @@ public class JetHighlightingColors { CodeInsightColors.INSTANCE_FIELD_ATTRIBUTES.getDefaultAttributes() ); + public static final TextAttributesKey NAMESPACE_PROPERTY = TextAttributesKey.createTextAttributesKey( + "KOTLIN_NAMESPACE_PROPERTY", + CodeInsightColors.STATIC_FIELD_ATTRIBUTES.getDefaultAttributes() + ); + + public static final TextAttributesKey NAMESPACE_PROPERTY_WITH_BACKING_FIELD = TextAttributesKey.createTextAttributesKey( + "KOTLIN_NAMESPACE_PROPERTY_WITH_BACKING_FIELD", + TextAttributes.fromFlyweight(CodeInsightColors.STATIC_FIELD_ATTRIBUTES.getDefaultAttributes() + .getFlyweight().withEffectType(EffectType.BOLD_DOTTED_LINE).withEffectColor( + CodeInsightColors.STATIC_FIELD_ATTRIBUTES.getDefaultAttributes().getForegroundColor())) ); + + public static final TextAttributesKey NAMESPACE_BACKING_FIELD_ACCESS = TextAttributesKey.createTextAttributesKey( + "KOTLIN_NAMESPACE_BACKING_FIELD_ACCESS", + CodeInsightColors.INSTANCE_FIELD_ATTRIBUTES.getDefaultAttributes() + ); + public static final TextAttributesKey FUNCTION_LITERAL_DEFAULT_PARAMETER = TextAttributesKey.createTextAttributesKey( "KOTLIN_CLOSURE_DEFAULT_PARAMETER", new TextAttributes(null, null, null, null, Font.BOLD) @@ -203,7 +227,7 @@ public class JetHighlightingColors { public static final TextAttributesKey LABEL = TextAttributesKey.createTextAttributesKey( "KOTLIN_LABEL", - new TextAttributes(new Color(74, 134, 232), null, null, null, Font.PLAIN) + new TextAttributes(new Color(0x4a86e8), null, null, null, Font.PLAIN) ); public static final TextAttributesKey DEBUG_INFO = TextAttributesKey.createTextAttributesKey( diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/JetPsiChecker.java b/idea/src/org/jetbrains/jet/plugin/highlighter/JetPsiChecker.java index d136a1bb452..820443ce9c7 100644 --- a/idea/src/org/jetbrains/jet/plugin/highlighter/JetPsiChecker.java +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/JetPsiChecker.java @@ -65,7 +65,7 @@ public class JetPsiChecker implements Annotator { private static HighlightingVisitor[] getAfterAnalysisVisitor(AnnotationHolder holder, BindingContext bindingContext) { return new AfterAnalysisHighlightingVisitor[]{ - new BackingFieldHighlightingVisitor(holder, bindingContext), + new PropertiesHighlightingVisitor(holder, bindingContext), new VariablesHighlightingVisitor(holder, bindingContext), }; } diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/PropertiesHighlightingVisitor.java b/idea/src/org/jetbrains/jet/plugin/highlighter/PropertiesHighlightingVisitor.java new file mode 100644 index 00000000000..6ad441e6fa4 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/PropertiesHighlightingVisitor.java @@ -0,0 +1,95 @@ +/* + * Copyright 2010-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.highlighter; + +import com.intellij.lang.annotation.AnnotationHolder; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; +import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; +import org.jetbrains.jet.lang.descriptors.VariableDescriptor; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lexer.JetTokens; + +class PropertiesHighlightingVisitor extends AfterAnalysisHighlightingVisitor { + PropertiesHighlightingVisitor(AnnotationHolder holder, BindingContext bindingContext) { + super(holder, bindingContext); + } + + @Override + public void visitSimpleNameExpression(JetSimpleNameExpression expression) { + // TODO highlight extension properties + DeclarationDescriptor target = bindingContext.get(BindingContext.REFERENCE_TARGET, expression); + if (!(target instanceof PropertyDescriptor)) { + return; + } + + boolean namespace = target.getContainingDeclaration() instanceof NamespaceDescriptor; + if (expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER) { + holder.createInfoAnnotation(expression, null).setTextAttributes( + (namespace ? + JetHighlightingColors.NAMESPACE_BACKING_FIELD_ACCESS : + JetHighlightingColors.INSTANCE_BACKING_FIELD_ACCESS) + ); + } else { + putPropertyAnnotation(expression, namespace, false); + } + } + + @Override + public void visitProperty(@NotNull JetProperty property) { + PsiElement nameIdentifier = property.getNameIdentifier(); + if (nameIdentifier == null) return; + VariableDescriptor propertyDescriptor = bindingContext.get(BindingContext.VARIABLE, property); + if (propertyDescriptor instanceof PropertyDescriptor) { + Boolean backingFieldRequired = bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, (PropertyDescriptor)propertyDescriptor); + boolean namespace = propertyDescriptor.getContainingDeclaration() instanceof NamespaceDescriptor; + putPropertyAnnotation(nameIdentifier, namespace, Boolean.TRUE.equals(backingFieldRequired)); + } + } + + @Override + public void visitParameter(@NotNull JetParameter parameter) { + PsiElement nameIdentifier = parameter.getNameIdentifier(); + if (nameIdentifier == null) return; + PropertyDescriptor propertyDescriptor = bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter); + if (propertyDescriptor != null) { + Boolean backingFieldRequired = bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor); + putPropertyAnnotation(nameIdentifier, false, Boolean.TRUE.equals(backingFieldRequired)); + } + } + + @Override + public void visitJetElement(@NotNull JetElement element) { + element.acceptChildren(this); + } + + private void putPropertyAnnotation(@NotNull PsiElement elementToHighlight, boolean namespace, boolean withBackingField) { + holder.createInfoAnnotation( + elementToHighlight, + "This property has a backing field") + .setTextAttributes(withBackingField ? + (namespace + ? JetHighlightingColors.NAMESPACE_PROPERTY_WITH_BACKING_FIELD + : JetHighlightingColors.INSTANCE_PROPERTY_WITH_BACKING_FIELD) : + (namespace + ? JetHighlightingColors.NAMESPACE_PROPERTY + : JetHighlightingColors.INSTANCE_PROPERTY)); + } +}