/*
* This file is part of the X10 project (http://x10-lang.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* This file was originally derived from the Polyglot extensible compiler framework.
*
* (C) Copyright 2000-2007 Polyglot project group, Cornell University
* (C) Copyright IBM Corporation 2007-2012.
*/
package polyglot.visit;
import polyglot.ast.*;
import polyglot.frontend.ExtensionInfo;
import polyglot.types.*;
import polyglot.types.Package;
import polyglot.util.InternalCompilerError;
/**
* This visitor overwrites all extension object refs with null,
* sets delegate object refs to point back to the node,
* and strips type information out.
**/
public class ExtensionCleaner extends NodeVisitor {
protected NodeFactory nf;
protected TypeSystem ts;
protected ExtensionInfo javaExt;
public ExtensionCleaner(ExtensionInfo javaExt) {
this.javaExt = javaExt;
this.nf = javaExt.nodeFactory();
this.ts = javaExt.typeSystem();
}
public Node leave(Node old, Node n, NodeVisitor v) {
n = n.ext(null);
n = n.del(null);
n = strip(n);
return n;
}
protected Node strip(Node n) {
// FIXME: should use method dispatch for this.
if (n instanceof Call) {
n = ((Call) n).methodInstance(null);
}
if (n instanceof ClassDecl) {
n = ((ClassDecl) n).classDef(null);
}
if (n instanceof ConstructorCall) {
n = ((ConstructorCall) n).constructorInstance(null);
}
if (n instanceof Field) {
n = ((Field) n).fieldInstance(null);
}
if (n instanceof FieldDecl) {
n = ((FieldDecl) n).fieldDef(null);
n = ((FieldDecl) n).initializerDef(null);
}
if (n instanceof Formal) {
n = ((Formal) n).localDef(null);
}
if (n instanceof Initializer) {
n = ((Initializer) n).initializerDef(null);
}
if (n instanceof Local) {
n = ((Local) n).localInstance(null);
}
if (n instanceof LocalDecl) {
n = ((LocalDecl) n).localDef(null);
}
if (n instanceof MethodDecl) {
n = ((MethodDecl) n).methodDef(null);
}
if (n instanceof New) {
n = ((New) n).anonType(null);
n = ((New) n).constructorInstance(null);
}
if (n instanceof TypeNode) {
n = convert((TypeNode) n);
}
if (n instanceof PackageNode) {
n = convert((PackageNode) n);
}
if (n instanceof Expr) {
n = ((Expr) n).type((Type) null);
}
return n;
}
protected TypeNode convert(TypeNode n) {
Type t = n.type();
if (n instanceof CanonicalTypeNode) {
if (t.typeSystem() == ts) {
return n;
}
else {
throw new InternalCompilerError("Unexpected Jx type: " + t + " found in rewritten AST.");
}
}
// Must be an ambiguous TypeNode
if (t != null) {
if (t.typeSystem() == ts) {
return nf.CanonicalTypeNode(n.position(), t);
}
}
// ### unimplemented
assert false;
// n = n.type(null);
return n;
}
protected PackageNode convert(PackageNode n) {
Package p = Types.get(n.package_());
if (p != null) {
if (p.typeSystem() == ts) {
return nf.PackageNode(n.position(), Types.ref(p));
}
}
return nf.PackageNode(n.position(), Types.ref(ts.createPackage(QName.make(n.toString()))));
}
}