private void PreprocessDefinition() { Definition.ApplyTypeSubstitutions(Settings.TargetId); Definition.ApplyNamespaceSubsitutions(Settings.TargetId); foreach (var type in Definition.AllTypes) { if (type.Origin != TypeOrigin.Mapped) { if (type.IsObject && type.Origin != TypeOrigin.Managed && type.Assembly == Definition.Assembly) { AllGeneratedClasses.Add((AST.Object)type); } else if (type.IsStruct) { AllGeneratedStructs.Add((AST.Struct)type); } else if (type.IsEnum && type.Origin != TypeOrigin.Managed && type.Assembly == Definition.Assembly) { AllGeneratedEnums.Add((AST.Enum)type); } else if (type.IsDelegate && !((AST.Delegate)type).IsGeneric) { AllGeneratedDelegates.Add((AST.Delegate)type); } } } foreach (var type in Definition.AllTypes) { if (type.IsDelegate) { AllTranslatedDelegates.Add((AST.Delegate)type); } else if (type.IsStruct && CppRender.RequiresABITranslation(type.ToVariable())) { AllTranslatedStructs.Add((AST.Struct)type); } } Definition.StripAllGluonAttributes(); Definition.PutDefaultConstructorsFirst(); Definition.InsertDefaultConstructorsWhereNoneAreDefined(); var builder = new AST.Builder(Definition); _assemblyNS = builder.Resolve(Definition.Assembly.Name); _gluonNS = builder.Resolve("Gluon"); builder.Resolve(typeof(DllImportAttribute)); builder.Resolve(typeof(MarshalAsAttribute)); builder.Resolve(typeof(GluonObject)); builder.Resolve(typeof(DelegateBlob)); }
public void GenerateStruct(AST.Struct type, bool abi) { var strata = Strata; Guid id = (strata == ApiStrata.ABI ? type.Id : type.PrivateId); Namespace(type.Namespace, abi, () => { var localTranslations = CppRender.GetLocalTranslations(type); if (strata == ApiStrata.ABI) { localTranslations = null; } var fields = type.Fields; Spacer(); WriteXmlDocumentation(type.XmlDoc); Line("struct comid(\"{0}\") {1}", id, type.Name); Block(() => { if (strata == ApiStrata.Normal && CppRender.RequiresABITranslation(type.ToVariable())) { Line("typedef {0} ABIType;", TypeRef(type, true)); Spacer(); } if (localTranslations != null) { UseLocalTranslations = false; foreach (var kvp in localTranslations) { Line("using {0} = {1};", kvp.Value, TypeRef(kvp.Key, false)); } UseLocalTranslations = true; Spacer(); } LocalTranslationsBlock(localTranslations, () => { foreach (var field in fields) { WriteXmlDocumentation(field.XmlDoc); Line("{0} {1};", VariableType(field, AST.VariableContext.Member), field.Name); } Spacer(); // Default constructor Line("{0}() {{ }}", type.Name); // Full constructor var constructorArgs = fields.Select(f => f.Morph("_" + f.Name, AST.VariableContext.In)); if (strata == ApiStrata.ABI) { constructorArgs = constructorArgs.GetABIParametersCpp(); } Line("{0}({1}) : ", type.Name, DeclParameters(constructorArgs)); Indent++; List(() => { foreach (var field in fields) { if (strata == ApiStrata.ABI && field.IsArray) { ListItem("{0}(_{0}, _{0}_count)", field.Name); } else if (strata == ApiStrata.ABI && field.Type.IsDelegate) { ListItem("{0}(_{0}, _{0}_context)", field.Name); } else { ListItem("{0}(_{0})", field.Name); } } }); Indent--; Line(); Line("{ }"); }); }, ";"); }); var prefix = (abi ? "::ABI" : ""); if (type.Namespace.IsGlobal) { Line(@"IS_VALUETYPE({0}::{1}, ""{2}"");", prefix, type.Name, id); } else { Line(@"IS_VALUETYPE({0}::{1}::{2}, ""{3}"");", prefix, type.Namespace.FullName("::"), type.Name, id); } }
public void ABIWrappedCall(AST.ICallSignature m, string returnArg = null, string callNameOverride = null) { string name = m.Name; if (!string.IsNullOrEmpty(callNameOverride)) { name = callNameOverride; } if (returnArg == null) { returnArg = m.Return.Name; } Code("try "); Block(() => { var args = m.Parameters; if (!m.Return.IsVoid) { if (m.Return.IsArray) { string refType = VariableType(m.Return.Type.ToVariable(), true); Code("ABI::ArrayRef<{0}>({1}, {1}_count) = ABIUtil<{2}>::ToABI({3}(", refType, returnArg, TypeRef(m.Return, false), name); } else if (m.Return.Type.IsDelegate) { string refType = TypeRef(m.Return.Type, true); Code("ABI::DelegateRef<{0}>({1}, {1}_context) = ABIUtil<{2}>::ToABI({3}(", refType, returnArg, TypeRef(m.Return, false), name); } else if (CppRender.RequiresABITranslation(m.Return)) { Code("*{0} = ABIUtil<{1}>::ToABI({2}(", returnArg, TypeRef(m.Return, false), name); } else { Code("*{0} = {1}(", returnArg, name); } } else { Code($"{name}("); } if (args.Count > 1) { Line(); } List(args.Count > 1 ? CodeListStyle.MultiLine : CodeListStyle.SingleLine, () => { if (args.Count > 1) { Indent++; } foreach (var arg in args) { if (CppRender.RequiresABITranslation(arg)) { string fwd; if (arg.IsArray) { fwd = arg.Name + ", " + arg.Name + "_count"; } else if (arg.Type.IsDelegate) { fwd = "(void**)" + arg.Name + ", " + arg.Name + "_context"; } else { fwd = arg.Name; } if (arg.IsOut || arg.IsRef) { ListItem($"ABIUtil<{TypeRef(arg, false)}>::Ref({fwd})"); } else { ListItem($"ABIUtil<{TypeRef(arg, false)}>::FromABI({fwd})"); } } else { ListItem(arg.Name); } } if (args.Count > 1) { Indent--; } }); if (!m.Return.IsVoid && CppRender.RequiresABITranslation(m.Return)) { Line("));"); } else { Line(");"); } Line("return S_OK;"); }, " TRANSLATE_EXCEPTIONS"); }
public void CallToABIMethodBody(AST.ICallSignature m, params string[] prependArgs) { AST.IVariable returnArg; bool isCtor = m.Return == null; if (!isCtor) { returnArg = m.Return.Morph("___ret", AST.VariableContext.Out); } else { returnArg = new AST.Parameter(BasicTypes.Void, "", AST.VariableContext.Return, false); } foreach (var arg in m.Parameters) { if (arg.IsArray || arg.Type.IsDelegate) { if (arg.IsWriteable()) { Line("ABICallbackRef<{0}> {1}_abi({1});", TypeRef(arg), arg.Name); } else { Line("auto {0}_abi = ABIUtil<{1}>::ToABI({0});", arg.Name, TypeRef(arg)); } } } if (!returnArg.IsVoid) { Line("{0} {1};", VariableType(returnArg, AST.VariableContext.Member, isCtor), returnArg.Name); if (returnArg.IsArray || returnArg.Type.IsDelegate) { Line("{"); Indent++; Line("ABICallbackRef<{0}> {1}_abi({1});", TypeRef(returnArg), returnArg.Name); } } Line($"TRANSLATE_TO_EXCEPTIONS({m.Name}("); Indent++; List(CodeListStyle.MultiLine, () => { foreach (var arg in prependArgs) { ListItem(arg); } Action <AST.IVariable, string> translateArg = (arg, name) => { if (arg.IsArray || arg.Type.IsDelegate) { name += "_abi"; } if (arg.IsArray) { if (arg.IsWriteable() || arg.Context == AST.VariableContext.Return) { ListItem("&{0}.Data, &{0}.Count", name); } else { ListItem("{0}.begin(), {0}.size()", name); } } else if (arg.Type.IsDelegate) { if (arg.IsWriteable() || arg.Context == AST.VariableContext.Return) { ListItem("({0}*)&{1}.Fn, &{1}.Ctx", TypeRef(arg, true), name); } else { ListItem("({0}){1}.Fn, {1}.Ctx", TypeRef(arg, true), name); } } else if (arg.IsWriteable() || arg.Context == AST.VariableContext.Return) { ListItem("ABICallbackRef<{0}>({1})", TypeRef(arg), name); } else if (CppRender.RequiresABITranslation(arg)) { ListItem("ABIUtil<{0}>::ToABI({1})", TypeRef(arg), name); } else { ListItem(name); } }; foreach (var arg in m.Parameters) { translateArg(arg, arg.Name); } if (isCtor) { ListItem("&instance"); } else if (!returnArg.IsVoid) { translateArg(returnArg, returnArg.Name); } }); Indent--; Line("));"); //if (!returnArg.IsVoid) //{ // Line("{0} {1};", VariableType(returnArg, AST.VariableContext.Member, isCtor), returnArg.Name); // if (returnArg.IsArray || returnArg.Type.IsDelegate) if (!returnArg.IsVoid) { if (returnArg.IsArray || returnArg.Type.IsDelegate) { Indent--; Line("}"); } Line("return {0};", returnArg.Name); } }