public static string ConstructTypeName(XElement typeElement, out bool isPrimitive) {
if(typeElement == null) {
isPrimitive = false;
return string.Empty;
} else if(typeElement.Name != SRC.Type) {
throw new ArgumentException(string.Format("The passed XElement must represent a <type> element. Received a <{0}> element.", typeElement.Name.ToString()), "typeElement");
}
//Find the name of the type
StringBuilder typeName = new StringBuilder();
isPrimitive = false;
XElement typeNameElement;
if(typeElement.Elements(SRC.Name).Any()) {
//the Type element may actually contain several Name elements because access modifiers (e.g. static, private, etc.) get tagged as Names
//We assume that all keywords appear before the actual type name, except for const, which can appear afterwards
//Therefore, grab the last non-const name element
typeNameElement = typeElement.Elements(SRC.Name).Last(ne => ne.Value != "const");
if(primitiveTypes.Contains(typeNameElement.Value)) {
//last name element is a primitive type, look for more primitive names preceding it
//e.g. "unsigned short int"
isPrimitive = true;
typeName.Append(typeNameElement.Value);
foreach(var currElem in typeNameElement.ElementsBeforeSelf().Reverse()) {
if(currElem.Name == SRC.Name && primitiveTypes.Contains(currElem.Value)) {
typeName.Insert(0, currElem.Value + " ");
} else {
break;
}
}
} else {
//A name element might contain several child name elements, in the case where the name is qualified
//E.g. <Namespace>::<typeName>
//This grabs the last child name element, assuming that it is the actual type name
var childNames = typeNameElement.Elements(SRC.Name);
if(childNames != null && childNames.Any()) {
typeNameElement = childNames.Last();
}
typeName.Append(typeNameElement.Value);
}
} else {
//It's possible to have zero name elements, in the case of "..." for variable length argument lists.
typeNameElement = null;
}
//append any type modifiers that are present, e.g. '*' or '&'
IEnumerable<XElement> typeModifierCollection;
if(typeNameElement != null) {
typeModifierCollection = typeNameElement.ElementsAfterSelf(TYPE.Modifier);
} else {
//no type name, probably because type is "...", so append all modifiers
typeModifierCollection = typeElement.Elements(TYPE.Modifier);
}
foreach(var typeModifier in typeModifierCollection) {
typeName.Append(typeModifier.Value);
}
return typeName.ToString();
}