public boolean areSemanticallyEqual(Expression left, Expression right) { if (left.eClass() != right.eClass()) return false; if (left instanceof OrExpression) { OrExpression leftOrExpression = (OrExpression) left; OrExpression rightOrExpression = (OrExpression) right; return (areSemanticallyEqual(leftOrExpression.getLeft(), rightOrExpression.getLeft()) && areSemanticallyEqual(leftOrExpression.getRight(), rightOrExpression.getRight())) || (areSemanticallyEqual(leftOrExpression.getRight(), rightOrExpression.getLeft()) && areSemanticallyEqual(leftOrExpression.getLeft(), rightOrExpression.getRight())); } if (left instanceof AndExpression) { AndExpression leftAndExpression = (AndExpression) left; AndExpression rightAndExpression = (AndExpression) right; return (areSemanticallyEqual(leftAndExpression.getLeft(), rightAndExpression.getLeft()) && areSemanticallyEqual(leftAndExpression.getRight(), rightAndExpression.getRight())) || (areSemanticallyEqual(leftAndExpression.getRight(), rightAndExpression.getLeft()) && areSemanticallyEqual(leftAndExpression.getLeft(), rightAndExpression.getRight())); } if (left instanceof NotExpression) { return areSemanticallyEqual( ((NotExpression) left).getExpression(), ((NotExpression) right).getExpression()); } if (left instanceof Comparison) { Comparison leftComparison = (Comparison) left; Comparison rightComparison = (Comparison) right; return ((Comparison) left).getOperator().equals(rightComparison.getOperator()) && areSemanticallyEqual(leftComparison.getLeft(), rightComparison.getLeft()) && areSemanticallyEqual(leftComparison.getRight(), rightComparison.getRight()); } if (left instanceof NumberLiteral) { int leftValue = ((NumberLiteral) left).getValue(); int rightValue = ((NumberLiteral) right).getValue(); return leftValue == rightValue; } if (left instanceof MethodCall) { String leftMethod = ((MethodCall) left).getValue(); String rightMethod = ((MethodCall) right).getValue(); return leftMethod.equals(rightMethod); } throw new IllegalStateException(left + " - " + right); }
@Override public Expression caseOrExpression(OrExpression object) { if (object.getRight() == null) return doSwitch(object.getLeft()); if (object.getLeft() == null) return doSwitch(object.getRight()); Expression left = doSwitch(object.getLeft()); Expression right = doSwitch(object.getRight()); if (areSemanticallyEqual(left, right)) return left; if (left instanceof AndExpression) { AndExpression leftAsAnd = (AndExpression) left; if (areSemanticallyEqual(leftAsAnd.getLeft(), right) || areSemanticallyEqual(leftAsAnd.getRight(), right)) return right; } else if (right instanceof AndExpression) { AndExpression rightAsAnd = (AndExpression) right; if (areSemanticallyEqual(rightAsAnd.getLeft(), left) || areSemanticallyEqual(rightAsAnd.getRight(), left)) return left; } if (left instanceof OrExpression) { OrExpression leftAsOr = (OrExpression) left; if (areSemanticallyEqual(leftAsOr.getLeft(), right) || areSemanticallyEqual(leftAsOr.getRight(), right)) return left; } else if (right instanceof OrExpression) { OrExpression rightAsOr = (OrExpression) right; if (areSemanticallyEqual(rightAsOr.getLeft(), left) || areSemanticallyEqual(rightAsOr.getRight(), left)) return right; } object.setLeft(left); object.setRight(right); return object; }