// // ObjCRepresentationIsPrimitive // // Returns true if ObjC repesentation of facet is a primitive. // Returns false if ObjC repesentation of facet is an object. // public bool ObjCRepresentationIsPrimitive(CodeFacet facet) { // if a type association exits then query it ObjCTypeAssociation objCTypeAssociate = ObjCTypeAssociate(facet); if (objCTypeAssociate != null) { if (objCTypeAssociate.IsNSObject) { return(false); } else { return(true); } } // Order is important here if (facet.IsGenericType) { return(false); } if (facet.IsStruct) { return(false); } // pointers are not value types! if (facet.IsValueType || facet.IsPointer) { return(true); } return(false); }
// // ObjCValueToManaged // // Return an ObjC expression that converts an ObjC object to its corresponding managed representation // public string ObjCValueToManaged(string objCVarName, string objCTypeDecl, CodeFacet managedFacet) { string exp = null; // extract type info in a format suitable for association string managedType = ManagedTypeForAssociation(managedFacet); // if type is an enum then use its underlying type if (managedFacet.IsEnum) { managedType = managedFacet.UnderlyingType; } // retrieve an ObjCTypeAssociation for the given managedType string key = ObjCTypeAssociation.UniqueTypeName(objCTypeDecl, managedType); if (ManagedTypeAssociations.ContainsKey(key)) { ManagedTypeAssociation managedTypeAssoc = ManagedTypeAssociations[key]; ObjCTypeAssociation objCTypeAssoc = ObjCTypeAssociations[managedType]; // use the value object format specifier if available string setterFormat = objCTypeAssoc.SetterFormat; if (setterFormat != null) { if (managedFacet.IsPointer) { setterFormat = "&{0}"; } exp = string.Format(setterFormat, objCVarName); } // use custom method else if (objCTypeAssoc.SetterMethod != null) { string methodName = objCTypeAssoc.SetterMethod; Type type = GetType(); MethodInfo method = type.GetMethod(methodName); if (method != null) { exp = (string)method.Invoke(this, new object[] { objCVarName, objCTypeDecl }); } } } // no ObjC expression defined. // generate default object representation expression. if (exp == null) { if (ObjCRepresentationIsPrimitive(managedFacet)) { exp = string.Format("&{0}", objCVarName); } else { exp = string.Format("[{0} monoObject]", objCVarName); } } return(exp); }
// // WriteClassSetup // public void WriteClassSetup(CodeFacet facet) { WritePragmaMark("Setup"); WriteLine(""); WriteLine($"+ (const char *)monoClassName{LT}"); if (OutputFileType == OutputType.Implementation) { string name = CodeFacet.NormalizeGenericTypesInManagedIdentifier(facet.NameFromType); WriteLine("{"); PushTabIndent(); WriteLine($"return \"{facet.TypeNamespace}.{name}\";"); PopIndent(); WriteLine("}"); WriteLine(""); } WriteLine($"+ (const char *)monoAssemblyName{LT}"); if (OutputFileType == OutputType.Implementation) { WriteLine("{"); PushTabIndent(); WriteLine($"return \"{AssemblyFacet.Name}\";"); PopIndent(); WriteLine("}"); } }
// // WriteClassStart // public void WriteClassStart(CodeFacet facet, string module, bool writeBanner = true) { // Allocate property name list this.StaticObjectPropertyStorageNames = new List <string>(); // prefix defines interface or implementation string classPrefix = OutputDeclarationPrefix(); string superClass = OutputDeclarationSuffix(facet); string implementedProtocols = ""; bool outputImplementedProtocols = true; if (outputImplementedProtocols) { implementedProtocols = OutputImplementedProtocolSuffix(facet); } if (writeBanner) { WriteModuleBanner(facet, module); } if (OutputFileType == OutputType.Interface) { WriteFacetPreDeclarations(facet); } WriteLine($"@{classPrefix} {facet.ObjCFacet.Type}{superClass}{implementedProtocols}"); WriteClassSetup(facet); }
public void WriteFacet(CodeFacet facet) { Type ft = facet.GetType(); if (ft == typeof(EnumerationFacet)) { WriteEnumeration((EnumerationFacet)facet); } else if (ft == typeof(InterfaceFacet)) { WriteInterface((InterfaceFacet)facet); // provide access to the properties and methods of an explicit interface WriteInterfaceClass((InterfaceFacet)facet); // for protocol definitions we don't want to overwrite the class header so we append a suffix. facet.OutputFileNameSuffix = ".Protocol"; WriteInterface((InterfaceFacet)facet); facet.OutputFileNameSuffix = ""; } else if (ft == typeof(StructFacet)) { WriteStruct((StructFacet)facet); } else if (ft == typeof(ClassFacet)) { WriteClass((ClassFacet)facet); } }
/// <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(""); } } } }
// // OutputDeclarationSuffix() // // Return a class declaration suffix based on the outputType // string OutputDeclarationSuffix(CodeFacet facet) { string value = ""; if (OutputFileType == OutputType.Interface) { value = " : " + ObjCTypeNameFromManagedTypeName(facet.BaseType); } return(value); }
/// <summary> /// Returns all ObjC forward class and protocol declarations required to fully represent the facet. /// </summary> /// <param name="facet"></param> /// <returns></returns> public List <string> ObjCForwardDeclarations(CodeFacet facet) { List <string> imports = new List <string>(); if (!Config.GenerateFacetBinding(facet)) { return(imports); } // objC type // note that a constructor has no return type string objCType = facet.ObjCFacet.Type; if (!string.IsNullOrEmpty(objCType)) { // if the type is a generic parameter if (facet.IsGenericParameterOrRef()) { objCType = "System_Object"; } string import = String.Format("@class {0};", objCType); imports.Add(import); if (facet.IsArray == true) { import = String.Format("@class {0};", facet.ObjCFacet.BaseType); imports.Add(import); } if (facet.GetType() == typeof(InterfaceFacet) || facet.IsInterface) { import = String.Format("@protocol {0}_;", objCType); imports.Add(import); import = String.Format("@protocol {0};", objCType); imports.Add(import); } } // forward declare objC facet types for all children List <CodeFacet> children = facet.Children(); foreach (CodeFacet child in children) { imports.AddRange(ObjCForwardDeclarations(child)); } // return a distinct list to remove duplicates imports = imports.Distinct().ToList(); imports.Sort(); return(imports); }
/// <summary> /// Returns additional required ObjC import directives. /// </summary> /// <param name="facet"></param> /// <returns></returns> public List <string> ObjCImportDirectives(CodeFacet facet, bool filter = true) { List <string> imports = new List <string>(); if (!Config.GenerateFacetBinding(facet)) { return(imports); } // objC type // note that a constructor has no return type string objCType = facet.ObjCFacet.Type; string importStr = null; if (!string.IsNullOrEmpty(objCType)) { // we only need to import types defined in the current assembly. // other types will be imported via their own assembly's header if (AssemblyFacet.DefinesFacetType(facet.Type)) { // if the type is an enum if (facet.IsEnum) { objCType = facet.ObjCFacet.Type; importStr = $"#import \"{objCType}.h\""; imports.Add(importStr); } } } // forward declare objC facet types for all children List <CodeFacet> children = facet.Children(); foreach (CodeFacet child in children) { imports.AddRange(ObjCImportDirectives(child, false)); } // remove duplicates imports = imports.Distinct().ToList(); imports.Sort(); // the filter ensures that the import list doesn't include // the header that the import directives will be inserted into if (filter && importStr != null) { imports.Remove(importStr); } return(imports); }
// // WriteClassTeardown // public void WriteClassTeardown(CodeFacet facet) { if (OutputFileType == OutputType.Implementation) { WritePragmaMark("Teardown"); WriteLine(""); WriteLine("- (void)dealloc"); WriteLine("{"); PushTabIndent(); // we have no output here as yet but the opportunity exists PopIndent(); WriteLine("}"); } }
/** * Returns true if should generate binding for facet * * white list contains System.Threading.Tasks.Task * black list contains System.Runtime.CompilerServices * System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1<System.Threading.Tasks.Task`1+TResult> * * we need to ensure that every component of the constructed type is valid. */ public bool GenerateFacetBinding(CodeFacet facet) { // confirm member binding if (facet.GetType() == typeof(MethodFacet) || facet.GetType() == typeof(PropertyFacet) || facet.GetType() == typeof(FieldFacet)) { // the accessor form for generic types requires that we use the RootType string accessor = CodeFacet.RootType(facet.Parent.Type) + ":" + facet.Name; if (!GenerateMemberBinding(accessor)) { return(false); } } // initial type test string type; if (facet.TypeNamespace != null) { type = facet.TypeNamespace + "." + facet.NameFromType; } else { type = facet.NameFromType; } // hmm... would not be clearer to reference facet.Type in the above if (facet.Type != type) { // we do see warnings here so a bit more investigation is required //Console.WriteLine($"Warning: facet.Type {facet.Type} != {type}"); } if (!GenerateTypeBinding(type)) { return(false); } // generic parameter type tests foreach (string t in facet.GenericArgumentTypes) { if (!GenerateTypeBinding(t)) { return(false); } } return(true); }
// // ObjCGenericArgumentTypeNamesStringFromManagedFacet // public string ObjCGenericArgumentTypeNamesStringFromManagedFacet(CodeFacet managedFacet) { int idx = 0; string typeNames = ""; foreach (string genericParameterType in managedFacet.GenericArgumentTypes) { if (idx > 0) { typeNames += ","; } string objCTypeName = ObjCTypeNameFromManagedTypeName(genericParameterType); typeNames += objCTypeName; idx++; } return(typeNames); }
// // WriteProtocolEnd // public void WriteProtocolEnd(CodeFacet facet, bool writeAux = false) { if (!writeAux) { WriteLine("#endif"); WriteLine(""); } WriteLine(""); WriteLine("@end"); WriteLine(""); if (writeAux) { WriteModuleFooter(); } }
// // ObjCTypeDeclFromManagedFacet() // public string ObjCTypeDeclFromManagedFacet(CodeFacet managedFacet, bool allowObjCTypeAssociation = true) { string decl = ""; // if the facet represents a generic parameter (or ref) then we // won't know the actual type until runtime, so we default to the System_Object; if (managedFacet.IsGenericParameterOrRef()) { decl = "System_Object *"; return(decl); } string managedType = ManagedTypeForAssociation(managedFacet); if (managedType == null) { return("????"); } if (allowObjCTypeAssociation && ObjCTypeAssociations.ContainsKey(managedType)) { decl = ObjCTypeAssociations[managedType].ObjCTypeDecl; if (managedFacet.IsPointer) { decl += " *"; } } else { // canonical type name. decl = ObjCIdentifierFromManagedIdentifier(managedType); if (managedFacet.IsEnum) { decl = "enum" + decl; } else { decl += " *"; } } return(decl); }
// // WriteFacetTypeInfo // public string WriteFacetTypeInfo(CodeFacet facet) { StringBuilder s = new StringBuilder(); if (facet.IsByRef) { s.Append("ref "); } if (facet.IsGenericParameter) { s.Append("<"); } s.Append(facet.Type); if (facet.IsGenericParameter) { s.Append(">"); } return(s.ToString()); }
// // WriteClassPredeclaration // public void WriteClassPredeclaration(CodeFacet facet) { if (!Config.GenerateFacetBinding(facet)) { WriteSkippedItem("type", facet.Description()); return; } string namespacePrefix = ObjCAcronymFromManagedIdentifier(facet.TypeNamespace); string classDefine = ObjCIdentifierFromManagedIdentifier(namespacePrefix + facet.Name) + "_"; string classObjCType = facet.ObjCFacet.Type; // collision warning facility can be useful but it's loud when it kicks in! bool warnAboutCollisions = false; if (warnAboutCollisions) { WriteLine($"#ifdef {classDefine}"); WriteLine($"#warning {classDefine} class name collision."); WriteLine($"#else"); WriteLine($"#define {@classDefine} {@classObjCType}"); WriteLine($"#endif"); WriteLine($""); } else { // issue the define if unique in this scope. if (!_classDefines.Contains(classDefine)) { _classDefines.Add(classDefine); WriteLine($"#define {@classDefine} {@classObjCType}"); } else { WriteLine($"//#define <#=@classDefine#> <#=@classObjCType#> // WARNING: duplicate detected in file scope"); } } }
// // ManagedTypeForAssociation // // Processes the managed type so that it can act as a type // suitable for Obj-C type association // string ManagedTypeForAssociation(CodeFacet managedFacet) { string managedType = null; // if the type represents a generic type parameter then the actual // type argument will remain unknown until runtime. if (managedFacet.IsGenericParameter) { managedType = GenericTypePlaceholder; } else if (managedFacet.IsArray) { // We want System.Byte[] to associate with NSData if (managedFacet.Type != "System.Byte[]") { managedType = "System.Array"; } } else if (managedFacet.IsGenericType) { managedType = CodeFacet.NormalizeGenericTypesInManagedIdentifier(managedFacet.Type); } if (managedType == null) { if (managedFacet.IsByRef || managedFacet.IsPointer) { managedType = managedFacet.ElementType; } else { managedType = managedFacet.Type; } } return(managedType); }
// // WriteModuleBanner // public void WriteModuleBanner(CodeFacet facet, string module) { string outputFile = facet.OutputFileName() + OutputFileSuffix(); #line default #line hidden #line 87 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("//++"); #line default #line hidden #line 88 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(GenToolName)); #line default #line hidden #line 88 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" "); #line default #line hidden #line 88 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(outputFile)); #line default #line hidden #line 88 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\r\n//\r\n// Managed "); #line default #line hidden #line 90 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(module)); #line default #line hidden #line 90 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" : "); #line default #line hidden #line 90 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(facet.Name)); #line default #line hidden #line 90 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\r\n//\r\n"); #line default #line hidden #line 92 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" if (OutputFileType == OutputType.Interface) { // ObjC interface string optionalImport = facet.ObjCFacet.Type + ".__Extra__.h"; List <string> declarations = ObjCForwardDeclarations(facet); string forwardDeclarations = String.Join("\n", declarations); string derivationImportDirectives = String.Join("\n", ObjCDerivationImportDirectives(facet)); string importDirectives = String.Join("\n", ObjCImportDirectives(facet)); #line default #line hidden #line 101 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("//\r\n// Frameworks\r\n//\r\n#import <Dubrovnik/Dubrovnik.h>\r\n\r\n//\r\n// Optional extra i" + "mport. Not auto generated. Add manually to project only if required.\r\n//\r\n#if __" + "has_include(\""); #line default #line hidden #line 110 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(optionalImport)); #line default #line hidden #line 110 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\")\r\n#import \""); #line default #line hidden #line 111 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(optionalImport)); #line default #line hidden #line 111 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\"\r\n#endif\r\n\r\n//\r\n// Forward class and protocol declarations\r\n//\r\n"); #line default #line hidden #line 117 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(forwardDeclarations)); #line default #line hidden #line 117 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\r\n\r\n//\r\n// Local assembly imports\r\n//\r\n"); #line default #line hidden #line 122 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(importDirectives)); #line default #line hidden #line 122 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\r\n\r\n//\r\n// Import superclass and adopted protocols\r\n//\r\n"); #line default #line hidden #line 127 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(derivationImportDirectives)); #line default #line hidden #line 127 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\r\n\r\n"); #line default #line hidden #line 129 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" } else { string optionalImport = ObjCAssemblyName + ".private.h"; #line default #line hidden #line 134 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\r\n// ARC is required\r\n#if ! __has_feature(objc_arc)\r\n#error This file requires A" + "RC. \r\n#endif\r\n\r\n// Local assembly import\r\n#import \""); #line default #line hidden #line 142 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(InterfaceFile)); #line default #line hidden #line 142 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\"\r\n\r\n#if __has_include(\""); #line default #line hidden #line 144 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(optionalImport)); #line default #line hidden #line 144 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\")\r\n#import \""); #line default #line hidden #line 145 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(optionalImport)); #line default #line hidden #line 145 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\" // Not auto generated. Add manually to project.\r\n#endif\r\n\r\n"); #line default #line hidden #line 148 "C:\Users\Jonathan Mitchell\Documents\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" } }
// // ManagedTypeForAssociation // // Processes the managed type so that it can act as a type // suitable for Obj-C type association // string ManagedTypeForAssociation(CodeFacet managedFacet) { string managedType = null; // if the type represents a generic type parameter then the actual // type argument will remain unknown until runtime. if (managedFacet.IsGenericParameter) { managedType = GenericTypePlaceholder; } else if (managedFacet.IsArray) { // We want System.Byte[] to associate with NSData if (managedFacet.Type != "System.Byte[]") { managedType = "System.Array"; } } else if (managedFacet.IsGenericType) { managedType = CodeFacet.NormalizeGenericTypesInManagedIdentifier(managedFacet.Type); } if (managedType == null) { if (managedFacet.IsByRef || managedFacet.IsPointer) { managedType = managedFacet.ElementType; } else { managedType = managedFacet.Type; } } return managedType; }
// // ObjCIdentifierFromManagedIdentifier // public static string ObjCIdentifierFromManagedIdentifier(string prefix, string managedName) { return(CodeFacet.ObjCIdentifierFromManagedIdentifier(prefix, managedName)); }
// // ObjCTypeDeclFromManagedFacet() // string ObjCTypeDeclFromManagedFacet(CodeFacet managedFacet) { string decl = ""; string managedType = ManagedTypeForAssociation(managedFacet); if (managedType == null) return "????"; if (!ObjCTypeAssociations.ContainsKey(managedType)) { // If no explicit type found then return a canonical type name. decl = ObjCIdentifierFromManagedIdentifier(managedType); // if ObjC rep is NSObject or pointer then append deref operator. if (ObjCRepresentationIsObject(managedFacet) || managedFacet.IsPointer) { decl += " *"; } } else { decl = ObjCTypeAssociations[managedType].ObjCTypeDecl; if (managedFacet.IsPointer) { decl += " *"; } } return decl; }
// // WriteFacetTypeInfo // public string WriteFacetTypeInfo(CodeFacet facet) { StringBuilder s = new StringBuilder(); if (facet.IsByRef) s.Append("ref "); if (facet.IsGenericParameter) s.Append("<"); s.Append(facet.Type); if (facet.IsGenericParameter) s.Append(">"); return s.ToString(); }
public Accessor(Net2ObjC n2c, CodeFacet facet, Dictionary <string, object> options = null) { Name = facet.Name; Description = facet is PropertyFacet ? "property" : "field"; // define getters and setters GetterName = Name.FirstCharacterToLower(); SetterName = "set" + Name.FirstCharacterToUpper(); ObjCMethodType = null; if (facet.IsStatic) { ObjCMethodType = "+"; // decorate class accessor method names known to be unsafe if (n2c.UnsafeObjCClassMethodNames().Contains(GetterName)) { GetterName += "_"; SetterName += "_"; } } else { ObjCMethodType = "-"; } string accessorType = facet.Type; ObjCTypeDecl = n2c.ObjCTypeDeclFromManagedFacet(facet); IsObjectProperty = n2c.ObjCRepresentationIsObject(facet); MonoObjectPtr = "MonoObject *"; // some NSObject properties need a bit of TLC BaseProperties = new List <string> { "description" }; // property storage and evaluation PropertyAttributes = ""; PropertyStorage = "_" + GetterName; if (facet.IsStatic) { PropertyStorage = "m" + PropertyStorage; if (IsObjectProperty) { n2c.StaticObjectPropertyStorageNames.Add(PropertyStorage); } } DoPropertyEqualityTest = ""; if (IsObjectProperty) { // test if mono object pointer and property storage reference the same managed object DoPropertyEqualityTest = string.Format("if ([self object:{0} isEqualToMonoObject:{1}]) return {0};", PropertyStorage, ManagedVariableName); } // instance property. if (!facet.IsStatic) { string attributes = "nonatomic"; // object property attributes if (n2c.ObjCRepresentationIsObject(facet)) { attributes += ", strong"; } if (!facet.IsWritable) { attributes += ", readonly"; } PropertyAttributes = String.Format("({0}) ", attributes); } // create Obj-C representation of managed object ManagedValueToObjC = n2c.ManagedValueToObjc(ManagedVariableName, facet); ObjCValueToMono = n2c.ObjCValueToManaged(ObjCVariableName, ObjCTypeDecl, facet); ObjCTypeAssociation objCTypeAssociate = n2c.ObjCTypeAssociate(facet); // form mono method invocation name. // a prefix may be required, for instance when calling explicit interface properties. string monoMethodPrefix = ""; if (options != null) { if (options.ContainsKey("cAPIMethodPrefix")) { monoMethodPrefix = (string)options["cAPIMethodPrefix"]; } } MonoInvocationName = monoMethodPrefix + Name; IsValid = true; }
private void WriteGetter(CodeFacet facet, Accessor accessor) { WriteLine($"{accessor.ObjCMethodType} ({accessor.ObjCTypeDecl}){accessor.GetterName}{LT}"); if (OutputFileType == OutputType.Implementation) { if (facet is PropertyFacet) { // thunking : primitive value types and enumerations are returned by value. // other value types, such as DateTime are returned as boxed values string thunkTypeDecl = null; if (ObjCRepresentationIsPrimitive(facet)) { accessor.ManagedValueToObjC = "monoObject"; thunkTypeDecl = accessor.ObjCTypeDecl; } else { thunkTypeDecl = "MonoObject *"; } // note that the thunk is valid only for a specific class instance. // if the obj-C receiver represents a managed interface then the cached thunk // must be regenerated if the thunk is invalid for the receiver mono class. WriteLine("{"); PushTabIndent(); if (facet.IsStatic) { WriteLine($"typedef {thunkTypeDecl} (*Thunk)(MonoObject**);"); } else { WriteLine($"typedef {thunkTypeDecl} (*Thunk)(MonoObject *, MonoObject**);"); } WriteLine("static Thunk thunk;"); WriteLine("static MonoClass* thunkClass;"); WriteLine("MonoObject* monoException = NULL;"); WriteLine("if (!thunk || thunkClass != self.monoClass) {"); PushTabIndent(); WriteLine("thunkClass = self.monoClass;"); WriteLine($"MonoMethod* monoMethod = GetPropertyGetMethod(thunkClass, \"{accessor.MonoInvocationName}\");"); WriteLine("thunk = (Thunk)mono_method_get_unmanaged_thunk(monoMethod);"); PopIndent(); WriteLine("}"); if (facet.IsStatic) { WriteLine($"{thunkTypeDecl} monoObject = thunk(&monoException);"); } else { WriteLine($"{thunkTypeDecl} monoObject = thunk(self.monoObject, &monoException);"); } WriteLine("if (monoException != NULL) @throw(NSExceptionFromMonoException(monoException, @{}));"); } else { // field string getFormat; if (!facet.IsStatic) { getFormat = "[self getMonoField:\"{0}\"]"; } else { getFormat = "[[self class] getMonoClassField:\"{0}\"]"; } string getExpression = String.Format(getFormat, accessor.MonoInvocationName); WriteLine("{"); PushTabIndent(); WriteLine($"{accessor.MonoObjectPtr}{ManagedVariableName} = {getExpression};"); } // write object equality test if (accessor.IsObjectProperty) { WriteLine($"{accessor.DoPropertyEqualityTest}"); } WriteLine($"{accessor.PropertyStorage} = {accessor.ManagedValueToObjC};"); WriteLine(""); WriteLine($"return {accessor.PropertyStorage};"); PopIndent(); WriteLine("}"); } }
// // WriteClassSetup // public void WriteClassSetup(CodeFacet facet) { WritePragmaMark("Setup"); #line default #line hidden #line 385 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\t// obligatory override\r\n\t+ (const char *)monoClassName"); #line default #line hidden #line 387 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(LT)); #line default #line hidden #line 387 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\r\n"); #line default #line hidden #line 388 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" if (OutputFileType == OutputType.Implementation) { string name = CodeFacet.NormalizeGenericTypesInManagedIdentifier(facet.NameFromType); #line default #line hidden #line 392 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\t{\r\n\t\treturn \""); #line default #line hidden #line 394 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(facet.TypeNamespace)); #line default #line hidden #line 394 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("."); #line default #line hidden #line 394 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(name)); #line default #line hidden #line 394 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\";\r\n\t}\r\n"); #line default #line hidden #line 396 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" } #line default #line hidden #line 398 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\t// obligatory override\r\n\t+ (const char *)monoAssemblyName"); #line default #line hidden #line 400 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(LT)); #line default #line hidden #line 400 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\r\n"); #line default #line hidden #line 401 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" if (OutputFileType == OutputType.Implementation) { #line default #line hidden #line 404 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\t{\r\n\t\treturn \""); #line default #line hidden #line 406 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(AssemblyFacet.Name)); #line default #line hidden #line 406 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\";\r\n\t}\r\n"); #line default #line hidden #line 408 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" } }
// // OutputImplementedProtocolSuffix() // // Return a class declaration suffix based on the outputType // string OutputImplementedProtocolSuffix(CodeFacet facet) { string value = ""; if (OutputFileType == OutputType.Interface) { // class or interface facet if (facet is InterfaceFacet) { var interfaceFacet = (InterfaceFacet)facet; IList <ImplementedInterfaceFacet> implementedInterfaces = interfaceFacet.ImplementedInterfaces; // heed required type binding implementedInterfaces = implementedInterfaces.Where(f => Config.GenerateFacetBinding(f)).ToList(); if (implementedInterfaces.Count > 0) { // we may wish to naively filter out system interfaces while full // system code generation is pending. // this will hopefully let us usefully represent user implemented interfaces. if (Config.FilterSystemInterfaces) { var interfaces = new List <ImplementedInterfaceFacet>(); foreach (ImplementedInterfaceFacet implementedInterfaceFacet in implementedInterfaces) { string interfaceType = implementedInterfaceFacet.Type; bool isNativeSystemType = interfaceType.StartsWith("System.", StringComparison.OrdinalIgnoreCase); if (!isNativeSystemType) { interfaces.Add(implementedInterfaceFacet); } } implementedInterfaces = interfaces; } if (implementedInterfaces.Count > 0) { // cast IList <CodeFacet> codeFacets = implementedInterfaces.Cast <CodeFacet>().ToList(); // facet is interface facet type? if (facet.GetType() == typeof(InterfaceFacet)) { // insert the interface's own type as we are defining the protocols // that will be used to define a class representing the interface codeFacets.Insert(0, facet); } value = " <"; int i = 0; foreach (CodeFacet codeFacet in codeFacets) { if (i++ > 0) { value += ", "; } value += (ObjCIdentifierFromManagedIdentifier(codeFacet.Type) + "_"); } value += ">"; } } } } return(value); }
// // GenerateTypeWarnings // public void GenerateTypeWarnings(CodeFacet facet) { // in production quality code we should not have any warnings! }
// // ObjCTypeAssociate() // public ObjCTypeAssociation ObjCTypeAssociate(CodeFacet managedFacet) { string managedType = ManagedTypeForAssociation(managedFacet); return(ObjCTypeAssociate(managedType)); }
// // ManagedValueToObjc() // // Return an ObjC expression that converts a Managed object to its corresponding ObjC representation // public string ManagedValueToObjc(string managedVarName, CodeFacet managedFacet, IList <string> args = null) { string managedType = ManagedTypeForAssociation(managedFacet); string exp = null; string objCType = null; // if type is an enum then use its underlying type if (managedFacet.IsEnum) { managedType = managedFacet.UnderlyingType; } // use type association if available ObjCTypeAssociation typeAssoc = ObjCTypeAssociate(managedType); if (typeAssoc != null) { // Use the getter format specifier if available. // This takes up to two arguments: // 1. a MonoObject * pointing to the underlying MonoObject. // 2. a Obj-C Class indicating the class to be used for types occurring in collections. string GetterFormat = typeAssoc.GetterFormat; if (GetterFormat != null) { List <string> getterArgs = new List <string>(); getterArgs.Add(managedVarName); if (managedFacet.IsPointer) { GetterFormat = "DB_UNBOX_PTR({0})"; } else { // add any child type arguments representing generic types if (managedFacet.ObjCFacet.GenericArgumentTypes != null && managedFacet.ObjCFacet.GenericArgumentTypes.Count() > 0) { getterArgs.AddRange(managedFacet.ObjCFacet.GenericArgumentTypes); } // TODO: provide class representation for arrays. // Just as we provide a class rep for a generic the same will be required for an array. if (managedFacet.IsArray) { getterArgs.Add("System_Object"); } // We may require at least two arguments. if (getterArgs.Count < 2) { getterArgs.Add("System_Object"); } // add additional arguments if (args != null) { getterArgs.AddRange(args); } } exp = string.Format(GetterFormat, getterArgs.ToArray <string>()); } // use custom method formatter else if (typeAssoc.GetterMethod != null) { string methodName = typeAssoc.GetterMethod; Type type = GetType(); MethodInfo method = type.GetMethod(methodName); if (method != null) { exp = (string)method.Invoke(this, new object[] { managedVarName, managedType }); } } // use default object type else if (typeAssoc.IsNSObject) { objCType = typeAssoc.ObjCType; } } if (exp == null) { // default to canonical type representation if (objCType == null) { objCType = ObjCIdentifierFromManagedIdentifier(managedType); } // create DBManagedObject subclass exp = string.Format("[{0} bestObjectWithMonoObject:{1}]", objCType, managedVarName); } return(exp); }
// // WriteClassEnd // public void WriteClassEnd(CodeFacet facet) { WriteClassTeardown(facet); #line default #line hidden #line 418 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("@end\r\n"); #line default #line hidden #line 420 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" WriteModuleFooter(); }
// // WriteClassEnd // public void WriteClassEnd(CodeFacet facet) { WriteClassTeardown(facet); WriteLine("@end"); WriteModuleFooter(); }
// // WriteClassTeardown // public void WriteClassTeardown(CodeFacet facet) { if (OutputFileType == OutputType.Implementation) { WritePragmaMark("Teardown"); #line default #line hidden #line 432 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\t- (void)dealloc\r\n\t{\r\n"); #line default #line hidden #line 435 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" foreach (string staticObjectPropertyName in StaticObjectPropertyStorageNames) { #line default #line hidden #line 438 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\t\t"); #line default #line hidden #line 439 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(staticObjectPropertyName)); #line default #line hidden #line 439 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" = nil;\r\n"); #line default #line hidden #line 440 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" } #line default #line hidden #line 442 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\t}\r\n"); #line default #line hidden #line 444 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.StaticObjectPropertyStorageNames = null; } }
private void WriteSetter(CodeFacet facet, Accessor accessor) { WriteLine($"{accessor.ObjCMethodType} (void){accessor.SetterName}:({accessor.ObjCTypeDecl}){ObjCVariableName}{LT}"); if (OutputFileType == OutputType.Implementation) { // // Property setter // if (facet is PropertyFacet) { string thunkArgTypeDecl, thunkArg; if (ObjCRepresentationIsPrimitive(facet)) { thunkArgTypeDecl = accessor.ObjCTypeDecl; thunkArg = ObjCVariableName; } else { thunkArgTypeDecl = "MonoObject *"; thunkArg = string.Format("[{0} monoObject]", ObjCVariableName); } WriteLine("{"); PushTabIndent(); WriteLine($"{accessor.PropertyStorage} = {ObjCVariableName};"); if (facet.IsStatic) { WriteLine($"typedef void (*Thunk)({thunkArgTypeDecl}, MonoObject**);"); } else { WriteLine($"typedef void (*Thunk)(MonoObject *, {thunkArgTypeDecl}, MonoObject**);"); } WriteLine("static Thunk thunk;"); WriteLine("static MonoClass* thunkClass;"); WriteLine("MonoObject* monoException = NULL;"); WriteLine("if (!thunk || thunkClass != self.monoClass) {"); PushTabIndent(); WriteLine("thunkClass = self.monoClass;"); WriteLine($"MonoMethod* monoMethod = GetPropertySetMethod(thunkClass, \"{accessor.MonoInvocationName}\");"); WriteLine("thunk = (Thunk)mono_method_get_unmanaged_thunk(monoMethod);"); PopIndent(); WriteLine("}"); if (facet.IsStatic) { WriteLine($"thunk({thunkArg}, &monoException);"); } else { WriteLine($"thunk(self.monoObject, {thunkArg}, &monoException);"); } WriteLine("if (monoException != NULL) @throw(NSExceptionFromMonoException(monoException, @{}));"); PopIndent(); WriteLine("}"); } else { // // field setter // string setFormat; if (!facet.IsStatic) { setFormat = "[self setMonoField:\"{0}\" valueObject:{1}]"; } else { setFormat = "[[self class] setMonoClassField:\"{0}\" valueObject:{1}]"; } string setExpression = String.Format(setFormat, accessor.MonoInvocationName, ManagedVariableName); WriteLine("{"); PushTabIndent(); WriteLine($"{accessor.PropertyStorage} = {ObjCVariableName};"); WriteLine($"{accessor.MonoObjectPtr}{ManagedVariableName} = {accessor.ObjCValueToMono};"); WriteLine($"{setExpression};"); PopIndent(); WriteLine("}"); } } }
// // OutputDeclarationSuffix() // // Return a class declaration suffix based on the outputType // string OutputDeclarationSuffix(CodeFacet facet) { string value = ""; if (OutputFileType == OutputType.Interface) { value = " : " + ObjCTypeNameFromManagedTypeName(facet.BaseType); } return value; }
// // WriteFacetAsAccessor // public void WriteFacetAsAccessor(CodeFacet facet, Dictionary <string, object> options = null) { Net2ObjC.Accessor accessor = new Net2ObjC.Accessor(this, facet, options); if (!accessor.IsValid) { return; } // Interface if (OutputFileType == OutputType.Interface) { // write accessor headerdoc info string tab = " "; string tab2 = " "; WriteLine(""); WriteLine("/**"); PushIndent(tab); WriteLine($"Managed {accessor.Description}."); WriteLine("@textblock"); WriteLine("Name"); PushIndent(tab2); WriteLine($"{accessor.Name}"); PopIndent(); WriteLine("");; WriteLine("Type"); PushIndent(tab2); WriteLine($"{WriteFacetTypeInfo(facet)}"); PopIndent(); WriteLine("@/textblock"); PopIndent(); WriteLine("*/"); // instance property if (!facet.IsStatic) { // avoid overriding NSObject properties as we may generate an attribute mismmatch and // trigger a storm of warnings string prefix = ""; if (accessor.BaseProperties.Contains(accessor.GetterName)) { prefix = "// Avoid potential property attribute clash // "; } WriteLine($"{prefix}@property {accessor.PropertyAttributes}{accessor.ObjCTypeDecl} {accessor.GetterName};"); return; } } // implementation else { WriteLine(""); // instance property if (!facet.IsStatic) { // synthesize ivar property storage WriteLine($"@synthesize {accessor.GetterName} = {accessor.PropertyStorage};"); } else // declare static property storage { WriteLine($"static {accessor.ObjCTypeDecl} {accessor.PropertyStorage};"); } } // write getter if (facet.IsReadable) { WriteGetter(facet, accessor); } // write setter if (facet.IsWritable) { WriteSetter(facet, accessor); } }
// // ManagedValueToObjc() // // Return an ObjC expression that converts a Managed object to its corresponding ObjC representation // public string ManagedValueToObjc(string managedVarName, CodeFacet managedFacet, IList<string> args = null) { string managedType = ManagedTypeForAssociation(managedFacet); string exp = null; string objCType = null; // if type is an enum then use its underlying type if (managedFacet.IsEnum) { managedType = managedFacet.UnderlyingType; } // use type association if available ObjCTypeAssociation typeAssoc = ObjCTypeAssociate(managedType); if (typeAssoc != null) { // Use the getter format specifier if available. // This takes up to two arguments: // 1. a MonoObject * pointing to the underlying MonoObject. // 2. a Obj-C Class indicating the class to be used for types occurring in collections. string GetterFormat = typeAssoc.GetterFormat; if (GetterFormat != null) { List<string> getterArgs = new List<string>(); getterArgs.Add(managedVarName); if (managedFacet.IsPointer) { GetterFormat = "DB_UNBOX_PTR({0})"; } else { // add any child type arguments representing generic types if (managedFacet.ObjCFacet.GenericArgumentTypes != null && managedFacet.ObjCFacet.GenericArgumentTypes.Count() > 0) { getterArgs.AddRange(managedFacet.ObjCFacet.GenericArgumentTypes); } // TODO: provide class representation for arrays. // Just as we provide a class rep for a generic the same will be required for an array. if (managedFacet.IsArray) { getterArgs.Add("System_Object"); } // We may require at least two arguments. if (getterArgs.Count < 2) { getterArgs.Add("System_Object"); } // add additional arguments if (args != null) { getterArgs.AddRange(args); } } exp = string.Format(GetterFormat, getterArgs.ToArray<string>()); } // use custom method formatter else if (typeAssoc.GetterMethod != null) { string methodName = typeAssoc.GetterMethod; Type type = GetType(); MethodInfo method = type.GetMethod(methodName); if (method != null) { exp = (string)method.Invoke(this, new object[] { managedVarName, managedType }); } } // use default object type else if (typeAssoc.IsNSObject) { objCType = typeAssoc.ObjCType; } } if (exp == null) { // default to canonical type representation if (objCType == null) { objCType = ObjCIdentifierFromManagedIdentifier(managedType); } // create DBManagedObject subclass exp = string.Format("[{0} objectWithMonoObject:{1}]", objCType, managedVarName); } return exp; }
// // ObjCRepresentationIsPrimitive // // Returns true if ObjC repesentation of facet is a primitive. // Returns false if ObjC repesentation of facet is an object. // public bool ObjCRepresentationIsPrimitive(CodeFacet facet) { // if a type association exits then query it ObjCTypeAssociation objCTypeAssociate = ObjCTypeAssociate(facet); if (objCTypeAssociate != null) { if (objCTypeAssociate.IsNSObject) { return false; } else { return true; } } // Order is important here if (facet.IsGenericType) return false; if (facet.IsStruct) return false; if (facet.IsValueType || facet.IsPointer) { return true; } return false; }
// // ObjCGenericArgumentTypeNamesStringFromManagedFacet // public string ObjCGenericArgumentTypeNamesStringFromManagedFacet(CodeFacet managedFacet) { int idx = 0; string typeNames = ""; foreach (string genericParameterType in managedFacet.GenericArgumentTypes) { if (idx > 0) typeNames += ","; string objCTypeName = ObjCTypeNameFromManagedTypeName(genericParameterType); typeNames += objCTypeName; idx++; } return typeNames; }
// // ObjCRepresentationIsObject // // Returns true if ObjC repesentation of facet is an object. // Returns false if ObjC repesentation of facet is a primitive. // public bool ObjCRepresentationIsObject(CodeFacet facet) { return(!ObjCRepresentationIsPrimitive(facet)); }
// // OutputImplementedProtocolSuffix() // // Return a class declaration suffix based on the outputType // string OutputImplementedProtocolSuffix(CodeFacet facet) { string value = ""; if (OutputFileType == OutputType.Interface) { // class or interface facet if (facet is InterfaceFacet) { var interfaceFacet = (InterfaceFacet)facet; IList<ImplementedInterfaceFacet> implementedInterfaces = interfaceFacet.ImplementedInterfaces; if (implementedInterfaces.Count > 0) { // we may wish to naively filter out system interfaces while full // system code generation is pending. // this will hopefully let us usefully represent user implemented interfaces. if (Config.FilterSystemInterfaces) { var interfaces = new List<ImplementedInterfaceFacet>(); foreach ( ImplementedInterfaceFacet implementedInterfaceFacet in implementedInterfaces) { string interfaceType = implementedInterfaceFacet.Type; bool isNaiveSystemType = interfaceType.StartsWith("System.", StringComparison.OrdinalIgnoreCase); if (!isNaiveSystemType) { interfaces.Add(implementedInterfaceFacet); } } implementedInterfaces = interfaces; } if (implementedInterfaces.Count > 0) { // cast IList<CodeFacet> codeFacets = implementedInterfaces.Cast<CodeFacet>().ToList(); // facet is interface facet type? if (facet.GetType() == typeof(InterfaceFacet)) { // insert the interface's own type as we are defining the protocols // that will be used to define a class representing the interface codeFacets.Insert(0, facet); } value = " <"; int i = 0; foreach (CodeFacet codeFacet in codeFacets) { if (i++ > 0) value += ", "; value += ObjCIdentifierFromManagedIdentifier(codeFacet.Type); } value += ">"; } } } } return value; }
// // WriteModuleBanner // public void WriteModuleBanner(CodeFacet facet, string module) { string outputFile = facet.OutputFileName() + OutputFileSuffix(); // There is an argument that says - Lets add the date here! // However this leads to what I think are excessively noisey commits. #line default #line hidden #line 93 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\r\n//++"); #line default #line hidden #line 95 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(GenToolName)); #line default #line hidden #line 95 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" "); #line default #line hidden #line 95 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(outputFile)); #line default #line hidden #line 95 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\r\n//\r\n// Managed "); #line default #line hidden #line 97 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(module)); #line default #line hidden #line 97 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" : "); #line default #line hidden #line 97 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(facet.Name)); #line default #line hidden #line 97 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\r\n//\r\n"); #line default #line hidden #line 99 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" if (OutputFileType == OutputType.Implementation) { WriteModuleFeatureRequirements(); } }
// // ObjCValueToManaged // // Return an ObjC expression that converts an ObjC object to its corresponding managed representation // public string ObjCValueToManaged(string objCVarName, string objCTypeDecl, CodeFacet managedFacet) { string exp = null; // extract type info in a format suitable for association string managedType = ManagedTypeForAssociation(managedFacet); // if type is an enum then use its underlying type if (managedFacet.IsEnum) { managedType = managedFacet.UnderlyingType; } // retrieve an ObjCTypeAssociation for the given managedType string key = ObjCTypeAssociation.UniqueTypeName(objCTypeDecl, managedType); if (ManagedTypeAssociations.ContainsKey(key)) { ManagedTypeAssociation managedTypeAssoc = ManagedTypeAssociations[key]; ObjCTypeAssociation objCTypeAssoc = ObjCTypeAssociations[managedType]; // use the value object format specifier if available string setterFormat = objCTypeAssoc.SetterFormat; if (setterFormat != null) { if (managedFacet.IsPointer) { setterFormat = "DB_VALUE({0}"; } exp = string.Format(setterFormat, objCVarName); } // use custom method else if (objCTypeAssoc.SetterMethod != null) { string methodName = objCTypeAssoc.SetterMethod; Type type = GetType(); MethodInfo method = type.GetMethod(methodName); if (method != null) { exp = (string)method.Invoke(this, new object[] { objCVarName, objCTypeDecl }); } } } // no ObjC expression defined. // generate default object representation expression. if (exp == null) { if (ObjCRepresentationIsPrimitive(managedFacet)) { exp = string.Format("DB_VALUE({0})", objCVarName); } else { exp = string.Format("[{0} monoObject]", objCVarName); } } return exp; }
// // WriteClassPredeclaration // public void WriteClassPredeclaration(CodeFacet facet) { string namespacePrefix = ObjCAcronymFromManagedIdentifier(facet.TypeNamespace); string classDefine = ObjCIdentifierFromManagedIdentifier(namespacePrefix + facet.Name) + "_"; string classObjCType = facet.ObjCFacet.Type; #line default #line hidden #line 198 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("@class "); #line default #line hidden #line 199 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(classObjCType)); #line default #line hidden #line 199 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(";\r\n#ifdef "); #line default #line hidden #line 200 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(classDefine)); #line default #line hidden #line 200 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\r\n#warning "); #line default #line hidden #line 201 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(classDefine)); #line default #line hidden #line 201 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" class name collision.\r\n#else\r\n#define "); #line default #line hidden #line 203 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(@classDefine)); #line default #line hidden #line 203 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" "); #line default #line hidden #line 203 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(@classObjCType)); #line default #line hidden #line 203 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\r\n#endif\r\n\r\n"); #line default #line hidden #line 206 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" }
// // ObjCRepresentationIsObject // // Returns true if ObjC repesentation of facet is an object. // Returns false if ObjC repesentation of facet is a primitive. // public bool ObjCRepresentationIsObject(CodeFacet facet) { return !ObjCRepresentationIsPrimitive(facet); }
// // WriteInterfaceEnd // public void WriteInterfaceEnd(CodeFacet facet, bool writeAux = false) { if (!writeAux) { #line default #line hidden #line 332 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("#endif\r\n\r\n"); #line default #line hidden #line 335 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" } // if !writeAux #line default #line hidden #line 337 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\r\n@end\r\n\r\n"); #line default #line hidden #line 341 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" if (writeAux) { WriteModuleFooter(); } }
// // ObjCTypeAssociate() // ObjCTypeAssociation ObjCTypeAssociate(CodeFacet managedFacet) { string managedType = ManagedTypeForAssociation(managedFacet); return ObjCTypeAssociate(managedType); }
// // WriteClassStart // public void WriteClassStart(CodeFacet facet, string module, bool writeBanner = true) { // Allocate property name list this.StaticObjectPropertyStorageNames = new List<string>(); // prefix defines interface or implementation string classPrefix = OutputDeclarationPrefix(); string superClass = OutputDeclarationSuffix(facet); string implementedProtocols = ""; // implemented protocol support is available but // we may not be quite ready to supply all the framework managed interfaces that // are commonly referenced bool outputImplementedProtocols = true; if (true) { implementedProtocols = OutputImplementedProtocolSuffix(facet); } if (writeBanner) { WriteModuleBanner(facet, module); } #line default #line hidden #line 372 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("@"); #line default #line hidden #line 373 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(classPrefix)); #line default #line hidden #line 373 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" "); #line default #line hidden #line 373 "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 373 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(superClass)); #line default #line hidden #line 373 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(implementedProtocols)); #line default #line hidden #line 373 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\r\n"); #line default #line hidden #line 374 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" WriteClassSetup(facet); }
// // WriteFacetAsAccessor // public void WriteFacetAsAccessor(CodeFacet facet, Dictionary<string, object> options = null) { // define getters and setters string accessorName = facet.Name; string accessorDescription = facet is PropertyFacet ? "property" : "field"; string getterName = accessorName.FirstCharacterToLower(); string setterName = "set" + accessorName.FirstCharacterToUpper(); string accessorType = facet.Type; string objCTypeDecl = ObjCTypeDeclFromManagedFacet(facet); bool isObjectProperty = ObjCRepresentationIsObject(facet); string monoObjectPtr = "MonoObject *"; // some NSObject properties need a bit of TLC List<string> baseProperties = new List<string> {"description"}; // property storage and evaluation string propertyAttributes = ""; string propertyStorage = "_" + getterName; if (facet.IsStatic) { propertyStorage = "m" + propertyStorage; if (isObjectProperty) { this.StaticObjectPropertyStorageNames.Add(propertyStorage); } } string doPropertyEqualityTest = ""; if (isObjectProperty) { // test if mono object pointer and property storage reference the same managed object doPropertyEqualityTest = string.Format("if ([self object:{0} isEqualToMonoObject:{1}]) return {0};", propertyStorage, ManagedVariableName); } // field access string fieldAccessExpression =""; // instance property. if (!facet.IsStatic) { string attributes = "nonatomic"; // object property attributes if (ObjCRepresentationIsObject(facet)) { attributes += ", strong"; } if (!facet.IsWritable) { attributes += ", readonly"; } propertyAttributes = String.Format("({0}) ", attributes); } // create Obj-C representation of managed object string managedValueToObjC = ManagedValueToObjc(ManagedVariableName, facet); string objCValueToMono = ObjCValueToManaged(ObjCVariableName, objCTypeDecl, facet); ObjCTypeAssociation objCTypeAssociate = ObjCTypeAssociate(facet); string objCMethodType = !facet.IsStatic ? "-" : "+"; string getFormat, setFormat; // property if (facet is PropertyFacet) { if (!facet.IsStatic) { getFormat = "[self getMonoProperty:\"{0}\"]"; setFormat = "[self setMonoProperty:\"{0}\" valueObject:{1}]"; } else { getFormat = "[[self class] getMonoClassProperty:\"{0}\"]"; setFormat = "[[self class] setMonoClassProperty:\"{0}\" valueObject:{1}]"; } } // field else if (facet is FieldFacet) { if (!facet.IsStatic) { getFormat = "[self getMonoField:\"{0}\"]"; setFormat = "[self setMonoField:\"{0}\" valueObject:{1}]"; } else { getFormat = "[[self class] getMonoClassField:\"{0}\"]"; setFormat = "[[self class] setMonoClassField:\"{0}\" valueObject:{1}]"; } } // invalid facet else { throw new Exception("Cannot write facet as accessor"); } // form mono method invocation name. // a prefix may be required, for instance when calling explicit interface properties. string monoMethodPrefix = ""; if (options != null) { if (options.ContainsKey("cAPIMethodPrefix")) { monoMethodPrefix = (string)options["cAPIMethodPrefix"]; } } string monoInvocationName = monoMethodPrefix + accessorName; string getExpression = String.Format(getFormat, monoInvocationName, ManagedVariableName); string setExpression = String.Format(setFormat, monoInvocationName, ManagedVariableName); // Info comment #line default #line hidden #line 602 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\r\n\t// Managed "); #line default #line hidden #line 604 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(accessorDescription)); #line default #line hidden #line 604 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" name : "); #line default #line hidden #line 604 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(accessorName)); #line default #line hidden #line 604 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\r\n\t// Managed "); #line default #line hidden #line 605 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(accessorDescription)); #line default #line hidden #line 605 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" type : "); #line default #line hidden #line 605 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(WriteFacetTypeInfo(facet))); #line default #line hidden #line 605 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\r\n"); #line default #line hidden #line 606 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" // Interface if (OutputFileType == OutputType.Interface) { // instance property if (!facet.IsStatic) { // avoid overriding NSObject properties as we may generate an attribute mismmatch and // trigger a storm of warnings string prefix = ""; if (baseProperties.Contains(getterName)) { prefix = "// Avoid potential property attribute clash // "; } #line default #line hidden #line 619 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" "); #line default #line hidden #line 620 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(prefix)); #line default #line hidden #line 620 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("@property "); #line default #line hidden #line 620 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(propertyAttributes)); #line default #line hidden #line 620 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(objCTypeDecl)); #line default #line hidden #line 620 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" "); #line default #line hidden #line 620 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(getterName)); #line default #line hidden #line 620 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(";\r\n"); #line default #line hidden #line 621 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" return; } } else { // implementation // instance property if (!facet.IsStatic) { // synthesize ivar property storage #line default #line hidden #line 633 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" @synthesize "); #line default #line hidden #line 634 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(getterName)); #line default #line hidden #line 634 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" = "); #line default #line hidden #line 634 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(propertyStorage)); #line default #line hidden #line 634 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(";\r\n"); #line default #line hidden #line 635 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" } else { // declare static property storage #line default #line hidden #line 640 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" static "); #line default #line hidden #line 641 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(objCTypeDecl)); #line default #line hidden #line 641 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" "); #line default #line hidden #line 641 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(propertyStorage)); #line default #line hidden #line 641 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(";\r\n"); #line default #line hidden #line 642 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" } } // // write getter method // if (facet.IsReadable) { #line default #line hidden #line 651 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" "); #line default #line hidden #line 652 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(objCMethodType)); #line default #line hidden #line 652 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" ("); #line default #line hidden #line 652 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(objCTypeDecl)); #line default #line hidden #line 652 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(")"); #line default #line hidden #line 652 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(getterName)); #line default #line hidden #line 652 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(LT)); #line default #line hidden #line 652 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\r\n"); #line default #line hidden #line 653 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" if (OutputFileType == OutputType.Implementation) { #line default #line hidden #line 656 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" {\r\n\t\t"); #line default #line hidden #line 658 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(monoObjectPtr)); #line default #line hidden #line 658 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(ManagedVariableName)); #line default #line hidden #line 658 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" = "); #line default #line hidden #line 658 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(getExpression)); #line default #line hidden #line 658 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(";\r\n"); #line default #line hidden #line 659 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" if (isObjectProperty) { #line default #line hidden #line 662 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\t\t"); #line default #line hidden #line 663 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(doPropertyEqualityTest)); #line default #line hidden #line 663 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\t\t\t\t\t\r\n"); #line default #line hidden #line 664 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" } #line default #line hidden #line 666 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\t\t"); #line default #line hidden #line 667 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(propertyStorage)); #line default #line hidden #line 667 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" = "); #line default #line hidden #line 667 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(managedValueToObjC)); #line default #line hidden #line 667 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(";\r\n\r\n\t\treturn "); #line default #line hidden #line 669 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(propertyStorage)); #line default #line hidden #line 669 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(";\r\n\t}\r\n"); #line default #line hidden #line 671 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" } // if Implementation } // if IsReadable // // write setter method // if (facet.IsWritable) { #line default #line hidden #line 681 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" "); #line default #line hidden #line 682 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(objCMethodType)); #line default #line hidden #line 682 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" (void)"); #line default #line hidden #line 682 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(setterName)); #line default #line hidden #line 682 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(":("); #line default #line hidden #line 682 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(objCTypeDecl)); #line default #line hidden #line 682 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(")"); #line default #line hidden #line 682 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(ObjCVariableName)); #line default #line hidden #line 682 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(LT)); #line default #line hidden #line 682 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\r\n"); #line default #line hidden #line 683 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" if (OutputFileType == OutputType.Implementation) { #line default #line hidden #line 686 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("\t{\r\n\t\t"); #line default #line hidden #line 688 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(propertyStorage)); #line default #line hidden #line 688 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" = "); #line default #line hidden #line 688 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(ObjCVariableName)); #line default #line hidden #line 688 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(";\r\n\t\t"); #line default #line hidden #line 689 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(monoObjectPtr)); #line default #line hidden #line 689 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(ManagedVariableName)); #line default #line hidden #line 689 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(" = "); #line default #line hidden #line 689 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(objCValueToMono)); #line default #line hidden #line 689 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(";\r\n\t\t"); #line default #line hidden #line 690 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write(this.ToStringHelper.ToStringWithCulture(setExpression)); #line default #line hidden #line 690 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" this.Write("; \r\n\t}\r\n"); #line default #line hidden #line 692 "C:\Users\jonathan\Documents\Thesaurus\Development\Dubrovnik\dotNET\Dubrovnik.Tools\Dubrovnik.Tools\Net2ObjC.tt" } // if Implementation } // if IsWritable }
/// <summary> /// Returns all ObjC import directives required to fully derive an ObjC class from its subclass and its adopted protocols. /// These directives constitute the minimum required to define a class in an ObjC interface header file. /// </summary> /// <param name="facet">Facet</param> /// <returns>List of ObjC import directives.</returns> public List <string> ObjCDerivationImportDirectives(CodeFacet facet) { List <string> imports = new List <string>(); // iterate over the sub facets required to derive the native representation List <CodeFacet> derivation = facet.Derivation(); foreach (CodeFacet cursor in derivation) { string objCType = null; // Managed interfaces don't derive from a base type but from other interfaces (see GetInterfaces) // https://msdn.microsoft.com/en-us/library/system.type.basetype(v=vs.110).aspx // However, our native implementation of the managed interface is a class of System.Object. if (cursor.GetType() == typeof(InterfaceFacet)) { if (AssemblyFacet.DefinesFacetType("System.Object")) { objCType = "System_Object"; imports.Add($"#import \"{objCType}.h\""); } } // for all interfaces we require to import a protocol if (cursor.GetType() == typeof(ImplementedInterfaceFacet) || cursor.GetType() == typeof(InterfaceFacet)) { if (!AssemblyFacet.DefinesFacetType(cursor.Type)) { continue; } // if this interface type is not required then just skip it. // this means that some of the interface methods etc may be represented // and others may not depending on the type exclusion settings if (!Config.GenerateFacetBinding(cursor)) { continue; } objCType = cursor.ObjCFacet.Type; imports.Add($"#import \"{objCType}_Protocol.h\""); } // use base type else { string baseType = cursor.BaseType; // System.Object has no base type if (baseType == null) { continue; } // Derived import directives will only be required for types // defined in the target assembly. If this is not the case // then the required import will have to be defined elsewhere, // most likely in a framework header. if (!AssemblyFacet.DefinesFacetType(baseType)) { continue; } // if we are not generating bindings for the given type then // a header file won't be available string importPrefix = ""; string importSuffix = ""; if (!Config.GenerateTypeBinding(baseType)) { importPrefix = "//"; importSuffix = " // class base defaults to System.Object"; } objCType = cursor.ObjCFacet.BaseType; imports.Add($"{importPrefix}#import \"{objCType}.h\"{importSuffix}"); } } // return a distinct list to remove duplicates imports = imports.Distinct().ToList(); imports.Sort(); return(imports); }