Search in sources :

Example 6 with PsiArrayType

use of com.intellij.psi.PsiArrayType in project intellij-community by JetBrains.

the class BaseScriptTransformationSupport method applyTransformation.

@Override
public void applyTransformation(@NotNull TransformationContext context) {
    if (!(context.getCodeClass() instanceof GroovyScriptClass))
        return;
    GroovyScriptClass scriptClass = (GroovyScriptClass) context.getCodeClass();
    LightMethodBuilder mainMethod = new LightMethodBuilder(scriptClass.getManager(), GroovyLanguage.INSTANCE, "main").setMethodReturnType(PsiType.VOID).addParameter("args", new PsiArrayType(PsiType.getJavaLangString(scriptClass.getManager(), scriptClass.getResolveScope()))).addModifiers(PsiModifier.PUBLIC, PsiModifier.STATIC);
    LightMethodBuilder runMethod = new LightMethodBuilder(scriptClass.getManager(), GroovyLanguage.INSTANCE, "run").setMethodReturnType(TypesUtil.getJavaLangObject(scriptClass)).addModifier(PsiModifier.PUBLIC);
    context.addMethod(runMethod, true);
    context.addMethod(mainMethod, true);
    context.setSuperType(getBaseClassType(scriptClass));
}
Also used : GroovyScriptClass(org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass) LightMethodBuilder(com.intellij.psi.impl.light.LightMethodBuilder) PsiArrayType(com.intellij.psi.PsiArrayType)

Example 7 with PsiArrayType

use of com.intellij.psi.PsiArrayType in project intellij-community by JetBrains.

the class GrContainerConverter method isConvertible.

@Nullable
@Override
public Boolean isConvertible(@NotNull PsiType lType, @NotNull PsiType rType, @NotNull GroovyPsiElement context) {
    if (lType instanceof PsiArrayType) {
        PsiType lComponentType = ((PsiArrayType) lType).getComponentType();
        PsiType rComponentType = ClosureParameterEnhancer.findTypeForIteration(rType, context);
        if (rComponentType != null && TypesUtil.isAssignable(lComponentType, rComponentType, context)) {
            return Boolean.TRUE;
        }
    }
    return null;
}
Also used : PsiArrayType(com.intellij.psi.PsiArrayType) PsiType(com.intellij.psi.PsiType) Nullable(org.jetbrains.annotations.Nullable)

Example 8 with PsiArrayType

use of com.intellij.psi.PsiArrayType in project kotlin by JetBrains.

the class ConstantEvaluator method evaluate.

/**
     * Evaluates the given node and returns the constant value it resolves to, if any
     *
     * @param node the node to compute the constant value for
     * @return the corresponding constant value - a String, an Integer, a Float, and so on
     */
