Statement.java

package edu.udel.cis.vsl.tass.model.impl.statement;

import java.io.File;
import java.io.PrintWriter;

import edu.udel.cis.vsl.tass.model.IF.FunctionIF;
import edu.udel.cis.vsl.tass.model.IF.ModelFactoryIF;
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.statement.StatementIF;
import edu.udel.cis.vsl.tass.model.IF.type.TypeIF.TypeKind;
import edu.udel.cis.vsl.tass.model.impl.Function;
import edu.udel.cis.vsl.tass.util.Source;

public class Statement implements StatementIF {

	protected ExpressionIF guard;

	protected LocationIF sourceLocation;

	protected LocationIF targetLocation = null;

	protected StatementKind kind;

	private Source sourceCode;

	protected ModelFactoryIF factory;

	protected StatementIF nextStatement = null;

	protected boolean isLocal = false;

	public Statement(ModelFactoryIF factory, ExpressionIF guard,
			LocationIF sourceLocation, StatementKind kind)
			throws SyntaxException {
		if (sourceLocation == null)
			throw new NullPointerException("Null sourceLocation");
		if (guard == null)
			throw new SyntaxException(sourceLocation, "Null guard");
		if (guard.type().kind() != TypeKind.BOOLEAN)
			throw new SyntaxException(guard, "Guard is not boolean");
		if (factory == null)
			throw new NullPointerException("Null model factory");
		factory.checkScope(guard, sourceLocation.scope());
		this.guard = guard;
		this.sourceLocation = sourceLocation;
		this.kind = kind;
		this.factory = factory;
		((Function) sourceLocation.function()).addStatement(this);
	}

	/** Assume guard is "true". */
	public Statement(ModelFactoryIF factory, LocationIF sourceLocation,
			StatementKind kind) throws SyntaxException {
		this(factory, factory.booleanLiteralExpression(true), sourceLocation,
				kind);
	}

	public void setNext(StatementIF statement) {
		nextStatement = statement;
	}

	public StatementIF next() {
		return nextStatement;
	}

	public LocationIF sourceLocation() {
		return sourceLocation;
	}

	public LocationIF targetLocation() {
		return targetLocation;
	}

	public void setTargetLocation(LocationIF target) {
		this.targetLocation = target;
	}

	public ExpressionIF guard() {
		return guard;
	}

	public FunctionIF function() {
		return sourceLocation.function();
	}

	public Source getSource() {
		return sourceCode;
	}

	public void setSource(Source sourceCode) {
		this.sourceCode = sourceCode;
	}

	public StatementKind kind() {
		return kind;
	}

	public ProcessIF process() {
		return function().process();
	}

	public ModelIF model() {
		return function().process().model();
	}

	public void complete() throws SyntaxException {
		if (targetLocation == null)
			throw new SyntaxException(this, "null target location");
	}

	public boolean isLocal() {
		return isLocal;
	}

	public void print(PrintWriter out) {
		ProcessIF process = process();
		Source source = getSource();
		int lineNumber = -1;
		String text = "";
		File file = null;

		if (source != null) {
			lineNumber = source.firstLine();
			text = source.text();
			file = source.file();
		}
		if (file != null)
			out.print(file.getName());
		if (lineNumber >= 0)
			out.print(" line " + lineNumber);
		if (process != null && model().numProcs() > 1)
			out.print(" proc " + process.pid());
		out.print(" [" + sourceLocation.function().name() + "@"
				+ sourceLocation.id() + "->" + targetLocation.function().name()
				+ "@" + targetLocation.id() + "]");
		out.print(" \"" + text + "\"");
		if (sourceLocation instanceof LoopLocationIF) {
			StatementIF trueBranch = ((LoopLocationIF) sourceLocation)
					.trueBranch();
			StatementIF falseBranch = ((LoopLocationIF) sourceLocation)
					.falseBranch();

			if (this == trueBranch)
				out.print(" [true]");
			else if (this == falseBranch)
				out.print(" [false]");
		}
		if (sourceLocation instanceof BranchLocationIF) {
			StatementIF trueBranch = ((BranchLocationIF) sourceLocation)
					.trueBranch();
			StatementIF falseBranch = ((BranchLocationIF) sourceLocation)
					.falseBranch();

			if (this == trueBranch)
				out.print(" [true]");
			else if (this == falseBranch)
				out.print(" [false]");
		}
	}
}