static GacUDT[] ExtractRelatedUDT(GacType type) { if (type == null) { return(new GacUDT[0]); } return(ExtractRelatedUDT(type.ElementType).Concat( ExtractRelatedUDT(type.ReturnType).Concat( (type.ParameterTypes == null ? new GacUDT[0] : type.ParameterTypes.SelectMany(ExtractRelatedUDT)).Concat( type.AssociatedUDT == null ? new GacUDT[0] : new GacUDT[] { type.AssociatedUDT } ))).Distinct().ToArray()); }
static GacType DecorateType(GacType type, XElement typeElement) { if (typeElement.Attribute("const").Value == "true") { type = new GacType { Name = type.Name + " const", Kind = GacTypeKind.Const, ElementType = type, }; } if (typeElement.Attribute("volatile").Value == "true") { type = new GacType { Name = type.Name + " volatile", Kind = GacTypeKind.Volatile, ElementType = type, }; } return(type); }
static GacType TranslateTypeInternal(Dictionary <string, GacUDT> udts, XElement typeElement) { switch (typeElement.Name.LocalName) { case "primitive": return(new GacType { Name = typeElement.Attribute("name").Value, Kind = GacTypeKind.Primitive, }); case "classType": case "enumType": { string name = typeElement.Attribute("name").Value; if (name.StartsWith("vl::Ptr<")) { string newName = name.Substring(8, name.Length - 9); return(new GacType { Name = name, Kind = GacTypeKind.SmartPointer, ElementType = new GacType { Name = newName, Kind = GacTypeKind.UDT, AssociatedUDT = udts[newName], }, }); } else { return(new GacType { Name = name, Kind = GacTypeKind.UDT, AssociatedUDT = udts[name], }); } } case "pointer": { GacType elementType = TranslateType(udts, typeElement.Elements().First()); return(new GacType { Name = elementType.Name + "*", Kind = GacTypeKind.Pointer, ElementType = elementType, }); } case "reference": { GacType elementType = TranslateType(udts, typeElement.Elements().First()); return(new GacType { Name = elementType.Name + "&", Kind = GacTypeKind.Reference, ElementType = elementType, }); } case "rightValueReference": { GacType elementType = TranslateType(udts, typeElement.Elements().First()); return(new GacType { Name = elementType.Name + "&&", Kind = GacTypeKind.RValueReference, ElementType = elementType, }); } case "array": { GacType elementType = TranslateType(udts, typeElement.Element("element").Elements().First()); int arrayLength = int.Parse(typeElement.Element("count").Attribute("value").Value); return(new GacType { Name = elementType.Name + "[" + arrayLength.ToString() + "]", Kind = GacTypeKind.Array, ElementType = elementType, ArrayLength = arrayLength, }); } case "function": { GacType returnType = TranslateType(udts, typeElement.Element("return").Elements().First()); GacType[] parameterTypes = typeElement.Element("arguments").Elements("argument") .Select(e => TranslateType(udts, e.Elements().First())) .ToArray(); string callingConversion = typeElement.Element("callconv").Attribute("value").Value; return(new GacType { Name = returnType.Name + "(" + callingConversion + ")(" + parameterTypes.Select(t => t.Name).Aggregate("", (a, b) => a == "" ? b : a + ", " + b) + ")", Kind = GacTypeKind.Function, ReturnType = returnType, ParameterTypes = parameterTypes, CallingConversion = callingConversion, }); } default: throw new ArgumentException(); } }