blob: a1c31b25f07fb9537c9eda6240f7dda26f9f3da5 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2015, 2020 Willink Transformations 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:
* E.D.Willink - Initial API and implementation
*******************************************************************************/
package org.eclipse.qvtd.compiler.internal.qvtb2qvts;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.CompleteClass;
import org.eclipse.ocl.pivot.CompleteModel;
import org.eclipse.ocl.pivot.CompletePackage;
import org.eclipse.ocl.pivot.DataType;
import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.StandardLibrary;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.TypedElement;
import org.eclipse.ocl.pivot.utilities.EnvironmentFactory;
import org.eclipse.ocl.pivot.utilities.PivotUtil;
import org.eclipse.qvtd.compiler.CompilerOptions;
import org.eclipse.qvtd.compiler.ProblemHandler;
import org.eclipse.qvtd.compiler.internal.qvtb2qvts.trace.NameGenerator;
import org.eclipse.qvtd.compiler.internal.qvtb2qvts.trace.Transformation2TracePackage;
import org.eclipse.qvtd.compiler.internal.usage.RootDomainUsageAnalysis;
import org.eclipse.qvtd.pivot.qvtbase.Transformation;
import org.eclipse.qvtd.pivot.qvtbase.TypedModel;
import org.eclipse.qvtd.pivot.qvtschedule.ClassDatum;
import org.eclipse.qvtd.pivot.qvtschedule.NavigationEdge;
import org.eclipse.qvtd.pivot.qvtschedule.Node;
import org.eclipse.qvtd.pivot.qvtschedule.PropertyDatum;
import org.eclipse.qvtd.pivot.qvtschedule.ScheduleModel;
import org.eclipse.qvtd.pivot.qvtschedule.utilities.DomainUsage;
import org.eclipse.qvtd.pivot.qvtschedule.utilities.QVTscheduleUtil;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
public abstract class BasicScheduleManager extends AbstractScheduleManager
{
protected final @NonNull NameGenerator nameGenerator;
protected final @NonNull DatumCaches datumCaches;
private @Nullable ClassDatum booleanClassDatum;
private @Nullable ClassDatum oclVoidClassDatum;
/**
* The extended analysis of each ClassDatum.
*/
private final @NonNull Set<@NonNull ClassDatum> classDatums = new HashSet<>();
/**
* Property used as a navigation to cast to a specific type.
*/
// private final @NonNull Map<Type, Property> type2castProperty = new HashMap<>();
/**
* Property used as a navigation to iterate collection elements.
*/
private final @NonNull Map<Type, Property> type2iterateProperty = new HashMap<>();
private final @NonNull Map<@NonNull Transformation, @NonNull Transformation2TracePackage> transformation2transformation2TracePackage = new HashMap<>();
protected BasicScheduleManager(@NonNull ScheduleModel scheduleModel, @NonNull EnvironmentFactory environmentFactory,
@NonNull Transformation transformation, @NonNull ProblemHandler problemHandler, CompilerOptions.@Nullable StepOptions schedulerOptions) {
this(scheduleModel, environmentFactory, transformation, problemHandler, schedulerOptions, null, null, null);
}
protected BasicScheduleManager(@NonNull ScheduleModel scheduleModel, @NonNull EnvironmentFactory environmentFactory,
@NonNull Transformation transformation, @NonNull ProblemHandler problemHandler, CompilerOptions.@Nullable StepOptions schedulerOptions,
@Nullable NameGenerator nameGenerator, @Nullable DatumCaches datumCaches, @Nullable RootDomainUsageAnalysis domainUsageAnalysis) {
super(scheduleModel, environmentFactory, transformation, problemHandler, schedulerOptions, domainUsageAnalysis);
this.nameGenerator = nameGenerator != null ? nameGenerator : createNameGenerator();
this.datumCaches = datumCaches != null ? datumCaches : new DatumCaches(this);
}
@Override
public void analyzeCompletePackage(@NonNull TypedModel typedModel, @NonNull CompletePackage completePackage) {
// domainUsageAnalysis.analyzeTracePackage(typedModel, tracePackage);
datumCaches.analyzeCompletePackage(typedModel, completePackage);
}
@Override
public void analyzeTracePackage(@NonNull TypedModel typedModel, org.eclipse.ocl.pivot.@NonNull Package tracePackage) {
domainUsageAnalysis.analyzeTracePackage(typedModel, tracePackage);
CompleteModel completeModel = environmentFactory.getCompleteModel();
CompletePackage completePackage = completeModel.getCompletePackage(tracePackage);
datumCaches.analyzeCompletePackage(typedModel, completePackage);
}
@Override
public @NonNull Iterable<@NonNull PropertyDatum> getAllPropertyDatums(@NonNull ClassDatum classDatum) {
return datumCaches.getAllPropertyDatums(classDatum);
}
@Override
public @NonNull ClassDatum getBooleanClassDatum() {
ClassDatum booleanClassDatum2 = booleanClassDatum;
if (booleanClassDatum2 == null) {
TypedModel primitiveTypedModel = domainUsageAnalysis.getPrimitiveTypedModel();
StandardLibrary standardLibrary = environmentFactory.getStandardLibrary();
booleanClassDatum = booleanClassDatum2 = getClassDatum(primitiveTypedModel, standardLibrary.getBooleanType());
}
return booleanClassDatum2;
}
@Override
public @NonNull ClassDatum getClassDatum(@NonNull TypedModel typedModel, @NonNull CompleteClass completeClass) {
return datumCaches.getClassDatum(typedModel, completeClass);
}
@Override
public @NonNull ClassDatum getClassDatum(@NonNull TypedModel typedModel, @NonNull Iterable<@NonNull CompleteClass> completeClasses) {
int size = Iterables.size(completeClasses);
if (size == 1) {
return datumCaches.getClassDatum(typedModel, completeClasses.iterator().next());
}
else {
return datumCaches.getClassDatum(typedModel, Sets.newHashSet(completeClasses));
}
}
@Override
public @NonNull ClassDatum getClassDatum(@NonNull TypedElement asTypedElement) {
org.eclipse.ocl.pivot.Class asType = (org.eclipse.ocl.pivot.Class)asTypedElement.getType();
assert asType != null;
Type elementType = PivotUtil.getElementalType(asType);
TypedModel typedModel;
if (elementType instanceof DataType) {
typedModel = getDomainUsageAnalysis().getPrimitiveTypedModel();
}
else {
DomainUsage domainUsage = getDomainUsage(asTypedElement);
assert domainUsage != null;
typedModel = domainUsage.getTypedModel(asTypedElement);
assert typedModel != null;
}
return datumCaches.getClassDatum(typedModel, asType);
}
@Override
public @NonNull ClassDatum getClassDatum(@NonNull TypedModel typedModel, @NonNull Type asType) {
return datumCaches.getClassDatum(typedModel, asType);
}
@Override
public @NonNull Iterable<@NonNull ClassDatum> getClassDatums() {
return classDatums;
}
@Override
public @NonNull ContainmentAnalysis getContainmentAnalysis() {
return datumCaches.getContainmentAnalysis();
}
@Override
public @NonNull ClassDatum getElementalTargetClassDatum(@NonNull PropertyDatum propertyDatum) {
return datumCaches.getElementalTargetClassDatum(propertyDatum);
}
@Override
public @NonNull Property getIterateProperty(@NonNull Type type) {
Property iterateProperty = type2iterateProperty.get(type);
if (iterateProperty == null) {
iterateProperty = createProperty("«iterate»", type, true);
type2iterateProperty.put(type, iterateProperty);
}
return iterateProperty;
}
@Override
public @NonNull NameGenerator getNameGenerator() {
return nameGenerator;
}
// @Override
// public @NonNull Iterable<@NonNull PropertyDatum> getOclContainerPropertyDatums(@NonNull ClassDatum classDatum) {
// return datumCaches.getOclContainerPropertyDatums(classDatum);
// }
@Override
public @NonNull ClassDatum getOclVoidClassDatum() {
ClassDatum oclVoidClassDatum2 = oclVoidClassDatum;
if (oclVoidClassDatum2 == null) {
TypedModel primitiveTypedModel = domainUsageAnalysis.getPrimitiveTypedModel();
StandardLibrary standardLibrary = environmentFactory.getStandardLibrary();
oclVoidClassDatum = oclVoidClassDatum2 = getClassDatum(primitiveTypedModel, standardLibrary.getOclVoidType());
}
return oclVoidClassDatum2;
}
@Override
public @NonNull PropertyDatum getPropertyDatum(@NonNull ClassDatum sourceClassDatum, @NonNull Property property, @Nullable ClassDatum targetClassDatum) {
return datumCaches.getPropertyDatum(sourceClassDatum, property, targetClassDatum);
}
@Override
public @NonNull Iterable<@NonNull PropertyDatum> getPropertyDatums(@NonNull NavigationEdge navigationEdge) {
Property property = QVTscheduleUtil.getReferredProperty(navigationEdge);
if (property == standardLibraryHelper.getOclContainerProperty()) {
Node targetNode = QVTscheduleUtil.getSourceNode(navigationEdge);
Node castTarget = targetNode;
ClassDatum classDatum = QVTscheduleUtil.getClassDatum(castTarget);
return datumCaches.getOclContainerPropertyDatums(classDatum);
}
else {
return Collections.singletonList(getPropertyDatum(navigationEdge));
}
}
@Override
public @NonNull PropertyDatum getSuccessPropertyDatum(@NonNull Property successProperty) {
return datumCaches.getSuccessPropertyDatum(successProperty);
}
@Override
public @NonNull Transformation2TracePackage getTransformation2TracePackage(@NonNull Transformation transformation) {
Transformation2TracePackage transformation2TracePackage = transformation2transformation2TracePackage.get(transformation);
if (transformation2TracePackage == null) {
transformation2TracePackage = createTransformation2TracePackage(transformation);
transformation2transformation2TracePackage.put(transformation, transformation2TracePackage);
}
return transformation2TracePackage;
}
}