/* * 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 x10.types.constants.StringValue; import polyglot.visit.ContextVisitor; import polyglot.visit.NodeVisitor; import x10.ast.AmbMacroTypeNode_c; import x10.ast.AnnotationNode; import x10.ast.X10StringLit_c; import x10.config.Configuration; import x10.config.ConfigurationError; import x10.config.OptionError; import x10.extension.X10Ext; import x10.types.X10ClassType; import x10.errors.Errors; // Drop node from ast according to @Ifdef and @Ifndef annotations // 1. drop node if it has an @Ifndef annotation for a defined macro // 2. drop node if it has at least one @Ifdef annotation and none of the macros are defined public class IfdefVisitor extends ContextVisitor { public IfdefVisitor(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; } List<AnnotationNode> annotations = ((X10Ext) n.ext()).annotations(); for (Iterator<AnnotationNode> i = annotations.iterator(); i.hasNext(); ) { AnnotationNode a = i.next(); TypeNode tn = a.annotationType(); if (!(tn instanceof AmbMacroTypeNode_c)) { continue; } AmbMacroTypeNode_c at = (AmbMacroTypeNode_c) tn; if (!"Ifndef".equals(at.name().toString())) { continue; } List<Expr> l = at.args(); if (l.size() != 1 || !l.get(0).isConstant() || !l.get(0).type().isSubtype(ts.String(), context)) { Errors.issue(job, new SemanticException("@Ifndef must have a unique constant String parameter"), n); continue; } String macro = ((StringValue) l.get(0).constantValue()).value(); if (job.extensionInfo().getOptions().macros.contains(macro)) { return null; } } boolean ifdef = true; for (Iterator<AnnotationNode> i = annotations.iterator(); i.hasNext(); ) { AnnotationNode a = i.next(); TypeNode tn = a.annotationType(); if (!(tn instanceof AmbMacroTypeNode_c)) { continue; } AmbMacroTypeNode_c at = (AmbMacroTypeNode_c) tn; if (!"Ifdef".equals(at.name().toString())) { continue; } ifdef = false; List<Expr> l = at.args(); if (l.size() != 1 || !l.get(0).isConstant() || !l.get(0).type().isSubtype(ts.String(), context)) { Errors.issue(job, new SemanticException("@Ifdef must have a unique constant String parameter"), n); continue; } String macro = ((StringValue) l.get(0).constantValue()).value(); if (job.extensionInfo().getOptions().macros.contains(macro)) { return n; } } return ifdef ? n : null; } }