/*
* 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
*
* (C) Copyright IBM Corporation 2006-2010.
*/
package x10.compiler.ws.util;
import polyglot.ast.Field;
import polyglot.ast.Local;
import polyglot.ast.Node;
import polyglot.ast.NodeFactory;
import polyglot.frontend.Job;
import polyglot.types.ClassDef;
import polyglot.types.Context;
import polyglot.types.LocalInstance;
import polyglot.types.MethodDef;
import polyglot.types.Types;
import polyglot.types.VarDef;
import polyglot.types.VarInstance;
import polyglot.visit.ContextVisitor;
import polyglot.visit.NodeVisitor;
import x10.ast.Closure;
import x10.ast.X10Special;
import x10.types.ClosureDef;
import x10.types.ClosureDef_c;
import x10.types.EnvironmentCapture;
import x10.types.ThisDef;
import x10.types.X10ClassType;
import x10.types.X10MemberDef;
import x10.visit.Desugarer;
import x10.visit.Desugarer.ClosureCaptureVisitor;
import polyglot.types.TypeSystem;
import polyglot.util.InternalCompilerError;
/**
*
* In a ws code transformation, each code path will be transformed into fast and
* slow path.
*
* But for a closure, originally it has one declare and one def.
* But after transformation, it will have two declares with still only one def,
* which causes error for further transformation.
*
* This code visitor will create a new closure def for all closure in the AST tree.
*
* It should be added as one job in synthesizing the slow path
*
* @author Haichuan
*/
public class ClosureDefReinstantiator extends ContextVisitor {
public ClosureDefReinstantiator(Job job, TypeSystem ts, NodeFactory nf) {
super(job, ts, nf);
}
public Node leaveCall(Node old, Node n, NodeVisitor v) {
if(n instanceof Closure){
Context ct = context();
Closure c = (Closure)n;
//WSUtil.debug("Found closure", c);
ClosureDef cd = c.closureDef();
cd.setStaticContext(ct.inStaticContext());
cd.setTypeContainer(Types.ref(ct.currentClassDef().asType()));
cd.setMethodContainer(Types.ref(ct.currentCode().asInstance()));
c = c.closureDef(cd);
// //Now show current vars
// ClosureDef_c cdc = (ClosureDef_c)cd;
// for(VarInstance<? extends VarDef> vi : cdc.capturedEnvironment()){
// WSUtil.debug("as-is var:"+ vi.toString());
// }
//Now set the CapturedEnvironment
NodeVisitor captureEnvVisitor = new Desugarer.ClosureCaptureVisitor(context, c.closureDef());
c.visit(captureEnvVisitor);
// for(VarInstance<? extends VarDef> vi : cdc.capturedEnvironment()){
// WSUtil.debug("afer-process var:"+ vi.toString());
// }
return c;
}
return n;
}
}