blob: 77fb4fd91a88af171995af88349c716ea90ef956 [file] [log] [blame]
/**
* <copyright>
*
* Copyright (c) 2012, 2013 E.D.Willink 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:
* E.D.Willink - initial API and implementation
*
* </copyright>
*/
package org.eclipse.ocl.examples.xtext.essentialocl.attributes;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.examples.domain.elements.DomainOperation;
import org.eclipse.ocl.examples.pivot.CollectionType;
import org.eclipse.ocl.examples.pivot.Element;
import org.eclipse.ocl.examples.pivot.Iteration;
import org.eclipse.ocl.examples.pivot.OCLExpression;
import org.eclipse.ocl.examples.pivot.PivotConstants;
import org.eclipse.ocl.examples.pivot.Type;
import org.eclipse.ocl.examples.pivot.manager.MetaModelManager;
import org.eclipse.ocl.examples.pivot.utilities.PivotUtil;
import org.eclipse.ocl.examples.xtext.base.basecs.PathElementCS;
import org.eclipse.ocl.examples.xtext.base.basecs.PathNameCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.AbstractNameExpCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.ExpCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.InvocationExpCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.NavigatingArgCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.NavigationOperatorCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.NavigationRole;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.OperatorCS;
public class NavigationUtil
{
/**
* Return the NavigationOperatorCS for which csExp is the left node of the navigation operator's argument tree.
*/
public static @Nullable NavigationOperatorCS getNavigationOperator(@NonNull AbstractNameExpCS csExp) {
EObject eContainer = csExp.eContainer();
if (eContainer instanceof AbstractNameExpCS) {
csExp = (AbstractNameExpCS) eContainer;
}
for (ExpCS csChild = csExp; true; csChild = csChild.getParent()) {
OperatorCS csOperator = csChild.getParent();
if (csOperator == null) {
return null;
}
ExpCS csSource = csOperator.getSource();
if (csSource == csChild) { // e.g. ... -> (X... -> ...)
;
}
else if (csOperator instanceof NavigationOperatorCS) { // e.g ... -> X
return (NavigationOperatorCS) csOperator;
}
else { // e.g. ... and X
return null;
}
}
}
/**
* Return the source type of a navigation adjusting any implicit collect to the flattened source type, and
* and implicit oclAsSet to the Set type.
*
*/
public static @Nullable Type getNavigationSourceType(@NonNull MetaModelManager metaModelManager, @NonNull NavigationOperatorCS csOperator) {
ExpCS csSource = csOperator.getSource();
if (csSource == null) {
return null;
}
OCLExpression source = PivotUtil.getPivot(OCLExpression.class, csSource);
if (source == null) {
return null;
}
Type type = source.getType();
if (type == null) {
return null;
}
String opName = csOperator.getName();
if (opName.equals(PivotConstants.COLLECTION_NAVIGATION_OPERATOR)) {
if (type instanceof CollectionType) { // collection->collection-feature-name...
return type;
}
else { // object.oclAsSet()->collection-feature-name...
return metaModelManager.getCollectionType(false, true, type, null, null);
}
}
else {
if (type instanceof CollectionType) { // collection->implicit-collect(object-feature-name...)
while (type instanceof CollectionType) { // implicit-collect flattens
type = ((CollectionType)type).getElementType();
}
return type;
}
else { // object.object-feature-name...
return type;
}
}
}
public static boolean isIteration(@NonNull MetaModelManager metaModelManager, @NonNull InvocationExpCS csInvocationExp, @NonNull CollectionType type) {
for (NavigatingArgCS csArg : csInvocationExp.getArgument()) {
if (csArg.getRole() != NavigationRole.EXPRESSION) {
return true;
}
}
PathNameCS pathName = csInvocationExp.getPathName();
List<PathElementCS> path = pathName.getPath();
if (path.size() != 1) {
return false;
}
PathElementCS csPathElement = path.get(0);
Element unresolvedElement = csPathElement.basicGetElement();
if ((unresolvedElement != null) && !unresolvedElement.eIsProxy()) {
return unresolvedElement instanceof Iteration;
}
String name = csPathElement.toString();
assert name != null;
for (DomainOperation operation : metaModelManager.getAllOperations(type, false, name)) {
return operation instanceof Iteration; // mixed overload are not allowed
}
return false;
}
}