// Copyright 2002-2007, FreeHEP.
package org.freehep.aid;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;
import org.freehep.rtti.IClass;
import org.freehep.rtti.IMethod;
import org.freehep.rtti.INamedType;
import org.freehep.rtti.IType;
import org.freehep.util.UserProperties;
import org.freehep.util.io.IndentPrintWriter;
/**
* @author Mark Donszelmann
* @version $Id: AbstractCPPGenerator.java 13274 2007-08-21 20:29:55Z duns $
*/
public abstract class AbstractCPPGenerator extends AbstractGenerator {
protected final static String language = "cpp";
protected UserProperties typeProperties = new UserProperties();
protected UserProperties sysIncludeProperties = new UserProperties();
protected UserProperties includeProperties = new UserProperties();
protected UserProperties valueProperties = new UserProperties();
protected UserProperties namesProperties = new UserProperties();
protected CPPTypeConverter converter;
public AbstractCPPGenerator(String propDir) {
super();
AidUtil.loadProperties(properties, getClass(), propDir, "aid.cpp.properties");;
AidUtil.loadProperties(sysIncludeProperties, getClass(), propDir, "aid.sysincludes."+language+".properties");
AidUtil.loadProperties(includeProperties, getClass(), propDir, "aid.includes."+language+".properties");
AidUtil.loadProperties(valueProperties, getClass(), propDir, "aid.values."+language+".properties");
AidUtil.loadProperties(typeProperties, getClass(), propDir, "aid.types."+language+".properties");
AidUtil.loadProperties(namesProperties, getClass(), propDir, "aid.names."+language+".properties");
converter = new CPPTypeConverter(propDir);
}
protected abstract String prefix();
protected String namespace(IClass clazz) {
return converter.namespace(clazz.getPackageName());
}
protected SortedSet printIncludeStatements(IndentPrintWriter out, IClass clazz) {
SortedSet sysIncludes = new TreeSet();
SortedSet includes = new TreeSet();
SortedSet types = new TreeSet();
includeStatements(clazz, sysIncludes, includes, namespace(clazz), types);
Iterator it = sysIncludes.iterator();
if (it.hasNext()) out.println();
while (it.hasNext()) {
String includeName = (String)it.next();
if (includeName.indexOf("::") >= 0) System.err.println("WARNING: "+clazz.getName()+" does not map '"+includeName+"' to a proper include file...");
out.println("#include <"+includeName+">");
}
it = includes.iterator();
if (it.hasNext()) out.println();
while (it.hasNext()) {
String includeName = (String)it.next();
if (includeName.indexOf("::") >= 0) System.err.println("WARNING: "+clazz.getName()+" does not map '"+includeName+"' to a proper include file...");
out.println("#include \""+includeName+"\"");
}
return types;
}
protected void includeStatements(IClass clazz, SortedSet sysIncludes, SortedSet includes, String namespace, SortedSet types) {
IMethod[] methods = clazz.getMethods();
for (int m=0; m<methods.length; m++) {
// check return type
includeFrom(methods[m].getReturnType(), prefix()+clazz.getName(), sysIncludes, includes, namespace, types);
INamedType[] parameterTypes = methods[m].getParameterTypes();
for (int p=0; p<parameterTypes.length; p++) {
includeFrom(parameterTypes[p].getType(), prefix()+clazz.getName(), sysIncludes, includes, namespace, types);
// FIXME: need to do something with init values used from different class
}
// add includes for exceptions
if (properties.isProperty("useExceptions")) {
String[] exceptionTypes = methods[m].getExceptionTypes();
for (int e=0; e<exceptionTypes.length; e++) {
includeFrom(exceptionTypes[e], prefix()+clazz.getName(), sysIncludes, includes, namespace, types);
}
}
}
}
// protected void includeFrom(IType type, String className, SortedSet sysIncludes, SortedSet includes, SortedSet types) {
// includeFrom(type, className, sysIncludes, includes, "", types);
// }
protected void includeFrom(IType type, String className, SortedSet sysIncludes, SortedSet includes, String namespace, SortedSet types) {
if (type.getDimension() > 0) sysIncludes.add("vector");
if (type.isPrimitive()) return;
IType[] subTypes = type.getTypes();
for (int i=0; i<subTypes.length; i++) {
includeFrom(subTypes[i], className, sysIncludes, includes, namespace, types);
}
if (type.getName().equals("[]")) return;
includeFrom(type.getName(), className, sysIncludes, includes, namespace, types);
}
protected void includeFrom(String name, String className, SortedSet sysIncludes, SortedSet includes, String namespace, SortedSet types) {
if (name == null) return;
name = converter.qualifiedName(name, namespace);
String inc = sysIncludeProperties.getProperty(name, null);
if (inc != null) {
if (!inc.trim().equals("")) {
sysIncludes.add(inc);
}
return;
}
inc = includeProperties.getProperty(name, null);
if (inc != null) {
if (!inc.trim().equals("")) {
includes.add(inc);
}
return;
}
if (!name.equals("") && !name.equals(className)) {
types.add(name);
}
}
protected String namedType(INamedType namedType, String nameSpace) {
StringBuffer s = new StringBuffer();
s.append(converter.type(namedType.getType(), nameSpace));
s.append(" ");
String name = namedType.getName();
s.append(namesProperties.getProperty(name, name));
return s.toString();
}
}