/** * Copyright 2011-2017 Asakusa Framework Team. * * 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 com.asakusafw.utils.java.internal.model.util; import com.asakusafw.utils.java.model.syntax.ArrayCreationExpression; import com.asakusafw.utils.java.model.syntax.Expression; import com.asakusafw.utils.java.model.syntax.InfixExpression; import com.asakusafw.utils.java.model.syntax.InfixOperator; /** * Represents an association priorities in expressions. */ public enum ExpressionPriority { /** * The primary expressions. */ PRIMARY, /** * The array initializers. */ ARRAY_INITIALIZER, /** * The unary operators. */ UNARY, /** * The cast operators. */ CAST, /** * The multiplicative (multiply, division, and remainder) operators. */ MULTIPLICATIVE, /** * The additive (add and subtract) operators. */ ADDITIVE, /** * The shift operators. */ SHIFT, /** * The comparison operators. */ RELATIONAL, /** * The equality operators. */ EQUALITY, /** * The logical operators. */ LOGICAL, /** * The conditional {@code and} operators. */ CONDITIONAL_AND, /** * The conditional {@code or} operators. */ CONDITIONAL_OR, /** * The conditional operators. */ CONDITIONAL, /** * The assignment operators. */ ASSIGNMENT, ; /** * Returns the priority about the target infix operator. * @param operator the infix operator * @return the corresponded priority * @throws IllegalArgumentException if the parameter is {@code null} */ public static ExpressionPriority valueOf(InfixOperator operator) { if (operator == null) { throw new IllegalArgumentException("operator must not be null"); //$NON-NLS-1$ } switch (operator) { case TIMES: case DIVIDE: case REMAINDER: return MULTIPLICATIVE; case PLUS: case MINUS: return ADDITIVE; case LEFT_SHIFT: case RIGHT_SHIFT_SIGNED: case RIGHT_SHIFT_UNSIGNED: return SHIFT; case GREATER: case GREATER_EQUALS: case LESS: case LESS_EQUALS: return RELATIONAL; case EQUALS: case NOT_EQUALS: return EQUALITY; case AND: case OR: case XOR: return LOGICAL; case CONDITIONAL_AND: return CONDITIONAL_AND; case CONDITIONAL_OR: return CONDITIONAL_OR; default: throw new IllegalArgumentException(operator.toString()); } } /** * Returns the priority about the target expression. * @param expression the target expression * @return the corresponded priority * @throws IllegalArgumentException if the parameter is {@code null} */ public static ExpressionPriority valueOf(Expression expression) { if (expression == null) { throw new IllegalArgumentException("expression must not be null"); //$NON-NLS-1$ } switch (expression.getModelKind()) { case ARRAY_CREATION_EXPRESSION: if (((ArrayCreationExpression) expression).getArrayInitializer() == null) { return PRIMARY; } else { return ARRAY_INITIALIZER; } case ASSIGNMENT_EXPRESSION: return ASSIGNMENT; case CAST_EXPRESSION: return CAST; case CONDITIONAL_EXPRESSION: return CONDITIONAL; case INFIX_EXPRESSION: return valueOf(((InfixExpression) expression).getOperator()); case INSTANCEOF_EXPRESSION: return RELATIONAL; case POSTFIX_EXPRESSION: return UNARY; case UNARY_EXPRESSION: return UNARY; default: return PRIMARY; } } /** * Returns whether parentheses are required for comparing the priorities or not. * @param required the required priority * @param requiredInRight {@code true} if the required priority appears in the right term of infix expressions, * otherwise {@code false} * @param priority the target priority * @return {@code true} if parentheses are required, otherwise {@code false} * @throws IllegalArgumentException if the parameters are {@code null} */ public static boolean isParenthesesRequired( ExpressionPriority required, boolean requiredInRight, ExpressionPriority priority) { if (required == null) { throw new IllegalArgumentException("required must not be null"); //$NON-NLS-1$ } if (priority == null) { throw new NullPointerException("required must not be null"); //$NON-NLS-1$ } int contextOrder = required.ordinal() * 2; int priorityOrder = priority.ordinal() * 2; if (requiredInRight) { contextOrder--; } return (contextOrder < priorityOrder); } }