예제 #1
0
        public static ApiModel Parse(JObject root, IEnumerable <string> searchPaths)
        {
            var name = (string)root["name"];
            var api  = new ApiModel(name, ParseDependencies(root, searchPaths));

            // Translations and enumerations only need a single processing phase.
            ParseTranslations(root, api);
            ParseEnumerations(root, api);

            // Structure and interface models must be declared first, and
            // then defined in a second pass to prevent definition order problems.
            DeclareStructures(root, api);
            DeclareInterfaces(root, api);
            DefineStructures(root, api);
            DefineInterfaces(root, api);

            // Functions may reference any of the above, but cannot be referenced themselves,
            // and so can be parsed in one pass at the end.
            ParseFunctions(root, api);

            return(api);
        }
예제 #2
0
        /// <summary>
        /// Defines interfaces in an API model based on the contents of a JSON tree.
        /// </summary>
        /// <param name="root">The root of the JSON tree for the API.</param>
        /// <param name="api">The API model being constructed.</param>
        static void DefineInterfaces(JObject root, ApiModel api)
        {
            JToken items;

            if (root.TryGetValue("interfaces", out items))
            {
                foreach (var item in items)
                {
                    var key   = (string)item["key"];
                    var model = (InterfaceModel)api.FindType(key);

                    JToken parent = null;
                    if ((item as JObject).TryGetValue("type", out parent))
                    {
                        model.Parent = api.FindType((string)parent);
                    }

                    foreach (var method in ParseInterfaceMethods(item as JObject, api))
                    {
                        model.AddMethod(method);
                    }
                }
            }
        }
예제 #3
0
        static void RunGenerator(ApiModel api, Configuration configuration)
        {
            var templateDirectory = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Templates");
            var templateEngine    = new TemplateEngine(new[] { templateDirectory });

            templateEngine.RegisterCallback("ApiNamespace", (e, s) => api.Name);
            templateEngine.RegisterCallback("ApiName", (e, s) => TemplateCallbacks.GetApiClassName(api));
            templateEngine.RegisterCallback("ApiDll", (e, s) => TemplateCallbacks.GetApiDllName(api));
            templateEngine.RegisterCallbacks(typeof(TemplateCallbacks));

            var outputDirectory = configuration.GeneratorOutputPath;

            if (!Directory.Exists(outputDirectory))
            {
                Directory.CreateDirectory(outputDirectory);
            }

            ApplyTemplate(api, outputDirectory, templateEngine, "Api");
            ApplyTemplate(api.Enumerations, outputDirectory, templateEngine, "Enumeration");
            ApplyTemplate(api.Structures, outputDirectory, templateEngine, "Structure");
            ApplyTemplate(api.Interfaces, outputDirectory, templateEngine, "Interface");

            BuildTrampolineAssembly(api, outputDirectory, string.Format("{0}.Trampoline", api.Name));
        }
예제 #4
0
        static void BuildTrampolineAssembly(ApiModel api, string outputDirectory, string outputFile)
        {
            MarshallingService        marshaller        = new MarshallingService();
            TrampolineAssemblyBuilder trampolineBuilder = new TrampolineAssemblyBuilder();

            foreach (var interfaceModel in api.Interfaces)
            {
                foreach (var methodModel in interfaceModel.Methods)
                {
                    var methodType = marshaller.ResolveType(methodModel.Type);
                    if (methodType == null)
                    {
                        throw new InvalidOperationException(string.Format("Could not resolve return type for method '{0}.'", methodModel.Name));
                    }

                    var parameters = new List <TrampolineParameter>();
                    foreach (var parameterModel in methodModel.Parameters)
                    {
                        var parameterType = marshaller.ResolveType(parameterModel);
                        if (parameterType == null)
                        {
                            throw new InvalidOperationException(string.Format("Could not resolve type for parameter '{0}.'", parameterModel.Name));
                        }

                        TrampolineParameterFlags flags = TrampolineParameterFlags.Default;
                        if (parameterModel.Flags.HasFlag(ParameterModelFlags.IsOutput) && marshaller.ResolveBehavior(parameterModel) != MarshalBehavior.Structure && marshaller.ResolveBehavior(parameterModel) != MarshalBehavior.Enumeration && marshaller.ResolveBehavior(parameterModel) != MarshalBehavior.Array)
                        {
                            flags |= TrampolineParameterFlags.Reference;
                        }

                        parameters.Add(parameterModel.Type == ApiModel.VoidModel ? new TrampolineParameter(typeof(IntPtr), flags) : new TrampolineParameter(parameterType, flags));
                    }

                    trampolineBuilder.Add(new Trampoline(true, methodType, parameters.ToArray()));
                }
            }

            foreach (var functionModel in api.Functions)
            {
                var methodType = marshaller.ResolveType(functionModel.Type);
                if (methodType == null)
                {
                    throw new InvalidOperationException(string.Format("Could not resolve return type for method '{0}.'", functionModel.Name));
                }

                var parameters = new List <TrampolineParameter>();
                foreach (var parameterModel in functionModel.Parameters)
                {
                    var parameterType = marshaller.ResolveType(parameterModel);
                    if (parameterType == null)
                    {
                        throw new InvalidOperationException(string.Format("Could not resolve type for parameter '{0}.'", parameterModel.Name));
                    }

                    TrampolineParameterFlags flags = TrampolineParameterFlags.Default;
                    if (parameterModel.Flags.HasFlag(ParameterModelFlags.IsOutput))
                    {
                        flags |= TrampolineParameterFlags.Reference;
                    }

                    parameters.Add(parameterModel.Type == ApiModel.VoidModel ? new TrampolineParameter(typeof(IntPtr), flags) : new TrampolineParameter(parameterType, flags));
                }

                trampolineBuilder.Add(new Trampoline(false, methodType, parameters.ToArray()));
            }

            trampolineBuilder.CreateAssembly(outputDirectory, outputFile);
        }
예제 #5
0
 protected TypeModel(ApiModel api, string key, string name)
 {
     Api  = api;
     Key  = key;
     Name = name;
 }
예제 #6
0
 public FunctionModel(ApiModel api, string name, TypeModel returnType)
 {
     Api  = api;
     Name = name;
     Type = returnType;
 }
예제 #7
0
 internal EnumerationModel(ApiModel api, string key)
     : base(api, key, key)
 {
 }
예제 #8
0
 internal StructureModel(ApiModel api, string key)
     : base(api, key, key)
 {
 }
예제 #9
0
 public static string GetApiClassName(ApiModel api)
 {
     return(api.Name.Split('.').Last());
 }
예제 #10
0
 internal InterfaceModel(ApiModel api, string key, Guid guid)
     : base(api, key, key)
 {
     Guid = guid;
 }