/*
* 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.HashMap;
import java.util.List;
import java.util.Map;
import polyglot.ast.ClassMember;
import polyglot.ast.Expr;
import polyglot.ast.Node;
import polyglot.ast.NodeFactory;
import polyglot.ast.TypeNode;
import polyglot.frontend.Globals;
import polyglot.frontend.Job;
import polyglot.types.QName;
import polyglot.types.Ref;
import polyglot.types.SemanticException;
import polyglot.types.Type;
import polyglot.types.TypeSystem;
import polyglot.types.Types;
import polyglot.visit.ContextVisitor;
import polyglot.visit.NodeVisitor;
import x10.ast.AnnotationNode;
import x10.ast.X10ClassDecl;
import x10.ast.X10ConstructorDecl;
import x10.ast.X10FieldDecl;
import x10.ast.X10MethodDecl;
import x10.extension.X10Del;
import x10.types.X10ClassDef;
import x10.types.X10ClassType;
import x10.types.X10Def;
import x10.types.X10MethodDef;
import polyglot.types.TypeSystem;
import polyglot.util.Position;
/**
* Visitor to replace @NativeCPPExtern annotations with @Native annotations.
*/
public class ExternAnnotationVisitor extends ContextVisitor {
String theLanguage;
public ExternAnnotationVisitor(Job job, TypeSystem ts, NodeFactory nf, String theLanguage) {
super(job, ts, nf);
this.theLanguage = theLanguage;
}
boolean isExtern(X10Def o) {
return !o.annotationsNamed(QName.make("x10.compiler.NativeCPPExtern")).isEmpty();
}
void process(X10MethodDef def) {
StringBuilder sb = new StringBuilder(def.name() + "(");
for (int i=1; i<=def.formalTypes().size(); i++) {
if (i > 1) sb.append(",");
sb.append("(#" + i + ")");
if (Types.isX10Array(def.formalTypes().get(i-1).get()))
sb.append("->raw()->raw()");
}
sb.append(") /* ExternAnnotationVisitor */");
List<Expr> inits = new ArrayList<Expr>(2);
inits.add(nf.StringLit(Position.COMPILER_GENERATED, theLanguage));
inits.add(nf.StringLit(Position.COMPILER_GENERATED, sb.toString()));
List<Ref<? extends Type>> ats = new ArrayList<Ref<? extends Type>>(def.defAnnotations().size() + 1);
for (Ref<? extends Type> at : def.defAnnotations()) {
ats.add(at);
}
X10ClassType t = ts.NativeType();
ats.add(Types.ref(t.propertyInitializers(inits)));
def.setDefAnnotations(ats);
}
public Node leaveCall(Node old, Node n, NodeVisitor v) throws SemanticException {
if (n instanceof X10MethodDecl) {
X10MethodDef def = (X10MethodDef) ((X10MethodDecl) n).methodDef();
if (def.flags().isNative() && def.flags().isStatic() && isExtern(def))
process(def);
}
return n;
}
}