/* * 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_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.New; 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.AnnotationNode; import x10.ast.X10ConstructorDecl; 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 polyglot.frontend.Job; import polyglot.types.ClassType; import polyglot.types.ConstructorInstance; import polyglot.types.FieldInstance; import polyglot.types.SemanticException; import polyglot.types.Type; import polyglot.types.TypeSystem; import polyglot.visit.ContextVisitor; import polyglot.visit.NodeVisitor; import polyglot.visit.PruningVisitor; public class PropagateAnnotationsVisitor extends ContextVisitor { public PropagateAnnotationsVisitor(Job job, TypeSystem ts, NodeFactory nf) { super(job, ts, nf); } // public NodeVisitor begin() { // // Disable the pass if there are no plugins. // ExtensionInfo extInfo = (ExtensionInfo) ts.extensionInfo(); // if (extInfo.plugins().isEmpty()) { // return new PruningVisitor(); // } // return super.begin(); // } protected Node leaveCall(Node old, Node n, NodeVisitor v) throws SemanticException { n = super.leaveCall(old, n, v); new PropagateDependentAnnotationsVisitor(job, ts, nf).leave(old, n, v); List<AnnotationNode> as = null; if (n.ext() != null) { as = ((X10Ext) n.ext()).annotations(); } if (as == null) as = Collections.<AnnotationNode>emptyList(); List<X10ClassType> newAs = new ArrayList<X10ClassType>(as.size()); for (Iterator<AnnotationNode> i = as.iterator(); i.hasNext(); ) { AnnotationNode a = i.next(); newAs.add(a.annotationInterface()); } if (n instanceof CanonicalTypeNode) { CanonicalTypeNode tn = (CanonicalTypeNode) n; if (tn.type() instanceof X10Type) { X10Type t = (X10Type) tn.type(); t = (X10Type) t.annotations(newAs); return tn.type(t); } } if (n instanceof FieldDecl) { FieldDecl fd = (FieldDecl) n; X10FieldInstance fi = (X10FieldInstance) fd.fieldInstance(); fi.setDefAnnotations(newAs); fi.setType(fd.type().type()); } if (n instanceof Formal) { Formal f = (Formal) n; X10LocalInstance li = (X10LocalInstance) f.localDef(); li.setDefAnnotations(newAs); li.setType(f.type().type()); } if (n instanceof LocalDecl) { LocalDecl ld = (LocalDecl) n; X10LocalInstance li = (X10LocalInstance) ld.localDef(); li.setDefAnnotations(newAs); li.setType(ld.type().type()); } if (n instanceof MethodDecl) { MethodDecl md = (MethodDecl) n; X10MethodInstance mi = (X10MethodInstance) md.methodInstance(); mi.setDefAnnotations(newAs); mi.setReturnType(md.returnType().type()); List<Type> newFormals = new ArrayList<Type>(md.formals().size()); for (Iterator<Formal> i = md.formals().iterator(); i.hasNext(); ) { Formal f = i.next(); newFormals.add(f.type().type()); } mi.setFormalTypes(newFormals); List<Type> newThrows = new ArrayList<Type>(md.formals().size()); for (Iterator<TypeNode> i = md.throwTypes().iterator(); i.hasNext(); ) { TypeNode tn = i.next(); newThrows.add(tn.type()); } mi.setThrowTypes(newThrows); } if (n instanceof X10ConstructorDecl) { X10ConstructorDecl cd = (X10ConstructorDecl) n; X10ConstructorInstance ci = (X10ConstructorInstance) cd.constructorInstance(); ci.setDefAnnotations(newAs); ci.setReturnType((X10Type) cd.returnType().type()); List<Type> newFormals = new ArrayList<Type>(cd.formals().size()); for (Iterator<Formal> i = cd.formals().iterator(); i.hasNext(); ) { Formal f = i.next(); newFormals.add(f.type().type()); } ci.setFormalTypes(newFormals); List<Type> newThrows = new ArrayList<Type>(cd.formals().size()); for (Iterator<TypeNode> i = cd.throwTypes().iterator(); i.hasNext(); ) { TypeNode tn = i.next(); newThrows.add(tn.type()); } ci.setThrowTypes(newThrows); } if (n instanceof ClassDecl) { ClassDecl cd = (ClassDecl) n; X10ParsedClassType ct = (X10ParsedClassType) cd.type(); ct.setDefAnnotations(Collections.EMPTY_LIST); ct.setClassAnnotations(newAs); if (cd.superClass() != null) ct.superType(cd.superClass().type()); List<Type> newInterfaces = new ArrayList<Type>(cd.interfaces().size()); for (Iterator<TypeNode> i = cd.interfaces().iterator(); i.hasNext(); ) { TypeNode tn = i.next(); newInterfaces.add(tn.type()); } ct.setInterfaces(newInterfaces); // Force annotations to be set for the default constructor for (Iterator i = ct.constructors().iterator(); i.hasNext(); ) { X10ConstructorInstance ci = (X10ConstructorInstance) i.next(); if (! ci.annotationsSet()) ci.setDefAnnotations(Collections.EMPTY_LIST); } } if (n instanceof New) { New nw = (New) n; X10ParsedClassType ct = (X10ParsedClassType) nw.anonType(); if (ct != null) { ct.setDefAnnotations(Collections.EMPTY_LIST); ct.setClassAnnotations(Collections.EMPTY_LIST); ClassType superType = (ClassType) nw.objectType().type(); if (! superType.flags().isInterface()) { ct.superType(superType); } else { ct.setInterfaces(Collections.singletonList(superType)); } } } return n; } }