/* * 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.visit; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import polyglot.ast.Call_c; import polyglot.ast.CanonicalTypeNode; import polyglot.ast.ClassDecl; import polyglot.ast.ClassDecl_c; import polyglot.ast.ConstructorCall_c; import polyglot.ast.ConstructorDecl; import polyglot.ast.ConstructorDecl_c; import polyglot.ast.Expr; import polyglot.ast.Expr_c; import polyglot.ast.FieldDecl; import polyglot.ast.FieldDecl_c; import polyglot.ast.Field_c; import polyglot.ast.Formal; import polyglot.ast.Formal_c; import polyglot.ast.Import_c; import polyglot.ast.Initializer_c; import polyglot.ast.LocalDecl; import polyglot.ast.LocalDecl_c; import polyglot.ast.Local_c; import polyglot.ast.MethodDecl; import polyglot.ast.MethodDecl_c; import polyglot.ast.New_c; import polyglot.ast.Node; import polyglot.ast.NodeFactory; import polyglot.ast.PackageNode_c; import polyglot.ast.SourceFile; import polyglot.ast.TypeNode; import polyglot.ast.TypeNode_c; import x10.ExtensionInfo; import x10.ast.DepParameterExpr; import x10.extension.X10Ext; import x10.types.X10ClassType; import x10.types.X10ConstructorInstance; import x10.types.X10FieldInstance; import x10.types.X10LocalInstance; import x10.types.X10MethodInstance; import x10.types.X10ParsedClassType; import x10.types.X10Type; import x10.types.X10TypeObject; import polyglot.frontend.Job; import polyglot.frontend.MissingDependencyException; import polyglot.frontend.Scheduler; import polyglot.frontend.goals.Goal; import polyglot.main.Report; import polyglot.types.ArrayType; import polyglot.types.ClassType; import polyglot.types.FieldInstance; import polyglot.types.LocalInstance; import polyglot.types.MemberInstance; import polyglot.types.MethodInstance; import polyglot.types.ParsedClassType; import polyglot.types.SemanticException; import polyglot.types.Type; import polyglot.types.TypeObject; import polyglot.types.TypeSystem; import polyglot.types.reflect.ClassFileLazyClassInitializer; import polyglot.visit.ContextVisitor; import polyglot.visit.NodeVisitor; import polyglot.visit.PruningVisitor; public class PropagateDependentAnnotationsVisitor extends NodeVisitor { Job job; TypeSystem ts; NodeFactory nf; public PropagateDependentAnnotationsVisitor(Job job, TypeSystem ts, NodeFactory nf) { super(); this.job = job; this.ts = ts; this.nf = nf; } public Job job() { return job; } public Node leave(Node old, Node n, NodeVisitor v) { n = super.leave(old, n, v); X10DelegatingVisitor d = new X10DelegatingVisitor() { // public void visit(Node n) { // if (n.ext() instanceof X10Ext) { // for (Iterator<AnnotationNode> i = ((X10Ext) n.ext()).annotations().iterator(); i.hasNext(); ) { // AnnotationNode an = i.next(); // } // } // super.visit(n); // } protected void force(List l) { for (Iterator i = l.iterator(); i.hasNext(); ) { TypeObject o = (TypeObject) i.next(); force(o); } } protected void force(TypeObject o) { if (o instanceof X10TypeObject) { X10TypeObject xo = (X10TypeObject) o; if (xo instanceof FieldInstance) { FieldInstance fi = (FieldInstance) xo; fi.constantValue(); force(fi.type()); } else if (xo instanceof LocalInstance) { LocalInstance li = (LocalInstance) xo; li.constantValue(); force(li.type()); } else if (xo instanceof MethodInstance) { MethodInstance mi = (MethodInstance) xo; force(mi.returnType()); force(mi.formalTypes()); force(mi.throwTypes()); } else if (xo instanceof X10ConstructorInstance) { X10ConstructorInstance ci = (X10ConstructorInstance) xo; force(ci.returnType()); force(ci.formalTypes()); force(ci.throwTypes()); } else if (xo instanceof ArrayType) { ArrayType at = (ArrayType) xo; force(at.base()); } else if (xo instanceof X10ClassType) { X10ClassType ct = (X10ClassType) xo; DepParameterExpr dep = ct.dep(); if (dep != null) { dep.visit(PropagateDependentAnnotationsVisitor.this); } if (ct instanceof X10ParsedClassType) { force(((X10ParsedClassType) ct).classAnnotations()); } // force(ct.superType()); // force(ct.interfaces()); // force(ct.members()); } else if (xo instanceof ClassType) { ClassType ct = (ClassType) xo; // force(ct.superType()); // force(ct.interfaces()); // force(ct.members()); } if (xo instanceof X10ParsedClassType) { X10ParsedClassType ct = (X10ParsedClassType) xo; if (ct.job() == PropagateDependentAnnotationsVisitor.this.job()) { ct.setDefAnnotations(Collections.EMPTY_LIST); if (ct.isRootType()) ct.setClassAnnotations(Collections.EMPTY_LIST); return; } if (ct.job() == null) { ct.setDefAnnotations(Collections.EMPTY_LIST); if (ct.isRootType()) ct.setClassAnnotations(Collections.EMPTY_LIST); return; } } else if (xo instanceof MemberInstance) { MemberInstance mi = (MemberInstance) xo; boolean isRoot = false; if (mi instanceof X10FieldInstance && ((X10FieldInstance) mi).orig() == mi) isRoot = true; if (mi instanceof X10LocalInstance && ((X10LocalInstance) mi).orig() == mi) isRoot = true; if (mi instanceof X10MethodInstance && ((X10MethodInstance) mi).orig() == mi) isRoot = true; if (mi instanceof X10ConstructorInstance && ((X10ConstructorInstance) mi).orig() == mi) isRoot = true; if (mi.container() instanceof ParsedClassType) { ParsedClassType ct = (ParsedClassType) mi.container(); if (ct.job() == PropagateDependentAnnotationsVisitor.this.job()) { if (isRoot) { xo.setDefAnnotations(Collections.EMPTY_LIST); } return; } if (ct.job() == null) { if (isRoot) { xo.setDefAnnotations(Collections.EMPTY_LIST); } return; } } } else { return; } force(xo.defAnnotations()); } } @Override public void visit(Call_c n) { force(n.methodInstance()); super.visit(n); } @Override public void visit(ClassDecl_c n) { force(n.type()); super.visit(n); } @Override public void visit(ConstructorCall_c n) { force(n.constructorInstance()); super.visit(n); } @Override public void visit(ConstructorDecl_c n) { force(n.constructorInstance()); super.visit(n); } @Override public void visit(Expr_c n) { force(n.type()); super.visit(n); } @Override public void visit(Field_c n) { force(n.fieldInstance()); super.visit(n); } @Override public void visit(FieldDecl_c n) { force(n.fieldInstance()); super.visit(n); } @Override public void visit(Formal_c n) { force(n.localDef()); super.visit(n); } // @Override // public void visit(Import_c n) { // super.visit(n); // } @Override public void visit(Initializer_c n) { force(n.initializerInstance()); super.visit(n); } @Override public void visit(Local_c n) { force(n.localInstance()); super.visit(n); } @Override public void visit(LocalDecl_c n) { force(n.localDef()); super.visit(n); } @Override public void visit(MethodDecl_c n) { force(n.methodInstance()); super.visit(n); } @Override public void visit(New_c n) { force(n.constructorInstance()); super.visit(n); } @Override public void visit(PackageNode_c n) { force(n.package_()); super.visit(n); } @Override public void visit(TypeNode_c n) { force(n.type()); super.visit(n); } }; try { d.visitAppropriate(n); } catch (MissingDependencyException e) { if (Report.should_report(Report.frontend, 3)) e.printStackTrace(); Scheduler scheduler = job.extensionInfo().scheduler(); Goal g = scheduler.currentGoal(); scheduler.addDependencyAndEnqueue(g, e.goal(), e.prerequisite()); g.setUnreachableThisRun(); } return n; } }