public string MakeOutType(Generator generator, ITypeRequestSource source, bool isFactoryMethod) { string outType = String.Join(", ", OutTypes.Select(o => TypeHelpers.GetTypeName(generator, source, o.Item1, (o.Item2 || isFactoryMethod) ? TypeUsage.OutNonNull : TypeUsage.Out))); if (OutTypes.Count() != 1) { outType = "(" + outType + ")"; // also works for count == 0 (empty tuple) } return(outType); }
public static string GetInputTypeName(Generator gen, ITypeRequestSource source, TypeReference t, InputKind kind) { switch (kind) { case InputKind.Default: return(GetTypeName(gen, source, t, TypeUsage.In)); case InputKind.Raw: return(GetTypeName(gen, source, t, TypeUsage.Raw)); case InputKind.Slice: return($"&[{ GetTypeName(gen, source, t, TypeUsage.In) }]"); case InputKind.MutSlice: Assert(t.IsValueType); return($"&mut [{ GetTypeName(gen, source, t, TypeUsage.In) }]"); case InputKind.VecBuffer: return($"&mut Vec<{ GetTypeName(gen, source, t, TypeUsage.OutNonNull) }>"); default: throw new InvalidOperationException(); } }
// ---------------- The following should be split by types ---------------- // public static string GetTypeName(Generator gen, ITypeRequestSource source, TypeReference t, TypeUsage usage) { if (t.IsGenericParameter) { switch (usage) { case TypeUsage.Raw: return($"{ t.Name }::Abi"); case TypeUsage.In: return($"&{ t.Name }::In"); case TypeUsage.Out: return($"{ t.Name }::Out"); case TypeUsage.OutNonNull: return($"{ t.Name }::OutNonNull"); case TypeUsage.GenericArg: return(t.Name); default: throw new NotSupportedException(); } } if (t.IsByReference) { var ty = (ByReferenceType)t; return($"*mut { GetTypeName(gen, source, ty.ElementType, usage) }"); } else if (t.IsArray) { var ty = (ArrayType)t; if (usage == TypeUsage.Out) { return($"ComArray<{ GetTypeName(gen, source, ty.ElementType, TypeUsage.GenericArg) }>"); } else { return($"*mut { GetTypeName(gen, source, ty.ElementType, usage) }"); } } else { return(GetElementTypeName(gen, source, t, usage)); } }
public string[] MakeInputParameters(Generator generator, ITypeRequestSource source) { return(InputParameterNames.Zip(InputParameterTypes, (name, t) => name + ": " + TypeHelpers.GetInputTypeName(generator, source, t.Item1, t.Item2)).ToArray()); }
// ---------------- The following should be split by types ---------------- // public static string GetTypeName(Generator gen, ITypeRequestSource source, TypeReference t, TypeUsage usage, bool hasConstModifier = false) { if (hasConstModifier && !t.IsByReference) { throw new NotSupportedException(); // we don't expect this case to happen } else if (t.IsByReference) { var ty = (ByReferenceType)t; if (hasConstModifier) { if (usage == TypeUsage.Raw) { return($"*const { GetTypeName(gen, source, ty.ElementType, usage) }"); } else if (usage == TypeUsage.In) { return($"&{ GetTypeName(gen, source, ty.ElementType, usage) }"); } else { throw new NotSupportedException(); } } else { if (usage == TypeUsage.Raw) { return($"*mut { GetTypeName(gen, source, ty.ElementType, usage) }"); } else if (usage == TypeUsage.In) // currently never used { return($"&mut { GetTypeName(gen, source, ty.ElementType, usage) }"); } else { throw new NotSupportedException(); } } } else if (t.IsGenericParameter) { switch (usage) { case TypeUsage.Raw: return($"{ t.Name }::Abi"); case TypeUsage.In: return($"&{ t.Name }::In"); case TypeUsage.Out: return($"{ t.Name }::Out"); case TypeUsage.OutNonNull: return($"{ t.Name }::OutNonNull"); case TypeUsage.GenericArg: return(t.Name); default: throw new NotSupportedException(); } } else if (t.IsArray) { var ty = (ArrayType)t; if (usage == TypeUsage.Out) { return($"ComArray<{ GetTypeName(gen, source, ty.ElementType, TypeUsage.GenericArg) }>"); } else { return($"*mut { GetTypeName(gen, source, ty.ElementType, usage) }"); } } else if (t.IsOptionalModifier) { var ty = (OptionalModifierType)t; if (ty.ModifierType.FullName == "System.Runtime.CompilerServices.IsConst") { return(GetTypeName(gen, source, ty.ElementType, usage, true)); } else { // according to ECMA Partition II documentation, we can usually just ignore optional modifiers return(GetTypeName(gen, source, ty.ElementType, usage, hasConstModifier)); } } else if (t.IsRequiredModifier) { throw new NotImplementedException($"Unexpected reqmod { ((RequiredModifierType)t).ModifierType.FullName } is not implemented"); } else { return(GetElementTypeName(gen, source, t, usage)); } }
private static string GetElementTypeName(Generator gen, ITypeRequestSource source, TypeReference t, TypeUsage usage) { if (t.FullName == "System.String") { switch (usage) { case TypeUsage.Raw: return("HSTRING"); case TypeUsage.In: return("&HStringArg"); case TypeUsage.Out: return("HString"); case TypeUsage.GenericArg: return("HString"); default: throw new NotSupportedException(); } } else if (t.FullName == "System.Object") { switch (usage) { case TypeUsage.Raw: return("*mut IInspectable"); case TypeUsage.GenericArg: return("IInspectable"); case TypeUsage.In: return("&IInspectable"); case TypeUsage.Out: return("Option<ComPtr<IInspectable>>"); default: throw new InvalidOperationException(); } } else if (t.FullName == "System.Guid") { return("Guid"); } else if (t.IsPrimitive) { switch (t.FullName) { case "System.Boolean": return("bool"); case "System.SByte": return("i8"); case "System.Int16": return("i16"); case "System.Int32": return("i32"); case "System.Int64": return("i64"); case "System.Byte": return("u8"); case "System.UInt16": return("u16"); case "System.UInt32": return("u32"); case "System.UInt64": return("u64"); case "System.Single": return("f32"); case "System.Double": return("f64"); case "System.Char": return("Char"); default: throw new NotImplementedException("Primitive type: " + t.FullName); } } else { var def = gen.GetTypeDefinition(t); source.AddDependency(def); string name = def.GetPath(source.Module); int i = name.IndexOf('`'); if (i >= 0) { name = name.Substring(0, i); } if (t.IsGenericInstance) { var ty = (GenericInstanceType)t; if (!ty.ContainsGenericParameter) { gen.AddGenericInstance(ty); } name += $"<{ String.Join(", ", ty.GenericArguments.Select(a => GetTypeName(gen, source, a, TypeUsage.GenericArg))) }>"; } if (!t.IsValueType) { if (usage == TypeUsage.In) { name = $"&{ name }"; } else if (usage == TypeUsage.GenericArg) { // leave name unchanged } else if (usage == TypeUsage.Raw) { name = $"*mut { name }"; } else if (usage == TypeUsage.Out) { name = $"Option<ComPtr<{ name }>>"; } else if (usage == TypeUsage.OutNonNull) { name = $"ComPtr<{ name }>"; } } return(name); } }