java interface
Было бы неплохо поконкретнее описать ваши А,Б, что делает doA, что - doB.
А то пока что под ваше описание подходит интерфейс, скажем List. doA это add(Object), doB это get(int), и реализации - ArrayList и LinkedList. SomethingA в список добавляет, SomethingB - читает. Всё разумно.
я могу выложить два этих класса, но они большие.
тебе нужно в методе интерфейса передать параметр класса Object, а в имплементации в каждом классе сделать фильтр на тип объекта...
вы имеете ввиду скастовать нужный объект? тогда вся история с интерфейсом теряет свой смысл
Можете просто скопировать и вставить текст. Или разместите ссылку на файлообменник, например Яндекс-Диск.
Generic можно было бы использовать, если бы методы были одинаковые.
public interface TestInterface<T> {
public void a(T value);
}
public class TestImplA implements TestInterface<BigInteger> {
@Override
public void a(BigInteger value) { }}
Но тут названия методов отличаются, в первом случае А, а во втором - B:
public class A implements TestInterface{
public A(BigInteger value){
System.out.println("This is A");
}
}public class B implements TestInterface{
public B(BigDecimal value){
System.out.println("This is B");
}
}
Архитектура явно кривая, грубо нарушено Single Responsibility Rule, классы огромные итд. Необходимо разбить интерфейс на несколько, с использованием дженериков, выделить отдельные классы и так далее. Толку от использования общего интерфейса, если методы все равно разные, и по идее впоследствии в коде нужно будет делать проверки при их вызове в зависимости от аргумента?
TestInterface worker = TestInterfaceFactory.getTestInterface(value);
if (value instanceof BigInteger) {
worker.a(value);
} elseif (value instanceof BigDecimal) {
worker.b(value);
} else {
...
Но в любом разе решение - это фабрика:
public class TestInterfaceFactory {
public static TestInterface getInstance(Object value) {if (value instanceof BigInteger) {return new TestImplA();} else if (value instanceof BigDecimal) {return new TestImplB();} else {throw new IllegalArgumentException("unsopported value type");}}}
вот что я пока написал только для одного класса:
1) интерфейс
public interface NumberInterface {
public NumberInterface EMPTY();
public NumberInterface UNBOUND();
public NumberInterface BOOLEAN_INTERVAL();
public NumberInterface ZERO();
public NumberInterface ONE();
public boolean intersects(NumberInterface other);
public Number getLow();
public Number getHigh();
public boolean isGreaterThan(NumberInterface other);
public boolean isGreaterOrEqualThan(NumberInterface other);
public NumberInterface plus(NumberInterface interval);
public NumberInterface minus(NumberInterface other);
public NumberInterface times(NumberInterface other);
public NumberInterface divide(NumberInterface other);
public NumberInterface shiftLeft(NumberInterface offset);
public NumberInterface shiftRight(NumberInterface offset);
public NumberInterface modulo(NumberInterface other);
public boolean isUnbound();
public NumberInterface union(NumberInterface other) ;
public boolean contains(NumberInterface other);
public boolean isEmpty();
public NumberInterface negate();
// public
NumberInterface createUpperBoundedInterval(Long upperBound);
// public NumberInterface createLowerBoundedInterval(Long lowerBound);
public NumberInterface intersect(NumberInterface other);
public NumberInterface limitUpperBoundBy(NumberInterface other);
public NumberInterface limitLowerBoundBy(NumberInterface other);
}
класс который его имплеменитирует
public class IntegerInterval implements NumberInterface {
/**
* the lower bound of the interval
*/
private final Long low;
/**
* the upper bound of the interval
*/
private final Long high;
private static final IntegerInterval EMPTY = new IntegerInterval(null, null);
public static final IntegerInterval UNBOUND = new IntegerInterval(Long.MIN_VALUE, Long.MAX_VALUE);
public static final IntegerInterval BOOLEAN_INTERVAL = new IntegerInterval(0L, 1L);
public static final IntegerInterval ZERO = new IntegerInterval(0L, 0L);
public static final IntegerInterval ONE = new IntegerInterval(1L, 1L);
/**
* This method acts as constructor for a single-value interval.
*
* @param value
* for the
lower and upper bound
*/
public IntegerInterval(Long value) {
this.low = value;
this.high = value;
isSane();
}
/**
* This method acts as constructor for a long-based interval.
*
* @param low
* the lower bound
* @param high
* the upper bound
*/
public IntegerInterval(Long low, Long high) {
this.low = low;
this.high = high;
isSane();
}
@Override
public NumberInterface EMPTY() {
return EMPTY;
}
@Override
public NumberInterface UNBOUND() {
return UNBOUND;
}
@Override
public NumberInterface BOOLEAN_INTERVAL() {
return BOOLEAN_INTERVAL;
}
@Override
public NumberInterface ZERO() {
return ZERO;
}
@Override
public NumberInterface ONE() {
return ONE;
}
private boolean isSane() {
if ((low == null) != (high == null)) {
throw new IllegalStateException("invalid empty interval");
}
if (low != null && low > high) {
throw new IllegalStateException("low cannot be larger than high");
}
return true;
}
/**
* This method returns the lower bound of the interval.
*
* @return the lower bound
*/
@Override
public Long getLow() {
return low;
}
/**
* This method returns the upper bound of the interval.
*
* @return the upper bound
*/
@Override
public Long getHigh() {
return high;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object other) {
if (other != null && getClass().equals(other.getClass())) {
IntegerInterval another = (IntegerInterval) other;
return Objects.equals(low, another.getLow()) && Objects.equals(high, another.getHigh());
}
return false;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return Objects.hash(low, high);
}
/**
* This method creates
a new interval instance representing the union of
* this interval with another interval.
*
* The lower bound and upper bound of the new interval is the minimum of
* both lower bounds and the maximum of both upper bounds, respectively.
*
* @param other
* the other interval
* @return the new interval with the respective bounds
*/
@Override
public NumberInterface union(NumberInterface other) {
IntegerInterval tempOther = (IntegerInterval)other;
if (isEmpty() || tempOther.isEmpty()) {
return EMPTY;
} else if (low <= other.getLow() && high >= other.getHigh()) {
return this;
} else if (low >= other.getLow() && high <= other.getHigh()) {
return other;
} else {
return new IntegerInterval(Math.min(low, other.getLow()), Math.max(high, other.getHigh()));
}
}
/**
* This method creates a new interval instance representing the intersection
* of this interval with another interval.
*
* The lower bound and upper bound of the new interval is the maximum of
* both lower bounds and the minimum of both upper bounds, respectively.
*
* @param other
* the other interval
* @return the new interval with the respective bounds
*/
@Override
public NumberInterface intersect(NumberInterface other) {
if (this.intersects(other)) {
return new IntegerInterval(Math.max(low, other.getLow()), Math.min(high, other.getHigh()));
} else {
return
EMPTY;
}
}
/**
* This method determines if this interval is definitely greater than the
* other interval.
*
* @param other
* interval to compare with
* @return true if the lower bound of this interval is always strictly
* greater than the upper bound of the other interval, else false
*/
@Override
public boolean isGreaterThan(NumberInterface other) {
IntegerInterval tempOther = (IntegerInterval)other;
return !isEmpty() && !tempOther.isEmpty() && low > tempOther.getHigh();
}
/**
* This method determines if this interval is definitely greater or equal
* than the other interval. The equality is only satisfied for one
single
* value!
*
* @param other
* interval to compare with
* @return true if the lower bound of this interval is always strictly
* greater or equal than the upper bound of the other interval, else
* false
*/
@Override
public boolean isGreaterOrEqualThan(NumberInterface other) {
IntegerInterval tempOther = (IntegerInterval)other;
return !isEmpty() && !tempOther.isEmpty() && low >= tempOther.getHigh();
}
/**
* This method determines if this interval maybe greater than the other
* interval.
*
* @param other
* interval to compare with
* @return true if the upper bound of this interval is strictly greater than
* the lower bound of the other interval, else false
*/
public boolean mayBeGreaterThan(IntegerInterval other) {
return other.isEmpty() || (!isEmpty() && !other.isEmpty() && high > other.getLow());
}
/**
* This method determines if this interval maybe greater or equal than the
* other interval.
*
* @param other
* interval to compare with
* @return true if the upper bound of this interval is strictly greater than
* the lower bound of the other interval, else false
*/
public boolean mayBeGreaterOrEqualThan(IntegerInterval other) {
return other.isEmpty() || (!isEmpty() && !other.isEmpty() && high >= other.getLow());
}
/**
* New interval
instance after the modulo computation.
*
* @param other
* the other interval
* @return the new interval with the respective bounds.
*/
@Override
public NumberInterface modulo(NumberInterface other){
IntegerInterval tempOther = (IntegerInterval)other;
if (tempOther.contains(ZERO)) {
return IntegerInterval.UNBOUND;
}
// The interval doesn't contain zero, hence low and high has to be of
// the same sign.
// In that case we can call an absolute value on both, as "% (-x)" is
// the same as "% x".
other = new IntegerInterval(Math.abs(other.getLow()), Math.abs(other.getHigh()));
long newHigh;
long newLow;
// New high of the interval can't be higher than
the highest value in
// the divisor.
// If the divisible element is positive, it is also bounded by it's
// highest number,
// or by the absolute value of the lowest number.
// (-1 % 6 CAN be either -1 or 5 according to the C standard).
long top;
if (low >= 0) {
top = high;
} else {
if (low == Long.MIN_VALUE) {
top = Long.MAX_VALUE;
} else {
top = Math.max(Math.abs(low), high);
}
}
newHigh = Math.min(top, other.getHigh() - 1);
// Separate consideration for the case where the divisible number can be
// negative.
if
(low >= 0) { // If the divisible interval is all positive, the lowest
// we can ever get is 0.
// We can only get zero if we include 0 or the number higher than
// the smallest value of the other interval.
if (low == 0 || high >= other.getLow()) {
newLow = 0;
} else {
newLow = low;
}
} else {
// The remainder can go negative, but it can not be more negative
// than the negation of the highest value
// of the other interval plus 1.
// (e.g. X mod 14 can not be lower than -13)
// Remember, <low> is negative in this branch.
newLow = Math.max(low, 1 - other.getHigh());
}
IntegerInterval out = new IntegerInterval(newLow, newHigh);
return out;
}
/**
* This method returns a new interval with a limited, i.e. higher, lower
* bound.
*
* @param other
* the interval to limit this interval
* @return the new interval with the upper bound of this interval and the
* lower bound set to the maximum of this interval's and the other
* interval's lower bound or an empty interval if this interval is
* less than the other interval.
*/
@Override
public NumberInterface limitLowerBoundBy(NumberInterface other) {
IntegerInterval interval = null;
if (isEmpty() || other.isEmpty() || high < other.getLow()) {
interval = EMPTY;
} else {
interval = new IntegerInterval(Math.max(low, other.getLow()), high);
}
return interval;
}
/**
* This method returns a new interval with a limited, i.e. lower, upper
* bound.
*
* @param other
* the interval to limit this interval
* @return the new interval with the lower bound of this interval and the
* upper bound set to the minimum of this interval's and the other
* interval's upper bound or an empty interval if this
interval is
* greater than the other interval.
*/
@Override
public NumberInterface limitUpperBoundBy(NumberInterface other) {
IntegerInterval interval = null;
if (isEmpty() || other.isEmpty() || low > other.getHigh()) {
interval = EMPTY;
} else {
interval = new IntegerInterval(low, Math.min(high, other.getHigh()));
}
return interval;
}
/**
* This method determines if this interval intersects with another interval.
*
* @param other
* the other interval
* @return true if the intervals intersect, else false
*/
@Override
public boolean intersects(NumberInterface other) {
if (isEmpty() || other.isEmpty()) {
return false;
}
return
(low >= other.getLow() && low <= other.getHigh()) || (high >= other.getLow() && high <= other.getHigh())
|| (low <= other.getLow() && high >= other.getHigh());
}
/**
* This method determines if this interval contains another interval.
*
* The method still returns true, if the borders match. An empty interval
* does not contain any interval and is not contained in any interval
* either. So if the callee or parameter is an empty interval, this method
* will return false.
*
* @param other
* the other interval
* @return true if this interval contains the other interval, else false
*/
@Override
public boolean contains(NumberInterface other) {
IntegerInterval tempOther = (IntegerInterval)other;
return (!isEmpty() && !tempOther.isEmpty() && low <= other.getLow() && other.getHigh() <= high);
}
/**
* This method adds an interval from this interval, overflow is handled by
* setting the bound to Long.MIN_VALUE or Long.MAX_VALUE respectively.
*
* @param interval
* the interval to add
* @return a new interval with the respective bounds
*/
@Override
public NumberInterface plus(NumberInterface interval) {
IntegerInterval tempInterval = (IntegerInterval)interval;
if (isEmpty() || tempInterval.isEmpty()) {
return EMPTY;
}
return new IntegerInterval(scalarPlus(low, tempInterval.getLow()), scalarPlus(high, tempInterval.getHigh()));
}
/**
* This method adds a
constant offset to this interval, overflow is handled
* by setting the bound to Long.MIN_VALUE or Long.MAX_VALUE respectively.
*
* @param offset
* the constant offset to add
* @return a new interval with the respective bounds
*/
public NumberInterface plus(Long offset) {
return plus(new IntegerInterval(offset, offset));
}
/**
* This method subtracts an interval from this interval, overflow is handled
* by setting the bound to Long.MIN_VALUE or Long.MAX_VALUE respectively.
*
* @param other
* interval to subtract
* @return a new interval with the respective bounds
*/
@Override
public NumberInterface minus(NumberInterface other) {
IntegerInterval tempOther =
(IntegerInterval)other;
return plus(tempOther.negate());
}
/**
* This method subtracts a constant offset to this interval, overflow is
* handled by setting the bound to Long.MIN_VALUE or Long.MAX_VALUE
* respectively.
*
* @param offset
* the constant offset to subtract
* @return a new interval with the respective bounds
*/
public NumberInterface minus(Long offset) {
return plus(-offset);
}
/**
* This method multiplies this interval with another interval. In case of an
* overflow Long.MAX_VALUE and Long.MIN_VALUE are used instead.
*
* @param other
* interval to multiply this interval with
* @return new interval that represents
the result of the multiplication of
* the two intervals
*/
@Override
public NumberInterface times(NumberInterface other) {
Long[] values = { scalarTimes(low, other.getLow()), scalarTimes(low, other.getHigh()),
scalarTimes(high, other.getLow()), scalarTimes(high, other.getHigh()) };
return new IntegerInterval(Collections.min(Arrays.asList(values)), Collections.max(Arrays.asList(values)));
}
/**
* This method divides this interval by another interval. If the other
* interval contains "0" an unbound interval is returned.
*
* @param other
* interval to divide this interval by
* @return new interval that represents the result of the division of the
* two intervals
*/
@Override
public NumberInterface divide(NumberInterface other) {
// other interval
contains "0", return unbound interval
if (other.contains(ZERO)) {
return UNBOUND;
} else {
Long[] values = { low / other.getLow(), low / other.getHigh(), high / other.getLow(),
high / other.getHigh() };
return new IntegerInterval(Collections.min(Arrays.asList(values)), Collections.max(Arrays.asList(values)));
}
}
/**
* This method performs an arithmetical left shift of the interval bounds.
*
* @param offset
* Interval offset to perform an arithmetical left shift on the
* interval bounds. If the offset maybe less than zero an unbound
* interval is returned.
* @return new interval that represents the result of the arithmetical left
* shift
*/
@Override
public
NumberInterface shiftLeft(NumberInterface offset) {
// create an unbound interval upon trying to shift by a possibly
// negative offset
IntegerInterval tempOffset = (IntegerInterval)offset;
if (ZERO.mayBeGreaterThan(tempOffset)) {
return UNBOUND;
} else {
// if lower bound is negative, shift it by upper bound of offset,
// else by lower bound of offset
Long newLow = low << ((low < 0L) ? offset.getHigh() : offset.getLow());
// if upper bound is negative, shift it by lower bound of offset,
// else by upper bound of offset
Long newHigh = high << ((high < 0L) ? offset.getLow() : offset.getHigh());
if ((low < 0 && newLow > low) ||
(high > 0 && newHigh < high)) {
return UNBOUND;
} else {
return new IntegerInterval(newLow, newHigh);
}
}
}
/**
* This method performs an arithmetical right shift of the interval bounds.
* If the offset maybe less than zero an unbound interval is returned.
*
* @param offset
* Interval offset to perform an arithmetical right shift on the
* interval bounds
* @return new interval that represents the result of the arithmetical right
* shift
*/
@Override
public NumberInterface shiftRight(NumberInterface offset) {
// create an unbound interval upon trying to shift by a possibly
//
negative offset
IntegerInterval tempOffset = (IntegerInterval)offset;
if (ZERO.mayBeGreaterThan(tempOffset)) {
return UNBOUND;
} else {
// if lower bound is negative, shift it by lower bound of offset,
// else by upper bound of offset
Long newLow = low >> ((low < 0L) ? offset.getLow() : offset.getHigh());
// if upper bound is negative, shift it by upper bound of offset,
// else by lower bound of offset
Long newHigh = high >> ((high < 0L) ? offset.getHigh() : offset.getLow());
return new IntegerInterval(newLow, newHigh);
}
}
/**
* This method negates this interval.
*
* @return new negated interval
*/
@Override
public NumberInterface negate() {
return new IntegerInterval(scalarTimes(high, -1L), scalarTimes(low, -1L));
}
/**
* This method determines whether the interval is empty or not.
*
* @return true, if the interval is empty, i.e. the lower and upper bounds
* are null
*/
@Override
public boolean isEmpty() {
return low == null && high == null;
}
@Override
public boolean isUnbound() {
return !isEmpty() && low == Long.MIN_VALUE && high == Long.MAX_VALUE;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "[" + (low
== null ? "" : low) + "; " + (high == null ? "" : high) + "]";
}
/**
* This method is a factory method for a lower bounded interval.
*
* @param lowerBound
* the lower bound to set
* @return a lower bounded interval, i.e. the lower bound is set to the
* given lower bound, the upper bound is set to Long.MAX_VALUE
*/
public static NumberInterface createLowerBoundedInterval(Long lowerBound) {
return new IntegerInterval(lowerBound, Long.MAX_VALUE);
}
/**
* This method is a factory method for an upper bounded interval.
*
* @param upperBound
* the
upper bound to set
* @return an upper bounded interval, i.e. the lower bound is set to
* Long.MIN_VALUE, the upper bound is set to the given upper bound
*/
public static NumberInterface createUpperBoundedInterval(Long upperBound) {
return new IntegerInterval(Long.MIN_VALUE, upperBound);
}
/**
* This method adds two scalar values and returns their sum, or on overflow
* Long.MAX_VALUE or Long.MIN_VALUE, respectively.
*
* @param x
* the first scalar operand
* @param y
* the second scalar operand
* @return the sum of the first and second scalar operand or on overflow
* Long.MAX_VALUE and Long.MIN_VALUE, respectively.
*/
private
static Long scalarPlus(Long x, Long y) {
Long result = x + y;
// both operands are positive but the result is negative
if ((Long.signum(x) + Long.signum(y) == 2) && Long.signum(result) == -1) {
result = Long.MAX_VALUE;
} else if ((Long.signum(x) + Long.signum(y) == -2) && Long.signum(result) == +1) {
result = Long.MIN_VALUE;
}
return result;
}
/**
* This method multiplies two scalar values and returns their product, or on
* overflow Long.MAX_VALUE or Long.MIN_VALUE, respectively.
*
* @param x
* the first scalar operand
* @param y
* the second scalar operand
* @return the product
of the first and second scalar operand or on overflow
* Long.MAX_VALUE and Long.MIN_VALUE, respectively.
*/
private static Long scalarTimes(Long x, Long y) {
Long bound = (Long.signum(x) == Long.signum(y)) ? Long.MAX_VALUE : Long.MIN_VALUE;
// if overflow occurs, return the respective bound
if (x != 0 && ((y > 0 && y > (bound / x)) || (y < 0 && y < (bound / x)))) {
return bound;
} else {
return x * y;
}
}
}
class ExpressionValueVisitor extends DefaultCExpressionVisitor<NumberInterface, UnrecognizedCCodeException>
implements CRightHandSideVisitor<NumberInterface, UnrecognizedCCodeException> {
private final IntervalAnalysisState readableState;
private final CFAEdge cfaEdge;
public ExpressionValueVisitor(IntervalAnalysisState pState, CFAEdge edge) {
readableState = pState;
cfaEdge = edge;
}
@Override
protected NumberInterface visitDefault(CExpression expression) {
return new CreatorIntegerInterval().factoryMethod(null).UNBOUND();
}
@Override
public NumberInterface visit(CBinaryExpression binaryExpression) throws UnrecognizedCCodeException {
NumberInterface interval1 = binaryExpression.getOperand1().accept(this);
NumberInterface interval2 = binaryExpression.getOperand2().accept(this);
if (interval1 == null || interval2 == null) {
return new CreatorIntegerInterval().factoryMethod(null).UNBOUND();
}
BinaryOperator operator = binaryExpression.getOperator();
if (operator.isLogicalOperator()) {
return getLogicInterval(operator, interval1, interval2);
} else {
return getArithmeticInterval(operator, interval1, interval2);
}
}
private static NumberInterface getLogicInterval(
BinaryOperator operator, NumberInterface interval1, NumberInterface interval2) {
switch (operator) {
case EQUALS:
if (!interval1.intersects(interval2)) {
return new CreatorIntegerInterval().factoryMethod(null).ZERO();
} else if (interval1.getLow().equals(interval1.getHigh()) && interval1.equals(interval2)) {
// singular interval, [5;5]==[5;5]
return new CreatorIntegerInterval().factoryMethod(null).ONE();
} else {
return new CreatorIntegerInterval().factoryMethod(null).BOOLEAN_INTERVAL();
}
case NOT_EQUALS:
if (!interval1.intersects(interval2)) {
return new CreatorIntegerInterval().factoryMethod(null).ONE();
} else if (interval1.getLow().equals(interval1.getHigh()) && interval1.equals(interval2)) {
// singular interval, [5;5]!=[5;5]
return new CreatorIntegerInterval().factoryMethod(null).ZERO();
} else {
return new CreatorIntegerInterval().factoryMethod(null).BOOLEAN_INTERVAL();
}
case GREATER_THAN:
if (interval1.isGreaterThan(interval2)) {
return new CreatorIntegerInterval().factoryMethod(null).ONE();
} else if (interval2.isGreaterOrEqualThan(interval1)) {
return new CreatorIntegerInterval().factoryMethod(null).ZERO();
} else {
return new CreatorIntegerInterval().factoryMethod(null).BOOLEAN_INTERVAL();
}
case GREATER_EQUAL: // a>=b == a+1>b, works only for integers
return getLogicInterval(
BinaryOperator.GREATER_THAN, interval1.plus(new CreatorIntegerInterval().factoryMethod(null).ONE()), interval2);
case LESS_THAN: // a<b == b>a
return getLogicInterval(BinaryOperator.GREATER_THAN, interval2, interval1);
case LESS_EQUAL: // a<=b == b+1>a, works only for integers
return getLogicInterval(
BinaryOperator.GREATER_THAN, interval2.plus(new CreatorIntegerInterval().factoryMethod(null).ONE()), interval1);
default:
throw new AssertionError("unknown binary operator: " + operator);
}
}
private static NumberInterface getArithmeticInterval(
BinaryOperator operator, NumberInterface interval1, NumberInterface interval2) {
switch (operator) {
case PLUS:
return interval1.plus(interval2);
case MINUS:
return interval1.minus(interval2);
case MULTIPLY:
return interval1.times(interval2);
case DIVIDE:
return
interval1.divide(interval2);
case SHIFT_LEFT:
return interval1.shiftLeft(interval2);
case SHIFT_RIGHT:
return interval1.shiftRight(interval2);
case MODULO:
return interval1.modulo(interval2);
case BINARY_AND:
case BINARY_OR:
case BINARY_XOR:
return new CreatorIntegerInterval().factoryMethod(null).UNBOUND();
default:
throw new AssertionError("unknown binary operator: " + operator);
}
}
@Override
public NumberInterface visit(CCastExpression cast) throws UnrecognizedCCodeException {
return cast.getOperand().accept(this);
}
@Override
public NumberInterface visit(CFunctionCallExpression functionCall) {
return new CreatorIntegerInterval().factoryMethod(null).UNBOUND();
}
@Override
public NumberInterface visit(CCharLiteralExpression charLiteral) {
return new CreatorIntegerInterval().factoryMethod((long) charLiteral.getCharacter());
}
@Override
public NumberInterface visit(CImaginaryLiteralExpression exp) throws UnrecognizedCCodeException {
return exp.getValue().accept(this);
}
@Override
public NumberInterface visit(CIntegerLiteralExpression integerLiteral) {
//TODO BigInteger
return new CreatorIntegerInterval().factoryMethod(integerLiteral.asLong());
}
@Override
public NumberInterface visit(CFloatLiteralExpression integerLiteral) {
//TODO BigDecimal
return new CreatorIntegerInterval().factoryMethod(integerLiteral.getValue().longValue());
}
@Override
public NumberInterface visit(CIdExpression identifier) {
if (identifier.getDeclaration() instanceof CEnumerator) {
//TODO WTF
return new CreatorIntegerInterval().factoryMethod(((CEnumerator) identifier.getDeclaration()).getValue());///???
}
final String variableName = identifier.getDeclaration().getQualifiedName();
if (readableState.contains(variableName)) {
return readableState.getInterval(variableName);
} else {
return new CreatorIntegerInterval().factoryMethod(null).UNBOUND();
}
}
@Override
public NumberInterface visit(CUnaryExpression unaryExpression) throws UnrecognizedCCodeException {
NumberInterface interval = unaryExpression.getOperand().accept(this);
switch (unaryExpression.getOperator()) {
case MINUS:
return interval.negate();
case AMPER:
case TILDE:
return new CreatorIntegerInterval().factoryMethod(null).UNBOUND();
// valid expression, but it's a pointer value
default:
throw new UnrecognizedCCodeException("unknown unary operator", cfaEdge, unaryExpression);
}
}
}
а вот собственно класс который вызывает интерфейс. таких классов три, каждый что то свое вызывает. в данном случае интервалы
Тут есть тэг pre. Только надо в режиме прямого редактирования всё вносить
<pre>исходник</pre>
Ну и длинные простыни воспринимать весьма затруднительно, лучше как приложение сжелать.
Как там у вас я Яве принято не знаю.
Но константантам в интерфейсе по идее нечего делать.
public NumberInterface EMPTY(); public NumberInterface UNBOUND(); public NumberInterface BOOLEAN_INTERVAL(); public NumberInterface ZERO(); public NumberInterface ONE();
ну и не принято вроде, чтобы IsXxxx выбрасывала исключение.
это не константы, это методы, которые возвращают константы. тоже не совсем понятно как их прописать, в самом интерфейсе или оставить так.