blob: fb354bbebee75c1a3ac55c656964a4bf6f6f73bb [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2014, 2015 Willink Transformations 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:
* R.Dvorak and others - QVTo debugger framework
* E.D.Willink - revised API for OCL/QVTi debugger framework
*******************************************************************************/
package org.eclipse.qvtd.debug.evaluator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.examples.debug.vm.UnitLocation;
import org.eclipse.ocl.examples.debug.vm.evaluator.IVMRootEvaluationEnvironment;
import org.eclipse.ocl.examples.debug.vm.utils.ASTBindingHelper;
import org.eclipse.ocl.examples.debug.vm.utils.VMRuntimeException;
import org.eclipse.ocl.examples.debug.vm.utils.VMStackTraceBuilder;
import org.eclipse.ocl.pivot.Element;
import org.eclipse.ocl.pivot.NamedElement;
import org.eclipse.ocl.pivot.PivotFactory;
import org.eclipse.ocl.pivot.PivotPackage;
import org.eclipse.ocl.pivot.Variable;
import org.eclipse.ocl.pivot.internal.utilities.EnvironmentFactoryInternal;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.qvtd.debug.core.QVTiDebugCore;
import org.eclipse.qvtd.pivot.qvtbase.Transformation;
import org.eclipse.qvtd.pivot.qvtbase.TypedModel;
import org.eclipse.qvtd.pivot.qvtimperative.evaluation.QVTiModelManager;
import org.eclipse.qvtd.pivot.qvtimperative.evaluation.QVTiRootEvaluationEnvironment;
public class QVTiVMRootEvaluationEnvironment extends QVTiRootEvaluationEnvironment implements IQVTiVMEvaluationEnvironment,IVMRootEvaluationEnvironment<Transformation>
{
// private IContext myContext;
private List<Runnable> myDeferredTasks;
// private EObjectEStructuralFeaturePair myLastAssignLvalue;
// private ModelParameterExtent myUnboundExtent;
private boolean myIsDeferedExecution;
// private QvtRuntimeException myException;
// private Trace myTraces;
private @NonNull Element myCurrentIP;
private final long id;
private final @NonNull Variable pcVariable;
private final @NonNull Stack<StepperEntry> stepperStack = new Stack<StepperEntry>();
public QVTiVMRootEvaluationEnvironment(@NonNull EnvironmentFactoryInternal environmentFactory, @NonNull Transformation executableObject, @NonNull QVTiModelManager modelManager, long id) {
super(environmentFactory, executableObject, modelManager);
myCurrentIP = executableObject;
this.id = id;
pcVariable = ClassUtil.nonNullEMF(PivotFactory.eINSTANCE.createVariable());
pcVariable.setName("$pc");
String typeName = ClassUtil.nonNullEMF(PivotPackage.Literals.OCL_EXPRESSION.getName());
pcVariable.setType(environmentFactory.getMetamodelManager().getASClass(typeName));
}
@Override
public @NonNull IQVTiVMEvaluationEnvironment createClonedEvaluationEnvironment() {
throw new UnsupportedOperationException();
}
// @Override
// IContext getContext() {
// return myContext;
// }
@Override
public @NonNull Element getCurrentIP() {
return myCurrentIP;
}
public @NonNull UnitLocation getCurrentLocation() {
// if (myCurrentIP == null) {
// return null;
// }
// else {
int startPosition = ASTBindingHelper.getStartPosition(myCurrentIP);
int endPosition = ASTBindingHelper.getEndPosition(myCurrentIP);
return new UnitLocation(startPosition, endPosition, this, myCurrentIP);
// }
}
public @NonNull QVTiDebugCore getDebugCore() {
return QVTiDebugCore.INSTANCE;
}
@Override
public @NonNull Transformation getDebuggableElement() {
return getTransformation();
}
@Override
public int getDepth() {
return 1;
}
// @Override
// public QvtRuntimeException getException() {
// return myException;
// }
@Override
public long getID() {
return id;
}
@Override
public @NonNull QVTiVMModelManager getModelManager() {
return (QVTiVMModelManager) super.getModelManager();
}
public @NonNull Map<String, Resource> getModelParameterVariables() {
Transformation currentModule = getTransformation();
// if (!(currentModule instanceof Transformation)) {
// return Collections.emptyMap();
// }
Map<String, Resource> result = new HashMap<String, Resource>(2);
Transformation currentTransformation = currentModule;
QVTiVMModelManager modelManager = getModelManager();
for (TypedModel typedModel : currentTransformation.getModelParameter()) {
if (typedModel != null) {
Resource model = modelManager.getModel(typedModel);
result.put(typedModel.getName(), model);
}
}
// ModelInstance intermModel = currentTransformation.getAdapter(
// TransformationInstance.InternalTransformation.class)
// .getIntermediateExtent();
// if(intermModel != null) {
// result.put("_intermediate", intermModel);
// }
return result;
}
@Override
public @NonNull NamedElement getOperation() {
return getTransformation();
}
@Override
public @Nullable QVTiVMRootEvaluationEnvironment getParentEvaluationEnvironment() {
return (QVTiVMRootEvaluationEnvironment) super.getParentEvaluationEnvironment();
}
@Override
@NonNull public Variable getPCVariable() {
return pcVariable;
}
@Override
public @NonNull QVTiVMRootEvaluationEnvironment getRootEvaluationEnvironment() {
return this;
}
@Override
public @NonNull Stack<org.eclipse.ocl.examples.debug.vm.evaluator.IVMEvaluationEnvironment.StepperEntry> getStepperStack() {
return stepperStack;
}
@Override
public boolean isDeferredExecution() {
return myIsDeferedExecution;
}
@Override
public void processDeferredTasks() {
if (myDeferredTasks != null) {
try {
myIsDeferedExecution = true;
// make me re-entrant in case of errorenous call to #addDeferredTask()
// from running the task => concurrent modification exception
// This error condition should be handled elsewhere
List<Runnable> tasksCopy = new ArrayList<Runnable>(myDeferredTasks);
for (Runnable task : tasksCopy) {
task.run();
}
} finally {
myIsDeferedExecution = false;
}
}
}
protected void saveThrownException(@NonNull VMRuntimeException exception) {
// myException = exception;
}
public @NonNull Element setCurrentIP(@NonNull Element element) {
Element prevValue = myCurrentIP;
myCurrentIP = element;
return prevValue;
}
public void setException(@NonNull VMRuntimeException exception) {
saveThrownException(exception);
}
public void throwVMException(@NonNull VMRuntimeException exception) throws VMRuntimeException {
try {
saveThrownException(exception);
exception.setStackVMTrace(new VMStackTraceBuilder(this).buildStackTrace());
} catch (Exception e) {
getDebugCore().error("Failed to build VM stack trace", e); //$NON-NLS-1$
}
throw exception;
}
}