Ejemplo n.º 1
0
        static SLFile GenerateStubsFromTypes(TypeAggregator types, PlatformName platform, List <string> namespaces)
        {
            var imports = ImportsForPlatform(platform, types.AllTypes);

            SLConditionalCompilation.If(PlatformCondition(platform)).AttachBefore(imports);
            new SLComment(kRobotText, true).AttachBefore(imports);
            var slfile = new SLFile(imports);

            slfile.Functions.AddRange(MetaWrapperForFunc(platform, types.PublicEnums, TypeType.Enum, namespaces));
            slfile.Functions.AddRange(MetaWrapperForFunc(platform, types.PublicStructs, TypeType.Struct, namespaces));

            // can't do ordinal because function names can have Bockovers
            slfile.Functions.Sort((func1, func2) => String.Compare(func1.Name.Name, func2.Name.Name, StringComparison.InvariantCulture));

            slfile.Trailer.Add(SLConditionalCompilation.Endif);
            // can't do ordinal because module names can have Bockovers
            imports.Sort((import1, import2) => String.Compare(import1.Module, import2.Module, StringComparison.InvariantCulture));
            return(slfile);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates a hash table for all types, and a function to access them.
        /// </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>
        /// <returns>SLFile which, when written, has hash table and function as described in summary</returns>
        static SLFile GenerateSwiftHashTableFromTypes(TypeAggregator types, PlatformName platform, List <string> namespaces)
        {
            var imports = ImportsForPlatform(platform, types.AllTypes);

            SLConditionalCompilation.If(PlatformCondition(platform)).AttachBefore(imports);
            new SLComment(kRobotText, true).AttachBefore(imports);
            var slfile = new SLFile(imports);

            // collect and filter types
            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));

            // sort types into respective availability categories
            var availableCategories = new Dictionary <string, List <TypeDefinition> > ();

            foreach (var type in selectedTypes)
            {
                var typeAttributeObj = AvailableAttributeForType(platform, type);
                var typeAttribute    = typeAttributeObj == null ? "" : typeAttributeObj.StringRep;
                List <TypeDefinition> otherTypes;
                if (availableCategories.TryGetValue(typeAttribute, out otherTypes))
                {
                    otherTypes.Add(type);
                }
                else
                {
                    otherTypes = new List <TypeDefinition> {
                        type
                    };
                    availableCategories.Add(typeAttribute, otherTypes);
                }
            }

            // debug
            //foreach (var pair in availableCategories) {
            //	Console.WriteLine ($"Available attribute \"{pair.Key}\": {pair.Value.Aggregate("", (str, type) => str + ", " + type.Name).Substring(2)} (length: {pair.Value.Count})");
            //}

            // add map for each availability status
            var maps     = new StringBuilder();
            var mergeFns = new StringBuilder();

            mergeFns.AppendLine("private func addToTypes() {");
            foreach (var category in availableCategories)
            {
                var availableInfo = category.Key;
                var modifier      = "public";
                var prefix        = "";
                var header        = "";
                if (availableInfo != "")
                {
                    modifier = "private";
                    prefix   = AvailableDictPrefix(availableInfo);
                    header   = $"@{availableInfo}";
                }
                if (header != "")
                {
                    maps.AppendLine(header);
                }
                maps.AppendLine($"{modifier} var {prefix}types: [String:Any.Type] = [");
                maps.AppendLine(MapBodyForTypes(category.Value, platform));
                maps.AppendLine("]");
                maps.AppendLine();

                if (availableInfo != "")
                {
                    mergeFns.AppendLine($"	if #{availableInfo} {{");
                    mergeFns.AppendLine($"		types.merge({AvailableDictPrefix (availableInfo)}types) {{ (_, newer) in newer }}");
                    mergeFns.AppendLine("	}");
                }
            }
            if (!availableCategories.ContainsKey(""))
            {
                maps.AppendLine("public var types = [String:Any.Type]()");
            }
            mergeFns.AppendLine("}");
            slfile.Declarations.Add(new SLLine(new SLIdentifier(maps.ToString()), false));
            slfile.Declarations.Add(new SLLine(new SLIdentifier(mergeFns.ToString()), false));

            // add function to fetch type
            var handleTranslation = @"
private var merged = false

public func getSwiftType(str: UnsafeMutablePointer<String>, result: UnsafeMutablePointer<Any.Type>) -> Bool {
	if !merged {
		merged = true
		addToTypes()
	}
	if let mt = types[str.pointee] {
		result.initialize(to: mt)
		return true
	}
	return false
}";

            slfile.Declarations.Add(new SLLine(new SLIdentifier(handleTranslation), false));

            slfile.Trailer.Add(SLConditionalCompilation.Endif);
            // can't do ordinal because module names can have Bockovers
            imports.Sort((import1, import2) => String.Compare(import1.Module, import2.Module, StringComparison.InvariantCulture));
            return(slfile);
        }