public override string ToLiteral(object value, AST.Type type = null) { if (value == null) { return("null"); } var t = value.GetType(); if (t == typeof(float) || t == typeof(Single)) { return(((float)value).ToString("G9") + "f"); } else if (t == typeof(double) || t == typeof(Double)) { return(((double)value).ToString("G17")); } else if (t.IsEnum) { return(t.Name + "." + value.ToString()); } else if (t == typeof(string) || t == typeof(String)) { return("@\"" + ((string)value).Replace("\"", "\"\"") + "\""); } else if (t.IsPrimitive) { return(value.ToString()); } Errors.UnsupportedTypeInAttribute(t); return(null); }
public static void SubstituteType(this AST.Definition def, AST.Type oldType, AST.Type newType) { foreach (var variable in def.Declarations.OfType <AST.IVariable>().Where(v => v.Type == oldType)) { variable.Type = newType; } }
public void MethodImplementation(AST.ICallSignature m, AST.Type type, Action implementation = null) { if (Strata == ApiStrata.Normal) { UseLocalTranslations = false; Code("{0} {1}::{2}(", VariableType(m.Return), TypeRef(type), m.Name); UseLocalTranslations = true; Code(DeclParameters(m.Parameters)); if (m.IsConst) { Line(") const"); } else { Line(")"); } Block(() => { if (implementation != null) { implementation(); } else if (Settings.Mode == CppMode.PimplWrapper) { CallToABIMethodBody(m.Rename("_abi->_" + m.GetComCompatibleName())); } else { PlaceholderMethodBody(m); } }); } else { var args = m.Parameters; Line("HRESULT {0}::_{1}({2})", TypeRef(type.ToVariable(), false), m.GetComCompatibleName(), DeclParameters(m.GetABIParametersCpp())); Strata = ApiStrata.Normal; Block(() => { if (implementation == null) { CallFromABIMethodBody(m); } else { implementation(); } }); Strata = ApiStrata.ABI; } }
public static string FullName(this AST.Type t, string scopeOperator) { if (t.Namespace.IsGlobal || t.IsVoid || t.IsPrimitive || t.IsString) { return(t.Name); } else { return(FullName(t.Namespace, scopeOperator) + scopeOperator + t.Name); } }
public override string ToLiteral(object value, AST.Type type = null) { if (value == null) { return("null"); } var t = value.GetType(); var enumType = type as AST.Enum; if (t == typeof(float) || t == typeof(Single)) { var fvalue = (float)value; return((fvalue).ToString("G9") + (Math.Floor(fvalue) != fvalue ? "f" : "")); } else if (t == typeof(double) || t == typeof(Double)) { return(((double)value).ToString("G17")); } else if (t.IsEnum) { var x = (int)value; if (enumType == null) { return(x.ToString()); } string entryName = null; foreach (var e in enumType.Entries) { if (e.Value == x) { entryName = e.Name; break; } } return(TypeName(enumType) + "::" + entryName); } else if (t == typeof(string) || t == typeof(String)) { return("L\"" + U.StringLiteral((string)value) + "\""); } else if (t.IsPrimitive) { return(value.ToString()); } Errors.UnsupportedTypeInAttribute(t); return(null); }
public static Dictionary <AST.Type, string> GetLocalTranslations(AST.Type type) { var ret = new Dictionary <AST.Type, string>(); var obj = type as AST.Object; var st = type as AST.Struct; // Classes that have properties with the same name as declared types (happens a lot) // need to be disambiguated. // We do that by locally renaming the type to TypeName_t var allRefs = type.SelectReferencedTypes(); Dictionary <string, AST.Type> refNames = new Dictionary <string, AST.Type>(); foreach (var r in allRefs) { refNames[r.Name] = r; } if (obj != null) { foreach (var p in obj.Properties) { AST.Type refType; if (refNames.TryGetValue(p.Name, out refType)) { ret[refType] = p.Name + "_t"; } } } if (st != null) { foreach (var p in st.Fields) { AST.Type refType; if (refNames.TryGetValue(p.Name, out refType)) { ret[refType] = p.Name + "_t"; } } } return(ret); }
private string GetLocalTranslation(AST.Type type) { if (!UseLocalTranslations) { return(null); } string ret; if (LocalTranslations.TryGetValue(type, out ret)) { return(ret); } else { return(null); } }
public abstract string TypeName(AST.Type v, bool?abi = null);
public virtual string ToLiteral(object lit, AST.Type type = null) { return(lit.ToString()); }
public string Literal(object value, AST.Type type) { return(InlineNode(new LiteralNode(value, type))); }
public string TypeRef(AST.Type type, bool?abi = null) { return(InlineNode(new TypeRefNode(type, abi))); }
public void WriteArrayMemberConverter(AST.Type type) { var tn = TypeRef(type, false); var tnabi = TypeRef(type, true); if (type.IsDelegate) { tnabi = "DelegateBlob"; } Line("public static {0}[] FromABI{1}(IntPtr data, int count)", tn, type.ShortId); Block(() => { Line("if(data == IntPtr.Zero) return null;"); Line("var sz = Marshal.SizeOf<{0}>();", tnabi); Line("var r = new {0}[count];", tn); Line("for(int i = 0;i < count;i++)"); Block(() => { if (type.IsStruct) { if (CsRender.RequiresABITranslation(type.ToVariable())) { Line("r[i] = {0}.FromABI(Marshal.PtrToStructure<{0}>((IntPtr)((long)data + i * sz)));", tnabi); } else { Line("r[i] = Marshal.PtrToStructure<{0}>((IntPtr)((long)data + i * sz));", tnabi); } } else if (type.IsDelegate) { Line("var blob = Marshal.PtrToStructure<{0}>((IntPtr)((long)data + i * sz));", tnabi); Line("r[i] = D{0}.Wrap(blob.Fn, blob.Ctx);", type.ShortId); } else if (type.IsObject) { Line("r[i] = GluonObject.Of<{0}>(Marshal.ReadIntPtr((IntPtr)((long)data + i * sz)));", tn); } else { throw new InvalidOperationException("This writer only designed to write for structs, delegates, and classes"); } }); Line("Marshal.FreeCoTaskMem(data);"); Line("return r;"); }); Line("public static ArrayBlob ToABI{1}({0}[] arr)", tn, type.ShortId); Block(() => { Line("if(arr == null) return new ArrayBlob();"); Line("var sz = Marshal.SizeOf<{0}>();", tnabi); Line("var r = new ArrayBlob(Marshal.AllocCoTaskMem(sz * arr.Length), arr.Length);"); Line("for(int i = 0;i < arr.Length;i++)"); Block(() => { if (type.IsStruct) { if (CsRender.RequiresABITranslation(type.ToVariable())) { Line("Marshal.StructureToPtr({0}.ToABI(arr[i]), r.Ptr + sz * i, false);", tnabi); } else { Line("Marshal.StructureToPtr(arr[i], r.Ptr + sz * i, false);", tnabi); } } else if (type.IsDelegate) { Line("var blob = D{0}.Unwrap(arr[i]);", type.ShortId); Line("Marshal.StructureToPtr(blob, (IntPtr)((long)r.Ptr + sz * i), false);"); } else if (type.IsObject) { Line("var item = arr[i];"); Line("Marshal.WriteIntPtr((IntPtr)((long)r.Ptr + sz * i), item == null ? IntPtr.Zero : item.IPtr);"); } }); Line("return r;"); }); Line("public static void FreeABI{0}(IntPtr data, int count)", type.ShortId); Block(() => { Line("Marshal.FreeCoTaskMem(data);"); }); }
public override string TypeName(AST.Type type, bool?abi = null) { string ret = type.Name; if (abi ?? Strata == ApiStrata.ABI) { if (type == BasicTypes.String) { return("char*"); } else if (type == BasicTypes.IUnknown) { return("IUnknown"); } else if (type == BasicTypes.IObject) { return("IObject"); } if (type.IsDelegate) { var del = (AST.Delegate)type; return("fn_ptr<" + SignatureOf(del, abi) + ">"); } } else { if (type == BasicTypes.Boolean) { return("bool"); } else if (type == BasicTypes.IUnknown) { return("IUnknown"); } else if (type == BasicTypes.IObject) { return("IObject"); } if (type.IsDelegate) { var del = (AST.Delegate)type; if (del.IsGeneric) { return("Delegate<" + SignatureOf(del, abi) + ">"); } } } bool useabi = (abi ?? Strata == ApiStrata.ABI) && !type.IsPureReference && (type.IsStruct || type.IsObject) && type.Origin != TypeOrigin.Mapped && type.Origin != TypeOrigin.Native; string local = null; if (!useabi) { local = GetLocalTranslation(type); if (local != null) { return(local); } } if (WorkingNamespace == null || (WorkingABINamespace != useabi)) { if (!useabi) { for (var ns = type.Namespace; !ns.IsGlobal; ns = ns.Parent) { if (type.Origin == TypeOrigin.Gluon || type.Origin == TypeOrigin.Managed) { ret = ns.Name + "::" + ret; } else { ret = "::" + ns.Name + "::" + ret; } } } else if (useabi && (type.Origin == TypeOrigin.Gluon || type.Origin == TypeOrigin.Managed)) { for (var ns = type.Namespace; !ns.IsGlobal; ns = ns.Parent) { ret = ns.Name + "::" + ret; } ret = "::ABI::" + ret; } } else if (type.Namespace != null) { ret = ScopeTo(type.Namespace) + ret; } return(ret); }
public static void IncompatibleType(AST.Type badtype) { Warn(badtype.Name + " - ignoring Gluon-incompatible type"); }
public override string TypeName(AST.Type t, bool?abi = null) { var useabi = RequiresABITranslation(t.ToVariable()) && (abi ?? Strata == ApiStrata.ABI); if (t.IsVoid) { return("void"); } if (t == BasicTypes.IUnknown) { t = BasicTypes.IntPtr; } if (useabi && (/*v.IsArray ||*/ t.IsObject)) { return("IntPtr"); } var qn = t.Name; if (t.IsDelegate) { var d = (AST.Delegate)t; if (useabi) { return("IntPtr"); } else if (d.IsGeneric) { CsRender writer = new CsRender(); if (!d.Return.IsVoid) { writer.Code("Func<"); writer.BeginList(CodeListStyle.Compact); foreach (var arg in d.Parameters) { writer.ListItem(TypeName(arg, false)); } writer.ListItem(TypeName(d.Return)); writer.EndList(); writer.Code(">"); } else if (d.Parameters.Count == 0) { return("Action"); } else { writer.Code("Action<"); writer.BeginList(CodeListStyle.Compact); foreach (var arg in d.Parameters) { writer.ListItem(TypeName(arg, false)); } writer.EndList(); writer.Code(">"); } return(writer.ToString()); } } if ((t.IsObject || t.IsDelegate || t.IsStruct) && (WorkingABINamespace != useabi || WorkingNamespace != t.Namespace)) { if (useabi) { if (t.IsObject || t.IsDelegate) { return("IntPtr"); } else { return("ABI." + t.FullName(".")); } } else { return("global::" + t.FullName(".")); } } if (t.IsEnum && WorkingABINamespace) { return("global::" + t.FullName(".")); } return(ScopeTo(t.Namespace) + qn); }