/* * 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.Iterator; import java.util.List; import polyglot.ast.ClassDecl; import polyglot.ast.Expr; import polyglot.ast.FieldDecl; import polyglot.ast.Import; import polyglot.ast.MethodDecl; import polyglot.ast.Node; import polyglot.ast.NodeFactory; import polyglot.ast.PackageNode; import polyglot.ast.SourceFile; import polyglot.ast.Stmt; import polyglot.ast.TypeNode; import polyglot.frontend.Job; import polyglot.types.ClassType; import polyglot.types.QName; import polyglot.types.SemanticException; import polyglot.types.Type; import polyglot.types.TypeSystem; import polyglot.visit.ContextVisitor; import polyglot.visit.NodeVisitor; import x10.ast.AnnotationNode; import x10.extension.X10Ext; import x10.types.X10ClassType; import x10.errors.Errors; public class AnnotationChecker extends ContextVisitor { public AnnotationChecker(Job job, TypeSystem ts, NodeFactory nf) { super(job, ts, nf); } public Node leaveCall(Node parent, Node old, Node n, NodeVisitor v) { if (! (n.ext() instanceof X10Ext)) { return n; } init(); List<AnnotationNode> annotations = ((X10Ext) n.ext()).annotations(); for (Iterator<AnnotationNode> i = annotations.iterator(); i.hasNext(); ) { AnnotationNode a = i.next(); X10ClassType at = a.annotationInterface(); if (at.error() != null) { continue; } if (n instanceof TypeNode && ! at.isSubtype(TA, context)) { Errors.issue(job, new Errors.AnnotationMustImplementType(at, Errors.AnnotationMustImplementType.Element.types, TA, n.position())); } else if (n instanceof Expr && ! at.isSubtype(EA, context)) { Errors.issue(job, new Errors.AnnotationMustImplementType(at, Errors.AnnotationMustImplementType.Element.expressions, EA, n.position())); } else if (n instanceof Stmt && ! at.isSubtype(SA, context)) { Errors.issue(job, new Errors.AnnotationMustImplementType(at, Errors.AnnotationMustImplementType.Element.statements, SA, n.position())); } else if (n instanceof MethodDecl && ! at.isSubtype(MA, context)) { Errors.issue(job, new Errors.AnnotationMustImplementType(at, Errors.AnnotationMustImplementType.Element.method_declarations, MA, n.position())); } else if (n instanceof FieldDecl && ! at.isSubtype(FA, context)) { Errors.issue(job, new Errors.AnnotationMustImplementType(at, Errors.AnnotationMustImplementType.Element.field_declarations, FA, n.position())); } else if (n instanceof ClassDecl && ! at.isSubtype(CA, context)) { Errors.issue(job, new Errors.AnnotationMustImplementType(at, Errors.AnnotationMustImplementType.Element.class_declarations, CA, n.position())); } else if (n instanceof PackageNode && parent instanceof SourceFile && ! at.isSubtype(PA, context)) { Errors.issue(job, new Errors.AnnotationMustImplementType(at, Errors.AnnotationMustImplementType.Element.package_declarations, PA, n.position())); } else if (n instanceof Import && ! at.isSubtype(IA, context)) { Errors.issue(job, new Errors.AnnotationMustImplementType(at, Errors.AnnotationMustImplementType.Element.imports, IA, n.position())); } else if (! at.isSubtype(A, context)) { Errors.issue(job, new Errors.AnnotationMustImplementType(at, A, n.position())); } } return n; } Type A, TA, EA, SA, MA, FA, CA, IA, PA; public void init() { if (A != null) return; try { TA = ts.systemResolver().findOne(QName.make("x10.lang.annotations.TypeAnnotation")); EA = ts.systemResolver().findOne(QName.make("x10.lang.annotations.ExpressionAnnotation")); SA = ts.systemResolver().findOne(QName.make("x10.lang.annotations.StatementAnnotation")); MA = ts.systemResolver().findOne(QName.make("x10.lang.annotations.MethodAnnotation")); FA = ts.systemResolver().findOne(QName.make("x10.lang.annotations.FieldAnnotation")); CA = ts.systemResolver().findOne(QName.make("x10.lang.annotations.ClassAnnotation")); IA = ts.systemResolver().findOne(QName.make("x10.lang.annotations.ImportAnnotation")); PA = ts.systemResolver().findOne(QName.make("x10.lang.annotations.PackageAnnotation")); A = ts.systemResolver().findOne(QName.make("x10.lang.annotations.Annotation")); } catch (SemanticException e) { throw new RuntimeException(e); } } }