@Nullable
public Object evaluate(@Nullable PsiElement node) {
    if (node == null) {
        return null;
    }
    if (node instanceof PsiLiteral) {
        return ((PsiLiteral) node).getValue();
    } else if (node instanceof PsiPrefixExpression) {
        IElementType operator = ((PsiPrefixExpression) node).getOperationTokenType();
        Object operand = evaluate(((PsiPrefixExpression) node).getOperand());
        if (operand == null) {
            return null;
        }
        if (operator == JavaTokenType.EXCL) {
            if (operand instanceof Boolean) {
                return !(Boolean) operand;
            }
        } else if (operator == JavaTokenType.PLUS) {
            return operand;
        } else if (operator == JavaTokenType.TILDE) {
            if (operand instanceof Integer) {
                return ~(Integer) operand;
            } else if (operand instanceof Long) {
                return ~(Long) operand;
            } else if (operand instanceof Short) {
                return ~(Short) operand;
            } else if (operand instanceof Character) {
                return ~(Character) operand;
            } else if (operand instanceof Byte) {
                return ~(Byte) operand;
            }
        } else if (operator == JavaTokenType.MINUS) {
            if (operand instanceof Integer) {
                return -(Integer) operand;
            } else if (operand instanceof Long) {
                return -(Long) operand;
            } else if (operand instanceof Double) {
                return -(Double) operand;
            } else if (operand instanceof Float) {
                return -(Float) operand;
            } else if (operand instanceof Short) {
                return -(Short) operand;
            } else if (operand instanceof Character) {
                return -(Character) operand;
            } else if (operand instanceof Byte) {
                return -(Byte) operand;
            }
        }
    } else if (node instanceof PsiConditionalExpression) {
        PsiConditionalExpression expression = (PsiConditionalExpression) node;
        Object known = evaluate(expression.getCondition());
        if (known == Boolean.TRUE && expression.getThenExpression() != null) {
            return evaluate(expression.getThenExpression());
        } else if (known == Boolean.FALSE && expression.getElseExpression() != null) {
            return evaluate(expression.getElseExpression());
        }
    } else if (node instanceof PsiParenthesizedExpression) {
        PsiParenthesizedExpression parenthesizedExpression = (PsiParenthesizedExpression) node;
        PsiExpression expression = parenthesizedExpression.getExpression();
        if (expression != null) {
            return evaluate(expression);
        }
    } else if (node instanceof PsiBinaryExpression) {
        IElementType operator = ((PsiBinaryExpression) node).getOperationTokenType();
        Object operandLeft = evaluate(((PsiBinaryExpression) node).getLOperand());
        Object operandRight = evaluate(((PsiBinaryExpression) node).getROperand());
        if (operandLeft == null || operandRight == null) {
            if (mAllowUnknown) {
                if (operandLeft == null) {
                    return operandRight;
                } else {
                    return operandLeft;
                }
            }
            return null;
        }
        if (operandLeft instanceof String && operandRight instanceof String) {
            if (operator == JavaTokenType.PLUS) {
                return operandLeft.toString() + operandRight.toString();
            }
            return null;
        } else if (operandLeft instanceof Boolean && operandRight instanceof Boolean) {
            boolean left = (Boolean) operandLeft;
            boolean right = (Boolean) operandRight;
            if (operator == JavaTokenType.OROR) {
                return left || right;
            } else if (operator == JavaTokenType.ANDAND) {
                return left && right;
            } else if (operator == JavaTokenType.OR) {
                return left | right;
            } else if (operator == JavaTokenType.XOR) {
                return left ^ right;
            } else if (operator == JavaTokenType.AND) {
                return left & right;
            } else if (operator == JavaTokenType.EQEQ) {
                return left == right;
            } else if (operator == JavaTokenType.NE) {
                return left != right;
            }
        } else if (operandLeft instanceof Number && operandRight instanceof Number) {
            Number left = (Number) operandLeft;
            Number right = (Number) operandRight;
            boolean isInteger = !(left instanceof Float || left instanceof Double || right instanceof Float || right instanceof Double);
            boolean isWide = isInteger ? (left instanceof Long || right instanceof Long) : (left instanceof Double || right instanceof Double);
            if (operator == JavaTokenType.OR) {
                if (isWide) {
                    return left.longValue() | right.longValue();
                } else {
                    return left.intValue() | right.intValue();
                }
            } else if (operator == JavaTokenType.XOR) {
                if (isWide) {
                    return left.longValue() ^ right.longValue();
                } else {
                    return left.intValue() ^ right.intValue();
                }
            } else if (operator == JavaTokenType.AND) {
                if (isWide) {
                    return left.longValue() & right.longValue();
                } else {
                    return left.intValue() & right.intValue();
                }
            } else if (operator == JavaTokenType.EQEQ) {
                if (isInteger) {
                    return left.longValue() == right.longValue();
                } else {
                    return left.doubleValue() == right.doubleValue();
                }
            } else if (operator == JavaTokenType.NE) {
                if (isInteger) {
                    return left.longValue() != right.longValue();
                } else {
                    return left.doubleValue() != right.doubleValue();
                }
            } else if (operator == JavaTokenType.GT) {
                if (isInteger) {
                    return left.longValue() > right.longValue();
                } else {
                    return left.doubleValue() > right.doubleValue();
                }
            } else if (operator == JavaTokenType.GE) {
                if (isInteger) {
                    return left.longValue() >= right.longValue();
                } else {
                    return left.doubleValue() >= right.doubleValue();
                }
            } else if (operator == JavaTokenType.LT) {
                if (isInteger) {
                    return left.longValue() < right.longValue();
                } else {
                    return left.doubleValue() < right.doubleValue();
                }
            } else if (operator == JavaTokenType.LE) {
                if (isInteger) {
                    return left.longValue() <= right.longValue();
                } else {
                    return left.doubleValue() <= right.doubleValue();
                }
            } else if (operator == JavaTokenType.LTLT) {
                if (isWide) {
                    return left.longValue() << right.intValue();
                } else {
                    return left.intValue() << right.intValue();
                }
            } else if (operator == JavaTokenType.GTGT) {
                if (isWide) {
                    return left.longValue() >> right.intValue();
                } else {
                    return left.intValue() >> right.intValue();
                }
            } else if (operator == JavaTokenType.GTGTGT) {
                if (isWide) {
                    return left.longValue() >>> right.intValue();
                } else {
                    return left.intValue() >>> right.intValue();
                }
            } else if (operator == JavaTokenType.PLUS) {
                if (isInteger) {
                    if (isWide) {
                        return left.longValue() + right.longValue();
                    } else {
                        return left.intValue() + right.intValue();
                    }
                } else {
                    if (isWide) {
                        return left.doubleValue() + right.doubleValue();
                    } else {
                        return left.floatValue() + right.floatValue();
                    }
                }
            } else if (operator == JavaTokenType.MINUS) {
                if (isInteger) {
                    if (isWide) {
                        return left.longValue() - right.longValue();
                    } else {
                        return left.intValue() - right.intValue();
                    }
                } else {
                    if (isWide) {
                        return left.doubleValue() - right.doubleValue();
                    } else {
                        return left.floatValue() - right.floatValue();
                    }
                }
            } else if (operator == JavaTokenType.ASTERISK) {
                if (isInteger) {
                    if (isWide) {
                        return left.longValue() * right.longValue();
                    } else {
                        return left.intValue() * right.intValue();
                    }
                } else {
                    if (isWide) {
                        return left.doubleValue() * right.doubleValue();
                    } else {
                        return left.floatValue() * right.floatValue();
                    }
                }
            } else if (operator == JavaTokenType.DIV) {
                if (isInteger) {
                    if (isWide) {
                        return left.longValue() / right.longValue();
                    } else {
                        return left.intValue() / right.intValue();
                    }
                } else {
                    if (isWide) {
                        return left.doubleValue() / right.doubleValue();
                    } else {
                        return left.floatValue() / right.floatValue();
                    }
                }
            } else if (operator == JavaTokenType.PERC) {
                if (isInteger) {
                    if (isWide) {
                        return left.longValue() % right.longValue();
                    } else {
                        return left.intValue() % right.intValue();
                    }
                } else {
                    if (isWide) {
                        return left.doubleValue() % right.doubleValue();
                    } else {
                        return left.floatValue() % right.floatValue();
                    }
                }
            } else {
                return null;
            }
        }
    } else if (node instanceof PsiTypeCastExpression) {
        PsiTypeCastExpression cast = (PsiTypeCastExpression) node;
        Object operandValue = evaluate(cast.getOperand());
        if (operandValue instanceof Number) {
            Number number = (Number) operandValue;
            PsiTypeElement typeElement = cast.getCastType();
            if (typeElement != null) {
                PsiType type = typeElement.getType();
                if (PsiType.FLOAT.equals(type)) {
                    return number.floatValue();
                } else if (PsiType.DOUBLE.equals(type)) {
                    return number.doubleValue();
                } else if (PsiType.INT.equals(type)) {
                    return number.intValue();
                } else if (PsiType.LONG.equals(type)) {
                    return number.longValue();
                } else if (PsiType.SHORT.equals(type)) {
                    return number.shortValue();
                } else if (PsiType.BYTE.equals(type)) {
                    return number.byteValue();
                }
            }
        }
        return operandValue;
    } else if (node instanceof PsiReference) {
        PsiElement resolved = ((PsiReference) node).resolve();
        if (resolved instanceof PsiField) {
            PsiField field = (PsiField) resolved;
            Object value = field.computeConstantValue();
            if (value != null) {
                return value;
            }
            if (field.getInitializer() != null) {
                return evaluate(field.getInitializer());
            }
            return null;
        } else if (resolved instanceof PsiLocalVariable) {
            PsiLocalVariable variable = (PsiLocalVariable) resolved;
            PsiStatement statement = PsiTreeUtil.getParentOfType(node, PsiStatement.class, false);
            if (statement != null) {
                PsiStatement prev = PsiTreeUtil.getPrevSiblingOfType(statement, PsiStatement.class);
                String targetName = variable.getName();
                if (targetName == null) {
                    return null;
                }
                while (prev != null) {
                    if (prev instanceof PsiDeclarationStatement) {
                        for (PsiElement element : ((PsiDeclarationStatement) prev).getDeclaredElements()) {
                            if (variable.equals(element)) {
                                return evaluate(variable.getInitializer());
                            }
                        }
                    } else if (prev instanceof PsiExpressionStatement) {
                        PsiExpression expression = ((PsiExpressionStatement) prev).getExpression();
                        if (expression instanceof PsiAssignmentExpression) {
                            PsiAssignmentExpression assign = (PsiAssignmentExpression) expression;
                            PsiExpression lhs = assign.getLExpression();
                            if (lhs instanceof PsiReferenceExpression) {
                                PsiReferenceExpression reference = (PsiReferenceExpression) lhs;
                                if (targetName.equals(reference.getReferenceName()) && reference.getQualifier() == null) {
                                    return evaluate(assign.getRExpression());
                                }
                            }
                        }
                    }
                    prev = PsiTreeUtil.getPrevSiblingOfType(prev, PsiStatement.class);
                }
            }
        }
    } else if (node instanceof PsiNewExpression) {
        PsiNewExpression creation = (PsiNewExpression) node;
        PsiArrayInitializerExpression initializer = creation.getArrayInitializer();
        PsiType type = creation.getType();
        if (type instanceof PsiArrayType) {
            if (initializer != null) {
                PsiExpression[] initializers = initializer.getInitializers();
                Class<?> commonType = null;
                List<Object> values = Lists.newArrayListWithExpectedSize(initializers.length);
                int count = 0;
                for (PsiExpression expression : initializers) {
                    Object value = evaluate(expression);
                    if (value != null) {
                        values.add(value);
                        if (commonType == null) {
                            commonType = value.getClass();
                        } else {
                            while (!commonType.isAssignableFrom(value.getClass())) {
                                commonType = commonType.getSuperclass();
                            }
                        }
                    } else if (!mAllowUnknown) {
                        // Inconclusive
                        return null;
                    }
                    count++;
                    if (count == 20) {
                        // avoid large initializers
                        break;
                    }
                }
                type = type.getDeepComponentType();
                if (type == PsiType.INT) {
                    if (!values.isEmpty()) {
                        int[] array = new int[values.size()];
                        for (int i = 0; i < values.size(); i++) {
                            Object o = values.get(i);
                            if (o instanceof Integer) {
                                array[i] = (Integer) o;
                            }
                        }
                        return array;
                    }
                    return new int[0];
                } else if (type == PsiType.BOOLEAN) {
                    if (!values.isEmpty()) {
                        boolean[] array = new boolean[values.size()];
                        for (int i = 0; i < values.size(); i++) {
                            Object o = values.get(i);
                            if (o instanceof Boolean) {
                                array[i] = (Boolean) o;
                            }
                        }
                        return array;
                    }
                    return new boolean[0];
                } else if (type == PsiType.DOUBLE) {
                    if (!values.isEmpty()) {
                        double[] array = new double[values.size()];
                        for (int i = 0; i < values.size(); i++) {
                            Object o = values.get(i);
                            if (o instanceof Double) {
                                array[i] = (Double) o;
                            }
                        }
                        return array;
                    }
                    return new double[0];
                } else if (type == PsiType.LONG) {
                    if (!values.isEmpty()) {
                        long[] array = new long[values.size()];
                        for (int i = 0; i < values.size(); i++) {
                            Object o = values.get(i);
                            if (o instanceof Long) {
                                array[i] = (Long) o;
                            }
                        }
                        return array;
                    }
                    return new long[0];
                } else if (type == PsiType.FLOAT) {
                    if (!values.isEmpty()) {
                        float[] array = new float[values.size()];
                        for (int i = 0; i < values.size(); i++) {
                            Object o = values.get(i);
                            if (o instanceof Float) {
                                array[i] = (Float) o;
                            }
                        }
                        return array;
                    }
                    return new float[0];
                } else if (type == PsiType.CHAR) {
                    if (!values.isEmpty()) {
                        char[] array = new char[values.size()];
                        for (int i = 0; i < values.size(); i++) {
                            Object o = values.get(i);
                            if (o instanceof Character) {
                                array[i] = (Character) o;
                            }
                        }
                        return array;
                    }
                    return new char[0];
                } else if (type == PsiType.BYTE) {
                    if (!values.isEmpty()) {
                        byte[] array = new byte[values.size()];
                        for (int i = 0; i < values.size(); i++) {
                            Object o = values.get(i);
                            if (o instanceof Byte) {
                                array[i] = (Byte) o;
                            }
                        }
                        return array;
                    }
                    return new byte[0];
                } else if (type == PsiType.SHORT) {
                    if (!values.isEmpty()) {
                        short[] array = new short[values.size()];
                        for (int i = 0; i < values.size(); i++) {
                            Object o = values.get(i);
                            if (o instanceof Short) {
                                array[i] = (Short) o;
                            }
                        }
                        return array;
                    }
                    return new short[0];
                } else {
                    if (!values.isEmpty()) {
                        Object o = Array.newInstance(commonType, values.size());
                        return values.toArray((Object[]) o);
                    }
                    return null;
                }
            } else {
                // something like "new byte[3]" but with no initializer.
                // Look up the size and only if small, use it. E.g. if it was byte[3]
                // we return a byte[3] array, but if it's say byte[1024*1024] we don't
                // want to do that.
                PsiExpression[] arrayDimensions = creation.getArrayDimensions();
                int size = 0;
                if (arrayDimensions.length == 1) {
                    Object fixedSize = evaluate(arrayDimensions[0]);
                    if (fixedSize instanceof Number) {
                        size = ((Number) fixedSize).intValue();
                        if (size > 30) {
                            size = 30;
                        }
                    }
                }
                type = type.getDeepComponentType();
                if (type instanceof PsiPrimitiveType) {
                    if (PsiType.BYTE.equals(type)) {
                        return new byte[size];
                    }
                    if (PsiType.BOOLEAN.equals(type)) {
                        return new boolean[size];
                    }
                    if (PsiType.INT.equals(type)) {
                        return new int[size];
                    }
                    if (PsiType.LONG.equals(type)) {
                        return new long[size];
                    }
                    if (PsiType.CHAR.equals(type)) {
                        return new char[size];
                    }
                    if (PsiType.FLOAT.equals(type)) {
                        return new float[size];
                    }
                    if (PsiType.DOUBLE.equals(type)) {
                        return new double[size];
                    }
                    if (PsiType.SHORT.equals(type)) {
                        return new short[size];
                    }
                } else if (type instanceof PsiClassType) {
                    String className = type.getCanonicalText();
                    if (TYPE_STRING.equals(className)) {
                        //noinspection SSBasedInspection
                        return new String[size];
                    }
                    if (TYPE_OBJECT.equals(className)) {
                        //noinspection SSBasedInspection
                        return new Object[size];
                    }
                }
            }
        }
    }
    return null;
}
Also used : PsiPrefixExpression(com.intellij.psi.PsiPrefixExpression) PsiExpression(com.intellij.psi.PsiExpression) PsiReferenceExpression(com.intellij.psi.PsiReferenceExpression) PsiAssignmentExpression(com.intellij.psi.PsiAssignmentExpression) PsiLiteral(com.intellij.psi.PsiLiteral) PsiLocalVariable(com.intellij.psi.PsiLocalVariable) PsiArrayInitializerExpression(com.intellij.psi.PsiArrayInitializerExpression) PsiTypeCastExpression(com.intellij.psi.PsiTypeCastExpression) PsiArrayType(com.intellij.psi.PsiArrayType) PsiParenthesizedExpression(com.intellij.psi.PsiParenthesizedExpression) List(java.util.List) ArrayList(java.util.ArrayList) PsiElement(com.intellij.psi.PsiElement) PsiType(com.intellij.psi.PsiType) PsiStatement(com.intellij.psi.PsiStatement) PsiDeclarationStatement(com.intellij.psi.PsiDeclarationStatement) PsiPrimitiveType(com.intellij.psi.PsiPrimitiveType) PsiReference(com.intellij.psi.PsiReference) PsiNewExpression(com.intellij.psi.PsiNewExpression) PsiConditionalExpression(com.intellij.psi.PsiConditionalExpression) IElementType(com.intellij.psi.tree.IElementType) PsiClassType(com.intellij.psi.PsiClassType) PsiExpressionStatement(com.intellij.psi.PsiExpressionStatement) PsiTypeElement(com.intellij.psi.PsiTypeElement) PsiField(com.intellij.psi.PsiField) PsiClass(com.intellij.psi.PsiClass) PsiBinaryExpression(com.intellij.psi.PsiBinaryExpression) Nullable(com.android.annotations.Nullable)

