예제 #1
0
        static CSFile GeneratePInvokesFromTypes(TypeAggregator types, PlatformName platform, string framework)
        {
            var fileName  = Path.GetFileNameWithoutExtension(framework);             // /path/XamGlue.framework -> XamGlue
            var dylibFile = Path.Combine(framework, fileName);
            var funcs     = TLFunctionsForFile(dylibFile, platform);

            var ns  = new CSNamespace("SwiftRuntimeLibrary.SwiftMarshal");
            var use = new CSUsingPackages();

            use.And(new CSUsing("System.Runtime.InteropServices"))
            .And(new CSUsing("System"))
            .And(new CSUsing("System.Collections.Generic"))
            .And(new CSUsing("SwiftRuntimeLibrary"));

            var csFile  = new CSFile(use, new CSNamespace [] { ns });
            var csClass = new CSClass(CSVisibility.Internal, $"{fileName}Metadata");

            new CSComment(kRobotText).AttachBefore(use);

            CSConditionalCompilation.If(PlatformToCSCondition(platform)).AttachBefore(use);
            CSConditionalCompilation.Endif.AttachAfter(ns);
            ns.Block.Add(csClass);

            var typeOntoPinvoke = new List <KeyValuePair <CSBaseExpression, CSBaseExpression> > ();

            var typesToProcess = new List <TypeDefinition> ();

            typesToProcess.AddRange(types.PublicEnums);
            typesToProcess.AddRange(types.PublicStructs);

            // pre-sort by function name
            typesToProcess.Sort((type1, type2) => String.CompareOrdinal(FuncIDForTypeDefinition(type1), FuncIDForTypeDefinition(type2)));

            foreach (var type in typesToProcess)
            {
                if (type.HasGenericParameters)
                {
                    continue;
                }
                var moduleName = type.Namespace;
                var name       = type.Name;
                if (TypeAggregator.FilterModuleAndName(platform, moduleName, ref name))
                {
                    var pinvoke = PInvokeForType(type, funcs);
                    if (pinvoke != null)
                    {
                        csClass.Methods.Add(pinvoke);
                        use.AddIfNotPresent(type.Namespace);
                        var typeOf   = new CSSimpleType(type.FullName).Typeof();
                        var funcName = pinvoke.Name;
                        typeOntoPinvoke.Add(new KeyValuePair <CSBaseExpression, CSBaseExpression> (typeOf, funcName));
                    }
                }
            }

            var initializers = typeOntoPinvoke.Select(typeAndFunc => new CSInitializer(new CSBaseExpression [] { typeAndFunc.Key, typeAndFunc.Value }, false));
            var bindingExpr  = new CSInitializedType(new CSFunctionCall("Dictionary<Type, Func<SwiftMetatype>>", true), new CSInitializer(initializers, true));
            var bindingDecl  = new CSFieldDeclaration(new CSSimpleType("Dictionary<Type, Func<SwiftMetatype>>"), "ObjCBindingSwiftMetatypes", bindingExpr, CSVisibility.Internal, true);

            csClass.Fields.Add(new CSLine(bindingDecl));

            use.Sort((package1, package2) => String.CompareOrdinal(package1.Package, package2.Package));

            return(csFile);
        }
예제 #2
0
        /// <summary>
        /// Creates a list of all types, and a hash table which is initialized on first lookup from C# type
        /// to Swift types.
        /// </summary>
        /// <param name="types">Aggregated types, a subset of which are included</param>
        /// <param name="platform">Platform targeted (typically iOS or Mac)</param>
        /// <param name="namespaces">Namespaces to include</param>
        /// <param name="framework">Name of framework used (typically XamGlue)</param>
        /// <returns>CSFile which, when written, has function looking up in hash table as described in summary</returns>
        static CSFile GenerateCSharpHashTableFromTypes(TypeAggregator types, PlatformName platform, List <string> namespaces, string framework)
        {
            var fileName = Path.GetFileNameWithoutExtension(framework);
            var ns       = new CSNamespace("SwiftRuntimeLibrary.SwiftMarshal");
            var use      = new CSUsingPackages();

            use.And(new CSUsing("System.Runtime.InteropServices"))
            .And(new CSUsing("System"))
            .And(new CSUsing("System.Collections.Generic"))
            .And(new CSUsing("SwiftRuntimeLibrary"));

            var csFile  = new CSFile(use, new CSNamespace [] { ns });
            var csClass = new CSClass(CSVisibility.Internal, $"{fileName}Metadata");

            new CSComment(kRobotText).AttachBefore(use);

            CSConditionalCompilation.If(PlatformToCSCondition(platform)).AttachBefore(use);
            CSConditionalCompilation.Endif.AttachAfter(ns);
            ns.Block.Add(csClass);

            // collect all possible types, filter and sort
            var selectedTypes = new List <TypeDefinition> ();

            selectedTypes.AddRange(types.PublicEnums);
            selectedTypes.AddRange(types.PublicStructs);
            selectedTypes = selectedTypes.FindAll(type => IncludeType(type, namespaces, platform));
            selectedTypes.Sort((type1, type2) => String.CompareOrdinal(type1.FullName, type2.FullName));

            // add used namespaces to import list, sort list
            foreach (var type in selectedTypes)
            {
                use.AddIfNotPresent(type.Namespace);
            }
            use.Sort((package1, package2) => String.CompareOrdinal(package1.Package, package2.Package));

            // create list of types to translate
            var typesForList       = selectedTypes.Select(type => new CSSimpleType(type.FullName).Typeof());
            var listInitializeExpr = new CSInitializedType(
                new CSFunctionCall("List<Type>", true),
                new CSInitializer(typesForList, true)
                );
            var listBindingDecl = new CSFieldDeclaration(new CSSimpleType("List<Type>"), "csImportTypes", listInitializeExpr, CSVisibility.Internal, true);

            csClass.Fields.Add(new CSLine(listBindingDecl));

            // create pinvoke for function
            var dylibFile = Path.Combine(framework, fileName);
            var funcs     = TLFunctionsForFile(dylibFile, platform);

            var handleTranslationCode = new CSIdentifier(@"
		public static unsafe bool GetSwiftType (Type t, out SwiftMetatype md) {
			using (var swiftStr = new SwiftString (t.FullName)) {
				return SwiftCore.GetEnumMetadataByName (swiftStr.SwiftData, out md);
			}
		}

		internal static Dictionary<Type, SwiftMetatype> csImportMeta = null;
		internal static bool TryGetImportedMetadata (Type cSharpType, out SwiftMetatype md) {
			if (csImportMeta == null) {
				csImportMeta = new Dictionary<Type, SwiftMetatype> (csImportTypes.Count);
				foreach (var t in csImportTypes) {
					SwiftMetatype meta;
					GetSwiftType(t, out meta);
					csImportMeta [t] = meta;
				}
			}
			return csImportMeta.TryGetValue (cSharpType, out md);
		}"        );

            csClass.Fields.Add(new CSLine(handleTranslationCode, false));

            return(csFile);
        }