/******************************************************************************* * Copyright (c) 2005, 2008 committers of openArchitectureWare and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * committers of openArchitectureWare - initial API and implementation * Alexander Shatalin (Borland) *******************************************************************************/ package org.eclipse.gmf.internal.xpand.expression.ast; import java.util.Set; import org.eclipse.emf.ecore.EClassifier; import org.eclipse.emf.ecore.EDataType; import org.eclipse.emf.ecore.EcorePackage; import org.eclipse.gmf.internal.xpand.BuiltinMetaModel; import org.eclipse.gmf.internal.xpand.expression.AnalysationIssue; import org.eclipse.gmf.internal.xpand.expression.EvaluationException; import org.eclipse.gmf.internal.xpand.expression.ExecutionContext; public class BooleanOperation extends Expression { private static final String IMPLIES = "implies"; private static final String OR = "||"; private static final String AND = "&&"; private String operator; private Expression left; private Expression right; public BooleanOperation(final int start, final int end, final int line, final int startOffset, final int endOffset, final String operator, final Expression e, final Expression r) { super(start, end, line, startOffset, endOffset); assert operator != null; this.operator = operator; left = e; right = r; } @Override protected Object evaluateInternal(final ExecutionContext ctx) { final Boolean l = evaluateToBoolean(left, ctx); if (l == null) { return null; } if (isAndOperation()) { if (!l.booleanValue()) { return Boolean.FALSE; } final Boolean r = evaluateToBoolean(right, ctx); if (r == null) { return null; } return Boolean.valueOf(l.booleanValue() && r.booleanValue()); } else if (isOrOperation()) { if (l.booleanValue()) { return Boolean.TRUE; } final Boolean r = evaluateToBoolean(right, ctx); if (r == null) { return null; } return Boolean.valueOf(l.booleanValue() || r.booleanValue()); } else if (isImpliesOperation()) { if (!l.booleanValue()) { return Boolean.TRUE; } return evaluateToBoolean(right, ctx); } else { throw new EvaluationException("Unkown Boolean operator " + operator, this); } } private Boolean evaluateToBoolean(final Expression expr, final ExecutionContext ctx) { final Object l = expr.evaluate(ctx); if (l == null) { return null; } if (!(l instanceof Boolean)) { final EClassifier t = BuiltinMetaModel.getType(l); throw new EvaluationException("Boolean expected but was " + t.getName(), expr); } return (Boolean) l; } public EClassifier analyze(final ExecutionContext ctx, final Set<AnalysationIssue> issues) { final EClassifier l = left.analyze(ctx, issues); final EClassifier r = right.analyze(ctx, issues); if ((l == null) || (r == null)) { return null; } final EDataType dt = EcorePackage.eINSTANCE.getEBoolean(); if (!dt.equals(l)) { issues.add(new AnalysationIssue(AnalysationIssue.Type.INCOMPATIBLE_TYPES, "Boolean expected! Found : " + l.getName(), left)); } if (!dt.equals(r)) { issues.add(new AnalysationIssue(AnalysationIssue.Type.INCOMPATIBLE_TYPES, "Boolean expected! Found : " + r.getName(), right)); } return dt; } public Expression getLeft() { return left; } public Expression getRight() { return right; } public boolean isImpliesOperation() { return operator.equals(IMPLIES); } public boolean isOrOperation() { return operator.equals(OR); } public boolean isAndOperation() { return operator.equals(AND); } public String getOperator() { return operator; } }