/**
*
*/
package x10.types.checker;
import java.util.List;
import polyglot.ast.Expr;
import polyglot.ast.Node;
import polyglot.ast.NodeFactory;
import polyglot.frontend.Globals;
import polyglot.frontend.Job;
import polyglot.visit.ContextVisitor;
import polyglot.visit.ErrorHandlingVisitor;
import polyglot.visit.NodeVisitor;
import x10.ast.X10CanonicalTypeNode;
import x10.ast.X10Field_c;
import x10.ast.X10Special;
import polyglot.types.Type;
import polyglot.types.TypeSystem;
import polyglot.types.Types;
import x10.types.constraints.CConstraint;
import x10.util.Synthesizer;
/**
* Flags an error if visited node contains this. Used to flag inappropriate
* uses of this in constructor declarations.
* @author vj
*
*/
public class ThisChecker extends NodeVisitor {
protected boolean error;
protected TypeSystem ts;
protected NodeFactory nf;
public ThisChecker(Job job) {
ts = (TypeSystem) job.extensionInfo().typeSystem();
nf = (NodeFactory) job.extensionInfo().nodeFactory();
}
protected boolean catchErrors(Node n) { return false; }
@Override
public Node override(Node n) {
if (n instanceof X10Special) {
X10Special e = (X10Special) n;
error = error || e.kind() == X10Special.THIS || e.kind() == X10Special.SUPER;
return n;
}
// The here field is a fake field generated by the type-checker.
// Permit this.here to occur in types without tripping the This checker.
if (n instanceof X10Field_c) {
X10Field_c f = (X10Field_c) n;
if (f.name().toString().equals(PlaceChecker.HOME_NAME))
return n;
return null;
}
if (n instanceof X10CanonicalTypeNode) {
Type type = ((X10CanonicalTypeNode) n).type();
CConstraint rc = Types.xclause(type);
List<Expr> clauses = new Synthesizer(nf, ts).makeExpr(rc, Types.baseType(type), n.position());
for (Expr c : clauses) {
c.visit(this);
}
}
return null;
}
public boolean error() {
return error;
}
public void clearError() {
error = false;
}
}