/**
* Copyright 2004-2016 Riccardo Solmi. All rights reserved.
* This file is part of the Whole Platform.
*
* The Whole Platform is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Whole Platform is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whole.lang.java.reflect;
import org.whole.lang.exceptions.WholeIllegalArgumentException;
import org.whole.lang.java.model.InfixExpression;
import org.whole.lang.java.model.InfixOperatorEnum;
import org.whole.lang.model.EnumType;
import org.whole.lang.model.EnumValueImpl;
import org.whole.lang.model.IEntity;
import org.whole.lang.util.WholeMessages;
/**
* @author Giovanni De Facci
*/
public class OperatorGroupEnum extends EnumType<OperatorGroupEnum.OperatorGroup> {
public static final int LITERAL_ord = 0;
/**
* ++ post-increment
* -- post-decrement
*/
public static final int POSTFIX_ord = 1;
/**
* ++ pre-increment
* -- pre-decrement
* + unary plus
* - unary minus
* ! logical NOT
* ~ bitwise NOT
*/
public static final int PREFIX_ord = 2;
public static final int CREATION_CAST_ord = 3; // new (type)
public static final int MULTIPLICATIVE_ord = 4; // * / %
public static final int ADDITIVE_ord = 5; // + -
/**
* << >> shift
* >>>
*/
public static final int SHIFT_ord = 6; // + -
public static final int RELATIONAL_ord = 7; // < > <= >= instanceof
public static final int EQUALITY_ord = 8; // == !=
public static final int BITWISE_AND_ord = 9; // &
public static final int BITWISE_XOR_ord = 10; // ^
public static final int BITWISE_OR_ord = 11; // |
public static final int LOGICAL_AND_ord = 12; // &&
public static final int LOGICAL_OR_ord = 13; // ||
public static final int CONDITIONAL_ord = 14; // ?:
/**
* = += -=
* *= /= %=
* &= ^= |=
* <<= >>= >>>=
*/
public static final int ASSIGNMENT_ord = 15;
public static final OperatorGroupEnum instance = new OperatorGroupEnum();
public static final OperatorGroup LITERAL = instance.valueOf(LITERAL_ord);
public static final OperatorGroup POSTFIX = instance.valueOf(POSTFIX_ord);
public static final OperatorGroup PREFIX = instance.valueOf(PREFIX_ord);
public static final OperatorGroup CREATION_CAST = instance.valueOf(CREATION_CAST_ord);
public static final OperatorGroup MULTIPLICATIVE = instance.valueOf(MULTIPLICATIVE_ord);
public static final OperatorGroup ADDITIVE = instance.valueOf(ADDITIVE_ord);
public static final OperatorGroup SHIFT = instance.valueOf(SHIFT_ord);
public static final OperatorGroup RELATIONAL = instance.valueOf(RELATIONAL_ord);
public static final OperatorGroup EQUALITY = instance.valueOf(EQUALITY_ord);
public static final OperatorGroup BITWISE_AND = instance.valueOf(BITWISE_AND_ord);
public static final OperatorGroup BITWISE_XOR = instance.valueOf(BITWISE_XOR_ord);
public static final OperatorGroup BITWISE_OR = instance.valueOf(BITWISE_OR_ord);
/**
* FIXME: consider using "CONDITIONAL_" prefix instead of "LOGICAL_" prefix to keep consistent with org.whole.lang.java.model.InfixOperatorEnum
*/
public static final OperatorGroup LOGICAL_AND = instance.valueOf(LOGICAL_AND_ord);
/**
* FIXME: consider using "CONDITIONAL_" prefix instead of "LOGICAL_" prefix to keep consistent with org.whole.lang.java.model.InfixOperatorEnum
*/
public static final OperatorGroup LOGICAL_OR = instance.valueOf(LOGICAL_OR_ord);
public static final OperatorGroup CONDITIONAL = instance.valueOf(CONDITIONAL_ord);
public static final OperatorGroup ASSIGNMENT = instance.valueOf(ASSIGNMENT_ord);
private OperatorGroupEnum() {
enumValue(LITERAL_ord, "LITERAL");
enumValue(POSTFIX_ord, "POSTFIX");
enumValue(PREFIX_ord, "UNARY");
enumValue(CREATION_CAST_ord, "CREATION_CAST");
enumValue(MULTIPLICATIVE_ord, "MULTIPLICATIVE");
enumValue(ADDITIVE_ord, "ADDITIVE");
enumValue(SHIFT_ord, "SHIFT");
enumValue(RELATIONAL_ord, "RELATIONAL");
enumValue(EQUALITY_ord, "EQUALITY");
enumValue(BITWISE_AND_ord, "BITWISE_AND");
enumValue(BITWISE_XOR_ord, "BITWISE_XOR");
enumValue(BITWISE_OR_ord , "BITWISE_OR" );
enumValue(LOGICAL_AND_ord, "LOGICAL_AND");
enumValue(LOGICAL_OR_ord, "LOGICAL_OR");
enumValue(CONDITIONAL_ord, "CONDITIONAL");
enumValue(ASSIGNMENT_ord, "ASSIGNMENT");
}
public OperatorGroup valueOf(IEntity entity) {
switch (entity.wGetEntityOrd()) {
case JavaEntityDescriptorEnum.PostfixExpression_ord:
return POSTFIX;
case JavaEntityDescriptorEnum.PrefixExpression_ord:
return PREFIX;
case JavaEntityDescriptorEnum.InfixExpression_ord:
switch (((InfixExpression) entity).getOperator().getValue().getOrdinal()) {
case InfixOperatorEnum .times_ord:
case InfixOperatorEnum .divide_ord:
case InfixOperatorEnum .remainder_ord:
return MULTIPLICATIVE;
case InfixOperatorEnum .plus_ord:
case InfixOperatorEnum .minus_ord:
return ADDITIVE;
case InfixOperatorEnum .left_shift_ord:
case InfixOperatorEnum .right_shift_signed_ord:
case InfixOperatorEnum .right_shift_unsigned_ord:
return SHIFT;
case InfixOperatorEnum .less_ord:
case InfixOperatorEnum .less_equals_ord:
case InfixOperatorEnum .greater_ord:
case InfixOperatorEnum .greater_equals_ord:
return RELATIONAL;
case InfixOperatorEnum .equals_ord:
case InfixOperatorEnum .not_equals_ord:
return EQUALITY;
case InfixOperatorEnum .and_ord:
return BITWISE_AND;
case InfixOperatorEnum .xor_ord:
return BITWISE_XOR;
case InfixOperatorEnum .or_ord:
return BITWISE_OR;
case InfixOperatorEnum .conditional_and_ord:
return LOGICAL_AND;
case InfixOperatorEnum .conditional_or_ord:
return LOGICAL_OR;
default:
throw new WholeIllegalArgumentException(WholeMessages.no_data);
}
case JavaEntityDescriptorEnum.Assignment_ord:
return ASSIGNMENT;
default:
return LITERAL;
}
}
public static boolean hasUnknownOperator(IEntity entity) {
return entity.wGetEntityDescriptor().has(JavaFeatureDescriptorEnum.operator) &&
!JavaLanguageKit.URI.equals(entity.wGet(JavaFeatureDescriptorEnum.operator).wGetLanguageKit().getURI());
}
public static boolean hasPrecedence(IEntity e1, IEntity e2) {
if (!JavaLanguageKit.URI.equals(e2.wGetLanguageKit().getURI()))
return !e2.wGetEntityKind().isData();
else if (hasUnknownOperator(e2))
return true;
else if (hasUnknownOperator(e1))
return false;
return instance.valueOf(e1).hasPrecedence(instance.valueOf(e2));
}
private static final long serialVersionUID = 1;
protected void enumValue(int ordinal, String name) {
if (valueOf(name) == null)
putEnumValue(new OperatorGroup(ordinal, name));
}
public static class OperatorGroup extends EnumValueImpl {
private static final long serialVersionUID = 1L;
public OperatorGroup() {
super();
}
public OperatorGroup(int ordinal, String name) {
super(ordinal, name);
}
public boolean hasPrecedence(OperatorGroup op) {
return getOrdinal() < op.getOrdinal();
}
}
}