ReturnStatement.java

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

import java.util.Collection;

import edu.udel.cis.vsl.tass.model.IF.ModelFactoryIF;
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.ReturnLocationIF;
import edu.udel.cis.vsl.tass.model.IF.statement.ReturnStatementIF;
import edu.udel.cis.vsl.tass.model.IF.type.TypeIF.TypeKind;
import edu.udel.cis.vsl.tass.model.IF.variable.SharedVariableIF;
import edu.udel.cis.vsl.tass.model.IF.variable.VariableIF;

public class ReturnStatement extends Statement implements ReturnStatementIF {

	private ExpressionIF result;

	public ReturnStatement(ModelFactoryIF factory,
			ReturnLocationIF sourceLocation, ExpressionIF result)
			throws SyntaxException {
		super(factory, sourceLocation, StatementKind.RETURN);
		if (result == null) {
			if (function().returnType().kind() != TypeKind.VOID)
				throw new NullPointerException(
						"null return expression not allowed for function "
								+ function());
		} else {
			if (!result.type().equals(this.function().returnType())) {
				if (!(function().name().equals("main")))
					throw new SyntaxException(result, "Function " + function()
							+ " has return type " + function().returnType()
							+ " but argument to return has type "
							+ result.type());
			}
			factory.checkScope(result, sourceLocation.scope());
		}
		this.result = result;
	}

	public ExpressionIF result() {
		return result;
	}

	public String toString() {
		return "return " + result + ";";
	}

	public void complete() throws SyntaxException {
		Collection<SharedVariableIF> shared = process().model().scope()
				.properSharedVariables();

		super.complete();
		isLocal = true;
		if (this.result != null) {
			for (VariableIF variable : result.freeVariables()) {
				if (variable instanceof SharedVariableIF
						&& shared.contains((SharedVariableIF) variable)) {
					isLocal = false;
					break;
				}
			}
		}
	}

}