public override bool Equals(object obj) { if (obj == null) { return(false); } if (obj.GetType() == typeof(CppTypes)) { return(Equals(new CppType(obj))); } if (obj.GetType() != typeof(CppType)) { return(false); } CppType other = (CppType)obj; return((((internalModifiers == null || !internalModifiers.Any()) && (other.internalModifiers == null || !other.internalModifiers.Any())) || (internalModifiers != null && other.internalModifiers != null && CppModifiers.NormalizeOrder(internalModifiers).SequenceEqual(CppModifiers.NormalizeOrder(other.internalModifiers)))) && (((Namespaces == null || !Namespaces.Any()) && (other.Namespaces == null || !other.Namespaces.Any())) || (Namespaces != null && other.Namespaces != null && Namespaces.SequenceEqual(other.Namespaces))) && ElementType == other.ElementType && ElementTypeName == other.ElementTypeName); }
public CppType Subtract(CppModifiers modifier) { CppType newType = this; newType.internalModifiers = new List <CppModifiers> (((IEnumerable <CppModifiers>)newType.Modifiers).Reverse().WithoutFirst(modifier)); return(newType); }
public static CppType ForManagedType(Type type) { CppType mappedType = (from checkType in ManagedToCppTypeMap where checkType(type).ElementType != CppTypes.Unknown select checkType(type)).FirstOrDefault(); return(mappedType); }
public Type ToManagedType() { CppType me = this; Type mappedType = (from checkType in CppTypeToManagedMap where checkType(me) != null select checkType(me)).FirstOrDefault(); return(mappedType); }
// Removes the modifiers on the passed instance from this instance public CppType Subtract(CppType type) { if (internalModifiers == null) { return(this); } CppType current = this; foreach (var modifier in ((IEnumerable <CppModifiers>)type.Modifiers).Reverse()) { current = current.Subtract(modifier); } return(current); }
// note: this adds modifiers "backwards" (it is mainly used by the generator) public CppType Modify(CppModifiers modifier) { CppType newType = this; var newModifier = new CppModifiers [] { modifier }; if (newType.internalModifiers != null) { newType.internalModifiers.AddFirst(newModifier); } else { newType.internalModifiers = new List <CppModifiers> (newModifier); } return(newType); }
// Applies the element type of the passed instance // and combines its modifiers into this instance. // Use when THIS instance may have attributes you want, // but want the element type of the passed instance. public CppType CopyTypeFrom(CppType type) { ElementType = type.ElementType; ElementTypeName = type.ElementTypeName; Namespaces = type.Namespaces; List <CppModifiers> oldModifiers = internalModifiers; internalModifiers = type.internalModifiers; if (oldModifiers != null) { Modifiers.AddRange(oldModifiers); } return(this); }
void CreateMembers () { foreach (var ns in Lib.Namespaces) { var parentClass = ns.ParentNamespace as Class; var @enum = ns as Enumeration; if (@enum != null) { if (parentClass != null) parentClass.NestedEnums.Add (@enum); foreach (var enumValue in @enum.Node.Children.Where (o => o.Type == "EnumValue")) { int val; var item = new Enumeration.Item { Name = enumValue.Attributes ["name"] }; if (enumValue.HasValue ("init") && int.TryParse (enumValue.Attributes ["init"], out val)) item.Value = val; @enum.Items.Add (item); } continue; } var klass = ns as Class; if (klass == null || !klass.Node.HasValue ("members")) continue; klass.MangleType = GetType (klass.Node); if (parentClass != null) parentClass.NestedClasses.Add (klass); int fieldCount = 0; foreach (Node n in klass.Node ["members"].Split (new[] {' '}, StringSplitOptions.RemoveEmptyEntries).Select (id => Node.IdToNode [id])) { bool ctor = false; bool dtor = false; bool skip = false; switch (n.Type) { case "Field": var fieldType = GetType (GetTypeNode (n)); if (fieldType.ElementType == CppTypes.Unknown && fieldType.ElementTypeName == null) fieldType = new CppType (CppTypes.Void, CppModifiers.Pointer); string fieldName; if (n.Name != "") fieldName = n.Name; else fieldName = "field" + fieldCount++; klass.Fields.Add (new Field (fieldName, fieldType, (Access)Enum.Parse (typeof (Access), n ["access"]))); break; case "Constructor": ctor = true; break; case "Destructor": dtor = true; break; case "Method": break; default: continue; } if ((!dtor && n.HasValue ("overrides") && CheckPrimaryBases (klass, b => b.Node.CheckValueList ("members", n.Attributes ["overrides"]))) || // excl. virtual methods from primary base (except dtor) (!n.IsTrue ("extern") && !n.IsTrue ("inline"))) continue; if (n.IsTrue ("inline") && Lib.InlinePolicy == InlineMethods.NotPresent) skip = true; string name = dtor ? "Destruct" : n.Name; var method = new Method (n) { Name = name, Access = (Access)Enum.Parse (typeof (Access), n.Attributes ["access"]), IsVirtual = n.IsTrue ("virtual"), IsStatic = n.IsTrue ("static"), IsConst = n.IsTrue ("const"), IsInline = n.IsTrue ("inline"), IsArtificial = n.IsTrue ("artificial"), IsConstructor = ctor, IsDestructor = dtor }; if (method.Access == Access.@private) skip = true; if (dtor || method.IsArtificial) method.GenWrapperMethod = false; CppType retType; if (n.HasValue ("returns")) retType = GetType (n.NodeForAttr ("returns")); else retType = CppTypes.Void; if (retType.ElementType == CppTypes.Unknown) { retType = CppTypes.Void; skip = true; } if (CppTypeToManaged (retType) == null) { //Console.WriteLine ("\t\tS: " + retType); retType = CppTypes.Void; skip = true; } method.ReturnType = retType; int c = 0; var argTypes = new List<CppType> (); foreach (Node arg in n.Children.Where (o => o.Type == "Argument")) { string argname; if (arg.Name == null || arg.Name == "") argname = "arg" + c; else argname = arg.Name; var argtype = GetType (GetTypeNode (arg)); if (argtype.ElementType == CppTypes.Unknown) { //Console.WriteLine ("Skipping method " + klass.Name + "::" + member.Name + " () because it has an argument with unknown type '" + TypeNodeToString (arg) + "'."); argtype = new CppType (CppTypes.Void, CppModifiers.Pointer); skip = true; } if (CppTypeToManaged (argtype) == null) { //Console.WriteLine ("\t\tS: " + argtype); argtype = new CppType (CppTypes.Void, CppModifiers.Pointer); skip = true; } method.Parameters.Add (new Parameter (argname, argtype)); argTypes.Add (argtype); c++; } if (skip && !method.IsVirtual) continue; else if (skip && method.IsVirtual) method.GenWrapperMethod = false; // FIXME: More complete type name check if (ctor && argTypes.Count == 1 && argTypes [0].ElementType == CppTypes.Class && argTypes [0].ElementTypeName == klass.Name && argTypes [0].Modifiers.Count == 2 && argTypes [0].Modifiers.Contains (CppModifiers.Const) && argTypes [0].Modifiers.Contains (CppModifiers.Reference)) method.IsCopyCtor = true; Console.WriteLine ("\t" + klass.Name + "." + method.Name); klass.Methods.Add (method); } foreach (var method in klass.Methods) { if (AddAsProperty (klass, method)) method.GenWrapperMethod = false; } Field f2 = klass.Fields.FirstOrDefault (f => f.Type.ElementType == CppTypes.Unknown); if (f2 != null) { Console.WriteLine ("Skipping " + klass.Name + " because field " + f2.Name + " has unknown type."); klass.Disable = true; } } }
public MangleAsAttribute (string mangleTypeStr) { this.MangleType = new CppType (mangleTypeStr); }
public MangleAsAttribute (params object [] cppTypeSpec) { this.MangleType = new CppType (cppTypeSpec); }
public static bool IsCppType(CppType t) { return (t.ElementType == CppTypes.Class); }
public MangleAsAttribute(string mangleTypeStr) { this.MangleType = new CppType(mangleTypeStr); }
public Field (string name, CppType type, Access access) { Name = name; Type = type; Access = access; }
static public bool IsByVal (CppType t) { return ((t.ElementType == CppTypes.Class || t.ElementType == CppTypes.Struct) && !t.Modifiers.Contains (CppModifiers.Pointer) && !t.Modifiers.Contains (CppModifiers.Reference) && !t.Modifiers.Contains (CppModifiers.Array)); }
// FIXME: This makes no attempt to actually verify that the parts compose a valid C++ type. private void Parse(object [] parts) { foreach (object part in parts) { if (part is CppModifiers) { Modifiers.Add((CppModifiers)part); continue; } if (part is CppModifiers [] || part is IEnumerable <CppModifiers> ) { Modifiers.AddRange((IEnumerable <CppModifiers>)part); continue; } if (part is CppTypes) { ElementType = (CppTypes)part; continue; } Type managedType = part as Type; if (managedType != null) { CppType mapped = CppType.ForManagedType(managedType); CopyTypeFrom(mapped); continue; } string strPart = part as string; if (strPart != null) { var parsed = CppModifiers.Parse(strPart); if (parsed.Count > 0) { if (internalModifiers == null) { internalModifiers = parsed; } else { internalModifiers.AddRange(parsed); } strPart = CppModifiers.Remove(strPart); } // if we have something left, it must be a type name strPart = strPart.Trim(); if (strPart != "") { string [] qualifiedName = strPart.Split(new string [] { "::" }, StringSplitOptions.RemoveEmptyEntries); int numNamespaces = qualifiedName.Length - 1; if (numNamespaces > 0) { Namespaces = new string [numNamespaces]; for (int i = 0; i < numNamespaces; i++) { Namespaces [i] = qualifiedName [i]; } } strPart = qualifiedName [numNamespaces]; // FIXME: Fix this mess switch (strPart) { case "void": ElementType = CppTypes.Void; break; case "bool": ElementType = CppTypes.Bool; break; case "char": ElementType = CppTypes.Char; break; case "int": ElementType = CppTypes.Int; break; case "float": ElementType = CppTypes.Float; break; case "double": ElementType = CppTypes.Double; break; default: // otherwise it is the element type name... ElementTypeName = strPart; break; } } } } }
public virtual string GetTypeCode (CppType mangleType) { CppTypes element = mangleType.ElementType; IEnumerable<CppModifiers> modifiers = mangleType.Modifiers; StringBuilder code = new StringBuilder (); var ptr = For.AnyInputIn (CppModifiers.Pointer); var ptrRefOrArray = For.AnyInputIn (CppModifiers.Pointer, CppModifiers.Reference, CppModifiers.Array); var modifierCode = modifiers.Reverse ().Transform ( Choose.TopOne ( For.AllInputsIn (CppModifiers.Const, CppModifiers.Volatile).InAnyOrder ().After (ptrRefOrArray).Emit ('D'), For.AnyInputIn (CppModifiers.Const).After (ptrRefOrArray).Emit ('B'), For.AnyInputIn (CppModifiers.Volatile).After (ptrRefOrArray).Emit ('C'), For.AnyInput<CppModifiers> ().After (ptrRefOrArray).Emit ('A') ), For.AnyInputIn (CppModifiers.Array).Emit ('Q'), For.AnyInputIn (CppModifiers.Reference).Emit ('A'), Choose.TopOne ( ptr.After ().AllInputsIn (CppModifiers.Const, CppModifiers.Volatile).InAnyOrder ().Emit ('S'), ptr.After ().AnyInputIn (CppModifiers.Const).Emit ('Q'), ptr.After ().AnyInputIn (CppModifiers.Volatile).Emit ('R'), ptr.Emit ('P') ), ptrRefOrArray.AtEnd ().Emit ('A') ); code.Append (modifierCode.ToArray ()); switch (element) { case CppTypes.Void: code.Append ('X'); break; case CppTypes.Int: code.Append (modifiers.Transform ( For.AllInputsIn (CppModifiers.Unsigned, CppModifiers.Short).InAnyOrder ().Emit ('G') ).DefaultIfEmpty ('H').ToArray ()); break; case CppTypes.Char: code.Append ('D'); break; case CppTypes.Class: code.Append ('V'); code.Append(mangleType.ElementTypeName); code.Append ("@@"); break; case CppTypes.Struct: code.Append ('U'); code.Append(mangleType.ElementTypeName); code.Append ("@@"); break; case CppTypes.Union: code.Append ('T'); code.Append(mangleType.ElementTypeName); code.Append ("@@"); break; case CppTypes.Enum: code.Append ("W4"); code.Append(mangleType.ElementTypeName); code.Append ("@@"); break; } return code.ToString (); }
public TemplateModifier (CppType [] types) { Types = types; }
CppType GetType(Node n, CppType modifiers) { var fundamental = CppTypes.Unknown; switch (n.Type) { case "Typedef": return GetType (GetTypeNode (n), modifiers); case "ArrayType": CppModifiers mod = null; var max = n.Attributes ["max"]; var min = n.Attributes ["min"]; if (max != null && min != null) { var l = GetLongValue (max) - GetLongValue (min); mod = new CppModifiers.ArrayModifier ((int)l + 1); } else { mod = CppModifiers.Array; } return GetType(GetTypeNode(n), modifiers.Modify(mod)); case "PointerType": return GetType (GetTypeNode (n), modifiers.Modify (CppModifiers.Pointer)); case "ReferenceType": return GetType (GetTypeNode (n), modifiers.Modify (CppModifiers.Reference)); case "FundamentalType": return modifiers.CopyTypeFrom (new CppType (n.Name)); case "CvQualifiedType": if (n.IsTrue ("const")) return GetType (GetTypeNode (n), modifiers.Modify (CppModifiers.Const)); else throw new NotImplementedException (); case "Class": fundamental = CppTypes.Class; break; case "Struct": fundamental = CppTypes.Struct; break; case "Enumeration": fundamental = CppTypes.Enum; break; case "FunctionType": fundamental = CppTypes.Delegate; break; default: return CppTypes.Unknown; } if (!NodeToNamespace.ContainsKey (n)) { // FIXME: Do something better if(string.IsNullOrEmpty(n.Name)) { Console.WriteLine ("WARNING: Could not find type with id '{0}'", n.Id); } else { Console.WriteLine ("WARNING: Could not find type '{0}'", n.Name); } return CppTypes.Unknown; } return modifiers.CopyTypeFrom (new CppType (fundamental, string.Join ("::", NodeToNamespace [n].FullyQualifiedName))); }
public Filter GetFilterOrDefault(CppType cpptype) { var fqn = cpptype.ElementTypeName; // Convert any template types to their managed names var mod = cpptype.Modifiers.FirstOrDefault(m => m == CppModifiers.Template); if (mod != null) fqn = CreateTemplateClassName(fqn, mod.ToString()); if (cpptype.Namespaces != null) fqn = string.Join ("::", cpptype.Namespaces) + "::" + fqn; var newtype = new CppType (fqn, null); return GetFilterOrDefault (newtype.ToString ().Replace (" ", "")); }
public static bool IsDelegate(CppType t) { return (t.ElementType == CppTypes.Delegate); }
CppType GetType (Node n, CppType modifiers) { var fundamental = CppTypes.Unknown; switch (n.Type) { case "Typedef": return GetType (GetTypeNode (n), modifiers); case "ArrayType": CppModifiers mod = null; if (n.Attributes ["max"] != null && n.Attributes ["min"] != null) mod = new CppModifiers.ArrayModifier (int.Parse (n.Attributes ["max"].TrimEnd ('u')) - int.Parse (n.Attributes ["min"].TrimEnd ('u')) + 1); else mod = CppModifiers.Array; return GetType (GetTypeNode (n), modifiers.Modify (mod)); case "PointerType": return GetType (GetTypeNode (n), modifiers.Modify (CppModifiers.Pointer)); case "ReferenceType": return GetType (GetTypeNode (n), modifiers.Modify (CppModifiers.Reference)); case "FundamentalType": return modifiers.CopyTypeFrom (new CppType (n.Name)); case "CvQualifiedType": if (n.IsTrue ("const")) return GetType (GetTypeNode (n), modifiers.Modify (CppModifiers.Const)); else throw new NotImplementedException (); case "Class": fundamental = CppTypes.Class; break; case "Struct": fundamental = CppTypes.Struct; break; case "Enumeration": fundamental = CppTypes.Enum; break; default: return CppTypes.Unknown; } if (!NodeToNamespace.ContainsKey (n)) { // FIXME: Do something better return CppTypes.Unknown; } return modifiers.CopyTypeFrom (new CppType (fundamental, string.Join ("::", NodeToNamespace [n].FullyQualifiedName))); }
// Return the System.Type name corresponding to T, or null // Returned as a string, because other wrappers do not have System.Types yet public string CppTypeToManaged (CppType t) { Type mtype = t.ToManagedType (); if (mtype != null && mtype != typeof (ICppObject)) { return mtype.FullName; } switch (t.ElementType) { case CppTypes.Class: case CppTypes.Struct: case CppTypes.Enum: var filter = GetFilterOrDefault (t); var qname = filter.TypeName.Replace ("::", "."); if (filter.ImplType == ImplementationType.@struct && !IsByVal (t)) return qname + "&"; else return qname; } return null; }
public Parameter (String name, CppType type) { Name = name; Type = type; }
public Filter GetFilterOrDefault (CppType cpptype) { var fqn = cpptype.ElementTypeName; if (cpptype.Namespaces != null) fqn = string.Join ("::", cpptype.Namespaces) + "::" + fqn; var newtype = new CppType (fqn, cpptype.Modifiers.Where (m => m == CppModifiers.Template)); return GetFilterOrDefault (newtype.ToString ().Replace (" ", "")); }
public MangleAsAttribute (CppType mangleType) { this.MangleType = mangleType; }
public MangleAsAttribute(CppType mangleType) { this.MangleType = mangleType; }
// Applies the element type of the passed instance // and combines its modifiers into this instance. // Use when THIS instance may have attributes you want, // but want the element type of the passed instance. public CppType CopyTypeFrom (CppType type) { ElementType = type.ElementType; ElementTypeName = type.ElementTypeName; Namespaces = type.Namespaces; List<CppModifiers> oldModifiers = internalModifiers; internalModifiers = type.internalModifiers; if (oldModifiers != null) Modifiers.AddRange (oldModifiers); return this; }
public MangleAsAttribute(params object [] cppTypeSpec) { this.MangleType = new CppType(cppTypeSpec); }
// Removes the modifiers on the passed instance from this instance public CppType Subtract (CppType type) { if (internalModifiers == null) return this; CppType current = this; foreach (var modifier in ((IEnumerable<CppModifiers>)type.Modifiers).Reverse ()) current = current.Subtract (modifier); return current; }
public Property (string name, CppType type) { Name = name; Type = type; }
public virtual CppType GetMangleType (ICustomAttributeProvider icap, Type managedType) { CppType mangleType = new CppType (); MangleAsAttribute maa = (MangleAsAttribute)icap.GetCustomAttributes (typeof (MangleAsAttribute), false).FirstOrDefault (); if (maa != null) mangleType = maa.MangleType; // this means that either no MangleAsAttribute was defined, or // only CppModifiers were applied .. apply CppType from managed parameter type if (mangleType.ElementType == CppTypes.Unknown && mangleType.ElementTypeName == null) mangleType.CopyTypeFrom (CppType.ForManagedType (managedType)); else if (mangleType.ElementType == CppTypes.Unknown) // FIXME: otherwise, we just assume it's CppTypes.Class for now. mangleType.ElementType = CppTypes.Class; return mangleType; }