blob: d27049768640d5bcd59746390ff132508f8e6f68 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016, 2017 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:
* 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.RegionUtil;
import org.eclipse.qvtd.pivot.qvtschedule.Edge;
import org.eclipse.qvtd.pivot.qvtschedule.NavigableEdge;
import org.eclipse.qvtd.pivot.qvtschedule.Node;
import org.eclipse.qvtd.pivot.qvtschedule.Role;
import com.google.common.collect.Iterables;
/**
* The RealizedPartition identifies the nodes and edges required by an unspeculated micro-mapping
* which directly creates the realized variables.
*/
class RealizedPartition extends AbstractPartition
{
public RealizedPartition(@NonNull MappingPartitioner partitioner) {
super(partitioner);
Iterable<@NonNull Node> predicatedMiddleNodes = partitioner.getPredicatedMiddleNodes();
assert Iterables.isEmpty(predicatedMiddleNodes);
//
// The ends of loaded navigation edges are retained as is for the predicate.
//
addLoadedNavigationEdgeSourceAndTargetNodes();
//
// The trace nodes are realized as is.
//
for (@NonNull Node node : partitioner.getTraceNodes()) {
if (!hasNode(node)) {
addNode(node, RegionUtil.getNodeRole(node));
}
}
//
// The realized nodes are realized as is.
//
for (@NonNull Node node : partitioner.getRealizedOutputNodes()) {
if (!hasNode(node)) {
addNode(node, RegionUtil.getNodeRole(node));
}
}
//
// Add the outstanding predicates that can be checked by this partition.
//
resolveTrueNodes();
//
// Ensure that the predecessors of each node are included in the partition.
//
resolvePrecedingNodes();
//
// Join up the edges.
//
resolveEdges();
}
/**
* Add the ends of all the loaded edges. This gathers the loaded PatternNodeRoles and also the
* odd-balls such as Null nodes.
*/
protected void addLoadedNavigationEdgeSourceAndTargetNodes() {
for (@NonNull NavigableEdge edge : region.getNavigationEdges()) {
if (edge.isLoaded()) {
Node sourceNode = edge.getEdgeSource();
Node targetNode = edge.getEdgeTarget();
if (!hasNode(sourceNode)) {
addNode(sourceNode, RegionUtil.getNodeRole(sourceNode));
}
if (!hasNode(targetNode)) {
addNode(targetNode, RegionUtil.getNodeRole(targetNode));
}
}
}
}
/**
* Return a prioritized hint for the choice of head nodes.
* The override implementation returns null for no hint.
*/
@Override
protected @Nullable Iterable<@NonNull Node> getPreferredHeadNodes() {
return null;
}
@Override
protected @Nullable Role resolveEdgeRole(@NonNull Role sourceNodeRole, @NonNull Edge edge, @NonNull Role targetNodeRole) {
Role edgeRole = RegionUtil.getEdgeRole(edge);
if (edgeRole == Role.REALIZED) {
assert !partitioner.hasRealizedEdge(edge);
}
return edgeRole;
}
}