/* * Copyright (c) 2007 BUSINESS OBJECTS SOFTWARE LIMITED * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Business Objects nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * JavaOperator.java * Creation date: Sep 10, 2003. * By: Edward Lam */ package org.openquark.cal.internal.javamodel; import java.util.Arrays; import java.util.HashSet; import java.util.Set; /** * An enum class to provide object representations of symbolic Java operators. * * @author Edward Lam */ public final class JavaOperator { // Unary arithmetic operator: - ("+" not supported for now) public static final JavaOperator NEGATE_INT = new JavaOperator("-", JavaTypeName.INT); public static final JavaOperator NEGATE_DOUBLE = new JavaOperator("-", JavaTypeName.DOUBLE); public static final JavaOperator NEGATE_FLOAT = new JavaOperator("-", JavaTypeName.FLOAT); public static final JavaOperator NEGATE_LONG = new JavaOperator("-", JavaTypeName.LONG); // Binary arithmetic operators: + - * / % public static final JavaOperator ADD_INT = new JavaOperator("+", JavaTypeName.INT); public static final JavaOperator ADD_DOUBLE = new JavaOperator("+", JavaTypeName.DOUBLE); public static final JavaOperator ADD_LONG = new JavaOperator("+", JavaTypeName.LONG); public static final JavaOperator ADD_FLOAT = new JavaOperator("+", JavaTypeName.FLOAT); public static final JavaOperator SUBTRACT_INT = new JavaOperator("-", JavaTypeName.INT); public static final JavaOperator SUBTRACT_DOUBLE = new JavaOperator("-", JavaTypeName.DOUBLE); public static final JavaOperator SUBTRACT_LONG = new JavaOperator("-", JavaTypeName.LONG); public static final JavaOperator SUBTRACT_FLOAT = new JavaOperator("-", JavaTypeName.FLOAT); public static final JavaOperator MULTIPLY_INT = new JavaOperator("*", JavaTypeName.INT); public static final JavaOperator MULTIPLY_DOUBLE = new JavaOperator("*", JavaTypeName.DOUBLE); public static final JavaOperator MULTIPLY_LONG = new JavaOperator("*", JavaTypeName.LONG); public static final JavaOperator MULTIPLY_FLOAT = new JavaOperator("*", JavaTypeName.FLOAT); public static final JavaOperator DIVIDE_INT = new JavaOperator("/", JavaTypeName.INT); public static final JavaOperator DIVIDE_DOUBLE = new JavaOperator("/", JavaTypeName.DOUBLE); public static final JavaOperator DIVIDE_LONG = new JavaOperator("/", JavaTypeName.LONG); public static final JavaOperator DIVIDE_FLOAT = new JavaOperator("/", JavaTypeName.FLOAT); public static final JavaOperator REM_INT = new JavaOperator("%", JavaTypeName.INT); public static final JavaOperator REM_LONG = new JavaOperator("%", JavaTypeName.LONG); public static final JavaOperator REM_DOUBLE = new JavaOperator("%", JavaTypeName.DOUBLE); public static final JavaOperator REM_FLOAT = new JavaOperator("%", JavaTypeName.FLOAT); // Relational operators: > >= < <= == != public static final JavaOperator GREATER_THAN_INT = new JavaOperator(">", JavaTypeName.INT); public static final JavaOperator GREATER_THAN_DOUBLE = new JavaOperator(">", JavaTypeName.DOUBLE); public static final JavaOperator GREATER_THAN_LONG = new JavaOperator(">", JavaTypeName.LONG); public static final JavaOperator GREATER_THAN_CHAR = new JavaOperator(">", JavaTypeName.CHAR); public static final JavaOperator GREATER_THAN_EQUALS_INT = new JavaOperator(">=", JavaTypeName.INT); public static final JavaOperator GREATER_THAN_EQUALS_DOUBLE = new JavaOperator(">=", JavaTypeName.DOUBLE); public static final JavaOperator GREATER_THAN_EQUALS_LONG = new JavaOperator(">=", JavaTypeName.LONG); public static final JavaOperator GREATER_THAN_EQUALS_CHAR = new JavaOperator(">=", JavaTypeName.CHAR); public static final JavaOperator LESS_THAN_INT = new JavaOperator("<", JavaTypeName.INT); public static final JavaOperator LESS_THAN_DOUBLE = new JavaOperator("<", JavaTypeName.DOUBLE); public static final JavaOperator LESS_THAN_LONG = new JavaOperator("<", JavaTypeName.LONG); public static final JavaOperator LESS_THAN_CHAR = new JavaOperator("<", JavaTypeName.CHAR); public static final JavaOperator LESS_THAN_EQUALS_INT = new JavaOperator("<=", JavaTypeName.INT); public static final JavaOperator LESS_THAN_EQUALS_DOUBLE = new JavaOperator("<=", JavaTypeName.DOUBLE); public static final JavaOperator LESS_THAN_EQUALS_LONG = new JavaOperator("<=", JavaTypeName.LONG); public static final JavaOperator LESS_THAN_EQUALS_CHAR = new JavaOperator("<=", JavaTypeName.CHAR); public static final JavaOperator EQUALS_INT = new JavaOperator("==", JavaTypeName.INT); public static final JavaOperator EQUALS_DOUBLE = new JavaOperator("==", JavaTypeName.DOUBLE); public static final JavaOperator EQUALS_LONG = new JavaOperator("==", JavaTypeName.LONG); public static final JavaOperator EQUALS_CHAR = new JavaOperator("==", JavaTypeName.CHAR); public static final JavaOperator EQUALS_OBJECT = new JavaOperator("==", JavaTypeName.OBJECT); public static final JavaOperator NOT_EQUALS_INT = new JavaOperator("!=", JavaTypeName.INT); public static final JavaOperator NOT_EQUALS_DOUBLE = new JavaOperator("!=", JavaTypeName.DOUBLE); public static final JavaOperator NOT_EQUALS_LONG = new JavaOperator("!=", JavaTypeName.LONG); public static final JavaOperator NOT_EQUALS_CHAR = new JavaOperator("!=", JavaTypeName.CHAR); public static final JavaOperator NOT_EQUALS_OBJECT = new JavaOperator("!=", JavaTypeName.OBJECT); public static final JavaOperator GREATER_THAN_SHORT = new JavaOperator(">", JavaTypeName.SHORT); public static final JavaOperator GREATER_THAN_EQUALS_SHORT = new JavaOperator(">=", JavaTypeName.SHORT); public static final JavaOperator LESS_THAN_SHORT = new JavaOperator("<", JavaTypeName.SHORT); public static final JavaOperator LESS_THAN_EQUALS_SHORT = new JavaOperator("<=", JavaTypeName.SHORT); public static final JavaOperator EQUALS_SHORT = new JavaOperator("==", JavaTypeName.SHORT); public static final JavaOperator NOT_EQUALS_SHORT = new JavaOperator("!=", JavaTypeName.SHORT); public static final JavaOperator GREATER_THAN_BYTE = new JavaOperator(">", JavaTypeName.BYTE); public static final JavaOperator GREATER_THAN_EQUALS_BYTE = new JavaOperator(">=", JavaTypeName.BYTE); public static final JavaOperator LESS_THAN_BYTE = new JavaOperator("<", JavaTypeName.BYTE); public static final JavaOperator LESS_THAN_EQUALS_BYTE = new JavaOperator("<=", JavaTypeName.BYTE); public static final JavaOperator EQUALS_BYTE = new JavaOperator("==", JavaTypeName.BYTE); public static final JavaOperator NOT_EQUALS_BYTE = new JavaOperator("!=", JavaTypeName.BYTE); public static final JavaOperator GREATER_THAN_FLOAT = new JavaOperator(">", JavaTypeName.FLOAT); public static final JavaOperator GREATER_THAN_EQUALS_FLOAT = new JavaOperator(">=", JavaTypeName.FLOAT); public static final JavaOperator LESS_THAN_FLOAT = new JavaOperator("<", JavaTypeName.FLOAT); public static final JavaOperator LESS_THAN_EQUALS_FLOAT = new JavaOperator("<=", JavaTypeName.FLOAT); public static final JavaOperator EQUALS_FLOAT = new JavaOperator("==", JavaTypeName.FLOAT); public static final JavaOperator NOT_EQUALS_FLOAT = new JavaOperator("!=", JavaTypeName.FLOAT); // Logical operators: & | ^ ! && || public static final JavaOperator LOGICAL_NEGATE = new JavaOperator("!", JavaTypeName.BOOLEAN); // unary public static final JavaOperator CONDITIONAL_AND = new JavaOperator("&&", JavaTypeName.BOOLEAN); public static final JavaOperator CONDITIONAL_OR = new JavaOperator("||", JavaTypeName.BOOLEAN); // binary bitwise operators: & | ^ public static final JavaOperator BITWISE_AND_INT = new JavaOperator ("&", JavaTypeName.INT); public static final JavaOperator BITWISE_OR_INT = new JavaOperator ("|", JavaTypeName.INT); public static final JavaOperator BITWISE_XOR_INT = new JavaOperator ("^", JavaTypeName.INT); public static final JavaOperator SHIFTL_INT = new JavaOperator ("<<", JavaTypeName.INT); public static final JavaOperator SHIFTR_INT = new JavaOperator (">>", JavaTypeName.INT); public static final JavaOperator SHIFTR_UNSIGNED_INT = new JavaOperator (">>>", JavaTypeName.INT); public static final JavaOperator BITWISE_AND_LONG = new JavaOperator ("&", JavaTypeName.LONG); public static final JavaOperator BITWISE_OR_LONG = new JavaOperator ("|", JavaTypeName.LONG); public static final JavaOperator BITWISE_XOR_LONG = new JavaOperator ("^", JavaTypeName.LONG); public static final JavaOperator SHIFTL_LONG = new JavaOperator ("<<", JavaTypeName.LONG); public static final JavaOperator SHIFTR_LONG = new JavaOperator (">>", JavaTypeName.LONG); public static final JavaOperator SHIFTR_UNSIGNED_LONG = new JavaOperator (">>>", JavaTypeName.LONG); // unary bit operator ~ public static final JavaOperator COMPLEMENT_INT = new JavaOperator ("~", JavaTypeName.INT); public static final JavaOperator COMPLEMENT_LONG = new JavaOperator ("~", JavaTypeName.LONG); // ternary operator: ?: // note: can't use string form in source. Also, operands can be any object or primitive (as long as their types match). public static final JavaOperator TERNARY = new JavaOperator("?:", JavaTypeName.OBJECT); // string concatenation: + public static final JavaOperator STRING_CONCATENATION = new JavaOperator("+", JavaTypeName.STRING); /** Set of String representing arithmetic symbols * Since this set is only mutated by code in the static initialization block * it isn't synchronized. If, however, the map is ever mutated by code outside * the static initilization block it will need to be synchronized. */ private static Set<String> arithmeticSymbols = new HashSet<String>(); /** Set of String representing relational symbols * Since this set is only mutated by code in the static initialization block * it isn't synchronized. If, however, the map is ever mutated by code outside * the static initilization block it will need to be synchronized. */ private static Set<String> relationalSymbols = new HashSet<String>(); /** Set of String representing logical symbols * Since this set is only mutated by code in the static initialization block * it isn't synchronized. If, however, the map is ever mutated by code outside * the static initilization block it will need to be synchronized. */ private static Set<String> logicalSymbols = new HashSet<String>(); /** Set of String representing bit operation symbols * Since this set is only mutated by code in the static initialization block * it isn't synchronized. If, however, the map is ever mutated by code outside * the static initilization block it will need to be synchronized. */ private static Set<String> bitOpSymbols = new HashSet<String>(); static { //warning: do not add ++ or -- here. Because of their side effects, they are not //true operators and should not be treated as subclasses of JavaExpression.OperatorExpression. arithmeticSymbols.addAll(Arrays.asList(new String[] {"+", "-", "*", "/", "%"})); relationalSymbols.addAll(Arrays.asList(new String[] {">", ">=", "<", "<=", "==", "!="})); logicalSymbols.addAll(Arrays.asList(new String[] {"!", "&&", "||"})); bitOpSymbols.addAll (Arrays.asList (new String[]{"&", "|", "^", "~", "<<", ">>", ">>>"})); GREATER_THAN_INT.notComposedOperator = LESS_THAN_EQUALS_INT; GREATER_THAN_EQUALS_INT.notComposedOperator = LESS_THAN_INT; LESS_THAN_INT.notComposedOperator = GREATER_THAN_EQUALS_INT; LESS_THAN_EQUALS_INT.notComposedOperator = GREATER_THAN_INT; EQUALS_INT.notComposedOperator = NOT_EQUALS_INT; NOT_EQUALS_INT.notComposedOperator = EQUALS_INT; GREATER_THAN_CHAR.notComposedOperator = LESS_THAN_EQUALS_CHAR; GREATER_THAN_EQUALS_CHAR.notComposedOperator = LESS_THAN_CHAR; LESS_THAN_CHAR.notComposedOperator = GREATER_THAN_EQUALS_CHAR; LESS_THAN_EQUALS_CHAR.notComposedOperator = GREATER_THAN_CHAR; EQUALS_CHAR.notComposedOperator = NOT_EQUALS_CHAR; NOT_EQUALS_CHAR.notComposedOperator = EQUALS_CHAR; GREATER_THAN_LONG.notComposedOperator = LESS_THAN_EQUALS_LONG; GREATER_THAN_EQUALS_LONG.notComposedOperator = LESS_THAN_LONG; LESS_THAN_LONG.notComposedOperator = GREATER_THAN_EQUALS_LONG; LESS_THAN_EQUALS_LONG.notComposedOperator = GREATER_THAN_LONG; EQUALS_LONG.notComposedOperator = NOT_EQUALS_LONG; NOT_EQUALS_LONG.notComposedOperator = EQUALS_LONG; //do not add the double comparison operators here!!! They don't work for NAN. EQUALS_DOUBLE.notComposedOperator = NOT_EQUALS_DOUBLE; NOT_EQUALS_DOUBLE.notComposedOperator = EQUALS_DOUBLE; EQUALS_OBJECT.notComposedOperator = NOT_EQUALS_OBJECT; NOT_EQUALS_OBJECT.notComposedOperator = EQUALS_OBJECT; } /** The type of the values operated on by the operator. */ private final JavaTypeName valueType; /** The symbol for the operator used in source. */ private final String symbol; /** the operator that you get composing this operator with null, or null if there is none such */ private JavaOperator notComposedOperator; /** * Constructor for a JavaOperator * @param symbol the symbol for the operator used in source. * @param valueType the type of the operator. */ private JavaOperator(String symbol, JavaTypeName valueType) { if (symbol == null || valueType == null) { throw new IllegalArgumentException ("Unable to create JavaOperator: null argument."); } this.valueType = valueType; this.symbol = symbol; } /** * {@inheritDoc} */ @Override public String toString() { return "JavaOperator: " + symbol + ". Value type: " + valueType; } /** * Get the symbol for the operator used in source. * @return String */ public String getSymbol() { return symbol; } /** * @return JavaTypeName The type of the values operated on by the operator. */ public JavaTypeName getValueType() { return valueType; } /** * Return whether this operator is an arithmetic operator. * @return boolean */ public boolean isArithmeticOp() { return arithmeticSymbols.contains(symbol) && !valueType.equals(JavaTypeName.STRING); } /** * Return whether this operator is a relational operator. * @return boolean */ public boolean isRelationalOp() { return relationalSymbols.contains(symbol); } /** * Return whether this operator is a logical operator. * @return boolean */ public boolean isLogicalOp() { return logicalSymbols.contains(symbol); } /** * Return whether this operator is a logical operator. * @return boolean */ public boolean isBitOp () { return bitOpSymbols.contains(symbol); } /** * For example, the notComposed operator for LESS_THAN_INT is GREATER_THAN_EQUALS since * not (x < y) is equals to x >= y for all x, y that are ints. * * It is not the case that the notComposed operator for LESS_THAN_DOUBLE is GREATER_THAN_DOUBLE since * the above equation does not hold for NAN. For example, not (NAN < 0.0) is true while NAN >= 0.0 is false. * * @return the operator composed with not, or null if there is no such operator. */ public JavaOperator getNotComposedOperator() { return notComposedOperator; } }