diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 9dd218c18f9..42b91ab5f81 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -40,7 +40,7 @@ + text="Error Reporting Enabled"> @@ -67,7 +67,7 @@ - + @@ -81,6 +81,8 @@ + + @@ -126,10 +128,8 @@ - - - - + + @@ -140,7 +140,7 @@ - + diff --git a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties index c7e432bff68..db441d6bf92 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties +++ b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties @@ -50,3 +50,30 @@ macro.suggest.variable.name=kotlinSuggestVariableName() macro.fun.parameters=functionParameters() macro.fun.anonymousSuper=anonymousSuper() change.visibility.modifier=Change visibility modifier + +options.jet.attribute.descriptor.builtin.annotation=Built-in annotation +options.jet.attribute.descriptor.closure.braces=Function literal braces +options.jet.attribute.descriptor.safe.access=Safe access dot +options.jet.attribute.descriptor.arrow=Arrow +options.jet.attribute.descriptor.kdoc.comment=KDoc comment +options.jet.attribute.descriptor.kdoc.tag=KDoc tag +options.jet.attribute.descriptor.kdoc.tag.value=KDoc tag value +options.jet.attribute.descriptor.kdoc.markup=KDoc markup +options.jet.attribute.descriptor.trait=Trait +options.jet.attribute.descriptor.annotation=Annotation +options.jet.attribute.descriptor.var=Mutable variable, parameter or property (var) +options.jet.attribute.descriptor.local.variable=Local variable +options.jet.attribute.descriptor.bound.variable=Function literal or anonymous object bound variable +options.jet.attribute.descriptor.instance.property=Instance property +options.jet.attribute.descriptor.namespace.property=Namespace property +options.jet.attribute.descriptor.property.with.backing=Property with backing field +options.jet.attribute.descriptor.backing.field.access=Backing field access +options.jet.attribute.descriptor.extension.property=Extension property +options.jet.attribute.descriptor.it=Function literal default parameter +options.jet.attribute.descriptor.fun=Function declaration +options.jet.attribute.descriptor.fun.call=Function call +options.jet.attribute.descriptor.namespace.fun.call=Namespace function call +options.jet.attribute.descriptor.extension.fun.call=Extension function call +options.jet.attribute.descriptor.constructor.call=Constructor call +options.jet.attribute.descriptor.auto.casted=Automatically casted value +options.jet.attribute.descriptor.label=Label diff --git a/idea/src/org/jetbrains/jet/plugin/JetHighlighter.java b/idea/src/org/jetbrains/jet/plugin/JetHighlighter.java deleted file mode 100644 index 15c6f57e089..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/JetHighlighter.java +++ /dev/null @@ -1,202 +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. - */ - -/* - * @author max - */ -package org.jetbrains.jet.plugin; - -import com.intellij.lexer.Lexer; -import com.intellij.openapi.editor.HighlighterColors; -import com.intellij.openapi.editor.SyntaxHighlighterColors; -import com.intellij.openapi.editor.colors.TextAttributesKey; -import com.intellij.openapi.editor.markup.EffectType; -import com.intellij.openapi.editor.markup.TextAttributes; -import com.intellij.openapi.fileTypes.SyntaxHighlighterBase; -import com.intellij.psi.TokenType; -import com.intellij.psi.tree.IElementType; -import com.intellij.ui.Colors; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lexer.JetLexer; -import org.jetbrains.jet.lexer.JetTokens; - -import java.awt.*; -import java.util.HashMap; -import java.util.Map; - -public class JetHighlighter extends SyntaxHighlighterBase { - private static final Map keys1; - private static final Map keys2; - - private static final TextAttributesKey JET_KEYWORD = TextAttributesKey.createTextAttributesKey( - "JET.KEYWORD", - SyntaxHighlighterColors.KEYWORD.getDefaultAttributes() - ); - - public static final TextAttributesKey JET_SOFT_KEYWORD; - static { - TextAttributes attributes = SyntaxHighlighterColors.KEYWORD.getDefaultAttributes().clone(); - attributes.setForegroundColor(Colors.DARK_RED); - JET_SOFT_KEYWORD = TextAttributesKey.createTextAttributesKey( - "JET.SOFT.KEYWORD", - attributes - ); - } - - public static final TextAttributesKey JET_FIELD_IDENTIFIER = TextAttributesKey.createTextAttributesKey( - "JET.FIELD.IDENTIFIER", -// TODO: proper attributes - SyntaxHighlighterColors.NUMBER.getDefaultAttributes() - ); - - public static final TextAttributesKey JET_PROPERTY_WITH_BACKING_FIELD_IDENTIFIER = TextAttributesKey.createTextAttributesKey( - "JET.PROPERTY.WITH.BACKING.FIELD.IDENTIFIER", -// TODO: proper attributes - SyntaxHighlighterColors.NUMBER.getDefaultAttributes() - ); - - public static final TextAttributesKey JET_LABEL_IDENTIFIER = TextAttributesKey.createTextAttributesKey( - "JET.LABEL.IDENTIFIER", -// TODO: proper attributes - SyntaxHighlighterColors.NUMBER.getDefaultAttributes() - ); - - private static final TextAttributesKey JET_NUMBER = TextAttributesKey.createTextAttributesKey( - "JET.NUMBER", - SyntaxHighlighterColors.NUMBER.getDefaultAttributes() - ); - - public static final TextAttributesKey JET_STRING = TextAttributesKey.createTextAttributesKey( - "JET.STRING", - SyntaxHighlighterColors.STRING.getDefaultAttributes() - ); - - public static final TextAttributesKey JET_STRING_ESCAPE = TextAttributesKey.createTextAttributesKey( - "JET.STRING.ESCAPE", - SyntaxHighlighterColors.VALID_STRING_ESCAPE.getDefaultAttributes() - ); - - private static final TextAttributesKey JET_COMMENT; - static { - TextAttributes attributes = SyntaxHighlighterColors.LINE_COMMENT.getDefaultAttributes().clone(); - attributes.setFontType(Font.PLAIN); - JET_COMMENT = TextAttributesKey.createTextAttributesKey( - "JET.COMMENT", - attributes - ); - } - - private static final TextAttributesKey JET_BAD_CHARACTER = TextAttributesKey.createTextAttributesKey( - "JET.BADCHARACTER", - HighlighterColors.BAD_CHARACTER.getDefaultAttributes() - ); - - public static final TextAttributesKey JET_AUTO_CAST_EXPRESSION; - - static { - TextAttributes clone = SyntaxHighlighterColors.STRING.getDefaultAttributes().clone(); - clone.setFontType(Font.PLAIN); -// TODO: proper attributes - JET_AUTO_CAST_EXPRESSION = TextAttributesKey.createTextAttributesKey("JET.AUTO.CAST.EXPRESSION", clone); - } - - public static final TextAttributesKey JET_WRAPPED_INTO_REF; - - static { - TextAttributes attributes = new TextAttributes(); - attributes.setEffectType(EffectType.LINE_UNDERSCORE); - attributes.setEffectColor(Color.BLACK); - JET_WRAPPED_INTO_REF = TextAttributesKey.createTextAttributesKey("JET.WRAPPED.INTO.REF", attributes); - } - - public static final TextAttributesKey JET_AUTOCREATED_IT; - - static { - TextAttributes attributes = new TextAttributes(); - attributes.setFontType(Font.BOLD); -// TODO: proper attributes - JET_AUTOCREATED_IT = TextAttributesKey.createTextAttributesKey("JET.AUTO.CREATED.IT", attributes); - } - - public static final TextAttributesKey JET_FUNCTION_LITERAL_DELIMITER; - - static { - TextAttributes attributes = new TextAttributes(); - attributes.setFontType(Font.BOLD); -// TODO: proper attributes - JET_FUNCTION_LITERAL_DELIMITER = TextAttributesKey.createTextAttributesKey("JET.AUTO.CREATED.IT", attributes); - } - - public static final TextAttributesKey JET_DEBUG_INFO; - - static { - TextAttributes textAttributes = new TextAttributes(); - textAttributes.setEffectType(EffectType.ROUNDED_BOX); - textAttributes.setEffectColor(Color.BLACK); - JET_DEBUG_INFO = TextAttributesKey.createTextAttributesKey("JET.DEBUG.INFO", textAttributes); - } - - public static final TextAttributesKey JET_RESOLVED_TO_ERROR; - - static { - TextAttributes textAttributes = new TextAttributes(); - textAttributes.setEffectType(EffectType.ROUNDED_BOX); - textAttributes.setEffectColor(Color.RED); - JET_RESOLVED_TO_ERROR = TextAttributesKey.createTextAttributesKey("JET.RESOLVED.TO.ERROR", textAttributes); - } - - @NotNull - public Lexer getHighlightingLexer() { - return new JetLexer(); - } - - @NotNull - public TextAttributesKey[] getTokenHighlights(IElementType tokenType) { - return pack(keys1.get(tokenType), keys2.get(tokenType)); - } - - static { - keys1 = new HashMap(); - keys2 = new HashMap(); - - - fillMap(keys1, JetTokens.KEYWORDS, JET_KEYWORD); - - keys1.put(JetTokens.AS_SAFE, JET_KEYWORD); - keys1.put(JetTokens.LABEL_IDENTIFIER, JET_LABEL_IDENTIFIER); - keys1.put(JetTokens.ATAT, JET_LABEL_IDENTIFIER); - keys1.put(JetTokens.FIELD_IDENTIFIER, JET_FIELD_IDENTIFIER); - keys1.put(JetTokens.INTEGER_LITERAL, JET_NUMBER); - keys1.put(JetTokens.FLOAT_LITERAL, JET_NUMBER); - - keys1.put(JetTokens.OPEN_QUOTE, JET_STRING); - keys1.put(JetTokens.CLOSING_QUOTE, JET_STRING); - keys1.put(JetTokens.REGULAR_STRING_PART, JET_STRING); - keys1.put(JetTokens.LONG_TEMPLATE_ENTRY_END, JET_STRING_ESCAPE); - keys1.put(JetTokens.LONG_TEMPLATE_ENTRY_START, JET_STRING_ESCAPE); - keys1.put(JetTokens.SHORT_TEMPLATE_ENTRY_START, JET_STRING_ESCAPE); - - keys1.put(JetTokens.ESCAPE_SEQUENCE, JET_STRING_ESCAPE); - - keys1.put(JetTokens.CHARACTER_LITERAL, JET_STRING); - - keys1.put(JetTokens.EOL_COMMENT, JET_COMMENT); - keys1.put(JetTokens.BLOCK_COMMENT, JET_COMMENT); - keys1.put(JetTokens.DOC_COMMENT, JET_COMMENT); - - keys1.put(TokenType.BAD_CHARACTER, JET_BAD_CHARACTER); - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/actions/ToggleErrorReportingAction.java b/idea/src/org/jetbrains/jet/plugin/actions/ToggleErrorReportingAction.java index 41c33912ea1..eace7a6aac8 100644 --- a/idea/src/org/jetbrains/jet/plugin/actions/ToggleErrorReportingAction.java +++ b/idea/src/org/jetbrains/jet/plugin/actions/ToggleErrorReportingAction.java @@ -16,16 +16,23 @@ package org.jetbrains.jet.plugin.actions; -import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; import com.intellij.openapi.actionSystem.AnActionEvent; -import org.jetbrains.jet.plugin.annotations.JetPsiChecker; +import com.intellij.openapi.actionSystem.ToggleAction; +import org.jetbrains.jet.plugin.highlighter.JetPsiChecker; /** - * @author yole + * @author Andrey Breslav */ -public class ToggleErrorReportingAction extends AnAction { +public class ToggleErrorReportingAction extends ToggleAction { @Override - public void actionPerformed(AnActionEvent e) { - JetPsiChecker.setErrorReportingEnabled(!JetPsiChecker.isErrorReportingEnabled()); + public boolean isSelected(AnActionEvent e) { + return JetPsiChecker.isErrorReportingEnabled(); + } + + @Override + public void setSelected(AnActionEvent e, boolean state) { + JetPsiChecker.setErrorReportingEnabled(state); + DaemonCodeAnalyzer.getInstance(e.getProject()).restart(); } } diff --git a/idea/src/org/jetbrains/jet/plugin/annotations/JetLineMarkerProvider.java b/idea/src/org/jetbrains/jet/plugin/annotations/JetLineMarkerProvider.java deleted file mode 100644 index 82351ffefdf..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/annotations/JetLineMarkerProvider.java +++ /dev/null @@ -1,209 +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.annotations; - -import com.google.common.collect.Lists; -import com.intellij.codeHighlighting.Pass; -import com.intellij.codeInsight.daemon.GutterIconNavigationHandler; -import com.intellij.codeInsight.daemon.LineMarkerInfo; -import com.intellij.codeInsight.daemon.LineMarkerProvider; -import com.intellij.codeInsight.hint.HintUtil; -import com.intellij.codeInsight.navigation.NavigationUtil; -import com.intellij.ide.util.DefaultPsiElementCellRenderer; -import com.intellij.openapi.ui.popup.JBPopup; -import com.intellij.openapi.ui.popup.JBPopupFactory; -import com.intellij.openapi.util.IconLoader; -import com.intellij.openapi.util.Iconable; -import com.intellij.psi.PsiElement; -import com.intellij.psi.util.PsiUtilBase; -import com.intellij.ui.awt.RelativePoint; -import com.intellij.util.Function; -import com.intellij.util.PlatformIcons; -import com.intellij.util.PsiIconUtil; -import com.intellij.util.PsiNavigateUtil; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.descriptors.*; -import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; -import org.jetbrains.jet.resolve.DescriptorRenderer; - -import javax.swing.*; -import java.awt.event.MouseEvent; -import java.util.Collection; -import java.util.List; -import java.util.Set; - -/** - * @author abreslav - */ -public class JetLineMarkerProvider implements LineMarkerProvider { - - public static final Icon OVERRIDING_FUNCTION = IconLoader.getIcon("/general/overridingMethod.png"); - - @Override - public LineMarkerInfo getLineMarkerInfo(PsiElement element) { - JetFile file = (JetFile) element.getContainingFile(); - if (file == null) return null; - - final BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file) - .getBindingContext(); - - if (element instanceof JetClass) { - JetClass jetClass = (JetClass) element; - ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, jetClass); - String text = classDescriptor == null ? "Unresolved" : DescriptorRenderer.HTML.render(classDescriptor); - return createLineMarkerInfo(jetClass, text); - } - - if (element instanceof JetProperty) { - JetProperty jetProperty = (JetProperty) element; - final VariableDescriptor variableDescriptor = bindingContext.get(BindingContext.VARIABLE, jetProperty); - if (variableDescriptor instanceof PropertyDescriptor) { - return createLineMarkerInfo(element, DescriptorRenderer.HTML.render(variableDescriptor)); - } - } - - if (element instanceof JetNamedFunction) { - JetNamedFunction jetFunction = (JetNamedFunction) element; - - final SimpleFunctionDescriptor functionDescriptor = bindingContext.get(BindingContext.FUNCTION, jetFunction); - if (functionDescriptor == null) return null; - final Set overriddenFunctions = functionDescriptor.getOverriddenDescriptors(); - Icon icon = isMember(functionDescriptor) ? (overriddenFunctions.isEmpty() ? PlatformIcons.METHOD_ICON : OVERRIDING_FUNCTION) : PlatformIcons.FUNCTION_ICON; - return new LineMarkerInfo( - jetFunction, jetFunction.getTextOffset(), icon, Pass.UPDATE_ALL, - new Function() { - @Override - public String fun(JetNamedFunction jetFunction) { - StringBuilder builder = new StringBuilder(); - builder.append(DescriptorRenderer.HTML.render(functionDescriptor)); - int overrideCount = overriddenFunctions.size(); - if (overrideCount >= 1) { - builder.append(" overrides ").append(DescriptorRenderer.HTML.render(overriddenFunctions.iterator().next())); - } - if (overrideCount > 1) { - int count = overrideCount - 1; - builder.append(" and ").append(count).append(" other function"); - if (count > 1) { - builder.append("s"); - } - } - - return builder.toString(); - } - }, - new GutterIconNavigationHandler() { - @Override - public void navigate(MouseEvent event, JetNamedFunction elt) { - if (overriddenFunctions.isEmpty()) return; - final List list = Lists.newArrayList(); - for (FunctionDescriptor overriddenFunction : overriddenFunctions) { - PsiElement declarationPsiElement = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, overriddenFunction); - list.add(declarationPsiElement); - } - if (list.isEmpty()) { - String myEmptyText = "empty text"; - final JComponent renderer = HintUtil.createErrorLabel(myEmptyText); - final JBPopup popup = JBPopupFactory.getInstance().createComponentPopupBuilder(renderer, renderer).createPopup(); - if (event != null) { - popup.show(new RelativePoint(event)); - } - return; - } - if (list.size() == 1) { - PsiNavigateUtil.navigate(list.iterator().next()); - } - else { - final JBPopup popup = NavigationUtil.getPsiElementPopup(PsiUtilBase.toPsiElementArray(list), new DefaultPsiElementCellRenderer() { - @Override - public String getElementText(PsiElement element) { - if (element instanceof JetNamedFunction) { - JetNamedFunction function = (JetNamedFunction) element; - return DescriptorRenderer.HTML.render(bindingContext.get(BindingContext.FUNCTION, function)); - } - return super.getElementText(element); - } - }, DescriptorRenderer.HTML.render(functionDescriptor)); - if (event != null) { - popup.show(new RelativePoint(event)); - } - } - } - } - ); - } - - if (element instanceof JetNamespaceHeader) { - JetNamespaceHeader header = (JetNamespaceHeader) element; - if (header.getNameIdentifier() != null) { - return createLineMarkerInfo(header, - DescriptorRenderer.HTML.render(bindingContext.get(BindingContext.NAMESPACE, file))); - } - } - - if (element instanceof JetObjectDeclaration && !(element.getParent() instanceof JetExpression)) { - JetObjectDeclaration jetObjectDeclaration = (JetObjectDeclaration) element; - - return new LineMarkerInfo( - jetObjectDeclaration, jetObjectDeclaration.getTextOffset(), PlatformIcons.ANONYMOUS_CLASS_ICON, Pass.UPDATE_ALL, - new Function() { - @Override - public String fun(JetObjectDeclaration jetObjectDeclaration) { - ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, jetObjectDeclaration); - if (classDescriptor != null) { - return DescriptorRenderer.HTML.renderAsObject(classDescriptor); - } - return "<none>"; - } - }, - new GutterIconNavigationHandler() { - @Override - public void navigate(MouseEvent e, JetObjectDeclaration elt) { - } - } - ); - } - - return null; - } - - private LineMarkerInfo createLineMarkerInfo(T element, final String text) { - return new LineMarkerInfo( - element, element.getTextOffset(), PsiIconUtil.getProvidersIcon(element, Iconable.ICON_FLAG_CLOSED), Pass.UPDATE_ALL, - new Function() { - @Override - public String fun(T jetNamespace) { - return text; - } - }, - new GutterIconNavigationHandler() { - @Override - public void navigate(MouseEvent e, T elt) { - } - } - ); - } - - private boolean isMember(@NotNull SimpleFunctionDescriptor functionDescriptor) { - return functionDescriptor.getContainingDeclaration().getOriginal() instanceof ClassifierDescriptor; - } - - @Override - public void collectSlowLineMarkers(List elements, Collection result) { - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/annotations/LabelsAnnotator.java b/idea/src/org/jetbrains/jet/plugin/annotations/LabelsAnnotator.java deleted file mode 100644 index 32e4f0baf2c..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/annotations/LabelsAnnotator.java +++ /dev/null @@ -1,55 +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. - */ - -/* - * @author max - */ -package org.jetbrains.jet.plugin.annotations; - -import com.intellij.lang.annotation.AnnotationHolder; -import com.intellij.lang.annotation.Annotator; -import com.intellij.psi.PsiElement; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.psi.JetLabelQualifiedExpression; -import org.jetbrains.jet.lang.psi.JetPrefixExpression; -import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; -import org.jetbrains.jet.lang.psi.JetVisitorVoid; -import org.jetbrains.jet.lexer.JetTokens; -import org.jetbrains.jet.plugin.JetHighlighter; - -public class LabelsAnnotator implements Annotator { - public void annotate(@NotNull PsiElement element, @NotNull final AnnotationHolder holder) { -// if (ApplicationManager.getApplication().isUnitTestMode()) return; - element.accept(new JetVisitorVoid() { - @Override - public void visitPrefixExpression(JetPrefixExpression expression) { - JetSimpleNameExpression operationSign = expression.getOperationReference(); - if (JetTokens.LABELS.contains(operationSign.getReferencedNameElementType())) { - holder.createInfoAnnotation(operationSign, null).setTextAttributes(JetHighlighter.JET_LABEL_IDENTIFIER); - } - } - - @Override - public void visitLabelQualifiedExpression(JetLabelQualifiedExpression expression) { - JetSimpleNameExpression targetLabel = expression.getTargetLabel(); - if (targetLabel != null) { - holder.createInfoAnnotation(targetLabel, null).setTextAttributes(JetHighlighter.JET_LABEL_IDENTIFIER); - } - } - - }); - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/annotations/SoftKeywordsAnnotator.java b/idea/src/org/jetbrains/jet/plugin/annotations/SoftKeywordsAnnotator.java deleted file mode 100644 index 8bfcadbd58e..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/annotations/SoftKeywordsAnnotator.java +++ /dev/null @@ -1,82 +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. - */ - -/* - * @author max - */ -package org.jetbrains.jet.plugin.annotations; - -import com.intellij.lang.ASTNode; -import com.intellij.lang.annotation.AnnotationHolder; -import com.intellij.lang.annotation.Annotator; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.psi.PsiElement; -import com.intellij.psi.impl.source.tree.LeafPsiElement; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.lexer.JetTokens; -import org.jetbrains.jet.plugin.JetHighlighter; - -public class SoftKeywordsAnnotator implements Annotator { - public void annotate(@NotNull PsiElement element, @NotNull final AnnotationHolder holder) { - element.accept(new JetVisitorVoid() { - @Override - public void visitElement(PsiElement element) { - if (element instanceof LeafPsiElement) { - if (JetTokens.SOFT_KEYWORDS.contains(((LeafPsiElement) element).getElementType())) { - holder.createInfoAnnotation(element, null).setTextAttributes(JetHighlighter.JET_SOFT_KEYWORD); - } - } - } - - @Override - public void visitAnnotationEntry(JetAnnotationEntry annotationEntry) { - JetTypeReference typeReference = annotationEntry.getTypeReference(); - if (typeReference != null) { - JetTypeElement typeElement = typeReference.getTypeElement(); - markAnnotationIdentifiers(typeElement, holder); - } - } - - @Override - public void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression) { - if (ApplicationManager.getApplication().isUnitTestMode()) return; - JetFunctionLiteral functionLiteral = expression.getFunctionLiteral(); - holder.createInfoAnnotation(functionLiteral.getOpenBraceNode(), null).setTextAttributes(JetHighlighter.JET_FUNCTION_LITERAL_DELIMITER); - ASTNode closingBraceNode = functionLiteral.getClosingBraceNode(); - if (closingBraceNode != null) { - holder.createInfoAnnotation(closingBraceNode, null).setTextAttributes(JetHighlighter.JET_FUNCTION_LITERAL_DELIMITER); - } - ASTNode arrowNode = functionLiteral.getArrowNode(); - if (arrowNode != null) { - holder.createInfoAnnotation(arrowNode, null).setTextAttributes(JetHighlighter.JET_FUNCTION_LITERAL_DELIMITER); - } - } - }); - } - - private void markAnnotationIdentifiers(JetTypeElement typeElement, @NotNull AnnotationHolder holder) { - if (typeElement instanceof JetUserType) { - JetUserType userType = (JetUserType) typeElement; - if (userType.getQualifier() == null) { - JetSimpleNameExpression referenceExpression = userType.getReferenceExpression(); - if (referenceExpression != null) { - holder.createInfoAnnotation(referenceExpression.getNode(), "Annotation").setTextAttributes(JetHighlighter.JET_SOFT_KEYWORD); - } - } - } - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/AfterAnalysisHighlightingVisitor.java b/idea/src/org/jetbrains/jet/plugin/highlighter/AfterAnalysisHighlightingVisitor.java new file mode 100644 index 00000000000..55399cc865d --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/AfterAnalysisHighlightingVisitor.java @@ -0,0 +1,29 @@ +/* + * 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 org.jetbrains.jet.lang.resolve.BindingContext; + +abstract class AfterAnalysisHighlightingVisitor extends HighlightingVisitor { + protected BindingContext bindingContext; + + protected AfterAnalysisHighlightingVisitor(AnnotationHolder holder, BindingContext bindingContext) { + super(holder); + this.bindingContext = bindingContext; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/annotations/DebugInfoAnnotator.java b/idea/src/org/jetbrains/jet/plugin/highlighter/DebugInfoAnnotator.java similarity index 91% rename from idea/src/org/jetbrains/jet/plugin/annotations/DebugInfoAnnotator.java rename to idea/src/org/jetbrains/jet/plugin/highlighter/DebugInfoAnnotator.java index 75b593254df..6c809d52de2 100644 --- a/idea/src/org/jetbrains/jet/plugin/annotations/DebugInfoAnnotator.java +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/DebugInfoAnnotator.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.annotations; +package org.jetbrains.jet.plugin.highlighter; import com.google.common.collect.Sets; import com.intellij.lang.annotation.AnnotationHolder; @@ -34,7 +34,6 @@ import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lexer.JetTokens; -import org.jetbrains.jet.plugin.JetHighlighter; import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; import java.util.Collection; @@ -52,27 +51,20 @@ public class DebugInfoAnnotator implements Annotator { public static final TokenSet EXCLUDED = TokenSet.create(COLON, AS_KEYWORD, AS_SAFE, IS_KEYWORD, NOT_IS, OROR, ANDAND, EQ, EQEQEQ, EXCLEQEQEQ, ELVIS, EXCLEXCL); - private static volatile boolean debugInfoEnabled = true; - - public static void setDebugInfoEnabled(boolean value) { - debugInfoEnabled = value; - } - public static boolean isDebugInfoEnabled() { - return debugInfoEnabled; + return ApplicationManager.getApplication().isInternal(); } @Override public void annotate(@NotNull PsiElement element, @NotNull final AnnotationHolder holder) { - if (!debugInfoEnabled || !JetPsiChecker.isErrorReportingEnabled()) { + if (!isDebugInfoEnabled() || !JetPsiChecker.isErrorReportingEnabled()) { return; } if (element instanceof JetFile) { JetFile file = (JetFile) element; try { - final BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file) - .getBindingContext(); + final BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file).getBindingContext(); final Set unresolvedReferences = Sets.newHashSet(); for (Diagnostic diagnostic : bindingContext.getDiagnostics()) { @@ -121,13 +113,13 @@ public class DebugInfoAnnotator implements Annotator { boolean unresolved = unresolvedReferences.contains(expression); JetType expressionType = bindingContext.get(EXPRESSION_TYPE, expression); if (declarationDescriptor != null && !ApplicationManager.getApplication().isUnitTestMode() && (ErrorUtils.isError(declarationDescriptor) || ErrorUtils.containsErrorType(expressionType))) { - holder.createErrorAnnotation(expression, "[DEBUG] Resolved to error element").setTextAttributes(JetHighlighter.JET_RESOLVED_TO_ERROR); + holder.createErrorAnnotation(expression, "[DEBUG] Resolved to error element").setTextAttributes(JetHighlightingColors.RESOLVED_TO_ERROR); } if (resolved && unresolved) { - holder.createErrorAnnotation(expression, "[DEBUG] Reference marked as unresolved is actually resolved to " + target).setTextAttributes(JetHighlighter.JET_DEBUG_INFO); + holder.createErrorAnnotation(expression, "[DEBUG] Reference marked as unresolved is actually resolved to " + target).setTextAttributes(JetHighlightingColors.DEBUG_INFO); } else if (!resolved && !unresolved) { - holder.createErrorAnnotation(expression, "[DEBUG] Reference is not resolved to anything, but is not marked unresolved").setTextAttributes(JetHighlighter.JET_DEBUG_INFO); + holder.createErrorAnnotation(expression, "[DEBUG] Reference is not resolved to anything, but is not marked unresolved").setTextAttributes(JetHighlightingColors.DEBUG_INFO); } } diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/FunctionsHighlightingVisitor.java b/idea/src/org/jetbrains/jet/plugin/highlighter/FunctionsHighlightingVisitor.java new file mode 100644 index 00000000000..d58bc0a6654 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/FunctionsHighlightingVisitor.java @@ -0,0 +1,92 @@ +/* + * 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.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; + +/** + * @author Evgeny Gerashchenko + * @since 4/2/12 + */ +public class FunctionsHighlightingVisitor extends AfterAnalysisHighlightingVisitor { + public FunctionsHighlightingVisitor(AnnotationHolder holder, BindingContext bindingContext) { + super(holder, bindingContext); + } + + @Override + public void visitJetElement(JetElement element) { + element.acceptChildren(this); + } + + @Override + public void visitNamedFunction(JetNamedFunction function) { + PsiElement nameIdentifier = function.getNameIdentifier(); + if (nameIdentifier != null) { + JetPsiChecker.highlightName(holder, nameIdentifier, JetHighlightingColors.FUNCTION_DECLARATION); + } + + super.visitNamedFunction(function); + } + + @Override + public void visitDelegationToSuperCallSpecifier(JetDelegatorToSuperCall call) { + JetConstructorCalleeExpression calleeExpression = call.getCalleeExpression(); + JetTypeReference typeRef = calleeExpression.getTypeReference(); + if (typeRef != null) { + JetTypeElement typeElement = typeRef.getTypeElement(); + if (typeElement instanceof JetUserType) { + JetSimpleNameExpression nameExpression = ((JetUserType)typeElement).getReferenceExpression(); + if (nameExpression != null) { + JetPsiChecker.highlightName(holder, nameExpression, JetHighlightingColors.CONSTRUCTOR_CALL); + } + } + } + super.visitDelegationToSuperCallSpecifier(call); + } + + @Override + 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); + } + else if (calleeDescriptor instanceof FunctionDescriptor && !(calleeDescriptor instanceof VariableAsFunctionDescriptor)) { + FunctionDescriptor fun = (FunctionDescriptor)calleeDescriptor; + if (fun.getReceiverParameter() != ReceiverDescriptor.NO_RECEIVER) { + JetPsiChecker.highlightName(holder, callee, JetHighlightingColors.EXTENSION_FUNCTION_CALL); + } + else if (fun.getContainingDeclaration() instanceof NamespaceDescriptor) { + JetPsiChecker.highlightName(holder, callee, JetHighlightingColors.NAMESPACE_FUNCTION_CALL); + } + else { + JetPsiChecker.highlightName(holder, callee, JetHighlightingColors.FUNCTION_CALL); + } + } + } + } + + super.visitCallExpression(expression); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/HighlightingVisitor.java b/idea/src/org/jetbrains/jet/plugin/highlighter/HighlightingVisitor.java new file mode 100644 index 00000000000..62c7145a825 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/HighlightingVisitor.java @@ -0,0 +1,28 @@ +/* + * 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 org.jetbrains.jet.lang.psi.JetVisitorVoid; + +abstract class HighlightingVisitor extends JetVisitorVoid { + protected AnnotationHolder holder; + + protected HighlightingVisitor(AnnotationHolder holder) { + this.holder = holder; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/JetColorSettingsPage.java b/idea/src/org/jetbrains/jet/plugin/highlighter/JetColorSettingsPage.java new file mode 100644 index 00000000000..8e80f0f4016 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/JetColorSettingsPage.java @@ -0,0 +1,175 @@ +/* + * 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.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.fileTypes.SyntaxHighlighter; +import com.intellij.openapi.options.OptionsBundle; +import com.intellij.openapi.options.colors.AttributesDescriptor; +import com.intellij.openapi.options.colors.ColorDescriptor; +import com.intellij.openapi.options.colors.ColorSettingsPage; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.plugin.JetBundle; +import org.jetbrains.jet.plugin.JetIconProvider; + +import javax.swing.*; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.HashMap; +import java.util.Map; + +public class JetColorSettingsPage implements ColorSettingsPage { + @Override + public Icon getIcon() { + return JetIconProvider.KOTLIN_ICON; + } + + @NotNull + @Override + public SyntaxHighlighter getHighlighter() { + return new JetHighlighter(); + } + + @NotNull + @Override + public String getDemoText() { + return "/* Block comment */\n" + + "import kotlin.util.* // line comment\n" + + "\n" + + " Bad character: \\n\n" + + "/**\n" + + " * Doc comment here for `SomeClass`\n" + + " * @see Iterator#next()\n" + + " */\n" + + "[Deprecated]\n" + + "public class MyClass<out T : Iterable<T>>(var prop1 : Int) {\n" + + " fun foo(nullable : String?, r : Runnable, f : () -> Int) {\n" + + " println(\"length is ${nullable?.length} \\e\")\n" + + " val ints = java.util.ArrayList(2)\n" + + " ints[0] = 102 + f()\n" + + " var ref = ints.size()\n" + + " if (!ints.empty) {\n" + + " ints.forEach @lit {\n" + + " if (it == null) return @lit\n" + + " println(it + ref)\n" + + " }\n" + + " }\n" + + " }\n" + + "}\n" + + "\n" + + "var globalCounter : Int = 5\n" + + "get() {\n" + + " return $globalCounter\n" + + "}\n" + + "\n" + + "public abstract class Abstract {\n" + + "}"; + } + + @Override + public Map getAdditionalHighlightingTagToDescriptorMap() { + Map map = new HashMap(); + for (Field field : JetHighlightingColors.class.getFields()) { + if (Modifier.isStatic(field.getModifiers())) { + try { + map.put(field.getName(), (TextAttributesKey) field.get(null)); + } + catch (IllegalAccessException e) { + assert false; + } + } + } + return map; + } + + @NotNull + @Override + public AttributesDescriptor[] getAttributeDescriptors() { + return new AttributesDescriptor[]{ + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.keyword"), JetHighlightingColors.KEYWORD), + new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.builtin.annotation"), JetHighlightingColors.BUILTIN_ANNOTATION), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.number"), JetHighlightingColors.NUMBER), + + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.string"), JetHighlightingColors.STRING), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.valid.escape.in.string"), JetHighlightingColors.VALID_STRING_ESCAPE), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.invalid.escape.in.string"), JetHighlightingColors.INVALID_STRING_ESCAPE), + + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.operator.sign"), JetHighlightingColors.OPERATOR_SIGN), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.parentheses"), JetHighlightingColors.PARENTHESIS), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.braces"), JetHighlightingColors.BRACES), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.brackets"), JetHighlightingColors.BRACKETS), + new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.closure.braces"), JetHighlightingColors.FUNCTION_LITERAL_BRACES), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.comma"), JetHighlightingColors.COMMA), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.semicolon"), JetHighlightingColors.SEMICOLON), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.dot"), JetHighlightingColors.DOT), + new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.safe.access"), JetHighlightingColors.SAFE_ACCESS), + new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.arrow"), JetHighlightingColors.ARROW), + + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.line.comment"), JetHighlightingColors.LINE_COMMENT), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.block.comment"), JetHighlightingColors.BLOCK_COMMENT), + + // KDoc highlighting options are temporarily disabled, until actual highlighting and parsing of them is implemented + new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.kdoc.comment"), JetHighlightingColors.DOC_COMMENT), + //new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.kdoc.tag"), JetHighlightingColors.DOC_COMMENT_TAG), + //new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.kdoc.tag.value"), JetHighlightingColors.DOC_COMMENT_TAG_VALUE), + //new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.kdoc.markup"), JetHighlightingColors.DOC_COMMENT_MARKUP), + + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.class"), JetHighlightingColors.CLASS), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.type.parameter"), JetHighlightingColors.TYPE_PARAMETER), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.abstract.class"), JetHighlightingColors.ABSTRACT_CLASS), + new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.trait"), JetHighlightingColors.TRAIT), + new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.annotation"), JetHighlightingColors.ANNOTATION), + + new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.var"), JetHighlightingColors.MUTABLE_VARIABLE), + + new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.local.variable"), JetHighlightingColors.LOCAL_VARIABLE), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.parameter"), JetHighlightingColors.PARAMETER), + new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.bound.variable"), JetHighlightingColors.WRAPPED_INTO_REF), + + new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.instance.property"), JetHighlightingColors.INSTANCE_PROPERTY), + new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.namespace.property"), JetHighlightingColors.NAMESPACE_PROPERTY), + new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.property.with.backing"), JetHighlightingColors.PROPERTY_WITH_BACKING_FIELD), + new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.backing.field.access"), JetHighlightingColors.BACKING_FIELD_ACCESS), + new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.extension.property"), JetHighlightingColors.EXTENSION_PROPERTY), + + new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.it"), JetHighlightingColors.FUNCTION_LITERAL_DEFAULT_PARAMETER), + new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.fun"), JetHighlightingColors.FUNCTION_DECLARATION), + new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.fun.call"), JetHighlightingColors.FUNCTION_CALL), + new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.namespace.fun.call"), JetHighlightingColors.NAMESPACE_FUNCTION_CALL), + 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(OptionsBundle.message("options.java.attribute.descriptor.bad.character"), JetHighlightingColors.BAD_CHARACTER), + + new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.auto.casted"), JetHighlightingColors.AUTO_CASTED_VALUE), + + new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.label"), JetHighlightingColors.LABEL), + }; + } + + @NotNull + @Override + public ColorDescriptor[] getColorDescriptors() { + return ColorDescriptor.EMPTY_ARRAY; + } + + @NotNull + @Override + public String getDisplayName() { + return "Kotlin"; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlighter.java b/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlighter.java new file mode 100644 index 00000000000..6f99c1f92ae --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlighter.java @@ -0,0 +1,91 @@ +/* + * 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. + */ + +/* + * @author max + */ +package org.jetbrains.jet.plugin.highlighter; + +import com.intellij.lexer.Lexer; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.fileTypes.SyntaxHighlighterBase; +import com.intellij.psi.TokenType; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lexer.JetLexer; +import org.jetbrains.jet.lexer.JetTokens; + +import java.util.HashMap; +import java.util.Map; + +public class JetHighlighter extends SyntaxHighlighterBase { + private static final Map keys; + + @NotNull + public Lexer getHighlightingLexer() { + return new JetLexer(); + } + + @NotNull + public TextAttributesKey[] getTokenHighlights(IElementType tokenType) { + return pack(keys.get(tokenType)); + } + + static { + keys = new HashMap(); + + fillMap(keys, JetTokens.KEYWORDS, JetHighlightingColors.KEYWORD); + + keys.put(JetTokens.AS_SAFE, JetHighlightingColors.KEYWORD); + keys.put(JetTokens.LABEL_IDENTIFIER, JetHighlightingColors.LABEL); + keys.put(JetTokens.ATAT, JetHighlightingColors.LABEL); + keys.put(JetTokens.INTEGER_LITERAL, JetHighlightingColors.NUMBER); + keys.put(JetTokens.FLOAT_LITERAL, JetHighlightingColors.NUMBER); + + fillMap(keys, JetTokens.OPERATIONS.minus( + TokenSet.create(JetTokens.IDENTIFIER, JetTokens.LABEL_IDENTIFIER)).minus( + JetTokens.KEYWORDS), JetHighlightingColors.OPERATOR_SIGN); + keys.put(JetTokens.LPAR, JetHighlightingColors.PARENTHESIS); + keys.put(JetTokens.RPAR, JetHighlightingColors.PARENTHESIS); + keys.put(JetTokens.LBRACE, JetHighlightingColors.BRACES); + keys.put(JetTokens.RBRACE, JetHighlightingColors.BRACES); + keys.put(JetTokens.LBRACKET, JetHighlightingColors.BRACKETS); + keys.put(JetTokens.RBRACKET, JetHighlightingColors.BRACKETS); + keys.put(JetTokens.COMMA, JetHighlightingColors.COMMA); + keys.put(JetTokens.SEMICOLON, JetHighlightingColors.SEMICOLON); + keys.put(JetTokens.DOT, JetHighlightingColors.DOT); + keys.put(JetTokens.SAFE_ACCESS, JetHighlightingColors.SAFE_ACCESS); + keys.put(JetTokens.ARROW, JetHighlightingColors.ARROW); + + keys.put(JetTokens.OPEN_QUOTE, JetHighlightingColors.STRING); + keys.put(JetTokens.CLOSING_QUOTE, JetHighlightingColors.STRING); + keys.put(JetTokens.REGULAR_STRING_PART, JetHighlightingColors.STRING); + keys.put(JetTokens.LONG_TEMPLATE_ENTRY_END, JetHighlightingColors.VALID_STRING_ESCAPE); + keys.put(JetTokens.LONG_TEMPLATE_ENTRY_START, JetHighlightingColors.VALID_STRING_ESCAPE); + keys.put(JetTokens.SHORT_TEMPLATE_ENTRY_START, JetHighlightingColors.VALID_STRING_ESCAPE); + + keys.put(JetTokens.ESCAPE_SEQUENCE, JetHighlightingColors.VALID_STRING_ESCAPE); + + keys.put(JetTokens.CHARACTER_LITERAL, JetHighlightingColors.STRING); + + keys.put(JetTokens.EOL_COMMENT, JetHighlightingColors.LINE_COMMENT); + keys.put(JetTokens.BLOCK_COMMENT, JetHighlightingColors.BLOCK_COMMENT); + keys.put(JetTokens.DOC_COMMENT, JetHighlightingColors.DOC_COMMENT); + + keys.put(TokenType.BAD_CHARACTER, JetHighlightingColors.BAD_CHARACTER); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlightingColors.java b/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlightingColors.java new file mode 100644 index 00000000000..b3ca1bda1c9 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlightingColors.java @@ -0,0 +1,266 @@ +/* + * 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.openapi.editor.HighlighterColors; +import com.intellij.openapi.editor.SyntaxHighlighterColors; +import com.intellij.openapi.editor.colors.CodeInsightColors; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.editor.markup.EffectType; +import com.intellij.openapi.editor.markup.TextAttributes; + +import java.awt.*; + +public class JetHighlightingColors { + public final static TextAttributesKey KEYWORD = TextAttributesKey.createTextAttributesKey( + "KOTLIN_KEYWORD", + SyntaxHighlighterColors.KEYWORD.getDefaultAttributes() + ); + + public static final TextAttributesKey BUILTIN_ANNOTATION = TextAttributesKey.createTextAttributesKey( + "KOTLIN_BUILTIN_ANNOTATION", + SyntaxHighlighterColors.KEYWORD.getDefaultAttributes() + ); + + public static final TextAttributesKey NUMBER = TextAttributesKey.createTextAttributesKey( + "KOTLIN_NUMBER", + SyntaxHighlighterColors.NUMBER.getDefaultAttributes() + ); + + public static final TextAttributesKey STRING = TextAttributesKey.createTextAttributesKey( + "KOTLIN_STRING", + SyntaxHighlighterColors.STRING.getDefaultAttributes() + ); + + public static final TextAttributesKey VALID_STRING_ESCAPE = TextAttributesKey.createTextAttributesKey( + "KOTLIN_VALID_STRING_ESCAPE", + SyntaxHighlighterColors.VALID_STRING_ESCAPE.getDefaultAttributes() + ); + + public static final TextAttributesKey INVALID_STRING_ESCAPE = TextAttributesKey.createTextAttributesKey( + "KOTLIN_INVALID_STRING_ESCAPE", + SyntaxHighlighterColors.INVALID_STRING_ESCAPE.getDefaultAttributes() + ); + + public static final TextAttributesKey OPERATOR_SIGN = TextAttributesKey.createTextAttributesKey( + "KOTLIN_OPERATION_SIGN", + SyntaxHighlighterColors.OPERATION_SIGN.getDefaultAttributes() + ); + + public static final TextAttributesKey PARENTHESIS = TextAttributesKey.createTextAttributesKey( + "KOTLIN_PARENTHESIS", + SyntaxHighlighterColors.PARENTHS.getDefaultAttributes() + ); + + public static final TextAttributesKey BRACES = TextAttributesKey.createTextAttributesKey( + "KOTLIN_BRACES", + SyntaxHighlighterColors.BRACES.getDefaultAttributes() + ); + + public static final TextAttributesKey BRACKETS = TextAttributesKey.createTextAttributesKey( + "KOTLIN_BRACKETS", + SyntaxHighlighterColors.BRACKETS.getDefaultAttributes() + ); + + public static final TextAttributesKey FUNCTION_LITERAL_BRACES = TextAttributesKey.createTextAttributesKey( + "KOTLIN_FUNCTION_LITERAL_BRACES", + new TextAttributes(null, null, null, null, Font.BOLD) + ); + + public static final TextAttributesKey COMMA = TextAttributesKey.createTextAttributesKey( + "KOTLIN_COMMA", + SyntaxHighlighterColors.COMMA.getDefaultAttributes() + ); + + public static final TextAttributesKey SEMICOLON = TextAttributesKey.createTextAttributesKey( + "KOTLIN_SEMICOLON", + SyntaxHighlighterColors.JAVA_SEMICOLON.getDefaultAttributes() + ); + + public static final TextAttributesKey DOT = TextAttributesKey.createTextAttributesKey( + "KOTLIN_DOT", + SyntaxHighlighterColors.DOT.getDefaultAttributes() + ); + + public static final TextAttributesKey SAFE_ACCESS = TextAttributesKey.createTextAttributesKey( + "KOTLIN_SAFE_ACCESS", + SyntaxHighlighterColors.DOT.getDefaultAttributes() + ); + + public static final TextAttributesKey ARROW = TextAttributesKey.createTextAttributesKey( + "KOTLIN_ARROW", + SyntaxHighlighterColors.PARENTHS.getDefaultAttributes() + ); + + public static final TextAttributesKey LINE_COMMENT = TextAttributesKey.createTextAttributesKey( + "KOTLIN_LINE_COMMENT", + SyntaxHighlighterColors.LINE_COMMENT.getDefaultAttributes() + ); + + public static final TextAttributesKey BLOCK_COMMENT = TextAttributesKey.createTextAttributesKey( + "KOTLIN_BLOCK_COMMENT", + SyntaxHighlighterColors.JAVA_BLOCK_COMMENT.getDefaultAttributes() + ); + + public static final TextAttributesKey DOC_COMMENT = TextAttributesKey.createTextAttributesKey( + "KOTLIN_DOC_COMMENT", + SyntaxHighlighterColors.DOC_COMMENT.getDefaultAttributes() + ); + + public static final TextAttributesKey DOC_COMMENT_TAG = TextAttributesKey.createTextAttributesKey( + "KOTLIN_DOC_COMMENT_TAG", + SyntaxHighlighterColors.DOC_COMMENT_TAG.getDefaultAttributes() + ); + + public static final TextAttributesKey DOC_COMMENT_TAG_VALUE = TextAttributesKey.createTextAttributesKey( + "KOTLIN_DOC_COMMENT_TAG_VALUE", + CodeInsightColors.DOC_COMMENT_TAG_VALUE.getDefaultAttributes() + ); + + public static final TextAttributesKey DOC_COMMENT_MARKUP = TextAttributesKey.createTextAttributesKey( + "KOTLIN_DOC_COMMENT_MARKUP", + SyntaxHighlighterColors.DOC_COMMENT_MARKUP.getDefaultAttributes() + ); + + public static final TextAttributesKey CLASS = TextAttributesKey.createTextAttributesKey( + "KOTLIN_CLASS", + CodeInsightColors.CLASS_NAME_ATTRIBUTES.getDefaultAttributes() + ); + + public static final TextAttributesKey TYPE_PARAMETER = TextAttributesKey.createTextAttributesKey( + "KOTLIN_TYPE_PARAMETER", + CodeInsightColors.TYPE_PARAMETER_NAME_ATTRIBUTES.getDefaultAttributes() + ); + + public static final TextAttributesKey ABSTRACT_CLASS = TextAttributesKey.createTextAttributesKey( + "KOTLIN_ABSTRACT_CLASS", + CodeInsightColors.ABSTRACT_CLASS_NAME_ATTRIBUTES.getDefaultAttributes() + ); + + public static final TextAttributesKey TRAIT = TextAttributesKey.createTextAttributesKey( + "KOTLIN_TRAIT", + CodeInsightColors.INTERFACE_NAME_ATTRIBUTES.getDefaultAttributes() + ); + + public static final TextAttributesKey ANNOTATION = TextAttributesKey.createTextAttributesKey( + "KOTLIN_ANNOTATION", + CodeInsightColors.ANNOTATION_NAME_ATTRIBUTES.getDefaultAttributes() + ); + + public static final TextAttributesKey MUTABLE_VARIABLE = TextAttributesKey.createTextAttributesKey( + "KOTLIN_MUTABLE_VARIABLE", + new TextAttributes(null, null, Color.BLACK, EffectType.LINE_UNDERSCORE, 0) + ); + + public static final TextAttributesKey LOCAL_VARIABLE = TextAttributesKey.createTextAttributesKey( + "KOTLIN_LOCAL_VARIABLE", + CodeInsightColors.LOCAL_VARIABLE_ATTRIBUTES.getDefaultAttributes() + ); + + public static final TextAttributesKey PARAMETER = TextAttributesKey.createTextAttributesKey( + "KOTLIN_PARAMETER", + CodeInsightColors.PARAMETER_ATTRIBUTES.getDefaultAttributes() + ); + + public static final TextAttributesKey WRAPPED_INTO_REF = TextAttributesKey.createTextAttributesKey( + "KOTLIN_WRAPPED_INTO_REF", + 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 NAMESPACE_PROPERTY = TextAttributesKey.createTextAttributesKey( + "KOTLIN_NAMESPACE_PROPERTY", + CodeInsightColors.STATIC_FIELD_ATTRIBUTES.getDefaultAttributes() + ); + + public static final TextAttributesKey PROPERTY_WITH_BACKING_FIELD = TextAttributesKey.createTextAttributesKey( + "KOTLIN_PROPERTY_WITH_BACKING_FIELD", + new TextAttributes(null, new Color(0xf5d7ef), null, null, 0) +); + + public static final TextAttributesKey BACKING_FIELD_ACCESS = TextAttributesKey.createTextAttributesKey( + "KOTLIN_BACKING_FIELD_ACCESS", + new TextAttributes() + ); + + public static final TextAttributesKey EXTENSION_PROPERTY = TextAttributesKey.createTextAttributesKey( + "KOTLIN_EXTENSION_PROPERTY", + CodeInsightColors.STATIC_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) + ); + + public static final TextAttributesKey FUNCTION_DECLARATION = TextAttributesKey.createTextAttributesKey( + "KOTLIN_FUNCTION_DECLARATION", + CodeInsightColors.METHOD_DECLARATION_ATTRIBUTES.getDefaultAttributes() + ); + + public static final TextAttributesKey FUNCTION_CALL = TextAttributesKey.createTextAttributesKey( + "KOTLIN_FUNCTION_CALL", + CodeInsightColors.METHOD_CALL_ATTRIBUTES.getDefaultAttributes() + ); + + public static final TextAttributesKey NAMESPACE_FUNCTION_CALL = TextAttributesKey.createTextAttributesKey( + "KOTLIN_NAMESPACE_FUNCTION_CALL", + CodeInsightColors.STATIC_METHOD_ATTRIBUTES.getDefaultAttributes() + ); + + public static final TextAttributesKey EXTENSION_FUNCTION_CALL = TextAttributesKey.createTextAttributesKey( + "KOTLIN_EXTENSION_FUNCTION_CALL", + CodeInsightColors.STATIC_METHOD_ATTRIBUTES.getDefaultAttributes() + ); + + public static final TextAttributesKey CONSTRUCTOR_CALL = TextAttributesKey.createTextAttributesKey( + "KOTLIN_CONSTRUCTOR", + CodeInsightColors.CONSTRUCTOR_CALL_ATTRIBUTES.getDefaultAttributes() + ); + + public static final TextAttributesKey BAD_CHARACTER = TextAttributesKey.createTextAttributesKey( + "KOTLIN_BAD_CHARACTER", + HighlighterColors.BAD_CHARACTER.getDefaultAttributes() + ); + + public static final TextAttributesKey AUTO_CASTED_VALUE = TextAttributesKey.createTextAttributesKey( + "KOTLIN_AUTO_CASTED_VALUE", + new TextAttributes(null, new Color(0xdbffdb), null, null, Font.PLAIN) + ); + + public static final TextAttributesKey LABEL = TextAttributesKey.createTextAttributesKey( + "KOTLIN_LABEL", + new TextAttributes(new Color(0x4a86e8), null, null, null, Font.PLAIN) + ); + + public static final TextAttributesKey DEBUG_INFO = TextAttributesKey.createTextAttributesKey( + "KOTLIN_DEBUG_INFO", + new TextAttributes(null, null, Color.BLACK, EffectType.ROUNDED_BOX, Font.PLAIN) + ); + + public static final TextAttributesKey RESOLVED_TO_ERROR = TextAttributesKey.createTextAttributesKey( + "KOTLIN_RESOLVED_TO_ERROR", + new TextAttributes(null, null, Color.RED, EffectType.ROUNDED_BOX, Font.PLAIN) + ); + + private JetHighlightingColors() { + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/JetLineMarkerProvider.java b/idea/src/org/jetbrains/jet/plugin/highlighter/JetLineMarkerProvider.java new file mode 100644 index 00000000000..09713edb502 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/JetLineMarkerProvider.java @@ -0,0 +1,151 @@ +/* + * 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.google.common.collect.Lists; +import com.intellij.codeHighlighting.Pass; +import com.intellij.codeInsight.daemon.GutterIconNavigationHandler; +import com.intellij.codeInsight.daemon.LineMarkerInfo; +import com.intellij.codeInsight.daemon.LineMarkerProvider; +import com.intellij.codeInsight.hint.HintUtil; +import com.intellij.codeInsight.navigation.NavigationUtil; +import com.intellij.ide.util.DefaultPsiElementCellRenderer; +import com.intellij.openapi.ui.popup.JBPopup; +import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.util.IconLoader; +import com.intellij.psi.PsiElement; +import com.intellij.psi.util.PsiUtilCore; +import com.intellij.ui.awt.RelativePoint; +import com.intellij.util.Function; +import com.intellij.util.PsiNavigateUtil; +import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.Modality; +import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.lang.psi.JetNamedFunction; +import org.jetbrains.jet.lang.psi.JetProperty; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; +import org.jetbrains.jet.resolve.DescriptorRenderer; + +import javax.swing.*; +import java.awt.event.MouseEvent; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +/** + * @author abreslav + */ +public class JetLineMarkerProvider implements LineMarkerProvider { + public static final Icon OVERRIDING_MARK = IconLoader.getIcon("/gutter/overridingMethod.png"); + public static final Icon IMPLEMENTING_MARK = IconLoader.getIcon("/gutter/implementingMethod.png"); + + @Override + public LineMarkerInfo getLineMarkerInfo(final PsiElement element) { + JetFile file = (JetFile)element.getContainingFile(); + if (file == null) return null; + + if (!(element instanceof JetNamedFunction || element instanceof JetProperty)) return null; + + final BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file).getBindingContext(); + + final DeclarationDescriptor descriptor = + bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element); + if (!(descriptor instanceof CallableMemberDescriptor)) return null; + final Set overriddenMembers = ((CallableMemberDescriptor)descriptor).getOverriddenDescriptors(); + if (overriddenMembers.size() == 0) return null; + + boolean allOverriddenAbstract = true; + for (CallableMemberDescriptor function : overriddenMembers) { + allOverriddenAbstract &= function.getModality() == Modality.ABSTRACT; + } + + final String implementsOrOverrides = allOverriddenAbstract ? "implements" : "overrides"; + final String memberKind = element instanceof JetNamedFunction ? "function" : "property"; + + return new LineMarkerInfo( + element, + element.getTextOffset(), + allOverriddenAbstract ? IMPLEMENTING_MARK : OVERRIDING_MARK, + Pass.UPDATE_ALL, + new Function() { + @Override + public String fun(PsiElement element) { + StringBuilder builder = new StringBuilder(); + builder.append(DescriptorRenderer.HTML.render(descriptor)); + int overrideCount = overriddenMembers.size(); + if (overrideCount >= 1) { + builder.append(" ").append(implementsOrOverrides).append(" "); + builder.append(DescriptorRenderer.HTML.render(overriddenMembers.iterator().next())); + } + if (overrideCount > 1) { + int count = overrideCount - 1; + builder.append(" and ").append(count).append(" other ").append(memberKind); + if (count > 1) { + builder.append("s"); + } + } + + return builder.toString(); + } + }, + new GutterIconNavigationHandler() { + @Override + public void navigate(MouseEvent event, PsiElement elt) { + if (overriddenMembers.isEmpty()) return; + final List list = Lists.newArrayList(); + for (CallableMemberDescriptor overriddenMember : overriddenMembers) { + PsiElement declarationPsiElement = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, overriddenMember); + list.add(declarationPsiElement); + } + if (list.isEmpty()) { + String myEmptyText = "empty text"; + final JComponent renderer = HintUtil.createErrorLabel(myEmptyText); + final JBPopup popup = JBPopupFactory.getInstance().createComponentPopupBuilder(renderer, renderer).createPopup(); + if (event != null) { + popup.show(new RelativePoint(event)); + } + return; + } + if (list.size() == 1) { + PsiNavigateUtil.navigate(list.iterator().next()); + } + else { + final JBPopup popup = NavigationUtil.getPsiElementPopup(PsiUtilCore.toPsiElementArray(list), new DefaultPsiElementCellRenderer() { + @Override + public String getElementText(PsiElement element) { + if (element instanceof JetNamedFunction) { + JetNamedFunction function = (JetNamedFunction) element; + return DescriptorRenderer.HTML.render(bindingContext.get(BindingContext.FUNCTION, function)); + } + return super.getElementText(element); + } + }, DescriptorRenderer.HTML.render(descriptor)); + if (event != null) { + popup.show(new RelativePoint(event)); + } + } + } + } + ); + } + + @Override + public void collectSlowLineMarkers(List elements, Collection result) { + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/annotations/JetPsiChecker.java b/idea/src/org/jetbrains/jet/plugin/highlighter/JetPsiChecker.java similarity index 53% rename from idea/src/org/jetbrains/jet/plugin/annotations/JetPsiChecker.java rename to idea/src/org/jetbrains/jet/plugin/highlighter/JetPsiChecker.java index da008e95e08..937b121a7ef 100644 --- a/idea/src/org/jetbrains/jet/plugin/annotations/JetPsiChecker.java +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/JetPsiChecker.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.annotations; +package org.jetbrains.jet.plugin.highlighter; import com.google.common.collect.Sets; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInspection.ProblemHighlightType; -import com.intellij.lang.ASTNode; import com.intellij.lang.annotation.Annotation; import com.intellij.lang.annotation.AnnotationHolder; import com.intellij.lang.annotation.Annotator; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.colors.TextAttributesKey; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.util.TextRange; import com.intellij.psi.MultiRangeReference; @@ -31,15 +31,10 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiReference; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; -import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; -import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; -import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.diagnostics.*; -import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.lang.psi.JetReferenceExpression; import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.types.JetType; -import org.jetbrains.jet.plugin.JetHighlighter; import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; import org.jetbrains.jet.plugin.quickfix.JetIntentionActionFactory; import org.jetbrains.jet.plugin.quickfix.QuickFixes; @@ -48,13 +43,10 @@ import java.util.Collection; import java.util.List; import java.util.Set; -import static org.jetbrains.jet.lang.resolve.BindingContext.*; - /** * @author abreslav */ public class JetPsiChecker implements Annotator { - private static volatile boolean errorReportingEnabled = true; public static void setErrorReportingEnabled(boolean value) { @@ -65,20 +57,50 @@ public class JetPsiChecker implements Annotator { return errorReportingEnabled; } + static boolean isNamesHighlightingEnabled() { + return !ApplicationManager.getApplication().isUnitTestMode(); + } + + static void highlightName(@NotNull AnnotationHolder holder, + @NotNull PsiElement psiElement, + @NotNull TextAttributesKey attributesKey) { + if (isNamesHighlightingEnabled()) { + holder.createInfoAnnotation(psiElement, null).setTextAttributes(attributesKey); + } + } + + private static HighlightingVisitor[] getBeforeAnalysisVisitors(AnnotationHolder holder) { + return new HighlightingVisitor[]{ + new SoftKeywordsHighlightingVisitor(holder), + new LabelsHighlightingVisitor(holder), + new TypeKindHighlightingVisitor(holder), + }; + } + + private static HighlightingVisitor[] getAfterAnalysisVisitor(AnnotationHolder holder, BindingContext bindingContext) { + return new AfterAnalysisHighlightingVisitor[]{ + new PropertiesHighlightingVisitor(holder, bindingContext), + new FunctionsHighlightingVisitor(holder, bindingContext), + new VariablesHighlightingVisitor(holder, bindingContext), + }; + } + @Override public void annotate(@NotNull PsiElement element, @NotNull final AnnotationHolder holder) { + for (HighlightingVisitor visitor : getBeforeAnalysisVisitors(holder)) { + element.accept(visitor); + } + if (element instanceof JetFile) { - JetFile file = (JetFile) element; + JetFile file = (JetFile)element; try { - final BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file) - .getBindingContext(); + BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file).getBindingContext(); if (errorReportingEnabled) { Collection diagnostics = Sets.newLinkedHashSet(bindingContext.getDiagnostics()); Set redeclarations = Sets.newHashSet(); for (Diagnostic diagnostic : diagnostics) { - // This is needed because we have the same context for all files if (diagnostic.getPsiFile() != file) continue; @@ -86,57 +108,9 @@ public class JetPsiChecker implements Annotator { } } - highlightBackingFields(holder, file, bindingContext); - - file.acceptChildren(new JetVisitorVoid() { - @Override - public void visitSimpleNameExpression(@NotNull JetSimpleNameExpression expression) { - DeclarationDescriptor target = bindingContext.get(REFERENCE_TARGET, expression); - if (target instanceof ValueParameterDescriptor) { - ValueParameterDescriptor parameterDescriptor = (ValueParameterDescriptor) target; - if (bindingContext.get(AUTO_CREATED_IT, parameterDescriptor)) { - holder.createInfoAnnotation(expression, "Automatically declared based on the expected type").setTextAttributes(JetHighlighter.JET_AUTOCREATED_IT); - } - } - - markVariableAsWrappedIfNeeded(expression.getNode(), target); - super.visitSimpleNameExpression(expression); - } - - private void markVariableAsWrappedIfNeeded(@NotNull ASTNode node, DeclarationDescriptor target) { - if (target instanceof VariableDescriptor) { - VariableDescriptor variableDescriptor = (VariableDescriptor) target; - if (bindingContext.get(MUST_BE_WRAPPED_IN_A_REF, variableDescriptor)) { - holder.createInfoAnnotation(node, "Wrapped into a ref-object to be modifier when captured in a closure").setTextAttributes(JetHighlighter.JET_WRAPPED_INTO_REF); - } - - } - } - - @Override - public void visitProperty(@NotNull JetProperty property) { - DeclarationDescriptor declarationDescriptor = bindingContext.get(DECLARATION_TO_DESCRIPTOR, property); - PsiElement nameIdentifier = property.getNameIdentifier(); - if (nameIdentifier != null) { - markVariableAsWrappedIfNeeded(nameIdentifier.getNode(), declarationDescriptor); - } - super.visitProperty(property); - } - - @Override - public void visitExpression(@NotNull JetExpression expression) { - JetType autoCast = bindingContext.get(AUTOCAST, expression); - if (autoCast != null) { - holder.createInfoAnnotation(expression, "Automatically cast to " + autoCast).setTextAttributes(JetHighlighter.JET_AUTO_CAST_EXPRESSION); - } - expression.acceptChildren(this); - } - - @Override - public void visitJetElement(@NotNull JetElement element) { - element.acceptChildren(this); - } - }); + for (HighlightingVisitor visitor : getAfterAnalysisVisitor(holder, bindingContext)) { + file.acceptChildren(visitor); + } } catch (ProcessCanceledException e) { throw e; @@ -154,26 +128,24 @@ public class JetPsiChecker implements Annotator { } } - private void registerDiagnosticAnnotations( - @NotNull Diagnostic diagnostic, - @NotNull Set redeclarations, - @NotNull final AnnotationHolder holder - ) { + private static void registerDiagnosticAnnotations(@NotNull Diagnostic diagnostic, + @NotNull Set redeclarations, + @NotNull final AnnotationHolder holder) { List textRanges = diagnostic.getTextRanges(); if (diagnostic.getSeverity() == Severity.ERROR) { if (diagnostic.getFactory() == Errors.UNRESOLVED_IDE_TEMPLATE) { return; } if (diagnostic instanceof UnresolvedReferenceDiagnostic) { - UnresolvedReferenceDiagnostic unresolvedReferenceDiagnostic = (UnresolvedReferenceDiagnostic) diagnostic; + UnresolvedReferenceDiagnostic unresolvedReferenceDiagnostic = (UnresolvedReferenceDiagnostic)diagnostic; JetReferenceExpression referenceExpression = unresolvedReferenceDiagnostic.getPsiElement(); PsiReference reference = referenceExpression.getReference(); if (reference instanceof MultiRangeReference) { - MultiRangeReference mrr = (MultiRangeReference) reference; + MultiRangeReference mrr = (MultiRangeReference)reference; for (TextRange range : mrr.getRanges()) { Annotation annotation = holder.createErrorAnnotation( - range.shiftRight(referenceExpression.getTextOffset()), - diagnostic.getMessage()); + range.shiftRight(referenceExpression.getTextOffset()), + diagnostic.getMessage()); registerQuickFix(annotation, diagnostic); @@ -191,8 +163,15 @@ public class JetPsiChecker implements Annotator { return; } + if (diagnostic.getFactory() == Errors.ILLEGAL_ESCAPE_SEQUENCE) { + for (TextRange textRange : diagnostic.getTextRanges()) { + Annotation annotation = holder.createErrorAnnotation(textRange, diagnostic.getMessage()); + annotation.setTextAttributes(JetHighlightingColors.INVALID_STRING_ESCAPE); + } + } + if (diagnostic instanceof RedeclarationDiagnostic) { - RedeclarationDiagnostic redeclarationDiagnostic = (RedeclarationDiagnostic) diagnostic; + RedeclarationDiagnostic redeclarationDiagnostic = (RedeclarationDiagnostic)diagnostic; registerQuickFix(markRedeclaration(redeclarations, redeclarationDiagnostic, holder), diagnostic); return; } @@ -201,9 +180,6 @@ public class JetPsiChecker implements Annotator { for (TextRange textRange : textRanges) { Annotation errorAnnotation = holder.createErrorAnnotation(textRange, getMessage(diagnostic)); registerQuickFix(errorAnnotation, diagnostic); - if (diagnostic.getFactory() == Errors.INVISIBLE_MEMBER) { - errorAnnotation.setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL); - } } } else if (diagnostic.getSeverity() == Severity.WARNING) { @@ -222,10 +198,7 @@ public class JetPsiChecker implements Annotator { * Add a quick fix if and return modified annotation. */ @Nullable - private Annotation registerQuickFix( - @Nullable Annotation annotation, - @NotNull Diagnostic diagnostic) { - + private static Annotation registerQuickFix(@Nullable Annotation annotation, @NotNull Diagnostic diagnostic) { if (annotation == null) { return null; } @@ -250,7 +223,7 @@ public class JetPsiChecker implements Annotator { } @NotNull - private String getMessage(@NotNull Diagnostic diagnostic) { + private static String getMessage(@NotNull Diagnostic diagnostic) { if (ApplicationManager.getApplication().isInternal() || ApplicationManager.getApplication().isUnitTestMode()) { return "[" + diagnostic.getFactory().getName() + "] " + diagnostic.getMessage(); } @@ -258,48 +231,12 @@ public class JetPsiChecker implements Annotator { } @Nullable - private Annotation markRedeclaration(@NotNull Set redeclarations, @NotNull RedeclarationDiagnostic diagnostic, @NotNull AnnotationHolder holder) { + private static Annotation markRedeclaration(@NotNull Set redeclarations, + @NotNull RedeclarationDiagnostic diagnostic, + @NotNull AnnotationHolder holder) { if (!redeclarations.add(diagnostic.getPsiElement())) return null; List textRanges = diagnostic.getTextRanges(); if (textRanges.isEmpty()) return null; return holder.createErrorAnnotation(textRanges.get(0), getMessage(diagnostic)); } - - - private void highlightBackingFields(@NotNull final AnnotationHolder holder, @NotNull JetFile file, @NotNull final BindingContext bindingContext) { - file.acceptChildren(new JetVisitorVoid() { - @Override - public void visitProperty(@NotNull JetProperty property) { - VariableDescriptor propertyDescriptor = bindingContext.get(BindingContext.VARIABLE, property); - if (propertyDescriptor instanceof PropertyDescriptor) { - if (bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, (PropertyDescriptor) propertyDescriptor)) { - putBackingfieldAnnotation(holder, property); - } - } - } - - @Override - public void visitParameter(@NotNull JetParameter parameter) { - PropertyDescriptor propertyDescriptor = bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter); - if (propertyDescriptor != null && bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) { - putBackingfieldAnnotation(holder, parameter); - } - } - - @Override - public void visitJetElement(@NotNull JetElement element) { - element.acceptChildren(this); - } - }); - } - - private 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(JetHighlighter.JET_PROPERTY_WITH_BACKING_FIELD_IDENTIFIER); - } - } } diff --git a/idea/src/org/jetbrains/jet/plugin/JetSyntaxHighlighterFactory.java b/idea/src/org/jetbrains/jet/plugin/highlighter/JetSyntaxHighlighterFactory.java similarity index 95% rename from idea/src/org/jetbrains/jet/plugin/JetSyntaxHighlighterFactory.java rename to idea/src/org/jetbrains/jet/plugin/highlighter/JetSyntaxHighlighterFactory.java index f09da3ffceb..39fce092f05 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetSyntaxHighlighterFactory.java +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/JetSyntaxHighlighterFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin; +package org.jetbrains.jet.plugin.highlighter; import com.intellij.openapi.fileTypes.SingleLazyInstanceSyntaxHighlighterFactory; import com.intellij.openapi.fileTypes.SyntaxHighlighter; diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/LabelsHighlightingVisitor.java b/idea/src/org/jetbrains/jet/plugin/highlighter/LabelsHighlightingVisitor.java new file mode 100644 index 00000000000..a97798f6dcc --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/LabelsHighlightingVisitor.java @@ -0,0 +1,48 @@ +/* + * 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. + */ + +/* + * @author max + */ +package org.jetbrains.jet.plugin.highlighter; + +import com.intellij.lang.annotation.AnnotationHolder; +import org.jetbrains.jet.lang.psi.JetLabelQualifiedExpression; +import org.jetbrains.jet.lang.psi.JetPrefixExpression; +import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; +import org.jetbrains.jet.lexer.JetTokens; + +class LabelsHighlightingVisitor extends HighlightingVisitor { + LabelsHighlightingVisitor(AnnotationHolder holder) { + super(holder); + } + + @Override + public void visitPrefixExpression(JetPrefixExpression expression) { + JetSimpleNameExpression operationSign = expression.getOperationReference(); + if (JetTokens.LABELS.contains(operationSign.getReferencedNameElementType())) { + JetPsiChecker.highlightName(holder, operationSign, JetHighlightingColors.LABEL); + } + } + + @Override + public void visitLabelQualifiedExpression(JetLabelQualifiedExpression expression) { + JetSimpleNameExpression targetLabel = expression.getTargetLabel(); + if (targetLabel != null) { + JetPsiChecker.highlightName(holder, targetLabel, JetHighlightingColors.LABEL); + } + } +} 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..47e24abdbbb --- /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.*; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; +import org.jetbrains.jet.lexer.JetTokens; + +class PropertiesHighlightingVisitor extends AfterAnalysisHighlightingVisitor { + PropertiesHighlightingVisitor(AnnotationHolder holder, BindingContext bindingContext) { + super(holder, bindingContext); + } + + @Override + public void visitSimpleNameExpression(JetSimpleNameExpression expression) { + DeclarationDescriptor target = bindingContext.get(BindingContext.REFERENCE_TARGET, expression); + if (target instanceof VariableAsFunctionDescriptor) { + target = ((VariableAsFunctionDescriptor)target).getVariableDescriptor(); + } + if (!(target instanceof PropertyDescriptor)) { + return; + } + + if (((PropertyDescriptor)target).getReceiverParameter() != ReceiverDescriptor.NO_RECEIVER) { + JetPsiChecker.highlightName(holder, expression, JetHighlightingColors.EXTENSION_PROPERTY); + } + + boolean namespace = target.getContainingDeclaration() instanceof NamespaceDescriptor; + putPropertyAnnotation(expression, namespace, false); + if (expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER) { + JetPsiChecker.highlightName(holder, expression, JetHighlightingColors.BACKING_FIELD_ACCESS); + } + } + + @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)); + } + + super.visitProperty(property); + } + + @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) { + JetPsiChecker.highlightName(holder, elementToHighlight, + namespace ? JetHighlightingColors.NAMESPACE_PROPERTY : JetHighlightingColors.INSTANCE_PROPERTY + ); + if (withBackingField) { + holder.createInfoAnnotation( + elementToHighlight, + "This property has a backing field") + .setTextAttributes(JetHighlightingColors.PROPERTY_WITH_BACKING_FIELD); + } + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/SoftKeywordsHighlightingVisitor.java b/idea/src/org/jetbrains/jet/plugin/highlighter/SoftKeywordsHighlightingVisitor.java new file mode 100644 index 00000000000..4dacbfc30cf --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/SoftKeywordsHighlightingVisitor.java @@ -0,0 +1,58 @@ +/* + * 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. + */ + +/* + * @author max + */ +package org.jetbrains.jet.plugin.highlighter; + +import com.intellij.lang.ASTNode; +import com.intellij.lang.annotation.AnnotationHolder; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.impl.source.tree.LeafPsiElement; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lexer.JetTokens; + +class SoftKeywordsHighlightingVisitor extends HighlightingVisitor { + SoftKeywordsHighlightingVisitor(AnnotationHolder holder) { + super(holder); + } + + @Override + public void visitElement(PsiElement element) { + if (element instanceof LeafPsiElement) { + if (JetTokens.SOFT_KEYWORDS.contains(((LeafPsiElement) element).getElementType())) { + holder.createInfoAnnotation(element, null).setTextAttributes(JetHighlightingColors.KEYWORD); + } + } + } + + @Override + public void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression) { + if (ApplicationManager.getApplication().isUnitTestMode()) return; + JetFunctionLiteral functionLiteral = expression.getFunctionLiteral(); + holder.createInfoAnnotation(functionLiteral.getOpenBraceNode(), null).setTextAttributes(JetHighlightingColors.FUNCTION_LITERAL_BRACES); + ASTNode closingBraceNode = functionLiteral.getClosingBraceNode(); + if (closingBraceNode != null) { + holder.createInfoAnnotation(closingBraceNode, null).setTextAttributes(JetHighlightingColors.FUNCTION_LITERAL_BRACES); + } + ASTNode arrowNode = functionLiteral.getArrowNode(); + if (arrowNode != null) { + holder.createInfoAnnotation(arrowNode, null).setTextAttributes(JetHighlightingColors.FUNCTION_LITERAL_BRACES); + } + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/TypeKindHighlightingVisitor.java b/idea/src/org/jetbrains/jet/plugin/highlighter/TypeKindHighlightingVisitor.java new file mode 100644 index 00000000000..650e9f6b35a --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/TypeKindHighlightingVisitor.java @@ -0,0 +1,105 @@ +/* + * 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.openapi.editor.colors.TextAttributesKey; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lexer.JetTokens; + +/** + * @author Evgeny Gerashchenko + * @since 3/29/12 + */ +class TypeKindHighlightingVisitor extends HighlightingVisitor { + protected TypeKindHighlightingVisitor(AnnotationHolder holder) { + super(holder); + } + + @Override + public void visitAnnotationEntry(JetAnnotationEntry annotationEntry) { + JetTypeReference typeReference = annotationEntry.getTypeReference(); + if (typeReference == null) return; + JetTypeElement typeElement = typeReference.getTypeElement(); + if (!(typeElement instanceof JetUserType)) return; + JetUserType userType = (JetUserType)typeElement; + if (userType.getQualifier() != null) return; + JetSimpleNameExpression referenceExpression = userType.getReferenceExpression(); + if (referenceExpression != null) { + holder.createInfoAnnotation(referenceExpression.getNode(), null).setTextAttributes(JetHighlightingColors.ANNOTATION); + } + } + + private void visitNameExpression(JetExpression expression) { + PsiReference ref = expression.getReference(); + if (ref == null) return; + if (JetPsiChecker.isNamesHighlightingEnabled()) { + PsiElement target = ref.resolve(); + if (target instanceof JetClass) { + highlightClassByKind((JetClass)target, expression); + } else if (target instanceof JetTypeParameter) { + JetPsiChecker.highlightName(holder, expression, JetHighlightingColors.TYPE_PARAMETER); + } + } + } + + @Override + public void visitSimpleNameExpression(JetSimpleNameExpression expression) { + visitNameExpression(expression); + } + + @Override + public void visitQualifiedExpression(JetQualifiedExpression expression) { + visitNameExpression(expression); + } + + @Override + public void visitTypeParameter(JetTypeParameter parameter) { + PsiElement identifier = parameter.getNameIdentifier(); + if (identifier != null) { + JetPsiChecker.highlightName(holder, identifier, JetHighlightingColors.TYPE_PARAMETER); + } + } + + @Override + public void visitClass(JetClass klass) { + PsiElement identifier = klass.getNameIdentifier(); + if (identifier != null) { + highlightClassByKind(klass, identifier); + } + } + + private void highlightClassByKind(@NotNull JetClass klass, @NotNull PsiElement whatToHighlight) { + TextAttributesKey textAttributes = JetHighlightingColors.CLASS; + if (klass.isTrait()) { + textAttributes = JetHighlightingColors.TRAIT; + } else { + JetModifierList modifierList = klass.getModifierList(); + if (modifierList != null) { + if (modifierList.hasModifier(JetTokens.ANNOTATION_KEYWORD)) { + textAttributes = JetHighlightingColors.ANNOTATION; + } else if (modifierList.hasModifier(JetTokens.ABSTRACT_KEYWORD)) { + textAttributes = JetHighlightingColors.ABSTRACT_CLASS; + } + } + } + JetPsiChecker.highlightName(holder, whatToHighlight, textAttributes); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/VariablesHighlightingVisitor.java b/idea/src/org/jetbrains/jet/plugin/highlighter/VariablesHighlightingVisitor.java new file mode 100644 index 00000000000..148ee928e5a --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/VariablesHighlightingVisitor.java @@ -0,0 +1,114 @@ +/* + * 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.*; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.resolve.DescriptorRenderer; + +import static org.jetbrains.jet.lang.resolve.BindingContext.*; + +class VariablesHighlightingVisitor extends AfterAnalysisHighlightingVisitor { + VariablesHighlightingVisitor(AnnotationHolder holder, BindingContext bindingContext) { + super(holder, bindingContext); + } + + @Override + public void visitJetElement(@NotNull JetElement element) { + element.acceptChildren(this); + } + + @Override + public void visitSimpleNameExpression(@NotNull JetSimpleNameExpression 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( + JetHighlightingColors.FUNCTION_LITERAL_DEFAULT_PARAMETER); + } + } + + highlightVariable(expression, target); + super.visitSimpleNameExpression(expression); + } + + @Override + public void visitProperty(@NotNull JetProperty property) { + visitVariableDeclaration(property); + super.visitProperty(property); + } + + @Override + public void visitParameter(JetParameter parameter) { + visitVariableDeclaration(parameter); + super.visitParameter(parameter); + } + + @Override + public void visitExpression(@NotNull JetExpression expression) { + JetType autoCast = bindingContext.get(AUTOCAST, expression); + if (autoCast != null) { + holder.createInfoAnnotation(expression, "Automatically cast to " + DescriptorRenderer.TEXT.renderType(autoCast)).setTextAttributes( + JetHighlightingColors.AUTO_CASTED_VALUE); + } + super.visitExpression(expression); + } + + private void visitVariableDeclaration(JetNamedDeclaration declaration) { + DeclarationDescriptor declarationDescriptor = bindingContext.get(DECLARATION_TO_DESCRIPTOR, declaration); + PsiElement nameIdentifier = declaration.getNameIdentifier(); + if (nameIdentifier != null && declarationDescriptor != null) { + highlightVariable(nameIdentifier, declarationDescriptor); + } + } + + private void highlightVariable(@NotNull PsiElement elementToHighlight, @NotNull DeclarationDescriptor descriptor) { + if (descriptor instanceof VariableAsFunctionDescriptor) { + descriptor = ((VariableAsFunctionDescriptor)descriptor).getVariableDescriptor(); + //noinspection ConstantConditions + if (descriptor == null) return; + } + if (descriptor instanceof VariableDescriptor) { + VariableDescriptor variableDescriptor = (VariableDescriptor) descriptor; + if (variableDescriptor.isVar()) { + JetPsiChecker.highlightName(holder, elementToHighlight, JetHighlightingColors.MUTABLE_VARIABLE); + } + + if (Boolean.TRUE.equals(bindingContext.get(MUST_BE_WRAPPED_IN_A_REF, variableDescriptor))) { + holder.createInfoAnnotation(elementToHighlight, "Wrapped into a reference object to be modified when captured in a closure").setTextAttributes( + JetHighlightingColors.WRAPPED_INTO_REF); + } + + if (descriptor instanceof LocalVariableDescriptor) { + JetPsiChecker.highlightName(holder, elementToHighlight, JetHighlightingColors.LOCAL_VARIABLE); + } + + if (descriptor instanceof ValueParameterDescriptor) { + JetPsiChecker.highlightName(holder, elementToHighlight, JetHighlightingColors.PARAMETER); + } + } + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/libraries/JetContentBasedFileSubstitutor.java b/idea/src/org/jetbrains/jet/plugin/libraries/JetContentBasedFileSubstitutor.java index dd6224fea61..78666ae3631 100644 --- a/idea/src/org/jetbrains/jet/plugin/libraries/JetContentBasedFileSubstitutor.java +++ b/idea/src/org/jetbrains/jet/plugin/libraries/JetContentBasedFileSubstitutor.java @@ -25,7 +25,7 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.impl.compiled.ClsFileImpl; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.plugin.JetHighlighter; +import org.jetbrains.jet.plugin.highlighter.JetHighlighter; /** * @author Evgeny Gerashchenko diff --git a/idea/testData/checker/infos/Autocasts.jet b/idea/testData/checker/infos/Autocasts.jet index 4197d78d269..a6ce30da598 100644 --- a/idea/testData/checker/infos/Autocasts.jet +++ b/idea/testData/checker/infos/Autocasts.jet @@ -147,78 +147,78 @@ fun f15(a : A?) { fun getStringLength(obj : Any) : Char? { if (obj !is String) return null - return obj.get(0) // no cast to String is needed + return obj.get(0) // no cast to jet.String is needed } -fun toInt(i: Int?): Int = if (i != null) i else 0 +fun toInt(i: Int?): Int = if (i != null) i else 0 fun illegalWhenBody(a: Any): Int = when(a) { - is Int -> a + is Int -> a is String -> a else -> 1 } fun illegalWhenBlock(a: Any): Int { when(a) { - is Int -> return a + is Int -> return a is String -> return a else -> return 1 } } fun declarations(a: Any?) { if (a is String) { - val p4: #(Int, String) = #(2, a) + val p4: #(Int, String) = #(2, a) } if (a is String?) { if (a != null) { - val s: String = a + val s: String = a } } if (a != null) { if (a is String?) { - val s: String = a + val s: String = a } } } fun vars(a: Any?) { var b: Int = 0 if (a is Int) { - b = a + b = a } } fun tuples(a: Any?) { if (a != null) { - val s: #(Any, String) = #(a, a) + val s: #(Any, String) = #(a, a) } if (a is String) { - val s: #(Any, String) = #(a, a) + val s: #(Any, String) = #(a, a) } fun illegalTupleReturnType(): #(Any, String) = #(a, a) if (a is String) { - fun legalTupleReturnType(): #(Any, String) = #(a, a) + fun legalTupleReturnType(): #(Any, String) = #(a, a) } val illegalFunctionLiteral: Function0 = { a } val illegalReturnValueInFunctionLiteral: Function0 = { (): Int -> a } if (a is Int) { - val legalFunctionLiteral: Function0 = { a } - val alsoLegalFunctionLiteral: Function0 = { (): Int -> a } + val legalFunctionLiteral: Function0 = { a } + val alsoLegalFunctionLiteral: Function0 = { (): Int -> a } } } fun returnFunctionLiteralBlock(a: Any?): Function0 { - if (a is Int) return { a } + if (a is Int) return { a } else return { 1 } } fun returnFunctionLiteral(a: Any?): Function0 = - if (a is Int) { (): Int -> a } + if (a is Int) { (): Int -> a } else { () -> 1 } fun illegalTupleReturnType(a: Any): #(Any, String) = #(a, a) -fun declarationInsidePattern(x: #(Any, Any)): String = when(x) { is #(val a is String, *) -> a; else -> "something" } +fun declarationInsidePattern(x: #(Any, Any)): String = when(x) { is #(val a is String, *) -> a; else -> "something" } fun mergeAutocasts(a: Any?) { if (a is String || a is Int) { a.compareTo("") - a.toString() + a.toString() } if (a is Int || a is String) { a.compareTo("") @@ -227,9 +227,9 @@ fun mergeAutocasts(a: Any?) { is String, is Any -> a.compareTo("") } if (a is String && a is Any) { - val i: Int = a.compareTo("") + val i: Int = a.compareTo("") } - if (a is String && a.compareTo("") == 0) {} + if (a is String && a.compareTo("") == 0) {} if (a is String || a.compareTo("") == 0) {} }