From 60dc0fdff99a3363a6bd09a9a30980d27eb2f6b4 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Fri, 17 Feb 2017 17:24:50 +0100 Subject: [PATCH] UAST-based implementation of JavaColorProvider --- .../daemon/impl/JavaColorProvider.java | 96 ++++++++++++------- 1 file changed, 60 insertions(+), 36 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaColorProvider.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaColorProvider.java index e45361bf55fb..04a086d91dd3 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaColorProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaColorProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -27,8 +27,13 @@ import com.intellij.ui.ColorUtil; import com.intellij.ui.JBColor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.uast.*; +import org.jetbrains.uast.evaluation.UEvaluationContextKt; +import org.jetbrains.uast.values.UConstant; +import org.jetbrains.uast.values.UValue; -import java.awt.*; +import java.awt.Color; +import java.util.List; /** * @author Konstantin Bulenkov @@ -55,53 +60,54 @@ public class JavaColorProvider implements ElementColorProvider { @Nullable public static Color getJavaColorFromExpression(@Nullable PsiElement element) { - if (element instanceof PsiNewExpression) { - final PsiNewExpression expr = (PsiNewExpression)element; - if (isColorType(expr.getType())) { - return getColor(expr.getArgumentList()); - } + UCallExpression newExpression = UastContextKt.toUElement(element, UCallExpression.class); + if (newExpression != null && newExpression.getKind() == UastCallKind.CONSTRUCTOR_CALL && + isColorType(newExpression.getReturnType())) { + return getColor(newExpression.getValueArguments()); } else if (isIntLiteralInsideNewJBColorExpression(element)) { final String text = element.getText(); boolean hasAlpha = text != null && StringUtil.startsWithIgnoreCase(text, "0x") && text.length() > 8; - return new Color(getInt((PsiExpression)element), hasAlpha); + return new Color(getInt(newExpression), hasAlpha); } return null; } private static boolean isIntLiteralInsideNewJBColorExpression(PsiElement element) { - if (element instanceof PsiLiteralExpression && PsiType.INT.equals(((PsiLiteralExpression)element).getType())) { - PsiElement parent = element.getParent(); + ULiteralExpression literalExpression = UastContextKt.toUElement(element, ULiteralExpression.class); + if (literalExpression != null && PsiType.INT.equals(literalExpression.getExpressionType())) { + UElement parent = literalExpression.getUastParent(); if (parent != null) { - return isNewJBColorExpression(parent.getParent()); + return isNewJBColorExpression(parent); } } return false; } - private static boolean isNewJBColorExpression(PsiElement element) { - if (element instanceof PsiNewExpression) { - final PsiClass psiClass = PsiTypesUtil.getPsiClass(((PsiNewExpression)element).getType()); - if (psiClass != null && JBColor.class.getName().equals(psiClass.getQualifiedName())) { - return true; + private static boolean isNewJBColorExpression(UElement element) { + if (element instanceof UCallExpression) { + UCallExpression callExpression = (UCallExpression)element; + if (callExpression.getKind() == UastCallKind.CONSTRUCTOR_CALL) { + final PsiClass psiClass = PsiTypesUtil.getPsiClass(callExpression.getReturnType()); + if (psiClass != null && JBColor.class.getName().equals(psiClass.getQualifiedName())) { + return true; + } } } return false; } @Nullable - private static Color getColor(PsiExpressionList list) { + private static Color getColor(List args) { try { - final PsiExpression[] args = list.getExpressions(); - final PsiType[] types = list.getExpressionTypes(); - ColorConstructors type = getConstructorType(types); + ColorConstructors type = args.isEmpty() ? null : getConstructorType(args.size(), args.get(0).getExpressionType()); if (type != null) { switch (type) { - case INT: return new Color( getInt(args[0])); - case INT_BOOL: return new Color( getInt(args[0]), getBoolean(args[1])); - case INT_x3: return new Color( getInt(args[0]), getInt(args[1]), getInt(args[2])); - case INT_x4: return new Color( getInt(args[0]), getInt(args[1]), getInt(args[2]), getInt(args[3])); - case FLOAT_x3: return new Color(getFloat(args[0]), getFloat(args[1]), getFloat(args[2])); - case FLOAT_x4: return new Color(getFloat(args[0]), getFloat(args[1]), getFloat(args[2]), getFloat(args[3])); + case INT: return new Color( getInt(args.get(0))); + case INT_BOOL: return new Color( getInt(args.get(0)), getBoolean(args.get(1))); + case INT_x3: return new Color( getInt(args.get(0)), getInt(args.get(1)), getInt(args.get(2))); + case INT_x4: return new Color( getInt(args.get(0)), getInt(args.get(1)), getInt(args.get(2)), getInt(args.get(3))); + case FLOAT_x3: return new Color(getFloat(args.get(0)), getFloat(args.get(1)), getFloat(args.get(2))); + case FLOAT_x4: return new Color(getFloat(args.get(0)), getFloat(args.get(1)), getFloat(args.get(2)), getFloat(args.get(3))); } } } @@ -111,20 +117,25 @@ public class JavaColorProvider implements ElementColorProvider { } @Nullable - private static ColorConstructors getConstructorType(PsiType[] types) { - int len = types.length; - if (len == 0) return null; - - switch (len) { + private static ColorConstructors getConstructorType(int paramCount, PsiType paramType) { + switch (paramCount) { case 1: return ColorConstructors.INT; case 2: return ColorConstructors.INT_BOOL; - case 3: return PsiType.INT.equals(types[0]) ? ColorConstructors.INT_x3 : ColorConstructors.FLOAT_x3; - case 4: return PsiType.INT.equals(types[0]) ? ColorConstructors.INT_x4 : ColorConstructors.FLOAT_x4; + case 3: return PsiType.INT.equals(paramType) ? ColorConstructors.INT_x3 : ColorConstructors.FLOAT_x3; + case 4: return PsiType.INT.equals(paramType) ? ColorConstructors.INT_x4 : ColorConstructors.FLOAT_x4; } return null; } + public static int getInt(UExpression expr) { + return ((Integer)getObject(expr)).intValue(); + } + + public static float getFloat(UExpression expr) { + return ((Float)getObject(expr)).floatValue(); + } + public static int getInt(PsiExpression expr) { return ((Integer)getObject(expr)).intValue(); } @@ -133,7 +144,7 @@ public class JavaColorProvider implements ElementColorProvider { return ((Float)getObject(expr)).floatValue(); } - public static boolean getBoolean(PsiExpression expr) { + public static boolean getBoolean(UExpression expr) { return ((Boolean)getObject(expr)).booleanValue(); } @@ -141,6 +152,18 @@ public class JavaColorProvider implements ElementColorProvider { return JavaConstantExpressionEvaluator.computeConstantExpression(expr, true); } + private static Object getObject(UExpression expr) { + UValue value = UEvaluationContextKt.uValueOf(expr); + if (value == null) { + return null; + } + UConstant constant = value.toConstant(); + if (constant == null) { + return null; + } + return constant.getValue(); + } + @Override public void setColorTo(@NotNull PsiElement element, @NotNull Color color) { Runnable command; @@ -153,7 +176,8 @@ public class JavaColorProvider implements ElementColorProvider { assert argumentList != null; PsiExpression[] expr = argumentList.getExpressions(); - ColorConstructors type = getConstructorType(argumentList.getExpressionTypes()); + PsiType[] expressionTypes = argumentList.getExpressionTypes(); + ColorConstructors type = expressionTypes.length == 0 ? null : getConstructorType(expressionTypes.length, expressionTypes[0]); assert type != null; command = () -> { @@ -226,7 +250,7 @@ public class JavaColorProvider implements ElementColorProvider { expr.replace(factory.createExpressionFromText(String.valueOf(newValue) + "f", null)); } } - + private enum ColorConstructors { INT, INT_BOOL, INT_x3, INT_x4, FLOAT_x3, FLOAT_x4 }