blob: be1e0f0a812d1bf20ce64751b03d64afd4adc51a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008-2018 The University of York.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* Contributors:
* Dimitrios Kolovos - initial API and implementation
* Sina Madani - optimisation / refactoring
******************************************************************************/
package org.eclipse.epsilon.evl.execute.operations;
import java.util.List;
import org.eclipse.epsilon.common.module.ModuleElement;
import org.eclipse.epsilon.eol.exceptions.EolRuntimeException;
import org.eclipse.epsilon.eol.execute.context.IEolContext;
import org.eclipse.epsilon.eol.execute.operations.simple.SimpleOperation;
import org.eclipse.epsilon.eol.types.EolNoType;
import org.eclipse.epsilon.evl.dom.Constraint;
import org.eclipse.epsilon.evl.dom.Constraints;
import org.eclipse.epsilon.evl.dom.GlobalConstraintContext;
import org.eclipse.epsilon.evl.execute.context.IEvlContext;
import org.eclipse.epsilon.evl.execute.exceptions.EvlConstraintNotFoundException;
import org.eclipse.epsilon.evl.trace.ConstraintTrace;
//TODO: Detect cyclic dependencies and throw EvlCircularAssumptionException
public class SatisfiesOperation extends SimpleOperation {
protected boolean all = true;
public SatisfiesOperation(boolean all) {
super();
this.all = all;
}
public boolean isAll() {
return all;
}
public void setAll(boolean all) {
this.all = all;
}
@Override
public Boolean execute(Object source, List<?> parameters, IEolContext context_, ModuleElement ast) throws EolRuntimeException {
if (source == null)
return false;
IEvlContext context = (IEvlContext) context_;
ConstraintTrace constraintTrace = context.getConstraintTrace();
assert constraintTrace != null;
Constraints constraints = context.getModule().getConstraints();
for (Object parameter : parameters) {
String constraintName = context.getPrettyPrinterManager().toString(parameter);
Constraint constraint = constraints.getConstraint(constraintName, source, context)
.orElseThrow(() -> new EvlConstraintNotFoundException(constraintName, ast));
// This is to avoid duplication of global constraints
if (constraint.getConstraintContext() instanceof GlobalConstraintContext) {
source = EolNoType.Instance;
}
boolean valid; //Check the trace first
if (constraint.isDependedOn() && constraintTrace.isChecked(constraint, source)) {
valid = constraintTrace.isSatisfied(constraint, source);
}
else {
// Don't call execute() or shouldBeChecked because it might be a lazy constraint, so need to force appliesTo && check.
if (constraint.appliesTo(source, context)) {
valid = !constraint.check(source, context).isPresent();
}
else {
valid = false;
}
if (context.isOptimizeConstraintTrace()) {
constraintTrace.addChecked(constraint, source, valid);
}
constraint.setAsDependency();
}
if (all && !valid)
return false;
else if (valid)
return true;
}
return true;
}
}