// 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;
	public static ErrorMessage badMethodOverriding(ObjectType objectType,
			String methodName) {
		return new ErrorMessage("Bad overriding in class "+objectType+" for method "+methodName);
	}

	public static ErrorMessage fieldOverriding(ObjectType cls, String fieldName) {
		return new ErrorMessage("Class "+cls+" overrides field "+fieldName);
	}

	@Override
	public String toString() {
		return "ERROR -- "+msg;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((msg == null) ? 0 : msg.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
// 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;

	public static ErrorMessage badMethodOverriding(ObjectType objectType,
			String methodName) {
		return new ErrorMessage("Bad overriding in class "+objectType+" for method "+methodName);
	}

	public static ErrorMessage fieldOverriding(ObjectType cls, String fieldName) {
		return new ErrorMessage("Class "+cls+" overrides field "+fieldName);
	}

	@Override
	public String toString() {
		return "ERROR -- "+msg;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((msg == null) ? 0 : msg.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		ErrorMessage other = (ErrorMessage) obj;