public ObjCEvent(Net2ObjC n2c, InterfaceFacet interfaceFacet, EventFacet eventFacet, Dictionary <string, object> options = null) { // event name MonoEventName = eventFacet.Name; ObjCEventName = MonoEventName.FirstCharacterToLower(); // event handler type ObjCType = eventFacet.ObjCFacet.Type; ObjCTypeDecl = n2c.ObjCTypeDeclFromManagedFacet(eventFacet); // type name for the event block for this event string eventBlockName = $"_{ MonoEventName}_EventBlock"; ObjCEventBlockTypeName = $"{interfaceFacet.ObjCFacet.Type}{eventBlockName}"; ObjCEventBlockTypeMinimalName = $"{n2c.ObjCMinimalIdentifierFromManagedIdentifier(interfaceFacet.Type)}{eventBlockName}"; ObjCEventBlockParameterCount = eventFacet.Parameters.Count; ObjCEventBlockParameterGetters = new string[ObjCEventBlockParameterCount]; // process the parameters ProcessParameters(n2c, eventFacet, options); // finalize argument list representations ObjCEventBlockParameters = CParameterBuilder.ToString(); // if event handler type is generic then record type argument if (eventFacet.IsConstructedGenericType) { ObjCGenericTypeArgument = eventFacet.GenericTypeArguments[0].ObjCFacet.Type; } IsValid = true; }
// // WriteInterfaceClass // public void WriteInterfaceClass(InterfaceFacet facet) { if (!Config.GenerateFacetBinding(facet)) { return; } if (OutputFileType == OutputType.Interface) { // write interface as class interface // this will expose a managed interface as a bound ObjC class WriteClassStart(facet, "interface"); WriteProperties(facet.Properties); WriteMethods(facet.Methods); WriteEvents(facet, facet.Events); WriteClassEnd(facet); } else { // implementation var options = new Dictionary <string, object> { { "cAPIMethodPrefix", facet.Type + "." } }; WriteClassStart(facet, "interface"); WriteProperties(facet.Properties, options); WriteMethods(facet.Methods, options); WriteEvents(facet, facet.Events, options); WriteClassEnd(facet); } }
// // WriteInterface // public void WriteInterface(InterfaceFacet facet) { if (!Config.GenerateFacetBinding(facet)) { return; } if (OutputFileType == OutputType.Interface) { // write interface as protocol // this will be used to test for ObjC protocol conformance with // Class -conformsToProtocol while still permitting // the expression of explicit managed interfaces. // accessor foward declarations are omitted from the protocol by default. WriteProtocolStart(facet, "interface"); WriteProperties(facet.Properties); WriteMethods(facet.Methods); WriteEvents(facet, facet.Events); WriteProtocolEnd(facet); // write interface as auxiliary protocol // this can be used in expressions such as id <protocol> // where it is helpful if the accessors are predeclared in the protocol WriteProtocolStart(facet, "interface", true); WriteProperties(facet.Properties); WriteMethods(facet.Methods); WriteEvents(facet, facet.Events); WriteProtocolEnd(facet, true); } }
/// <summary> /// Write pre-declarations of defines, types etc prior to Obj-C interface declaration /// </summary> /// <param name="facet">Facet</param> public void WriteFacetPreDeclarations(CodeFacet facet) { var options = new Dictionary <string, object> { { "caller", nameof(WriteFacetPreDeclarations) } }; // if facet is an enum then output C enumeration if (facet is EnumerationFacet) { WriteLine(""); WriteLine("// C enumeration"); WriteFacetAsCEnumeration((EnumerationFacet)facet); WriteLine(""); } // if facet is an interface facet (this includes class facets_ else if (facet is InterfaceFacet) { InterfaceFacet interfaceFacet = (InterfaceFacet)facet; // output event support definitions if (interfaceFacet.Events.Count > 0) { WriteLine("// "); WriteLine("// Event support"); WriteLine("// "); foreach (EventFacet eventFacet in interfaceFacet.Events) { WriteFacetAsEvent(interfaceFacet, eventFacet, options); WriteLine(""); } } } }
// // WriteEvents // public void WriteEvents(InterfaceFacet interfaceFacet, IList <EventFacet> eventFacets, Dictionary <string, object> options = null) { if (eventFacets.Any()) { WritePragmaMark("Events"); foreach (EventFacet eventFacet in eventFacets) { WriteFacetAsEvent(interfaceFacet, eventFacet, options); } } }
public ObjCProtocol(Net2ObjC n2c, InterfaceFacet facet, bool writeImplementation) { string baseProtocol = "System_Object"; string adoptionProtocolSuffix = "_"; string adoptionProtocolName = facet.ObjCFacet.Type + adoptionProtocolSuffix; if (!writeImplementation) { // write adoption protocol string protocolSuffix = adoptionProtocolSuffix; ProtocolName = adoptionProtocolName; // build list of base protocols BaseProtocols = baseProtocol + protocolSuffix; foreach (ImplementedInterfaceFacet interfaceFacet in facet.ImplementedInterfaces) { string interfaceName = interfaceFacet.ObjCFacet.Type + protocolSuffix; if (n2c.Config.GenerateFacetBinding(interfaceFacet)) { BaseProtocols += (", " + interfaceName); } else { BaseProtocols += (" /*, " + interfaceName + "*/ "); } } } else { // write implementation protocol string protocolSuffix = ""; ProtocolName = facet.ObjCFacet.Type + protocolSuffix; // build list of base protocols BaseProtocols = adoptionProtocolName + ", " + baseProtocol; foreach (ImplementedInterfaceFacet interfaceFacet in facet.ImplementedInterfaces) { string interfaceName = interfaceFacet.ObjCFacet.Type + protocolSuffix; if (n2c.Config.GenerateFacetBinding(interfaceFacet)) { BaseProtocols += (", " + interfaceName); } else { BaseProtocols += (" /*, " + interfaceName + "*/ "); } } } IsValid = true; }
public void WriteFacetAsEvent(InterfaceFacet interfaceFacet, EventFacet eventFacet, Dictionary <string, object> options = null) { // test if binding generation required if (!Config.GenerateFacetBinding(eventFacet)) { WriteSkippedItem("event", eventFacet.Description()); return; } // create Obj-C event ouput object ObjCEvent event_ = new ObjCEvent(this, interfaceFacet, eventFacet, options); if (!event_.IsValid) { return; } // parse options bool isPreDelarations = false; if (options != null) { object outObj; if (options.TryGetValue("caller", out outObj)) { isPreDelarations = (string)outObj == nameof(WriteFacetPreDeclarations); } } // write unique interface output for start of class if (OutputFileType == OutputType.Interface && isPreDelarations) { WriteEventClassStart(event_, options); return; } // write event name accessor method WriteEventNameAccessor(event_, options); // write event handler add method WriteEventHandlerAddMethod(event_, options); }
// // WriteProtocolStart // public void WriteProtocolStart(InterfaceFacet facet, string module, bool writeImplementation = false) { if (!writeImplementation) { WriteModuleBanner(facet, module); } Net2ObjC.Protocol protocol = new Net2ObjC.Protocol(this, facet, writeImplementation); if (!writeImplementation) { #line default #line hidden #line 278 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\r\n/*\r\n A managed interface is represented as follows:\r\n\r\n 1. An adoption protocol" + " that advertises that a class has adopted a given protocol. For the reasons \r\n g" + "iven in the notes below this protocol by default declares no members. The code g" + "enerator will\r\n use this protocol when declaring classes and method parameters.\r" + "\n\r\n 2. An implementation protocol that declares the properties and methods defin" + "ed by the interface.\r\n The code generator will use this protocol when declaring " + "variables.\r\n\r\n 3. An interface header and implementation body. The explicit clas" + "s implementation of the managed interface\r\n can be used to create an instance th" + "at conforms to the given interface in order to access explicit properties.\r\n\r\n T" + "he above seems to give the best approach for interacting with complex managed in" + "terfaces.\r\n\r\n Notes:\r\n\r\n .Net support for explicit interfaces means that a class" + " can inherit two or more different\r\n signatures for the same property or method " + "from two or more interfaces. \r\n This is not supported by Objective-C. \r\n\r\n A sec" + "ond point is that properties declared in protocols don\'t get their ivars synthes" + "ized.\r\n This causes warnings to be issued when interface properties are exposed " + "explicitly.\r\n\r\n A third point is that even when we receive a managed interface a" + "s a return value from a property \r\n or method we still need to provide a full bi" + "nding in order access those properties and methods.\r\n\r\n A class can test for pro" + "tocol adoption using Class -conformsToProtocol: using the adoption protocol.\r\n B" + "y casting to the implementation protocol an instance can check for method implem" + "entation using respondsToSelector:.\r\n\r\n Properties and method predeclarations ca" + "n be conditionally included in the adoption protocol if required.\r\n\r\n*/\r\n\r\n//\r\n/" + "/ Adoption protocol\r\n//\r\n@protocol "); #line default #line hidden #line 317 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(protocol.ProtocolName)); #line default #line hidden #line 317 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" <"); #line default #line hidden #line 317 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(protocol.BaseProtocols)); #line default #line hidden #line 317 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(">\r\n\r\n@optional\r\n\r\n#ifdef DEF_P_AND_M_"); #line default #line hidden #line 321 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(protocol.ProtocolName.ToUpper())); #line default #line hidden #line 321 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\r\n"); #line default #line hidden #line 322 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" } else { #line default #line hidden #line 324 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\r\n//\r\n// Implementation protocol\r\n//\r\n@protocol "); #line default #line hidden #line 329 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(protocol.ProtocolName)); #line default #line hidden #line 329 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" <"); #line default #line hidden #line 329 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(protocol.BaseProtocols)); #line default #line hidden #line 329 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(">\r\n\r\n@optional\r\n\r\n"); #line default #line hidden #line 333 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" }// if !writeAux }
// // WriteInterfaceClass // public void WriteInterfaceClass(InterfaceFacet @interface) { if (OutputFileType == OutputType.Interface) { // write interface as class interface // this will expose a managed interface as a bound ObjC class WriteClassStart(@interface, "interface"); WriteProperties(@interface.Properties); WriteMethods(@interface.Methods); WriteClassEnd(@interface); } else { // implementation var options = new Dictionary<string, object> { { "cAPIMethodPrefix", @interface.Type + "." } }; WriteClassStart(@interface, "interface"); WriteProperties(@interface.Properties, options); WriteMethods(@interface.Methods, options); WriteClassEnd(@interface); } }
// // WriteInterface // public void WriteInterface(InterfaceFacet @interface) { if (OutputFileType == OutputType.Interface) { // write interface as protocol // this will be used to test for ObjC protocol conformance with // Class -conformsToProtocol while still permitting // the expression of explicit managed interfaces. // accessor foward declarations are omitted from the protocol by default. WriteInterfaceStart(@interface, "interface"); WriteProperties(@interface.Properties); WriteMethods(@interface.Methods); WriteInterfaceEnd(@interface); // write interface as auxiliary protocol // this can be used in expressions such as id <protocol> // where it is helpful if the accessors are predeclared in the protocol WriteInterfaceStart(@interface, "interface", true); WriteProperties(@interface.Properties); WriteMethods(@interface.Methods); WriteInterfaceEnd(@interface, true); } }
// // WriteInterfaceStart // public void WriteInterfaceStart(InterfaceFacet facet, string module, bool writeAux = false) { if (!writeAux) { WriteModuleBanner(facet, module); } // build list of base protocols string baseInterfaces = "NSObject"; foreach (ImplementedInterfaceFacet interfaceFacet in facet.ImplementedInterfaces) { baseInterfaces += ", "; baseInterfaces += interfaceFacet.ObjCFacet.Type; } if (!writeAux) { #line default #line hidden #line 275 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("@protocol "); #line default #line hidden #line 276 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(facet.ObjCFacet.Type)); #line default #line hidden #line 276 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" <"); #line default #line hidden #line 276 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(baseInterfaces)); #line default #line hidden #line 276 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(@"> @optional /* .Net support for explicit interfaces means that a class can inherit two or more different signatures for the same property or method from two or more interfaces. This is not supported by Objective-C. A second point is that properties declared in protocols don't get their ivars synthesized. This causes warnings to be issued when interface properties are exposed explicitly. A third point is that even when we receive a managed interface as a return value from a property or method we still need to provide a full binding in order access those properties and methods. A fourth point is that in general we will not be defining Obj-C classes that conform to managed protocols. These points make the inclusion of the actual content of the protocol somewhat debatable. In general it therefore seems best to omit the accessor predeclarations from the protocol declaration. It should still be possible to test for protocol conformance using Class -conformsToProtocol: The protocol properties and methods can be conditionally included if required. An auxliary protocol definition is also provided. */ #ifdef DEF_P_AND_M_"); #line default #line hidden #line 305 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(facet.ObjCFacet.Type)); #line default #line hidden #line 305 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\r\n"); #line default #line hidden #line 306 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" } else { #line default #line hidden #line 309 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\r\n/*\r\n \r\n Auxiliary protocol definition.\r\n\r\n*/\r\n\r\n@protocol db_aux_"); #line default #line hidden #line 317 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(facet.ObjCFacet.Type)); #line default #line hidden #line 317 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" <"); #line default #line hidden #line 317 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(baseInterfaces)); #line default #line hidden #line 317 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(">\r\n\r\n@optional\r\n\r\n"); #line default #line hidden #line 321 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" }// if !writeAux }