blob: 8ed43c43b3ab240503cdcd133f8646c25da52c19 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016, 2018 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.qvts2qvts.partitioner;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.qvtd.compiler.internal.qvtm2qvts.QVTm2QVTs;
import org.eclipse.qvtd.compiler.internal.qvts2qvts.utilities.ReachabilityForest;
import org.eclipse.qvtd.pivot.qvtschedule.BasicPartition;
import org.eclipse.qvtd.pivot.qvtschedule.Edge;
import org.eclipse.qvtd.pivot.qvtschedule.Node;
import org.eclipse.qvtd.pivot.qvtschedule.Role;
import org.eclipse.qvtd.pivot.qvtschedule.utilities.QVTscheduleUtil;
/**
* The Residual Partition copies everything adjuting to the preceding ActivatorPartotion.
*/
public class ResidualPartitionFactory extends AbstractSimplePartitionFactory
{
public ResidualPartitionFactory(@NonNull MappingPartitioner mappingPartitioner) {
super(mappingPartitioner);
}
@Override
public @NonNull BasicPartitionAnalysis createPartitionAnalysis(@NonNull PartitionedTransformationAnalysis partitionedTransformationAnalysis) {
ReachabilityForest reachabilityForest = createReachabilityForest();
String name = computeName("residue");
Iterable<@NonNull Node> headNodes = mappingPartitioner.getTraceNodes();
BasicPartition partition = createBasicPartition(name, headNodes);
int partitionNumber = region.getNextPartitionNumber();
BasicPartitionAnalysis basicPartitionAnalysis = new BasicPartitionAnalysis(partitionedTransformationAnalysis, partition, reachabilityForest, "«residue»", "_p" + partitionNumber);
initializePartition(basicPartitionAnalysis);
if (QVTm2QVTs.DEBUG_GRAPHS.isActive()) {
scheduleManager.writeDebugGraphs(partition, null);
}
return basicPartitionAnalysis;
}
protected void initializePartition(@NonNull BasicPartitionAnalysis partitionAnalysis) {
BasicPartition partition = partitionAnalysis.getPartition();
// Iterable<@NonNull Node> predicatedMiddleNodes = partitioner.getPredicatedMiddleNodes();
// assert Iterables.isEmpty(predicatedMiddleNodes);
//
// The trace nodes are always predicated.
//
for (@NonNull Node node : mappingPartitioner.getTraceNodes()) {
if (!partition.hasNode(node)) {
addNode(partition, node, Role.SPECULATED);
}
Node localSuccessNode = mappingPartitioner.basicGetLocalSuccessNode(node);
if (localSuccessNode != null) { // ?? localSuccess property is not mandatory
addNode(partition, localSuccessNode, Role.PREDICATED);
}
}
//
// All other nodes are as is
//
for (@NonNull Node node : QVTscheduleUtil.getOwnedNodes(region)) {
if (!partition.hasNode(node)) {
addNode(partition, node);
}
}
//
// Ensure that the predecessors of each node are included in the partition.
//
resolvePrecedingNodes(partitionAnalysis);
//
// Join up the edges.
//
resolveEdges(partitionAnalysis);
}
@Override
protected @Nullable Role resolveEdgeRole(@NonNull Role sourceNodeRole, @NonNull Edge edge, @NonNull Role targetNodeRole) {
Role edgeRole = QVTscheduleUtil.getEdgeRole(edge);
if (edgeRole == Role.REALIZED) {
if (mappingPartitioner.hasRealizedEdge(edge)) {
edgeRole = Role.PREDICATED;
}
}
return edgeRole;
}
}