// Copyright 2000-2005, FreeHEP.
package org.freehep.rtti;
import java.util.*;
/**
* Defines a type in the RTTI.
*
* This type may be cascaded (typedef in C++) to another type.
* The methods isPrimitive, isEnumeration, getDimension and getPointer accomodate for this.
*
* @author Mark Donszelmann
* @version $Id: IType.java 8584 2006-08-10 23:06:37Z duns $
*/
public class IType {
private String name;
private boolean primitive;
private boolean enumeration;
private boolean konst;
private IType alias;
private int pointer;
private boolean reference;
private int dimension;
private IType[] types;
IType(String name, boolean konst, boolean primitive, boolean enumeration,
boolean reference, int pointer, int dimension, IType[] types) {
this.name = name;
this.konst = konst;
this.primitive = primitive;
this.enumeration = enumeration;
this.alias = null;
this.reference = reference;
this.pointer = pointer;
this.dimension = dimension;
this.types = types;
}
IType(String name, IType alias, boolean reference, int pointer, int dimension) {
this.name = name;
this.primitive = false;
this.konst = false;
this.alias = alias;
this.reference = reference;
this.pointer = pointer;
this.dimension = dimension;
}
/**
* Returns the name of the type. This name may be fully qualified. Otherwise it belongs
* to the current package.
*
*
* @return name of the type
*/
public String getName() {
return (alias == null) ? name : alias.getName();
}
/**
* Indicates if this type is a primitive type.
*
*
* @return true if this type is a primitive
*/
public boolean isPrimitive() {
return (alias == null) ? primitive : alias.isPrimitive();
}
/**
* Indicates if this type is an enumerated type.
*
*
* @return true if this type is an enumeration
*/
public boolean isEnumeration() {
return (alias == null) ? enumeration : alias.isEnumeration();
}
/**
* Indicates if this type is a const type.
*
*
* @return true if this type is a const
*/
public boolean isConst() {
return (alias == null) ? konst : alias.isConst();
}
/**
* Indicates if this type is a reference.
*
*
* @return true if reference
*/
public boolean isReference() {
if (alias == null) {
return reference;
}
return alias.isReference();
}
/**
* Indicates the number of pointer postfixes this type has.
*
*
* @return pointer postfixes of this type (*)
*/
public int getPointer() {
if (alias == null) {
return pointer;
}
return alias.getPointer();
}
/**
* Indicates the dimension of this type.
* <p>1 = [], 2 = [][], etc...
*
* @return dimension of this type, 0 is no dimension.
*/
public int getDimension() {
return (alias == null) ? dimension : alias.getDimension()+dimension;
}
/**
* Indicates the template of this type.
*
* @return type of template
*/
public IType[] getTypes() {
return types;
}
public boolean isVoid()
{
return getName().equals("void");
}
public String getSignature(String packageName, Properties imports) {
StringBuffer s = new StringBuffer();
if (alias == null) {
if (isPrimitive() || isVoid()) {
s.append(getName());
} else {
// FIXME, if not found, add packagename of this class
String name = getName();
for (int i=getDimension(); i>0; i--) {
name = getTypes()[0].getName();
}
name = imports.getProperty(name,null);
s.append( name != null ? name : packageName+"."+getName());
}
} else {
s.append(alias.getSignature(packageName, imports));
}
for (int i = 0; i < getDimension(); i++) {
s.append("[]");
}
return org.apache.bcel.classfile.Utility.getSignature(s.toString());
}
/**
* Returns a string representation of this type.
*
*
* @return string representatoon of this type
*/
public String toString() {
StringBuffer s = new StringBuffer();
if (isConst()) {
s.append("const ");
}
if (isPrimitive()) {
s.append("#");
}
if (isEnumeration()) {
s.append("enum ");
}
s.append(getName());
IType[] types = getTypes();
if (types.length > 0) {
s.append("<");
s.append(types[0].toString());
for (int i=1; i<types.length; i++) {
s.append(", ");
s.append(types[i].toString());
}
s.append(">");
}
if (isReference()) {
s.append("&");
}
for (int i=0; i<getPointer(); i++) {
s.append("*");
}
for (int i = 0; i < getDimension(); i++) {
s.append("[]");
}
if (alias != null) {
s.append("{"+name+"}");
}
return s.toString();
}
/**
* returns true is the two types are equivalent, that is after all aliasing
* has been done
*/
public boolean equals(Object o) {
if (o instanceof IType) {
IType other = (IType) o;
if (!getName().equals(other.getName())) return false;
if (getDimension() != other.getDimension()) return false;
if (isReference() != other.isReference()) return false;
else return getPointer() == other.getPointer();
}
return false;
}
}