// Path: src/java/minijava/ast/Call.java
// public class Call extends Expression {
// 
// 	public final Expression receiver;
// 	public final String name;
// 	public final NodeList<Expression> rands;
// 
// 	public Call(Expression receiver, String name, NodeList<Expression> rands) {
// 		super();
// 		this.receiver = receiver;
// 		this.name = name;
// 		this.rands = rands;
// 	}
// 
// 	@Override
// 	public <R> R accept(Visitor<R> v) {
// 		return v.visit(this);
// 	}
// 
// }
// 
// Path: src/java/minijava/ast/Expression.java
// public abstract class Expression extends AST {
// 	
// 	/**
// 	 * The type of an expression is set by the type checking phase.
// 	 */
// 	public Type type;
// 
// 	public Type getType() {
// 		Assert.assertNotNull("Was this AST typechecked?", type);
// 		return type;
// 	}
// 	
// 	public void setType(Type theType) {
// 		//Assert.assertNull(type); 
// 		//As our visitor is written, we expect the types of some nodes to be set multiple times.
// 		//as long as there is no conflict in these type settings, there is no problem, and the assertion has been
// 		//modified to reflect that.
// 		assert(type==null || type.equals(theType));		
// 		type = theType;
// 	}
// 
// }
// 
// Path: src/java/minijava/ast/ObjectType.java
// public class ObjectType extends Type {
// 	
// 	public final String name;
// 
// 	public ObjectType(String name) {
// 		super();
// 		this.name = name;
// 	}
// 
// 	@Override
// 	public <R> R accept(Visitor<R> v) {
// 		return v.visit(this);
// 	}
// 
// 	@Override
// 	public boolean equals(Object other) {
// 		if (this.getClass()==other.getClass()) {
// 			return this.name.equals(((ObjectType)other).name);
// 		}
// 		return false;
// 	}
// }
// 
// Path: src/java/minijava/ast/Type.java
// public abstract class Type extends AST {
// 	
// 	@Override
// 	public abstract boolean equals(Object other);
// 
// }


import minijava.ast.Call;
import minijava.ast.Expression;
import minijava.ast.ObjectType;
import minijava.ast.Type;
package minijava.typechecker;


/**
 * A class to represent Entries in an Error report.
 * It provides static methods to create different types of messages.
 * <p>
 * If we assume that the TypeChecker only uses the ErrorReport and
 * ErrorMessage classes to create error reports than we can use this
 * to write relatively precise unit tests for the expected error output
 * without specifying the exact syntax of expected error messages 
 * (Unit tests can use the instances of ErrorMessage class or assume that
 * the implementation of the ErrorMessage class produces similar error Strings.
 */
public class ErrorMessage {
	
	private String msg;

	/**
	 * Constructor is private so that you can't make messages that are
	 * "arbitrarily formatted".
	 */
	private ErrorMessage(String msg) {
		this.msg = msg;
	}

	public static ErrorMessage undefinedId(String name) {
		return new ErrorMessage("Unbound Identifier: "+name);
	}
	
	public static ErrorMessage duplicateDefinition(String name) {
		return new ErrorMessage("Multiply defined Identifier: "+name);
	}
	
// Path: src/java/minijava/ast/Call.java
// public class Call extends Expression {
// 
// 	public final Expression receiver;
// 	public final String name;
// 	public final NodeList<Expression> rands;
// 
// 	public Call(Expression receiver, String name, NodeList<Expression> rands) {
// 		super();
// 		this.receiver = receiver;
// 		this.name = name;
// 		this.rands = rands;
// 	}
// 
// 	@Override
// 	public <R> R accept(Visitor<R> v) {
// 		return v.visit(this);
// 	}
// 
// }
// 
// Path: src/java/minijava/ast/Expression.java
// public abstract class Expression extends AST {
// 	
// 	/**
// 	 * The type of an expression is set by the type checking phase.
// 	 */
// 	public Type type;
// 
// 	public Type getType() {
// 		Assert.assertNotNull("Was this AST typechecked?", type);
// 		return type;
// 	}
// 	
// 	public void setType(Type theType) {
// 		//Assert.assertNull(type); 
// 		//As our visitor is written, we expect the types of some nodes to be set multiple times.
// 		//as long as there is no conflict in these type settings, there is no problem, and the assertion has been
// 		//modified to reflect that.
// 		assert(type==null || type.equals(theType));		
// 		type = theType;
// 	}
// 
// }
// 
// Path: src/java/minijava/ast/ObjectType.java
// public class ObjectType extends Type {
// 	
// 	public final String name;
// 
// 	public ObjectType(String name) {
// 		super();
// 		this.name = name;
// 	}
// 
// 	@Override
// 	public <R> R accept(Visitor<R> v) {
// 		return v.visit(this);
// 	}
// 
// 	@Override
// 	public boolean equals(Object other) {
// 		if (this.getClass()==other.getClass()) {
// 			return this.name.equals(((ObjectType)other).name);
// 		}
// 		return false;
// 	}
// }
// 
// Path: src/java/minijava/ast/Type.java
// public abstract class Type extends AST {
// 	
// 	@Override
// 	public abstract boolean equals(Object other);
// 
// }


// Path: src/java/minijava/typechecker/ErrorMessage.java
import minijava.ast.Call;
import minijava.ast.Expression;
import minijava.ast.ObjectType;
import minijava.ast.Type;

package minijava.typechecker;


/**
 * A class to represent Entries in an Error report.
 * It provides static methods to create different types of messages.
 * <p>
 * If we assume that the TypeChecker only uses the ErrorReport and
 * ErrorMessage classes to create error reports than we can use this
 * to write relatively precise unit tests for the expected error output
 * without specifying the exact syntax of expected error messages 
 * (Unit tests can use the instances of ErrorMessage class or assume that
 * the implementation of the ErrorMessage class produces similar error Strings.
 */
public class ErrorMessage {
	
	private String msg;

	/**
	 * Constructor is private so that you can't make messages that are
	 * "arbitrarily formatted".
	 */
	private ErrorMessage(String msg) {
		this.msg = msg;
	}

	public static ErrorMessage undefinedId(String name) {
		return new ErrorMessage("Unbound Identifier: "+name);
	}
	
	public static ErrorMessage duplicateDefinition(String name) {
		return new ErrorMessage("Multiply defined Identifier: "+name);
	}
	
	public static ErrorMessage typeError(Expression exp, Type expected,