Location.java
package edu.udel.cis.vsl.tass.model.impl.location;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import edu.udel.cis.vsl.tass.model.IF.CollectiveAssertionIF;
import edu.udel.cis.vsl.tass.model.IF.FunctionIF;
import edu.udel.cis.vsl.tass.model.IF.ModelIF;
import edu.udel.cis.vsl.tass.model.IF.ProcessIF;
import edu.udel.cis.vsl.tass.model.IF.SyntaxException;
import edu.udel.cis.vsl.tass.model.IF.expression.ExpressionIF;
import edu.udel.cis.vsl.tass.model.IF.location.BranchLocationIF;
import edu.udel.cis.vsl.tass.model.IF.location.LocationIF;
import edu.udel.cis.vsl.tass.model.IF.location.LoopLocationIF;
import edu.udel.cis.vsl.tass.model.IF.scope.LocalScopeIF;
import edu.udel.cis.vsl.tass.model.IF.statement.StatementIF;
import edu.udel.cis.vsl.tass.model.impl.statement.Statement;
import edu.udel.cis.vsl.tass.util.Source;
/**
* Implementation of LocationIF, the root of the location hierarchy. A location
* represents a control point within a function body.
*
* @author siegel
*/
public abstract class Location implements LocationIF {
/**
* The unique ID number for this location. It is only unique within the
* enclosing process. Another process may have a location with the same id
* as this one.
*/
protected int id;
protected FunctionIF function;
protected LocalScopeIF scope;
protected LocationKind kind;
protected StatementIF firstStatement = null;
protected StatementIF lastStatement = null;
protected LinkedHashSet<StatementIF> incoming = new LinkedHashSet<StatementIF>();
protected LinkedHashSet<StatementIF> outgoing = new LinkedHashSet<StatementIF>();
protected Source sourceCode;
protected Map<String, Object> annotationMap = new LinkedHashMap<String, Object>();
protected boolean isLocal = false;
protected LocationIF correspondingLocation = null;
protected CollectiveAssertionIF collectiveAssertion = null;
protected ExpressionIF collectiveExpression = null;
private LocationIF openLocation = null;
/**
* Locations can have labels. The label is used to help print and
* understand. May be null.
*/
protected String label = null;
protected Location(LocalScopeIF scope, LocationKind kind) {
assert scope != null;
this.scope = scope;
this.function = scope.function();
this.id = function.locations().size();
this.kind = kind;
}
@Override
public FunctionIF function() {
return function;
}
@Override
public int id() {
return id;
}
@Override
public StatementIF firstStatement() {
return firstStatement;
}
@Override
public StatementIF lastStatement() {
return lastStatement;
}
@Override
public String label() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
@Override
public boolean equals(Object object) {
if (object instanceof Location) {
Location that = (Location) object;
return id == that.id && function.equals(that.function);
}
return false;
}
@Override
public int hashCode() {
return id + 1024 * function.hashCode();
}
@Override
public String toString() {
String result = "loc[" + id;
if (label != null)
result += "," + label;
result += "]";
return result;
}
public void addIncoming(StatementIF statement) {
if (!incoming.add(statement)) {
throw new IllegalArgumentException(
"Attempt to add incoming statement that already exists: "
+ statement);
}
}
public void addOutgoing(StatementIF statement) {
if (!outgoing.add(statement)) {
throw new IllegalArgumentException(
"Attempt to add outgoing statement that already exists: "
+ statement);
}
if (firstStatement == null)
firstStatement = statement;
if (lastStatement != null)
((Statement) lastStatement).setNext(statement);
lastStatement = statement;
}
@Override
public Collection<StatementIF> incomingStatements() {
return incoming;
}
@Override
public LocationKind kind() {
return kind;
}
@Override
public Collection<StatementIF> statements() {
return outgoing;
}
@Override
public Source getSource() {
return sourceCode;
}
@Override
public void setSource(Source sourceCode) {
this.sourceCode = sourceCode;
}
@Override
public boolean isBranch() {
return this instanceof BranchLocationIF;
}
@Override
public boolean isLoop() {
return this instanceof LoopLocationIF;
}
@Override
public Collection<String> annotationKeys() {
return annotationMap.keySet();
}
@Override
public Object getAnnotation(String key) {
return annotationMap.get(key);
}
@Override
public void putAnnotation(String key, Object annotation) {
annotationMap.put(key, annotation);
}
@Override
public ProcessIF process() {
return function.process();
}
@Override
public ModelIF model() {
return function().model();
}
public void complete() throws SyntaxException {
for (StatementIF statement : outgoing)
((Statement) statement).complete();
isLocal = true;
for (StatementIF statement : outgoing) {
if (!statement.isLocal()) {
isLocal = false;
break;
}
}
}
public boolean isComplete() {
return model().isComplete();
}
/**
* How to print a location:
*
* <pre>
* location 17 is
* kind : ASSIGNMENT
* label: l2
* annote1: sfsfs
* annote2: dsfds
* x[i] = j+(k/2); goto location 18
* end location 17
* </pre>
*
* choice statement:
*
* <code>
* when x == 7 goto location 18;
* when x == 8 goto location 19;
* </code>
* */
public void print(String prefix, PrintWriter out) {
print(prefix, out, false);
}
public void print(String prefix, PrintWriter out, boolean withSource) {
out.println(prefix + "begin location " + id);
out.println(prefix + "| kind : " + kind + ";");
if (label != null)
out.println(prefix + "| label : " + label + ";");
for (String key : annotationKeys()) {
out.println(prefix + "| " + key + " : " + getAnnotation(key) + ";");
}
if (collectiveAssertion != null) {
out.println(prefix + "| collective assertion: "
+ collectiveAssertion.identifier() + ";");
}
if (collectiveExpression != null) {
out.println(prefix + "| collective expression: "
+ collectiveExpression + ";");
}
for (StatementIF statement : statements()) {
LocationIF targetLocation = statement.targetLocation();
String locationName = (targetLocation == null ? "<null>" : ""
+ targetLocation.id());
out.println(prefix + "| " + statement + " goto location "
+ locationName + ";");
if (withSource) {
out.println(prefix + "| | " + statement.getSource());
}
}
out.println(prefix + "end location " + id + ";");
out.flush();
}
@Override
public LocalScopeIF scope() {
return scope;
}
@Override
public boolean isLocal() {
return isLocal;
}
public void setCorrespondingLocation(LocationIF location) {
this.correspondingLocation = location;
}
@Override
public LocationIF correspondingLocation() {
return correspondingLocation;
}
public void setCollectiveAssertion(CollectiveAssertionIF assertion) {
collectiveAssertion = assertion;
}
@Override
public CollectiveAssertionIF collectiveAssertion() {
return collectiveAssertion;
}
public void setCollectiveExpression(ExpressionIF expression) {
collectiveExpression = expression;
}
@Override
public ExpressionIF collectiveExpression() {
return collectiveExpression;
}
@Override
public LocationIF openLocation() {
return openLocation;
}
@Override
public void setOpenLocation(LocationIF openLocation) {
this.openLocation = openLocation;
}
}