blob: 18d31f3a254c63e42f37ef86c3c378db907ab103 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2018 R.Dvorak and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Radek Dvorak - initial API and implementation
*******************************************************************************/
package org.eclipse.m2m.qvt.oml.debug.core.vm;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EEnumLiteral;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EParameter;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.m2m.internal.qvt.oml.ast.env.InternalEvaluationEnv;
import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalEvaluationEnv;
import org.eclipse.m2m.internal.qvt.oml.evaluator.ModuleInstance;
import org.eclipse.m2m.internal.qvt.oml.evaluator.TransformationInstance;
import org.eclipse.m2m.internal.qvt.oml.expressions.ContextualProperty;
import org.eclipse.m2m.internal.qvt.oml.expressions.Module;
import org.eclipse.m2m.internal.qvt.oml.expressions.OperationalTransformation;
import org.eclipse.ocl.Environment;
import org.eclipse.ocl.ecore.CallOperationAction;
import org.eclipse.ocl.ecore.Constraint;
import org.eclipse.ocl.ecore.SendSignalAction;
import org.eclipse.ocl.types.OCLStandardLibrary;
public class UnitLocationExecutionContext implements VMFrameExecutionContext {
private final Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral,
EParameter,EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> fEnv;
private final QvtOperationalEvaluationEnv fEvalEnv;
UnitLocationExecutionContext(
Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral,
EParameter,EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env,
QvtOperationalEvaluationEnv evalEnv) {
if (env == null || evalEnv == null) {
throw new IllegalArgumentException();
}
fEnv = env;
fEvalEnv = evalEnv;
}
public EClassifier getOCLType(EStructuralFeature feature) {
return fEnv.getUMLReflection().getOCLType(feature);
}
public OCLStandardLibrary<EClassifier> getStandardLibrary() {
return fEnv.getOCLStandardLibrary();
}
public List<EStructuralFeature> getAllFeatures(EClass eClass) {
List<EStructuralFeature> features = new ArrayList<EStructuralFeature>();
features.addAll(eClass.getEAllStructuralFeatures());
if(eClass instanceof Module) {
for (Iterator<EStructuralFeature> it = features.iterator(); it.hasNext();) {
EStructuralFeature feature = it.next();
if(feature instanceof ContextualProperty) {
it.remove();
}
}
}
collectIntermediateProperties(features, eClass);
return features;
}
public QvtOperationalEvaluationEnv getEvalEnv() {
return fEvalEnv;
}
public Object getValue(EStructuralFeature feature, EObject target) {
return fEvalEnv.navigateProperty(feature, null, target);
}
private void collectIntermediateProperties(List<EStructuralFeature> properties, EClass targetClass) {
QvtOperationalEvaluationEnv evalEnv = fEvalEnv;
InternalEvaluationEnv internEvalEnv = evalEnv.getAdapter(InternalEvaluationEnv.class);
ModuleInstance currentModule = internEvalEnv.getCurrentModule();
// check if we are in transformation execution context
if(currentModule instanceof TransformationInstance) {
collectIntermediateProperties(properties, targetClass, (TransformationInstance) currentModule);
}
}
// TODO - build a cache for all target types to avoid repeated lookups
private void collectIntermediateProperties(List<EStructuralFeature> properties, EClass targetClass, TransformationInstance scopeModule) {
OperationalTransformation operationalTransformation = scopeModule.getTransformation();
for (EStructuralFeature nextProperty : operationalTransformation.getIntermediateProperty()) {
if(nextProperty instanceof ContextualProperty) {
ContextualProperty ctxProperty = (ContextualProperty) nextProperty;
if(ctxProperty.getContext().isSuperTypeOf(targetClass)) {
properties.add(ctxProperty);
}
}
}
for (ModuleInstance importedModule : scopeModule.getImportedModules()) {
if(importedModule instanceof TransformationInstance) {
// Note: only transformation imported by <extends> have implicit module instances
collectIntermediateProperties(properties, targetClass, (TransformationInstance) importedModule);
}
}
}
}