/*
* Copyright 2013 Guidewire Software, Inc.
*/
package gw.plugin.ij.annotator;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
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.diagnostic.Logger;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiJavaToken;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiReference;
import com.intellij.psi.StubBasedPsiElement;
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
import com.intellij.psi.impl.source.tree.LeafPsiElement;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import gw.lang.parser.IParsedElement;
import gw.lang.parser.expressions.IBlockLiteralExpression;
import gw.lang.parser.expressions.INewExpression;
import gw.lang.reflect.gs.IGosuClass;
import gw.plugin.ij.highlighter.GosuHighlighterColors;
import gw.plugin.ij.lang.GosuTokenTypes;
import gw.plugin.ij.lang.parser.GosuElementTypes;
import gw.plugin.ij.lang.psi.api.auxilary.IGosuModifierList;
import gw.plugin.ij.lang.psi.impl.GosuBaseElementImpl;
import gw.plugin.ij.lang.psi.impl.GosuFragmentFileImpl;
import gw.plugin.ij.util.ExceptionUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class GosuSemanticAnnotator implements Annotator {
private static final Logger LOG = Logger.getInstance(GosuSemanticAnnotator.class);
@Override
public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) {
if (PsiTreeUtil.getParentOfType(element, GosuFragmentFileImpl.class) != null) {
return;
}
if (element.getChildren().length != 0) {
return;
}
try {
final TextAttributesKey key = visitPsiElement(element);
if (key != null && key != GosuHighlighterColors.DEFAULT_ATTRKEY) {
final Annotation annotation = holder.createInfoAnnotation(element, null);
annotation.setTextAttributes(key);
}
} catch (ProcessCanceledException e) {
throw e;
} catch (Exception e) {
if (ExceptionUtil.isWrappedCanceled(e)) {
throw new ProcessCanceledException(e);
}
LOG.error(e);
} catch (AssertionError e) {
LOG.error(e);
}
}
@Nullable
public TextAttributesKey visitPsiElement(@NotNull PsiElement element) {
if (element instanceof PsiJavaToken) {
if (((PsiJavaToken) element).getTokenType() == GosuTokenTypes.TT_IDENTIFIER) {
if (NATIVE_TYPES.contains(element.getText())) {
return GosuHighlighterColors.KEYWORD;
}
if (element instanceof ASTNode) {
return deriveFromParent((ASTNode) element);
}
}
} else if (element instanceof LeafPsiElement) {
final IElementType type = ((LeafPsiElement) element).getElementType();
return COLOR_MAP.get(type);
}
return null;
}
@Nullable
private TextAttributesKey deriveFromParent(@NotNull ASTNode child) {
ASTNode node = child.getTreeParent();
if (node == null || node == child) {
return null;
}
IElementType type = node.getElementType();
TextAttributesKey key;
if (type == GosuElementTypes.ELEM_TYPE_IdentifierExpression ||
type == GosuElementTypes.ELEM_TYPE_BeanMethodCallExpression ||
type == GosuElementTypes.ELEM_TYPE_MemberAccess ||
type == GosuElementTypes.ELEM_TYPE_TypeLiteral) {
key = deriveFromReference(node);
} else {
key = COLOR_MAP.get(type);
if (key == null) {
ASTNode parent = node.getTreeParent();
if (parent != null) {
// todo may need to short circuit this
key = deriveFromParent(parent);
}
} else {
PsiElement psi = node.getPsi();
if (type == GosuElementTypes.CLASS_DEFINITION) {
if (isAbstractClass(psi)) {
key = GosuHighlighterColors.ABSTRACT_CLASS_NAME_ATTRKEY;
}
} else if (type == GosuElementTypes.FIELD) {
if (psi instanceof IGosuModifierList) {
if (((IGosuModifierList) psi).hasModifierProperty("static")) {
key = GosuHighlighterColors.STATIC_FIELD_ATTRKEY;
}
}
} else if (type == GosuElementTypes.METHOD_DEFINITION) {
if (psi instanceof PsiMethod && ((PsiMethod) psi).isConstructor()) {
key = GosuHighlighterColors.CONSTRUCTOR_DECLARATION_ATTRKEY;
} else if (psi instanceof IGosuModifierList) {
if (((IGosuModifierList) psi).hasModifierProperty("static")) {
key = GosuHighlighterColors.STATIC_METHOD_ATTRKEY;
}
}
}
}
}
return key;
}
@Nullable
private TextAttributesKey deriveFromReference(@NotNull ASTNode node) {
TextAttributesKey key = null;
PsiElement psi = node.getPsi();
if (psi instanceof PsiReference) {
PsiElement resolve = null;
try {
resolve = ((PsiReference) psi).resolve();
} catch (Exception ex) {
// ignore... probably a bug, but it'll be caught and logged by some other operation.
}
if (resolve instanceof PsiClass) {
// XXX better way to do this?
ASTNode parentNode = node.getTreeParent();
IElementType parentType = parentNode != null ? parentNode.getElementType() : null;
if (((PsiClass) resolve).isAnnotationType()) {
key = GosuHighlighterColors.ANNOTATION_NAME_ATTRKEY;
} else if (parentType == GosuElementTypes.ELEM_TYPE_NewExpression && !isAnonymousClassExpr(parentNode)) {
key = GosuHighlighterColors.CONSTRUCTOR_CALL_ATTRKEY;
} else if (isAbstractClass(resolve)) {
key = GosuHighlighterColors.ABSTRACT_CLASS_NAME_ATTRKEY;
} else if (((PsiClass) resolve).isInterface()) {
key = GosuHighlighterColors.INTERFACE_NAME_ATTRKEY;
}
} else if (resolve == null && psi instanceof GosuBaseElementImpl) {
// block literals show up as psi class refs in the tree, but can't be resolved so handle them here
IParsedElement pe = ((GosuBaseElementImpl) psi).getParsedElement();
if (pe instanceof IBlockLiteralExpression) {
key = GosuHighlighterColors.PARAMETER_ATTRKEY;
}
}
if (key == null) {
if (resolve != null) {
final ASTNode resolvedNode = resolve.getNode();
if (resolvedNode != null) {
// IntelliJ doesn't differentiate variable references from declarations
// If we want to, use _colorRef map here to enable reference distinction for Gosu
key = COLOR_FROM_REF_MAP.get(resolvedNode.getElementType());
} else if (resolve instanceof StubBasedPsiElement) {
key = COLOR_FROM_REF_MAP.get(((StubBasedPsiElement) resolve).getElementType());
}
} else {
key = deriveFromParent(node);
}
}
}
return key;
}
private boolean isAnonymousClassExpr(@NotNull ASTNode node) {
final PsiElement psi = node.getPsi();
if (psi instanceof GosuBaseElementImpl) {
final IParsedElement pe = ((GosuBaseElementImpl) psi).getParsedElement();
if (pe instanceof INewExpression && ((INewExpression) pe).isAnonymousClass()) {
return true;
}
}
return false;
}
private boolean isAbstractClass(@NotNull PsiElement psi) {
if (psi instanceof GosuBaseElementImpl) {
final IParsedElement pe = ((GosuBaseElementImpl) psi).getParsedElement();
if (pe != null) {
final IGosuClass klass = pe.getGosuClass();
if (klass != null && klass.isAbstract()) {
return true;
}
}
}
return false;
}
private static final Map<IElementType, TextAttributesKey> COLOR_MAP = new HashMap<>();
static {
// elements that control search flow
COLOR_MAP.put(GosuElementTypes.ELEM_TYPE_StatementList, GosuHighlighterColors.DEFAULT_ATTRKEY); // short circuit
COLOR_MAP.put(GosuElementTypes.ELEM_TYPE_NamespaceStatement, GosuHighlighterColors.DEFAULT_ATTRKEY); // todo use package qualifier?
COLOR_MAP.put(GosuElementTypes.ELEM_TYPE_NewExpression, GosuHighlighterColors.DEFAULT_ATTRKEY);
// elements with real data
COLOR_MAP.put(GosuElementTypes.ELEM_TYPE_ClassDeclaration, GosuHighlighterColors.CLASS_NAME_ATTRKEY);
COLOR_MAP.put(GosuElementTypes.CLASS_DEFINITION, GosuHighlighterColors.CLASS_NAME_ATTRKEY);
COLOR_MAP.put(GosuElementTypes.INTERFACE_DEFINITION, GosuHighlighterColors.INTERFACE_NAME_ATTRKEY);
COLOR_MAP.put(GosuElementTypes.ENUM_DEFINITION, GosuHighlighterColors.ENUM_NAME_ATTRKEY);
COLOR_MAP.put(GosuElementTypes.FIELD, GosuHighlighterColors.INSTANCE_FIELD_ATTRKEY);
COLOR_MAP.put(GosuElementTypes.ENUM_CONSTANT, GosuHighlighterColors.STATIC_FIELD_ATTRKEY);
COLOR_MAP.put(GosuElementTypes.ELEM_TYPE_VarStatement, GosuHighlighterColors.LOCAL_VARIABLE_ATTRKEY);
COLOR_MAP.put(GosuElementTypes.ELEM_TYPE_LocalVarDeclaration, GosuHighlighterColors.LOCAL_VARIABLE_ATTRKEY);
COLOR_MAP.put(GosuElementTypes.ELEM_TYPE_ParameterDeclaration, GosuHighlighterColors.PARAMETER_ATTRKEY);
COLOR_MAP.put(GosuElementTypes.METHOD_DEFINITION, GosuHighlighterColors.METHOD_DECLARATION_ATTRKEY);
COLOR_MAP.put(GosuElementTypes.ELEM_TYPE_MethodCallExpression, GosuHighlighterColors.METHOD_CALL_ATTRKEY);
COLOR_MAP.put(GosuElementTypes.ELEM_TYPE_TypeVariableDefinitionExpression, GosuHighlighterColors.TYPE_VARIABLE_ATTRKEY);
// !PW Argh, this is awful! Need keyword/operator/brace flag on GosuElementType
// keywords and symbols
COLOR_MAP.put(GosuElementTypes.TT_true, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_false, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_NaN, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_Infinity, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_and, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_or, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_not, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_null, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_length, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_exists, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_in, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_startswith, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_contains, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_where, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_find, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_var, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_delegate, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_represents, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_as, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_typeof, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_statictypeof, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_typeis, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_typeas, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_print, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_package, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_uses, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_if, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_else, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_except, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_unless, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_foreach, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_for, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_index, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_while, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_do, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_continue, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_break, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_return, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_construct, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_function, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_property, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_get, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_set, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_try, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_catch, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_finally, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_this, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_throw, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_assert, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_new, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_switch, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_case, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_default, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_eval, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_private, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_internal, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_protected, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_public, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_abstract, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_override, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_hide, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_final, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_static, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_extends, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_transient, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_implements, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_readonly, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_class, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_interface, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_enum, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_super, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_outer, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_execution, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_request, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_session, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_application, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_void, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_block, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_enhancement, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_classpath, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_typeloader, GosuHighlighterColors.KEYWORD);
COLOR_MAP.put(GosuElementTypes.TT_using, GosuHighlighterColors.KEYWORD);
//
// Operators
//
COLOR_MAP.put(GosuElementTypes.TT_OP_assign, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_greater, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_less, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_not_logical, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_not_bitwise, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_question, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_colon, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_ternary, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_equals, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_less_equals, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_not_equals, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_not_equals_for_losers, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_logical_and, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_logical_or, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_increment, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_decrement, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_identity, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_not_identity, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_expansion, GosuHighlighterColors.OPERATOR);
// Arithmetic operators
COLOR_MAP.put(GosuElementTypes.TT_OP_plus, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_minus, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_multiply, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_divide, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_modulo, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_bitwise_and, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_bitwise_or, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_bitwise_xor, GosuHighlighterColors.OPERATOR);
// Null-safe arithmetic operators
COLOR_MAP.put(GosuElementTypes.TT_OP_nullsafe_plus, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_nullsafe_minus, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_nullsafe_multiply, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_nullsafe_divide, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_nullsafe_modulo, GosuHighlighterColors.OPERATOR);
// Compound operators
COLOR_MAP.put(GosuElementTypes.TT_OP_assign_plus, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_assign_minus, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_assign_multiply, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_assign_divide, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_assign_modulo, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_assign_and, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_assign_logical_and, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_assing_or, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_assing_logical_or, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_assign_xor, GosuHighlighterColors.OPERATOR);
// Block operators
COLOR_MAP.put(GosuElementTypes.TT_OP_escape, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_assign_closure, GosuHighlighterColors.OPERATOR);
// Member-access operators
COLOR_MAP.put(GosuElementTypes.TT_OP_dot, GosuHighlighterColors.DOT);
COLOR_MAP.put(GosuElementTypes.TT_OP_nullsafe_dot, GosuHighlighterColors.DOT);
// Null-safe array access
COLOR_MAP.put(GosuElementTypes.TT_OP_nullsafe_array_access, GosuHighlighterColors.OPERATOR);
// Interval operators
COLOR_MAP.put(GosuElementTypes.TT_OP_interval, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_interval_left_open, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_interval_right_open, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_interval_open, GosuHighlighterColors.OPERATOR);
// Feature Literals
COLOR_MAP.put(GosuElementTypes.TT_OP_feature_access, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_shift_left, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_shift_right, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_shift_right_unsigned, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_assign_shift_left, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_assign_shift_right, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_assign_shift_right_unsigned, GosuHighlighterColors.OPERATOR);
// Delimiters
COLOR_MAP.put(GosuElementTypes.TT_OP_brace_left, GosuHighlighterColors.BRACES);
COLOR_MAP.put(GosuElementTypes.TT_OP_brace_right, GosuHighlighterColors.BRACES);
COLOR_MAP.put(GosuElementTypes.TT_OP_paren_left, GosuHighlighterColors.PARENTHS);
COLOR_MAP.put(GosuElementTypes.TT_OP_paren_right, GosuHighlighterColors.PARENTHS);
COLOR_MAP.put(GosuElementTypes.TT_OP_bracket_left, GosuHighlighterColors.BRACKETS);
COLOR_MAP.put(GosuElementTypes.TT_OP_bracket_right, GosuHighlighterColors.BRACKETS);
COLOR_MAP.put(GosuElementTypes.TT_OP_quote_double, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_quote_single, GosuHighlighterColors.OPERATOR);
// Separators
COLOR_MAP.put(GosuElementTypes.TT_OP_at, GosuHighlighterColors.ANNOTATION_NAME_ATTRKEY);
COLOR_MAP.put(GosuElementTypes.TT_OP_dollar, GosuHighlighterColors.OPERATOR);
COLOR_MAP.put(GosuElementTypes.TT_OP_comma, GosuHighlighterColors.COMMA);
COLOR_MAP.put(GosuElementTypes.TT_OP_semicolon, GosuHighlighterColors.SEMICOLON);
}
// Lookup via referenced elements vs direct. Segregated if we ever want distinct colors for references (ala Eclipse)
private static final Map<IElementType, TextAttributesKey> COLOR_FROM_REF_MAP = new HashMap<>();
static {
// types
COLOR_FROM_REF_MAP.put(GosuElementTypes.CLASS_DEFINITION, GosuHighlighterColors.CLASS_NAME_ATTRKEY);
COLOR_FROM_REF_MAP.put(JavaStubElementTypes.CLASS, GosuHighlighterColors.CLASS_NAME_ATTRKEY);
COLOR_FROM_REF_MAP.put(GosuElementTypes.INTERFACE_DEFINITION, GosuHighlighterColors.INTERFACE_NAME_ATTRKEY);
COLOR_FROM_REF_MAP.put(GosuElementTypes.ENUM_DEFINITION, GosuHighlighterColors.ENUM_NAME_ATTRKEY);
// type variables
COLOR_FROM_REF_MAP.put(GosuElementTypes.ELEM_TYPE_TypeVariableDefinitionExpression, GosuHighlighterColors.TYPE_VARIABLE_ATTRKEY);
// methods
COLOR_FROM_REF_MAP.put(GosuElementTypes.METHOD_DEFINITION, GosuHighlighterColors.METHOD_CALL_ATTRKEY);
COLOR_FROM_REF_MAP.put(JavaStubElementTypes.METHOD, GosuHighlighterColors.METHOD_CALL_ATTRKEY);
// parameters
COLOR_FROM_REF_MAP.put(GosuElementTypes.ELEM_TYPE_ParameterDeclaration, GosuHighlighterColors.PARAMETER_ATTRKEY);
COLOR_FROM_REF_MAP.put(JavaStubElementTypes.PARAMETER, GosuHighlighterColors.PARAMETER_ATTRKEY);
// local variables
COLOR_FROM_REF_MAP.put(GosuElementTypes.ELEM_TYPE_VarStatement, GosuHighlighterColors.LOCAL_VARIABLE_ATTRKEY);
COLOR_FROM_REF_MAP.put(GosuElementTypes.ELEM_TYPE_LocalVarDeclaration, GosuHighlighterColors.LOCAL_VARIABLE_ATTRKEY);
// fields
COLOR_FROM_REF_MAP.put(GosuElementTypes.FIELD, GosuHighlighterColors.INSTANCE_FIELD_ATTRKEY);
COLOR_FROM_REF_MAP.put(JavaStubElementTypes.FIELD, GosuHighlighterColors.INSTANCE_FIELD_ATTRKEY);
// static fields
COLOR_FROM_REF_MAP.put(GosuElementTypes.ENUM_CONSTANT, GosuHighlighterColors.STATIC_FIELD_ATTRKEY);
COLOR_FROM_REF_MAP.put(JavaStubElementTypes.ENUM_CONSTANT, GosuHighlighterColors.STATIC_FIELD_ATTRKEY);
// properties
}
private static final Map<IElementType, TextAttributesKey> COLOR_FOR_REF_MAP = Maps.newHashMap();
static {
COLOR_FOR_REF_MAP.put(GosuElementTypes.ELEM_TYPE_ParameterDeclaration, GosuHighlighterColors.PARAMETER_ATTRKEY);
COLOR_FOR_REF_MAP.put(GosuElementTypes.ELEM_TYPE_VarStatement, GosuHighlighterColors.LOCAL_VARIABLE_ATTRKEY);
}
// TODO: use Keyword class here (or Guava immutable set)
private static final Set<String> GOSU_KEYWORDS = ImmutableSet.of(
"abstract", "and", "application", "as", "block",
"break", "case", "catch", "class", "classpath", "construct", "contains", "continue",
"default", "delegate", "do", "else", "enhancement", "enum", "eval", "except", "execution",
"exists", "extends", "false", "final", "finally", "find", "for", "foreach", "function",
"get", "hide", "if", "implements", "in", "index", "interface", "internal", "length", "new",
"not", "null", "or", "outer", "override", "package", "private", "property", "protected",
"public", "readonly", "represents", "request",
"return",
"session", "set", "startswith", "static", "statictypeof", "super", "switch", "this", "throw",
"transient", "true", "try", "typeas", "typeis", "typeof", "unless", "uses", "using", "var",
"void", "where", "while", "Infinity", "NaN");
private static final Set<String> NATIVE_TYPES = ImmutableSet.of(
"boolean", "byte", "char", "double", "float",
"int", "long", "short", "strictfp", "void");
private static final Set<String> NATIVE_CONSTANTS = ImmutableSet.of(
"true", "false", "null");
}