package edu.ucsd.arcum.interpreter.satisfier; import java.util.List; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.ITypeBinding; import com.google.common.collect.Lists; import edu.ucsd.arcum.interpreter.ast.TraitSignature; import edu.ucsd.arcum.interpreter.query.EntityDataBase; import edu.ucsd.arcum.interpreter.query.EntityTuple; import edu.ucsd.arcum.interpreter.query.TraitValue; import edu.ucsd.arcum.util.StringUtil; // Locations are determined by the built-in traits like hasField and hasMethod, which // can be "run in both directions." public class NodesWithLocations { private List<EntityTuple> nodes; private List<TraitValue> locations; // nodeLocations are assumed to be built-in traits public NodesWithLocations(List<EntityTuple> nodes, List<TraitValue> nodeLocations) { this.nodes = Lists.newArrayList(nodes); this.locations = Lists.newArrayList(nodeLocations); } public NodesWithLocations() { this.nodes = Lists.newArrayList(); this.locations = Lists.newArrayList(); } public List<EntityTuple> getNodes() { return nodes; } public ASTNode findParentLocation(ASTNode node, EntityDataBase edb) { for (TraitValue location : locations) { List<EntityTuple> entities = location.getEntities(); for (EntityTuple tuple : entities) { Object entity = tuple.lookupEntity(EntityDataBase.CHILD_VAR_REF); if (entity == node) { Object parent = tuple.lookupEntity(EntityDataBase.PARENT_VAR_REF); if (parent instanceof ITypeBinding) { parent = edb.lookupTypeDeclaration((ITypeBinding)parent); } return (ASTNode)parent; } } } return null; } public void merge(NodesWithLocations that) { this.nodes.addAll(that.nodes); toAdd: for (TraitValue trait : that.locations) { TraitSignature type = trait.getTraitType(); String name = type.getName(); for (TraitValue builtInAlreadyPresent : this.locations) { if (type.equals(builtInAlreadyPresent.getTraitType())) { for (EntityTuple entityTuple : trait.getEntities()) { builtInAlreadyPresent.addTuple(entityTuple); } continue toAdd; } } this.locations.add(trait); } } @Override public String toString() { StringBuilder buff = new StringBuilder(); String spacer = String.format("%n "); buff.append("Nodes:"); buff.append(spacer); buff.append(StringUtil.separate(nodes, spacer)); buff.append(String.format("%nLocations:")); buff.append(spacer); buff.append(StringUtil.separate(locations, spacer)); return buff.toString(); } public List<TraitValue> getLocations() { return locations; } }