Example 9 with PsiArrayType

use of com.intellij.psi.PsiArrayType in project kotlin by JetBrains.

the class ConstantEvaluator method evaluate.

/**
     * Evaluates the given node and returns the constant value it resolves to, if any
     *
     * @param node the node to compute the constant value for
     * @return the corresponding constant value - a String, an Integer, a Float, and so on
     */
@Nullable
public Object evaluate(@Nullable UElement node) {
    if (node == null) {
        return null;
    }
    if (node instanceof ULiteralExpression) {
        return ((ULiteralExpression) node).getValue();
    } else if (node instanceof UPrefixExpression) {
        UastPrefixOperator operator = ((UPrefixExpression) node).getOperator();
        Object operand = evaluate(((UPrefixExpression) node).getOperand());
        if (operand == null) {
            return null;
        }
        if (operator == UastPrefixOperator.LOGICAL_NOT) {
            if (operand instanceof Boolean) {
                return !(Boolean) operand;
            }
        } else if (operator == UastPrefixOperator.UNARY_PLUS) {
            return operand;
        } else if (operator == UastPrefixOperator.BITWISE_NOT) {
            if (operand instanceof Integer) {
                return ~(Integer) operand;
            } else if (operand instanceof Long) {
                return ~(Long) operand;
            } else if (operand instanceof Short) {
                return ~(Short) operand;
            } else if (operand instanceof Character) {
                return ~(Character) operand;
            } else if (operand instanceof Byte) {
                return ~(Byte) operand;
            }
        } else if (operator == UastPrefixOperator.UNARY_MINUS) {
            if (operand instanceof Integer) {
                return -(Integer) operand;
            } else if (operand instanceof Long) {
                return -(Long) operand;
            } else if (operand instanceof Double) {
                return -(Double) operand;
            } else if (operand instanceof Float) {
                return -(Float) operand;
            } else if (operand instanceof Short) {
                return -(Short) operand;
            } else if (operand instanceof Character) {
                return -(Character) operand;
            } else if (operand instanceof Byte) {
                return -(Byte) operand;
            }
        }
    } else if (node instanceof UIfExpression && ((UIfExpression) node).getExpressionType() != null) {
        UIfExpression expression = (UIfExpression) node;
        Object known = evaluate(expression.getCondition());
        if (known == Boolean.TRUE && expression.getThenExpression() != null) {
            return evaluate(expression.getThenExpression());
        } else if (known == Boolean.FALSE && expression.getElseExpression() != null) {
            return evaluate(expression.getElseExpression());
        }
    } else if (node instanceof UParenthesizedExpression) {
        UParenthesizedExpression parenthesizedExpression = (UParenthesizedExpression) node;
        UExpression expression = parenthesizedExpression.getExpression();
        return evaluate(expression);
    } else if (node instanceof UBinaryExpression) {
        UastBinaryOperator operator = ((UBinaryExpression) node).getOperator();
        Object operandLeft = evaluate(((UBinaryExpression) node).getLeftOperand());
        Object operandRight = evaluate(((UBinaryExpression) node).getRightOperand());
        if (operandLeft == null || operandRight == null) {
            if (mAllowUnknown) {
                if (operandLeft == null) {
                    return operandRight;
                } else {
                    return operandLeft;
                }
            }
            return null;
        }
        if (operandLeft instanceof String && operandRight instanceof String) {
            if (operator == UastBinaryOperator.PLUS) {
                return operandLeft.toString() + operandRight.toString();
            }
            return null;
        } else if (operandLeft instanceof Boolean && operandRight instanceof Boolean) {
            boolean left = (Boolean) operandLeft;
            boolean right = (Boolean) operandRight;
            if (operator == UastBinaryOperator.LOGICAL_OR) {
                return left || right;
            } else if (operator == UastBinaryOperator.LOGICAL_AND) {
                return left && right;
            } else if (operator == UastBinaryOperator.BITWISE_OR) {
                return left | right;
            } else if (operator == UastBinaryOperator.BITWISE_XOR) {
                return left ^ right;
            } else if (operator == UastBinaryOperator.BITWISE_AND) {
                return left & right;
            } else if (operator == UastBinaryOperator.IDENTITY_EQUALS || operator == UastBinaryOperator.EQUALS) {
                return left == right;
            } else if (operator == UastBinaryOperator.IDENTITY_NOT_EQUALS || operator == UastBinaryOperator.NOT_EQUALS) {
                return left != right;
            }
        } else if (operandLeft instanceof Number && operandRight instanceof Number) {
            Number left = (Number) operandLeft;
            Number right = (Number) operandRight;
            boolean isInteger = !(left instanceof Float || left instanceof Double || right instanceof Float || right instanceof Double);
            boolean isWide = isInteger ? (left instanceof Long || right instanceof Long) : (left instanceof Double || right instanceof Double);
            if (operator == UastBinaryOperator.BITWISE_OR) {
                if (isWide) {
                    return left.longValue() | right.longValue();
                } else {
                    return left.intValue() | right.intValue();
                }
            } else if (operator == UastBinaryOperator.BITWISE_XOR) {
                if (isWide) {
                    return left.longValue() ^ right.longValue();
                } else {
                    return left.intValue() ^ right.intValue();
                }
            } else if (operator == UastBinaryOperator.BITWISE_AND) {
                if (isWide) {
                    return left.longValue() & right.longValue();
                } else {
                    return left.intValue() & right.intValue();
                }
            } else if (operator == UastBinaryOperator.EQUALS || operator == UastBinaryOperator.IDENTITY_EQUALS) {
                if (isInteger) {
                    return left.longValue() == right.longValue();
                } else {
                    return left.doubleValue() == right.doubleValue();
                }
            } else if (operator == UastBinaryOperator.NOT_EQUALS || operator == UastBinaryOperator.IDENTITY_NOT_EQUALS) {
                if (isInteger) {
                    return left.longValue() != right.longValue();
                } else {
                    return left.doubleValue() != right.doubleValue();
                }
            } else if (operator == UastBinaryOperator.GREATER) {
                if (isInteger) {
                    return left.longValue() > right.longValue();
                } else {
                    return left.doubleValue() > right.doubleValue();
                }
            } else if (operator == UastBinaryOperator.GREATER_OR_EQUALS) {
                if (isInteger) {
                    return left.longValue() >= right.longValue();
                } else {
                    return left.doubleValue() >= right.doubleValue();
                }
            } else if (operator == UastBinaryOperator.LESS) {
                if (isInteger) {
                    return left.longValue() < right.longValue();
                } else {
                    return left.doubleValue() < right.doubleValue();
                }
            } else if (operator == UastBinaryOperator.LESS_OR_EQUALS) {
                if (isInteger) {
                    return left.longValue() <= right.longValue();
                } else {
                    return left.doubleValue() <= right.doubleValue();
                }
            } else if (operator == UastBinaryOperator.SHIFT_LEFT) {
                if (isWide) {
                    return left.longValue() << right.intValue();
                } else {
                    return left.intValue() << right.intValue();
                }
            } else if (operator == UastBinaryOperator.SHIFT_RIGHT) {
                if (isWide) {
                    return left.longValue() >> right.intValue();
                } else {
                    return left.intValue() >> right.intValue();
                }
            } else if (operator == UastBinaryOperator.UNSIGNED_SHIFT_RIGHT) {
                if (isWide) {
                    return left.longValue() >>> right.intValue();
                } else {
                    return left.intValue() >>> right.intValue();
                }
            } else if (operator == UastBinaryOperator.PLUS) {
                if (isInteger) {
                    if (isWide) {
                        return left.longValue() + right.longValue();
                    } else {
                        return left.intValue() + right.intValue();
                    }
                } else {
                    if (isWide) {
                        return left.doubleValue() + right.doubleValue();
                    } else {
                        return left.floatValue() + right.floatValue();
                    }
                }
            } else if (operator == UastBinaryOperator.MINUS) {
                if (isInteger) {
                    if (isWide) {
                        return left.longValue() - right.longValue();
                    } else {
                        return left.intValue() - right.intValue();
                    }
                } else {
                    if (isWide) {
                        return left.doubleValue() - right.doubleValue();
                    } else {
                        return left.floatValue() - right.floatValue();
                    }
                }
            } else if (operator == UastBinaryOperator.MULTIPLY) {
                if (isInteger) {
                    if (isWide) {
                        return left.longValue() * right.longValue();
                    } else {
                        return left.intValue() * right.intValue();
                    }
                } else {
                    if (isWide) {
                        return left.doubleValue() * right.doubleValue();
                    } else {
                        return left.floatValue() * right.floatValue();
                    }
                }
            } else if (operator == UastBinaryOperator.DIV) {
                if (isInteger) {
                    if (isWide) {
                        return left.longValue() / right.longValue();
                    } else {
                        return left.intValue() / right.intValue();
                    }
                } else {
                    if (isWide) {
                        return left.doubleValue() / right.doubleValue();
                    } else {
                        return left.floatValue() / right.floatValue();
                    }
                }
            } else if (operator == UastBinaryOperator.MOD) {
                if (isInteger) {
                    if (isWide) {
                        return left.longValue() % right.longValue();
                    } else {
                        return left.intValue() % right.intValue();
                    }
                } else {
                    if (isWide) {
                        return left.doubleValue() % right.doubleValue();
                    } else {
                        return left.floatValue() % right.floatValue();
                    }
                }
            } else {
                return null;
            }
        }
    } else if (node instanceof UBinaryExpressionWithType && ((UBinaryExpressionWithType) node).getOperationKind() == TYPE_CAST) {
        UBinaryExpressionWithType cast = (UBinaryExpressionWithType) node;
        Object operandValue = evaluate(cast.getOperand());
        if (operandValue instanceof Number) {
            Number number = (Number) operandValue;
            PsiType type = cast.getType();
            if (PsiType.FLOAT.equals(type)) {
                return number.floatValue();
            } else if (PsiType.DOUBLE.equals(type)) {
                return number.doubleValue();
            } else if (PsiType.INT.equals(type)) {
                return number.intValue();
            } else if (PsiType.LONG.equals(type)) {
                return number.longValue();
            } else if (PsiType.SHORT.equals(type)) {
                return number.shortValue();
            } else if (PsiType.BYTE.equals(type)) {
                return number.byteValue();
            }
        }
        return operandValue;
    } else if (node instanceof UReferenceExpression) {
        PsiElement resolved = ((UReferenceExpression) node).resolve();
        if (resolved instanceof PsiVariable) {
            PsiVariable variable = (PsiVariable) resolved;
            Object value = UastLintUtils.findLastValue(variable, node, mContext, this);
            if (value != null) {
                return value;
            }
            if (variable.getInitializer() != null) {
                return evaluate(variable.getInitializer());
            }
            return null;
        }
    } else if (UastExpressionUtils.isNewArrayWithDimensions((UExpression) node)) {
        UCallExpression call = (UCallExpression) node;
        PsiType arrayType = call.getExpressionType();
        if (arrayType instanceof PsiArrayType) {
            PsiType componentType = ((PsiArrayType) arrayType).getComponentType();
            // Single-dimension array
            if (!(componentType instanceof PsiArrayType) && call.getValueArgumentCount() == 1) {
                Object lengthObj = evaluate(call.getValueArguments().get(0));
                if (lengthObj instanceof Number) {
                    int length = ((Number) lengthObj).intValue();
                    if (length > 30) {
                        length = 30;
                    }
                    if (componentType == PsiType.BOOLEAN) {
                        return new boolean[length];
                    } else if (isObjectType(componentType)) {
                        return new Object[length];
                    } else if (componentType == PsiType.CHAR) {
                        return new char[length];
                    } else if (componentType == PsiType.BYTE) {
                        return new byte[length];
                    } else if (componentType == PsiType.DOUBLE) {
                        return new double[length];
                    } else if (componentType == PsiType.FLOAT) {
                        return new float[length];
                    } else if (componentType == PsiType.INT) {
                        return new int[length];
                    } else if (componentType == PsiType.SHORT) {
                        return new short[length];
                    } else if (componentType == PsiType.LONG) {
                        return new long[length];
                    } else if (isStringType(componentType)) {
                        return new String[length];
                    }
                }
            }
        }
    } else if (UastExpressionUtils.isNewArrayWithInitializer(node)) {
        UCallExpression call = (UCallExpression) node;
        PsiType arrayType = call.getExpressionType();
        if (arrayType instanceof PsiArrayType) {
            PsiType componentType = ((PsiArrayType) arrayType).getComponentType();
            // Single-dimension array
            if (!(componentType instanceof PsiArrayType)) {
                int length = call.getValueArgumentCount();
                List<Object> evaluatedArgs = new ArrayList<Object>(length);
                for (UExpression arg : call.getValueArguments()) {
                    Object evaluatedArg = evaluate(arg);
                    if (!mAllowUnknown && evaluatedArg == null) {
                        // Inconclusive
                        return null;
                    }
                    evaluatedArgs.add(evaluatedArg);
                }
                if (componentType == PsiType.BOOLEAN) {
                    boolean[] arr = new boolean[length];
                    for (int i = 0; i < length; ++i) {
                        Object o = evaluatedArgs.get(i);
                        if (o instanceof Boolean) {
                            arr[i] = (Boolean) o;
                        }
                    }
                    return arr;
                } else if (isObjectType(componentType)) {
                    Object[] arr = new Object[length];
                    for (int i = 0; i < length; ++i) {
                        arr[i] = evaluatedArgs.get(i);
                    }
                    return arr;
                } else if (componentType.equals(PsiType.CHAR)) {
                    char[] arr = new char[length];
                    for (int i = 0; i < length; ++i) {
                        Object o = evaluatedArgs.get(i);
                        if (o instanceof Character) {
                            arr[i] = (Character) o;
                        }
                    }
                    return arr;
                } else if (componentType.equals(PsiType.BYTE)) {
                    byte[] arr = new byte[length];
                    for (int i = 0; i < length; ++i) {
                        Object o = evaluatedArgs.get(i);
                        if (o instanceof Byte) {
                            arr[i] = (Byte) o;
                        }
                    }
                    return arr;
                } else if (componentType.equals(PsiType.DOUBLE)) {
                    double[] arr = new double[length];
                    for (int i = 0; i < length; ++i) {
                        Object o = evaluatedArgs.get(i);
                        if (o instanceof Double) {
                            arr[i] = (Double) o;
                        }
                    }
                    return arr;
                } else if (componentType.equals(PsiType.FLOAT)) {
                    float[] arr = new float[length];
                    for (int i = 0; i < length; ++i) {
                        Object o = evaluatedArgs.get(i);
                        if (o instanceof Float) {
                            arr[i] = (Float) o;
                        }
                    }
                    return arr;
                } else if (componentType.equals(PsiType.INT)) {
                    int[] arr = new int[length];
                    for (int i = 0; i < length; ++i) {
                        Object o = evaluatedArgs.get(i);
                        if (o instanceof Integer) {
                            arr[i] = (Integer) o;
                        }
                    }
                    return arr;
                } else if (componentType.equals(PsiType.SHORT)) {
                    short[] arr = new short[length];
                    for (int i = 0; i < length; ++i) {
                        Object o = evaluatedArgs.get(i);
                        if (o instanceof Short) {
                            arr[i] = (Short) o;
                        }
                    }
                    return arr;
                } else if (componentType.equals(PsiType.LONG)) {
                    long[] arr = new long[length];
                    for (int i = 0; i < length; ++i) {
                        Object o = evaluatedArgs.get(i);
                        if (o instanceof Long) {
                            arr[i] = (Long) o;
                        }
                    }
                    return arr;
                } else if (isStringType(componentType)) {
                    String[] arr = new String[length];
                    for (int i = 0; i < length; ++i) {
                        Object o = evaluatedArgs.get(i);
                        if (o instanceof String) {
                            arr[i] = (String) o;
                        }
                    }
                    return arr;
                }
            }
        }
    }
    if (node instanceof UExpression) {
        Object evaluated = ((UExpression) node).evaluate();
        if (evaluated != null) {
            return evaluated;
        }
    }
    return null;
}
Also used : ArrayList(java.util.ArrayList) PsiArrayType(com.intellij.psi.PsiArrayType) PsiElement(com.intellij.psi.PsiElement) PsiType(com.intellij.psi.PsiType) PsiVariable(com.intellij.psi.PsiVariable) UReferenceExpression(org.jetbrains.uast.UReferenceExpression) Nullable(com.android.annotations.Nullable)

