/**
* 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.queries.visitors;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.whole.lang.bindings.BindingManagerFactory;
import org.whole.lang.bindings.ITransactionScope;
import org.whole.lang.commons.model.Variable;
import org.whole.lang.commons.parsers.CommonsDataTypePersistenceParser;
import org.whole.lang.commons.reflect.CommonsEntityDescriptorEnum;
import org.whole.lang.commons.reflect.CommonsLanguageKit;
import org.whole.lang.commons.visitors.CommonsInterpreterVisitor;
import org.whole.lang.comparators.BusinessIdentityComparator;
import org.whole.lang.comparators.IEntityComparator;
import org.whole.lang.comparators.IdentityIteratorComparator;
import org.whole.lang.factories.GenericEntityFactory;
import org.whole.lang.iterators.ChooseByTypeIterator;
import org.whole.lang.iterators.DistinctScope;
import org.whole.lang.iterators.FilterByIndexRangeIterator;
import org.whole.lang.iterators.IEntityIterator;
import org.whole.lang.iterators.IteratorFactory;
import org.whole.lang.matchers.GenericMatcherFactory;
import org.whole.lang.matchers.Matcher;
import org.whole.lang.model.IEntity;
import org.whole.lang.model.adapters.IEntityAdapter;
import org.whole.lang.queries.codebase.IfWithTemplate;
import org.whole.lang.queries.codebase.IfWithTypeTest;
import org.whole.lang.queries.iterators.Placement;
import org.whole.lang.queries.iterators.QueriesIteratorFactory;
import org.whole.lang.queries.matchers.QueriesMatcherFactory;
import org.whole.lang.queries.model.*;
import org.whole.lang.queries.model.KindTestEnum.Value;
import org.whole.lang.queries.reflect.QueriesEntityDescriptorEnum;
import org.whole.lang.queries.reflect.QueriesLanguageKit;
import org.whole.lang.queries.util.MathUtils;
import org.whole.lang.reflect.EntityDescriptor;
import org.whole.lang.reflect.EntityKinds;
import org.whole.lang.reflect.ILanguageKit;
import org.whole.lang.reflect.ReflectionFactory;
import org.whole.lang.util.EntityUtils;
import org.whole.lang.visitors.GenericTraversalFactory;
import org.whole.lang.visitors.IVisitor;
import org.whole.lang.visitors.MissingVariableException;
/**
* @author Riccardo Solmi
*/
public class QueriesDynamicCompilerVisitor extends QueriesIdentityDefaultVisitor {
private boolean useInheritedSemantics;
private boolean useTemplateFactorySemantics = true;
private Set<String> declaredNames = new HashSet<String>();
private Set<String> templateNames = new HashSet<String>();
private Set<String> namesExp = new HashSet<String>();
private boolean useNamesComplement;
private DistinctScope<IEntity> distinctScope;
private FilterByIndexRangeIterator<IEntity> filterByIndexIterator;
private boolean canFilterByIndex;
private int startIndex;
private int endIndex;
public <E extends IEntity> IEntityIterator<E> getResultIterator() {
return super.getResultIterator();
}
private void setResultPredicate(IVisitor queryPredicate) {
setResult(BindingManagerFactory.instance.createValue(queryPredicate));
}
//TODO work in progress to support elimination of ExpressiontTest
private IVisitor compilePredicate(Predicate predicate) {
predicate.accept(this);
if (isResultIterator()) {
boolean hasMatchSemantics = true;
return hasMatchSemantics ?
GenericMatcherFactory.instance.match(getResultIterator()) :
GenericMatcherFactory.evalTrue(predicate);
} else
return getResultPredicate();
}
private IVisitor getResultPredicate() {
IEntity result = getResult();
return result != null ? (IVisitor) result.wGetValue() : GenericTraversalFactory.instance.identity();
}
protected boolean useInheritedSemantics() {
return useInheritedSemantics;
}
protected boolean useInheritedSemantics(boolean value) {
boolean oldValue = useInheritedSemantics;
useInheritedSemantics = value;
return oldValue;
}
protected boolean useTemplateFactorySemantics() {
return useTemplateFactorySemantics;
}
protected boolean useTemplateFactorySemantics(boolean value) {
boolean oldValue = useTemplateFactorySemantics;
if (!useInheritedSemantics())
useTemplateFactorySemantics = value;
return oldValue;
}
protected boolean useFactorySemantics(IEntity entity) {
if (Matcher.match(QueriesEntityDescriptorEnum.Filter, entity)) {
Filter filter = (Filter) entity;
StepExpression exp = filter.getExpression();
if (Matcher.match(QueriesEntityDescriptorEnum.VariableRefStep, exp) &&
Matcher.match(QueriesEntityDescriptorEnum.VariableTest, filter.getPredicate()))
return true;
else
return useFactorySemantics(exp);
} else if (Matcher.match(QueriesEntityDescriptorEnum.Path, entity))
return entity.wSize() == 0 ? false : useFactorySemantics(((Path) entity).get(0));
else
return EntityUtils.isStageUpFragment(entity) || EntityUtils.isSameStageFragment(entity) ||
!entity.wGetLanguageKit().equals(ReflectionFactory.getLanguageKit(QueriesLanguageKit.URI, false, null)) ||
Matcher.match(QueriesEntityDescriptorEnum.Tuple, entity);
}
@Override
public boolean visitAdapter(IEntityAdapter entity) {
IEntity adaptee = entity.wGetAdaptee(false);
EntityDescriptor<?> adapteeEd = adaptee.wGetEntityDescriptor();
if (adapteeEd.getLanguageKit().getURI().equals(CommonsLanguageKit.URI)) {
switch (adapteeEd.getOrdinal()) {
case CommonsEntityDescriptorEnum.Resolver_ord:
setResultIterator(IteratorFactory.emptyIterator().withSourceEntity(adaptee));
return false;
case CommonsEntityDescriptorEnum.Variable_ord:
case CommonsEntityDescriptorEnum.InlineVariable_ord:
throw new MissingVariableException(((Variable) adaptee).getVarName().toString()).withSourceEntity(adaptee).withBindings(getBindings());
case CommonsEntityDescriptorEnum.SameStageFragment_ord:
setResultIterator(QueriesIteratorFactory.templateInterpreterIterator(adaptee).withSourceEntity(adaptee));
return false;
case CommonsEntityDescriptorEnum.RootFragment_ord:
case CommonsEntityDescriptorEnum.StageDownFragment_ord:
setResultIterator(QueriesIteratorFactory.templateInterpreterIterator(
GenericEntityFactory.instance.create(
CommonsEntityDescriptorEnum.StageDownFragment,
EntityUtils.clone(entity))).withSourceEntity(adaptee));
return false;
case CommonsEntityDescriptorEnum.StageUpFragment_ord:
if (useTemplateFactorySemantics())
setResultIterator(QueriesIteratorFactory.templateInterpreterIterator(adaptee).withSourceEntity(adaptee));
else {
CommonsInterpreterVisitor.evaluateAdapter(entity, getOperation());//TODO test
setResultIterator(QueriesIteratorFactory.patternMatcherIterator(
getResult()).withSourceEntity(adaptee));
}
return false;
}
}
stagedVisit(adaptee, 0);
return false;
}
@Override
public void visit(IQueriesEntity entity) {
getOperation().stagedDefaultVisit(entity, 0);
}
@Override
public void visit(QueryDeclaration entity) {
String queryName = entity.getName().getValue();
declaredNames.add(queryName);
setResultIterator(IteratorFactory.filterIterator(
QueriesIteratorFactory.constantIterator(entity, true).withSourceEntity(entity),
GenericMatcherFactory.instance.defineVariableMatcher(queryName)).withSourceEntity(entity));
}
@Override
public void visit(Call entity) {
Expressions arguments = entity.getArguments();
boolean inheritedSemantics = useInheritedSemantics(false);
boolean templateFactorySemantics = useTemplateFactorySemantics(true);
IEntityIterator<? extends IEntity>[] argsIterators = new IEntityIterator<?>[arguments.wSize()];
for (int i=0, size=arguments.wSize(); i<size; i++) {
arguments.get(i).accept(this);
argsIterators[i] = getResultIterator();
}
useTemplateFactorySemantics(templateFactorySemantics);
useInheritedSemantics(inheritedSemantics);
setResultIterator(QueriesIteratorFactory.callIterator(
entity.getName().getValue(), argsIterators).withSourceEntity(entity));
}
@Override
public void visit(Scope entity) {
namesExp = Collections.emptySet();
entity.getLocalNames().accept(this);
Set<String> localNames = namesExp;
entity.getExpression().accept(this);
setResultIterator(QueriesIteratorFactory.scopeIterator(getResultIterator(), null, localNames).withSourceEntity(entity));
}
@Override
public void visit(Path entity) {
boolean useFactorySemantics = useFactorySemantics(entity);
boolean templateSemantics = useTemplateFactorySemantics(useFactorySemantics);//TODO test true);
boolean inheritedSemantics = useInheritedSemantics(true);
DistinctScope<IEntity> oldDistinctScope = distinctScope;
distinctScope = null;
int nestedIndex = entity.wSize()-1;
IEntityIterator<?>[] nestedIterators = new IEntityIterator<?>[nestedIndex>=0 ? nestedIndex : 0];
nestedIndex--;
for (int i = 0; i < entity.wSize()-1; i++) {
entity.get(i).accept(this);
nestedIterators[nestedIndex-i] = getResultIterator();
}
entity.get(entity.wSize()-1).accept(this);
setResultIterator(IteratorFactory.composeIterator(getResultIterator(), nestedIterators).withSourceEntity(entity));
if (distinctScope != null)
setResultIterator(distinctScope.withIterator(getResultIterator()));
distinctScope = oldDistinctScope;
useInheritedSemantics(false);
useTemplateFactorySemantics(templateSemantics);
useInheritedSemantics(inheritedSemantics);
}
@Override
public void visit(Choose entity) {
int size = entity.wSize();
if (size == 1)
entity.get(0).accept(this);
else {
boolean canOptimize = true;
ILanguageKit languageKit = null;
Map<EntityDescriptor<?>, PathExpression> typeMap = new HashMap<EntityDescriptor<?>, PathExpression>();
If ifWithTemplate = new IfWithTemplate().create();
If ifWithTypeTest = new IfWithTypeTest().create();
ITransactionScope ts = BindingManagerFactory.instance.createTransactionScope();
getBindings().wEnterScope(ts);
for (int i=0; i<size; i++) {
PathExpression child = entity.get(i);
try {
if (!Matcher.match(ifWithTemplate, child, getBindings()) &&
!Matcher.match(ifWithTypeTest, child, getBindings())) {
canOptimize = false;
break;
}
EntityDescriptor<?> ed = getBindings().wIsSet("typeTest") && getBindings().wGet("typeTest").wGetEntityDescriptor().getDataKind().isString() ?
CommonsDataTypePersistenceParser.getEntityDescriptor(getBindings().wStringValue("typeTest")) :
getBindings().wIsSet("pattern") ? getBindings().wGet("pattern").wGetEntityDescriptor() : null;
if (ed == null) {
canOptimize = false;
break;
}
if (typeMap.containsKey(ed)) {
PathExpression behavior = typeMap.get(ed);
boolean isPattern = behavior.wGetParent() == entity;
if (isPattern) {
canOptimize = false;
break;
}
} else {
if (languageKit == null)
languageKit = ed.getLanguageKit();
else if (!languageKit.equals(ed.getLanguageKit())) {// || !languageKit.getURI().equals("whole:org.whole.lang.javascript:JavaScript")) {
canOptimize = false;
break;
}
typeMap.put(ed, getBindings().wIsSet("pattern") ? child :
getBindings().wGet("expression").wGetAdapter(QueriesEntityDescriptorEnum.PathExpression));
}
} finally {
ts.rollback();
}
}
getBindings().wExitScope();
if (canOptimize) {
ChooseByTypeIterator<IEntity> chooseIterator = IteratorFactory.chooseIterator(languageKit);
for (Entry<EntityDescriptor<?>, PathExpression> entry : typeMap.entrySet()) {
boolean inheritedSemantics = useInheritedSemantics(false);
boolean templateSemantics = useTemplateFactorySemantics(false);
useInheritedSemantics(false);
useTemplateFactorySemantics(true);
Set<String> oldDeclaredNames = declaredNames;
entry.getValue().accept(this);
chooseIterator.setCase(entry.getKey(), getResultIterator());
declaredNames = oldDeclaredNames;
useInheritedSemantics(false);
useTemplateFactorySemantics(templateSemantics);
useInheritedSemantics(inheritedSemantics);
}
setResultIterator(chooseIterator.withSourceEntity(entity));
} else {
IEntityIterator<? extends IEntity>[] iteratorChain = new IEntityIterator<?>[size];
for (int i=0; i<size; i++) {
entity.get(i).accept(this);
iteratorChain[i] = getResultIterator();
}
setResultIterator(IteratorFactory.chooseIterator(iteratorChain).withSourceEntity(entity));
}
}
}
@Override
public void visit(Block entity) {
int size = entity.wSize();
if (size == 1)
entity.get(0).accept(this);
else {
IEntityIterator<? extends IEntity>[] iteratorChain = new IEntityIterator<?>[size];
for (int i=0; i<size; i++) {
entity.get(i).accept(this);
iteratorChain[i] = getResultIterator();
}
setResultIterator(IteratorFactory.blockIterator(iteratorChain).withSourceEntity(entity));
}
}
@Override
public void visit(Sequence entity) {
int size = entity.wSize();
if (size == 1)
entity.get(0).accept(this);//FIXME nested scope is exposed
else {
IEntityIterator<? extends IEntity>[] iteratorChain = new IEntityIterator<?>[size];
for (int i=0; i<size; i++) {
entity.get(i).accept(this);
iteratorChain[i] = getResultIterator();
}
setResultIterator(IteratorFactory.sequenceIterator(iteratorChain).withSourceEntity(entity));
}
}
@Override
public void visit(Prune entity) {
entity.getPredicate().accept(this);
}
@Override
public void visit(Filter entity) {
boolean useFactorySemantics = useFactorySemantics(entity);
boolean templateSemantics = useTemplateFactorySemantics(useFactorySemantics);
boolean inheritedSemantics = useInheritedSemantics(true);
FilterByIndexRangeIterator<IEntity> oldFilterByIndexIterator = filterByIndexIterator;
filterByIndexIterator = null;
DistinctScope<IEntity> oldDistinctScope = distinctScope;
distinctScope = null;
PruneOrPredicate predicate = entity.getPredicate();
StepExpression expression = entity.getExpression();
boolean optimizeIndexTest = false;
int oldStartIndex = startIndex;
int oldEndIndex = endIndex;
boolean oldCanFilterByIndex = canFilterByIndex;
startIndex = Integer.MAX_VALUE;
endIndex = 0;
canFilterByIndex = true;
boolean usePruneFilter = Matcher.matchImpl(QueriesEntityDescriptorEnum.Prune, predicate);
if (usePruneFilter)
predicate = ((Prune) predicate).getPredicate();
if (Matcher.matchImpl(QueriesEntityDescriptorEnum.ChildStep, expression)) {
if (Matcher.matchImpl(QueriesEntityDescriptorEnum.IndexTest, predicate)) {
int index = predicate.wGet(0).wIntValue();
setResultIterator(IteratorFactory.featureByIndexIterator(index).withSourceEntity(entity));
optimizeIndexTest = true;
} else if (Matcher.matchImpl(QueriesEntityDescriptorEnum.AtIndexTest, predicate)) {
int index = predicate.wIntValue();
setResultIterator(IteratorFactory.featureByIndexIterator(index).withSourceEntity(entity));
optimizeIndexTest = true;
}
}
if (!optimizeIndexTest) {
setResultPredicate(null);
predicate.accept(this);
IVisitor queryPredicate = getResultPredicate();
expression.accept(this);
if (filterByIndexIterator != null) {
filterByIndexIterator.withIterator(getResultIterator());
setResultIterator(filterByIndexIterator);
if (canFilterByIndex) {
// filterByIndexIterator.withStartIndex(startIndex);
filterByIndexIterator.withEndIndex(endIndex);
}
}
if (distinctScope != null &&
!(EntityUtils.hasParent(entity) &&
Matcher.match(QueriesEntityDescriptorEnum.Path, entity.wGetParent())))
setResultIterator(distinctScope.withIterator(getResultIterator()));
if (queryPredicate != null)
setResultIterator(IteratorFactory.filterIterator(
getResultIterator(), queryPredicate).withAutoPrune(usePruneFilter).withSourceEntity(entity));
}
startIndex = oldStartIndex;
endIndex = oldEndIndex;
canFilterByIndex = oldCanFilterByIndex;
filterByIndexIterator = oldFilterByIndexIterator;
distinctScope = oldDistinctScope;
useInheritedSemantics(false);
useTemplateFactorySemantics(templateSemantics);
useInheritedSemantics(inheritedSemantics);
}
@Override
public void visit(AspectStep entity) {
setResultIterator(IteratorFactory.aspectIterator().withSourceEntity(entity));
}
@Override
public void visit(AdjacentStep entity) {
setResultIterator(IteratorFactory.adjacentIterator().withSourceEntity(entity));
}
@Override
public void visit(ReachableStep entity) {
setResultIterator(IteratorFactory.reachableIterator(false).withSourceEntity(entity));
}
@Override
public void visit(ReachableOrSelfStep entity) {
setResultIterator(IteratorFactory.reachableIterator(true).withSourceEntity(entity));
}
@Override
public void visit(InverseAdjacentStep entity) {
setResultIterator(IteratorFactory.inverseAdjacentIterator().withSourceEntity(entity));
}
@Override
public void visit(InverseReachableStep entity) {
setResultIterator(IteratorFactory.inverseReachableIterator(false).withSourceEntity(entity));
}
@Override
public void visit(InverseReachableOrSelfStep entity) {
setResultIterator(IteratorFactory.inverseReachableIterator(true).withSourceEntity(entity));
}
@Override
public void visit(RootStep entity) {
setResultIterator(IteratorFactory.rootIterator().withSourceEntity(entity));
}
@Override
public void visit(FragmentRootStep entity) {
setResultIterator(IteratorFactory.fragmentRootIterator().withSourceEntity(entity));
}
@Override
public void visit(SelfStep entity) {
setResultIterator(IteratorFactory.selfIterator().withSourceEntity(entity));
}
@Override
public void visit(FeatureStep entity) {
setResultIterator(IteratorFactory.featureByNameIterator(entity.getValue()).withSourceEntity(entity));
}
@Override
public void visit(ChildStep entity) {
setResultIterator(IteratorFactory.childIterator().withSourceEntity(entity));
}
@Override
public void visit(DescendantStep entity) {
setResultIterator(IteratorFactory.descendantIterator().withSourceEntity(entity));
}
@Override
public void visit(DescendantOrSelfStep entity) {
setResultIterator(IteratorFactory.descendantOrSelfIterator().withSourceEntity(entity));
}
@Override
public void visit(FollowingSiblingStep entity) {
setResultIterator(IteratorFactory.followingSiblingIterator().withSourceEntity(entity));
}
@Override
public void visit(FollowingStep entity) {
setResultIterator(IteratorFactory.followingIterator().withSourceEntity(entity));
}
@Override
public void visit(ParentStep entity) {
setResultIterator(IteratorFactory.parentIterator().withSourceEntity(entity));
}
@Override
public void visit(AncestorStep entity) {
setResultIterator(IteratorFactory.ancestorIterator().withSourceEntity(entity));
}
@Override
public void visit(AncestorOrSelfStep entity) {
setResultIterator(IteratorFactory.ancestorOrSelfIterator().withSourceEntity(entity));
}
@Override
public void visit(PrecedingSiblingStep entity) {
setResultIterator(IteratorFactory.precedingSiblingIterator().withSourceEntity(entity));
}
@Override
public void visit(PrecedingStep entity) {
setResultIterator(IteratorFactory.precedingIterator().withSourceEntity(entity));
}
@Override
public void visit(VariableRefStep entity) {
setResultIterator(IteratorFactory.variableIterator(entity.getValue()).withSourceEntity(entity).withSourceEntity(entity));
}
@Override
public void visit(VariableTest entity) {
String varName = entity.getValue();
declaredNames.add(varName);
setResultPredicate(GenericMatcherFactory.instance.asVariableMatcher(varName).withSourceEntity(entity));
}
@Override
public void visit(CartesianProduct entity) {
IEntityIterator<?>[] iterators = new IEntityIterator<?>[entity.wSize()];
for (int i = 0; i < entity.wSize(); i++) {
entity.get(i).accept(this);
iterators[i] = getResultIterator();
}
setResultIterator(QueriesIteratorFactory.cartesianProductIterator(iterators).withSourceEntity(entity));
}
@Override
public void visit(PointwiseProduct entity) {
IEntityIterator<?>[] iterators = new IEntityIterator<?>[entity.wSize()];
for (int i = 0; i < entity.wSize(); i++) {
entity.get(i).accept(this);
iterators[i] = getResultIterator();
}
setResultIterator(QueriesIteratorFactory.pointwiseProductIterator(iterators).withSourceEntity(entity));
}
@Override
public void visit(Delete entity) {
boolean inheritedSemantics = useInheritedSemantics(false);
boolean templateSemantics = useTemplateFactorySemantics(false);
useInheritedSemantics(true);
entity.getFromClause().accept(this);
IEntityIterator<? extends IEntity> fromIterator = getResultIterator();
setResultIterator(QueriesIteratorFactory.deleteIterator(fromIterator).withSourceEntity(entity));
useInheritedSemantics(false);
useTemplateFactorySemantics(templateSemantics);
useInheritedSemantics(inheritedSemantics);
}
@Override
public void visit(CartesianUpdate entity) {
boolean inheritedSemantics = useInheritedSemantics(false);
boolean templateSemantics = useTemplateFactorySemantics(false);
useInheritedSemantics(true);
entity.getFromClause().accept(this);
IEntityIterator<IEntity> fromIterator = getResultIterator();
useInheritedSemantics(false);
useTemplateFactorySemantics(true);
setResultIterator(IteratorFactory.emptyIterator().withSourceEntity(entity));
entity.getValuesClause().accept(this);
IEntityIterator<? extends IEntity> valuesIterator = getResultIterator();
setResultIterator(QueriesIteratorFactory.cartesianUpdateIterator(valuesIterator, fromIterator).withSourceEntity(entity));
useInheritedSemantics(false);
useTemplateFactorySemantics(templateSemantics);
useInheritedSemantics(inheritedSemantics);
}
@Override
public void visit(PointwiseUpdate entity) {
boolean inheritedSemantics = useInheritedSemantics(false);
boolean templateSemantics = useTemplateFactorySemantics(false);
useInheritedSemantics(true);
entity.getFromClause().accept(this);
IEntityIterator<IEntity> fromIterator = getResultIterator();
useInheritedSemantics(false);
useTemplateFactorySemantics(true);
setResultIterator(IteratorFactory.emptyIterator().withSourceEntity(entity));
entity.getValuesClause().accept(this);
IEntityIterator<? extends IEntity> valuesIterator = getResultIterator();
setResultIterator(QueriesIteratorFactory.pointwiseUpdateIterator(
valuesIterator, fromIterator).withSourceEntity(entity));
useInheritedSemantics(false);
useTemplateFactorySemantics(templateSemantics);
useInheritedSemantics(inheritedSemantics);
}
@Override
public void visit(CartesianInsert entity) {
boolean inheritedSemantics = useInheritedSemantics(false);
boolean templateSemantics = useTemplateFactorySemantics(false);
useInheritedSemantics(true);
entity.getFromClause().accept(this);
IEntityIterator<IEntity> fromIterator = getResultIterator();
useInheritedSemantics(false);
useTemplateFactorySemantics(true);
setResultIterator(IteratorFactory.emptyIterator().withSourceEntity(entity));
entity.getValuesClause().accept(this);
IEntityIterator<? extends IEntity> valuesIterator = getResultIterator();
Placement placement = Placement.valueOf(entity.getPlacement().getValue().getName());
setResultIterator(QueriesIteratorFactory.cartesianInsertIterator(
valuesIterator, fromIterator, placement).withSourceEntity(entity));
useInheritedSemantics(false);
useTemplateFactorySemantics(templateSemantics);
useInheritedSemantics(inheritedSemantics);
}
@Override
public void visit(PointwiseInsert entity) {
boolean inheritedSemantics = useInheritedSemantics(false);
boolean templateSemantics = useTemplateFactorySemantics(false);
useInheritedSemantics(true);
entity.getFromClause().accept(this);
IEntityIterator<IEntity> fromIterator = getResultIterator();
useInheritedSemantics(false);
useTemplateFactorySemantics(true);
setResultIterator(IteratorFactory.emptyIterator().withSourceEntity(entity));
entity.getValuesClause().accept(this);
IEntityIterator<? extends IEntity> valuesIterator = getResultIterator();
Placement placement = Placement.valueOf(entity.getPlacement().getValue().getName());
setResultIterator(QueriesIteratorFactory.pointwiseInsertIterator(
valuesIterator, fromIterator, placement).withSourceEntity(entity));
useInheritedSemantics(false);
useTemplateFactorySemantics(templateSemantics);
useInheritedSemantics(inheritedSemantics);
}
@Override
public void visit(Select entity) {
boolean inheritedSemantics = useInheritedSemantics(false);
boolean templateSemantics = useTemplateFactorySemantics(false);
useInheritedSemantics(true);
Set<String> oldDeclaredNames = declaredNames;
Set<String> namesToBound = declaredNames = new HashSet<String>();
setResultPredicate(null);
PathExpressionOrPredicate fromClause = entity.getFromClause();
fromClause.accept(this);
IEntityIterator<? extends IEntity> fromIterator = isResultIterator() ?
getResultIterator() :
IteratorFactory.filterIterator(IteratorFactory.selfIterator().withSourceEntity(entity), getResultPredicate()).withSourceEntity(entity);
useInheritedSemantics(false);
useTemplateFactorySemantics(true);
setResultIterator(IteratorFactory.emptyIterator().withSourceEntity(entity));
entity.getWhereClause().accept(this);
IEntityIterator<? extends IEntity> whereIterator = getResultIterator();
useInheritedSemantics(false);
useTemplateFactorySemantics(true);
declaredNames = oldDeclaredNames;
entity.getSelectClause().accept(this);
IEntityIterator<? extends IEntity> selectIterator = getResultIterator();
templateNames = Matcher.vars(entity.getSelectClause(), true);
namesExp = declaredNames = namesToBound;
useNamesComplement = false;
entity.getClearClause().accept(this);
setResultIterator(QueriesIteratorFactory.selectIterator(
selectIterator, fromIterator, whereIterator)
.withNamesToBind(namesExp)
.withNamesComplement(useNamesComplement).withSourceEntity(entity));
declaredNames = oldDeclaredNames;
useInheritedSemantics(false);
useTemplateFactorySemantics(templateSemantics);
useInheritedSemantics(inheritedSemantics);
}
@Override
public void visit(AllNames entity) {
namesExp = new HashSet<String>();
useNamesComplement = true;
}
@Override
public void visit(TemplateNames entity) {
namesExp = templateNames;
}
@Override
public void visit(AddNames entity) {
entity.getExpression().accept(this);
Set<String> names = namesExp;
entity.getNames().accept(this);
names.addAll(namesExp);
namesExp = names;
}
@Override
public void visit(RemoveNames entity) {
entity.getExpression().accept(this);
Set<String> names = namesExp;
entity.getNames().accept(this);
names.removeAll(namesExp);
namesExp = names;
}
@Override
public void visit(Names entity) {
namesExp = new HashSet<String>();
for (int i = 0; i < entity.size(); i++)
entity.get(i).accept(this);
}
@Override
public void visit(Name entity) {
namesExp.add(entity.getValue());
}
@Override
public void visit(For entity) {
boolean inheritedSemantics = useInheritedSemantics(false);
boolean templateSemantics = useTemplateFactorySemantics(false);
useInheritedSemantics(true);
Set<String> oldDeclaredNames = declaredNames;
Set<String> namesToBound = declaredNames = new HashSet<String>();
entity.getFromClause().accept(this);
IEntityIterator<? extends IEntity> fromIterator = getResultIterator();
useInheritedSemantics(false);
useTemplateFactorySemantics(true);
declaredNames = oldDeclaredNames;
entity.getExpression().accept(this);
IEntityIterator<? extends IEntity> selectIterator = getResultIterator();
declaredNames = namesToBound;
setResultIterator(IteratorFactory.forIterator(
fromIterator, selectIterator).withSourceEntity(entity));
declaredNames = oldDeclaredNames;
useInheritedSemantics(false);
useTemplateFactorySemantics(templateSemantics);
useInheritedSemantics(inheritedSemantics);
}
@Override
public void visit(If entity) {
boolean inheritedSemantics = useInheritedSemantics(false);
boolean templateSemantics = useTemplateFactorySemantics(false);
useInheritedSemantics(true);
Set<String> oldDeclaredNames = declaredNames;
Set<String> namesToBound = declaredNames = new HashSet<String>();
setResultPredicate(null);
entity.getPredicate().accept(this);
IVisitor predicate = getResultPredicate();
useInheritedSemantics(false);
useTemplateFactorySemantics(true);
declaredNames = oldDeclaredNames;
entity.getExpression().accept(this);
IEntityIterator<? extends IEntity> selectIterator = getResultIterator();
declaredNames = namesToBound;
setResultIterator(IteratorFactory.ifIterator(
predicate, selectIterator).withSourceEntity(entity));
declaredNames = oldDeclaredNames;
useInheritedSemantics(false);
useTemplateFactorySemantics(templateSemantics);
useInheritedSemantics(inheritedSemantics);
}
@Override
public void visit(Do entity) {
boolean inheritedSemantics = useInheritedSemantics(false);
boolean templateSemantics = useTemplateFactorySemantics(false);
useInheritedSemantics(true);
Set<String> oldDeclaredNames = declaredNames;
// Set<String> namesToBound =
declaredNames = new HashSet<String>();
useInheritedSemantics(false);
useTemplateFactorySemantics(true);
declaredNames = oldDeclaredNames;
entity.getExpression().accept(this);
// IEntityIterator<? extends IEntity> selectIterator = getQueryIterator();
//
// declaredNames = namesToBound;
//
// setQueryIterator(QueriesIteratorFactory.doIterator(selectIterator)
// .useNamesToBound(namesToBound).withDomainEntity(entity));
declaredNames = oldDeclaredNames;
useInheritedSemantics(false);
useTemplateFactorySemantics(templateSemantics);
useInheritedSemantics(inheritedSemantics);
}
@Override
public void visit(Tuple entity) {
IEntityIterator<?>[] tupleIterators = new IEntityIterator<?>[entity.wSize()];
for (int i=0; i<entity.wSize(); i++) {
entity.get(i).accept(this);
tupleIterators[i] = getResultIterator();
}
setResultIterator(QueriesIteratorFactory.tupleFactoryIterator(tupleIterators).withSourceEntity(entity));
}
@Override
public void visit(One entity) {
entity.getFromClause().accept(this);
IEntityIterator<? extends IEntity> fromClause = getResultIterator();
entity.getWhereClause().accept(this);
setResultPredicate(QueriesMatcherFactory.one(fromClause, getResultPredicate()).withSourceEntity(entity));
}
@Override
public void visit(Some entity) {
entity.getFromClause().accept(this);
IEntityIterator<? extends IEntity> fromClause = getResultIterator();
entity.getWhereClause().accept(this);
setResultPredicate(QueriesMatcherFactory.some(fromClause, getResultPredicate()).withSourceEntity(entity));
}
@Override
public void visit(Every entity) {
entity.getFromClause().accept(this);
IEntityIterator<? extends IEntity> fromClause = getResultIterator();
entity.getWhereClause().accept(this);
setResultPredicate(QueriesMatcherFactory.all(fromClause, getResultPredicate()).withSourceEntity(entity));
}
@Override
public void visit(KindTest entity) {
Value kind = entity.getValue();
switch (kind.getOrdinal()) {
case KindTestEnum.IMPL_ord:
setResultPredicate(GenericMatcherFactory.instance.isImplMatcher().withSourceEntity(entity));
break;
case KindTestEnum.FRAGMENT_ord:
setResultPredicate(GenericMatcherFactory.instance.isFragmentMatcher().withSourceEntity(entity));
break;
case KindTestEnum.VARIABLE_ord:
setResultPredicate(GenericMatcherFactory.instance.isVariableMatcher().withSourceEntity(entity));
break;
case KindTestEnum.RESOLVER_ord:
setResultPredicate(GenericMatcherFactory.instance.isResolverMatcher().withSourceEntity(entity));
break;
//TODO test only remove
case KindTestEnum.ADAPTER_ord:
case KindTestEnum.PROXY_ord:
case KindTestEnum.SAME_STAGE_FRAGMENT_ord:
case KindTestEnum.STAGE_UP_FRAGMENT_ord:
case KindTestEnum.STAGE_DOWN_FRAGMENT_ord:
throw new IllegalArgumentException();
default:
EntityKinds ekind = EntityKinds.valueOf(kind.getName());
setResultPredicate(GenericMatcherFactory.instance.hasKindMatcher(ekind).withSourceEntity(entity));
}
}
@Override
public void visit(StageTest entity) {
StageTestEnum.Value stage = entity.getValue();
switch (stage.getOrdinal()) {
case StageTestEnum.HOST_STAGE_ord:
setResultPredicate(GenericMatcherFactory.instance.atHostStageMatcher().withSourceEntity(entity));
break;
case StageTestEnum.HOST_STAGE_0_ord:
setResultPredicate(GenericMatcherFactory.instance.atStageMatcher(0).withSourceEntity(entity));
break;
case StageTestEnum.TEMPLATE_STAGE_1_ord:
setResultPredicate(GenericMatcherFactory.instance.atStageMatcher(1).withSourceEntity(entity));
break;
case StageTestEnum.TEMPLATE_STAGE_ord:
setResultPredicate(GenericMatcherFactory.instance.atTemplateStageMatcher().withSourceEntity(entity));
break;
}
}
@Override
public void visit(StageVariableTest entity) {
setResultPredicate(GenericMatcherFactory.instance.atStageVariableMatcher(entity.getValue()).withSourceEntity(entity));
}
@Override
public void visit(LanguageTest entity) {
String languageURI = entity.getValue();
setResultPredicate(GenericMatcherFactory.instance.isLanguageMatcher(languageURI).withSourceEntity(entity));
}
@Override
public void visit(TypeTest entity) {
setResultPredicate(GenericMatcherFactory.instance.hasTypeMatcher(entity.getValue()).withSourceEntity(entity));
}
@Override
public void visit(SubtypeTest entity) {
setResultPredicate(GenericMatcherFactory.instance.isLanguageSubtypeOfMatcher(entity.getValue()).withSourceEntity(entity));
}
@Override
public void visit(SupertypeTest entity) {
setResultPredicate(GenericMatcherFactory.instance.isLanguageSupertypeOfMatcher(entity.getValue()).withSourceEntity(entity));
}
@Override
public void visit(ExtendedSubtypeTest entity) {
setResultPredicate(GenericMatcherFactory.instance.isExtendedLanguageSubtypeOfMatcher(entity.getValue()).withSourceEntity(entity));
}
@Override
public void visit(ExtendedSupertypeTest entity) {
setResultPredicate(GenericMatcherFactory.instance.isExtendedLanguageSupertypeOfMatcher(entity.getValue()).withSourceEntity(entity));
}
@Override
public void visit(ExpressionTest entity) {
PathExpression e = entity.getExpression();
if (EntityUtils.isStageUpFragment(e)) {
CommonsInterpreterVisitor.evaluateAdapter((IEntityAdapter) e, getOperation());
IEntity pe = getResult();
setResultPredicate(GenericMatcherFactory.instance.matchInScope(pe).withSourceEntity(entity));
IEntityIterator<IEntity> variableIterator = IteratorFactory.descendantOrSelfMatcherIterator()
.withPattern(GenericMatcherFactory.instance.isVariableMatcher()).withSourceEntity(entity);
variableIterator.reset(pe);
for (IEntity variableAdapter : variableIterator) {
Variable variable = (Variable) variableAdapter.wGetAdaptee(false);
declaredNames.add(variable.getVarName().getValue());
}
} else if (EntityUtils.isSameStageFragment(e)) {
setResultPredicate(GenericMatcherFactory.evalTrue(e.wGetAdaptee(false).wGetRoot()).withSourceEntity(entity));
} else if (!e.wGetLanguageKit().getURI().equals(QueriesLanguageKit.URI)) {
setResultPredicate(GenericMatcherFactory.evalTrue(e.wGetAdaptee(false)).withSourceEntity(entity));
} else if (Matcher.matchImpl(QueriesEntityDescriptorEnum.PointwiseEquals, e))
e.accept(this);
else if (QueriesEntityDescriptorEnum.Expression.isLanguageSupertypeOf(e.wGetEntityDescriptor())
|| QueriesEntityDescriptorEnum.MathStep.isLanguageSupertypeOf(e.wGetEntityDescriptor()))
setResultPredicate(GenericMatcherFactory.evalTrue(e).withSourceEntity(entity));
else {
e.accept(this);
setResultPredicate(GenericMatcherFactory.instance.match(getResultIterator()).withSourceEntity(entity));
}
}
@Override
public void visit(PointwiseEquals entity) {
entity.getPexp1().accept(this);
IEntityIterator<? extends IEntity> exp1Iterator = getResultIterator();
entity.getPexp2().accept(this);
setResultPredicate(QueriesMatcherFactory.pointwiseEquals(exp1Iterator, getResultIterator()).withSourceEntity(entity));
}
@Override
public void visit(AtTypeTest entity) {
setResultPredicate(GenericMatcherFactory.instance.atTypeMatcher(entity.getValue()).withSourceEntity(entity));
}
@Override
public void visit(AtFeatureTest entity) {
setResultPredicate(GenericMatcherFactory.instance.atFeatureMatcher(entity.getValue()).withSourceEntity(entity));
}
@Override
public void visit(AtIndexTest entity) {
setResultPredicate(GenericMatcherFactory.instance.atIndexMatcher(entity.getValue()).withSourceEntity(entity).withSourceEntity(entity));
}
@Override
public void visit(IndexVariableTest entity) {
String varName = entity.getValue();
declaredNames.add(varName);
if (filterByIndexIterator == null) {
filterByIndexIterator = IteratorFactory.filterByIndexRangeIterator();
filterByIndexIterator.withSourceEntity(entity);
}
setResultPredicate(GenericMatcherFactory.instance.matchIteratorIndexVariable(
filterByIndexIterator, varName).withSourceEntity(entity));
updateIndexRange(0, Integer.MAX_VALUE);
}
@Override
public void visit(IndexTest entity) {
if (filterByIndexIterator == null) {
filterByIndexIterator = IteratorFactory.filterByIndexRangeIterator();
filterByIndexIterator.withSourceEntity(entity);
}
int index = entity.getIndex().getValue();
setResultPredicate(GenericMatcherFactory.instance.matchIteratorIndex(
filterByIndexIterator, index).withSourceEntity(entity));
updateIndexRange(index, index);
}
@Override
public void visit(IndexRangeTest entity) {
if (filterByIndexIterator == null) {
filterByIndexIterator = IteratorFactory.filterByIndexRangeIterator();
filterByIndexIterator.withSourceEntity(entity);
}
int startIndexValue = entity.getStartIndex().getValue();
int endIndexValue;
IntLiteral endIndex = entity.getEndIndex();
if (Matcher.matchImpl(QueriesEntityDescriptorEnum.IntLiteral, endIndex))
endIndexValue = endIndex.getValue();
else
endIndexValue = Integer.MAX_VALUE;
setResultPredicate(GenericMatcherFactory.instance.matchIteratorIndexRange(
filterByIndexIterator, startIndexValue, endIndexValue).withSourceEntity(entity));
updateIndexRange(startIndexValue, endIndexValue);
}
protected void updateIndexRange(int startIndex, int endIndex) {
if (startIndex < this.startIndex)
this.startIndex = startIndex;
if (endIndex > this.endIndex)
this.endIndex = endIndex;
canFilterByIndex = true;
}
@Override
public void visit(VisitorTest entity) {
setResultPredicate(entity.getValue().withSourceEntity(entity));
}
@Override
public void visit(DistinctTest entity) {
IEntityComparator<IEntity> oldComparator = comparator;
comparator = BusinessIdentityComparator.instance;
entity.getComparator().accept(this);
if (distinctScope == null)
distinctScope = IteratorFactory.distinctScope();
distinctScope.withComparator(comparator);
setResultPredicate(distinctScope.distinctMatcher().withSourceEntity(entity));
comparator = oldComparator;
}
@Override
public void visit(And entity) {
visitFrom(entity, 0);
}
private void visitFrom(And entity, int from) {
int size = entity.wSize()-from;
IVisitor[] visitors = new IVisitor[size];
for (int i = from; i < size; i++) {
entity.get(i).accept(this);
visitors[i] = getResultPredicate();
}
setResultPredicate(GenericTraversalFactory.instance.all(visitors).withSourceEntity(entity));
}
@Override
public void visit(Or entity) {
boolean canFilterByIndexResult = canFilterByIndex;
int size = entity.wSize();
IVisitor[] visitors = new IVisitor[size];
for (int i = 0; i < size; i++) {
canFilterByIndex = false;
entity.get(i).accept(this);
visitors[i] = getResultPredicate();
canFilterByIndexResult &= !canFilterByIndex;
}
setResultPredicate(GenericTraversalFactory.instance.one(visitors).withSourceEntity(entity));
canFilterByIndex = canFilterByIndexResult;
}
@Override
public void visit(Not entity) {
entity.getPredicate().accept(this);
setResultPredicate(GenericTraversalFactory.instance.not(getResultPredicate()).withSourceEntity(entity));
}
@Override
public void visit(ParenthesizedPredicate entity) {
entity.getPredicate().accept(this);
}
@Override
public void visit(IdentityComparator entity) {
entity.getIdentity().accept(this);
comparator = new IdentityIteratorComparator<IEntity>(getResultIterator());
}
protected IEntityComparator<IEntity> comparator;
@Override
public void visit(Expressions entity) {
IEntityIterator<?>[] iteratorChain = new IEntityIterator<?>[entity.wSize()];
for (int i=0; i<entity.wSize(); i++) {
entity.get(i).accept(this);
iteratorChain[i] = getResultIterator();
}
this.iteratorChain = iteratorChain;
}
protected IEntityIterator<?>[] iteratorChain;
@Override
public void visit(UnionAll entity) {
entity.getExpressions().accept(this);
setResultIterator(IteratorFactory.unionAllIterator(iteratorChain).withSourceEntity(entity));
}
public void visitCollectByExpression(CollectByExpression entity) {
entity.getComparator().accept(this);
entity.getExpressions().accept(this);
}
@Override
public void visit(Union entity) {
IEntityComparator<IEntity> oldComparator = comparator;
comparator = BusinessIdentityComparator.instance;
visitCollectByExpression(entity);
setResultIterator(IteratorFactory.unionIterator(iteratorChain)
.withComparator(comparator).withSourceEntity(entity));
comparator = oldComparator;
}
@Override
public void visit(Intersect entity) {
IEntityComparator<IEntity> oldComparator = comparator;
comparator = BusinessIdentityComparator.instance;
visitCollectByExpression(entity);
setResultIterator(IteratorFactory.intersectIterator(iteratorChain)
.withComparator(comparator).withSourceEntity(entity));
comparator = oldComparator;
}
@Override
public void visit(Except entity) {
IEntityComparator<IEntity> oldComparator = comparator;
comparator = BusinessIdentityComparator.instance;
visitCollectByExpression(entity);
setResultIterator(IteratorFactory.exceptIterator(iteratorChain)
.withComparator(comparator).withSourceEntity(entity));
comparator = oldComparator;
}
protected void setLiteral(IEntity entity) {
setResultIterator(IteratorFactory.constantIterator(
BindingManagerFactory.instance.createSpecificValue(entity), true).withSourceEntity(entity));
}
public void visit(BooleanLiteral entity) {
setLiteral(entity);
}
public void visit(ByteLiteral entity) {
setLiteral(entity);
}
public void visit(CharLiteral entity) {
setLiteral(entity);
}
public void visit(DoubleLiteral entity) {
setLiteral(entity);
}
public void visit(FloatLiteral entity) {
setLiteral(entity);
}
public void visit(IntLiteral entity) {
setLiteral(entity);
}
public void visit(LongLiteral entity) {
setLiteral(entity);
}
public void visit(ShortLiteral entity) {
setLiteral(entity);
}
public void visit(DateLiteral entity) {
setLiteral(entity);
}
public void visit(StringLiteral entity) {
setLiteral(entity);
}
public void visit(VoidLiteral entity) {
setResultIterator(IteratorFactory.constantIterator(
BindingManagerFactory.instance.createVoid(), true).withSourceEntity(entity));
}
public void visitExpression(Expression entity) {
setResultIterator(QueriesIteratorFactory.templateInterpreterIterator(entity).withSourceEntity(entity));
}
protected IEntityIterator<?> compile(Expression entity) {
entity.accept(this);
return getResultIterator();
}
@Override
public void visit(AdditionStep entity) {
setResultIterator(MathUtils.additionStepIterator(compile(entity.getExpression())).withSourceEntity(entity));
}
@Override
public void visit(SubtractionStep entity) {
setResultIterator(MathUtils.subtractionStepIterator(compile(entity.getExpression())).withSourceEntity(entity));
}
@Override
public void visit(MultiplicationStep entity) {
setResultIterator(MathUtils.multiplicationStepIterator(compile(entity.getExpression())).withSourceEntity(entity));
}
@Override
public void visit(DivisionStep entity) {
setResultIterator(MathUtils.divisionStepIterator(compile(entity.getExpression())).withSourceEntity(entity));
}
@Override
public void visit(RemainderStep entity) {
setResultIterator(MathUtils.remainderStepIterator(compile(entity.getExpression())).withSourceEntity(entity));
}
@Override
public void visit(EqualsStep entity) {
setResultIterator(MathUtils.equalsStepIterator(compile(entity.getExpression())).withSourceEntity(entity));
}
@Override
public void visit(NotEqualsStep entity) {
setResultIterator(MathUtils.notEqualsStepIterator(compile(entity.getExpression())).withSourceEntity(entity));
}
@Override
public void visit(LessThanStep entity) {
setResultIterator(MathUtils.lessThanStepIterator(compile(entity.getExpression())).withSourceEntity(entity));
}
@Override
public void visit(LessOrEqualsStep entity) {
setResultIterator(MathUtils.lessOrEqualsStepIterator(compile(entity.getExpression())).withSourceEntity(entity));
}
@Override
public void visit(GreaterThanStep entity) {
setResultIterator(MathUtils.greaterThanStepIterator(compile(entity.getExpression())).withSourceEntity(entity));
}
@Override
public void visit(GreaterOrEqualsStep entity) {
setResultIterator(MathUtils.greaterOrEqualsStepIterator(compile(entity.getExpression())).withSourceEntity(entity));
}
@Override
public void visit(Addition entity) {
setResultIterator(MathUtils.additionIterator(compile(entity.getExp1()), compile(entity.getExp2())).withSourceEntity(entity));
}
@Override
public void visit(Subtraction entity) {
setResultIterator(MathUtils.subtractionIterator(compile(entity.getExp1()), compile(entity.getExp2())).withSourceEntity(entity));
}
@Override
public void visit(Multiplication entity) {
setResultIterator(MathUtils.multiplicationIterator(compile(entity.getExp1()), compile(entity.getExp2())).withSourceEntity(entity));
}
@Override
public void visit(Division entity) {
setResultIterator(MathUtils.divisionIterator(compile(entity.getExp1()), compile(entity.getExp2())).withSourceEntity(entity));
}
@Override
public void visit(Remainder entity) {
setResultIterator(MathUtils.remainderIterator(compile(entity.getExp1()), compile(entity.getExp2())).withSourceEntity(entity));
}
@Override
public void visit(Equals entity) {
setResultIterator(MathUtils.equalsIterator(compile(entity.getExp1()), compile(entity.getExp2())).withSourceEntity(entity));
}
@Override
public void visit(NotEquals entity) {
setResultIterator(MathUtils.notEqualsIterator(compile(entity.getExp1()), compile(entity.getExp2())).withSourceEntity(entity));
}
@Override
public void visit(LessThan entity) {
setResultIterator(MathUtils.lessThanIterator(compile(entity.getExp1()), compile(entity.getExp2())).withSourceEntity(entity));
}
@Override
public void visit(LessOrEquals entity) {
setResultIterator(MathUtils.lessOrEqualsIterator(compile(entity.getExp1()), compile(entity.getExp2())).withSourceEntity(entity));
}
@Override
public void visit(GreaterThan entity) {
setResultIterator(MathUtils.greaterThanIterator(compile(entity.getExp1()), compile(entity.getExp2())).withSourceEntity(entity));
}
@Override
public void visit(GreaterOrEquals entity) {
setResultIterator(MathUtils.greaterOrEqualsIterator(compile(entity.getExp1()), compile(entity.getExp2())).withSourceEntity(entity));
}
@Override
public void visit(Singleton entity) {
entity.getExpression().accept(this);
}
}