Aggregations

PsiArrayType (com.intellij.psi.PsiArrayType)9 PsiType (com.intellij.psi.PsiType)7 PsiElement (com.intellij.psi.PsiElement)3 PsiExpression (com.intellij.psi.PsiExpression)3 Nullable (com.android.annotations.Nullable)2 LookupElement (com.intellij.codeInsight.lookup.LookupElement)2 PsiTypeLookupItem (com.intellij.codeInsight.lookup.PsiTypeLookupItem)2 PsiAssignmentExpression (com.intellij.psi.PsiAssignmentExpression)2 PsiClassType (com.intellij.psi.PsiClassType)2 PsiDeclarationStatement (com.intellij.psi.PsiDeclarationStatement)2 PsiExpressionStatement (com.intellij.psi.PsiExpressionStatement)2 PsiField (com.intellij.psi.PsiField)2 PsiLocalVariable (com.intellij.psi.PsiLocalVariable)2 PsiNewExpression (com.intellij.psi.PsiNewExpression)2 PsiParenthesizedExpression (com.intellij.psi.PsiParenthesizedExpression)2 PsiReference (com.intellij.psi.PsiReference)2 PsiReferenceExpression (com.intellij.psi.PsiReferenceExpression)2 PsiStatement (com.intellij.psi.PsiStatement)2 PsiTypeCastExpression (com.intellij.psi.PsiTypeCastExpression)2 PsiTypeElement (com.intellij.psi.PsiTypeElement)2