Exemplo n.º 1
0
        private GccXmlDoc ParseHeaders(CastXml castXml)
        {
            StreamReader xmlReader       = null;
            const string progressMessage = "Parsing C++ headers starts, please wait...";

            try
            {
                Logger.Progress(15, progressMessage);

                var configRootHeader = Path.Combine(IntermediateOutputPath, Config.Id + ".h");

                xmlReader = castXml.Process(configRootHeader);

                if (xmlReader != null)
                {
                    return(GccXmlDoc.Load(xmlReader));
                }

                Logger.Progress(30, progressMessage);
            }
            catch (Exception ex)
            {
                Logger.Error(null, "Unexpected error", ex);
            }
            finally
            {
                xmlReader?.Dispose();

                Logger.Message("Parsing headers is finished.");
            }

            return(null);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Run CodeGenerator
        /// </summary>
        public GccXmlDoc Run()
        {
            GccXmlDoc doc = null;

            Logger.Progress(0, "Starting code generation...");

            try
            {
                var consumerConfig = new ConfigFile
                {
                    Id = ConsumerBindMappingConfigId
                };

                var filesWithIncludes = Config.GetFilesWithIncludes();

                var configsWithIncludes = new HashSet <ConfigFile>();

                // Add the root
                configsWithIncludes.Add(Config);

                foreach (var config in Config.ConfigFilesLoaded)
                {
                    if (filesWithIncludes.Contains(config.Id))
                    {
                        configsWithIncludes.Add(config);
                    }
                }

                GenerateHeaders(configsWithIncludes, consumerConfig);

                if (Logger.HasErrors)
                {
                    Logger.Fatal("Failed to generate C++ headers.");
                }

                var resolver = new IncludeDirectoryResolver(Logger);
                resolver.Configure(Config);

                var castXml = new CastXml(Logger, resolver, CastXmlExecutablePath)
                {
                    OutputPath = IntermediateOutputPath,
                };

                doc = ParseHeaders(castXml);

                if (Logger.HasErrors)
                {
                    Logger.Fatal("Header parsing failed");
                }

                OutputExternDefinition(doc);
            }
            finally
            {
                Logger.Progress(100, "Finished");
            }

            return(doc);
        }
Exemplo n.º 3
0
        private void OutputExternDefinition(GccXmlDoc doc)
        {
            Logger.Message("Generating Extern Definition");

            XElement  root    = new XElement("ChakraDefinitions");
            XDocument externs = new XDocument(new XDeclaration("1.0", "utf-8", "yes"), root);

            var groupedFunctions = doc.GetFunctionsInHeadersContainedInPath(Config.IncludeDirs.First().Path)
                                   .GroupBy(f => Path.GetFullPath(f.Item1.Name));

            foreach (var g in groupedFunctions.OrderBy(g =>
            {
                var include = Config.Includes.FirstOrDefault(i => Path.GetFullPath(i.File) == Path.GetFullPath(g.Key));
                if (include == null)
                {
                    return(Config.Includes.Count + 1);
                }
                return(Config.Includes.IndexOf(include));
            }))
            {
                root.Add(new XComment($@"
  ***************************************
  **
  ** {Path.GetFileName(g.First().Item1.Name)}
  **
  ***************************************
  "));
                foreach (var fn in g.OrderBy(f => int.Parse(f.Item2.Line)))
                {
                    bool skip = false;
                    foreach (var ignoreFunctionPattern in Config.IgnoreFunctions)
                    {
                        if (Regex.IsMatch(fn.Item2.Name, ignoreFunctionPattern))
                        {
                            skip = true;
                        }
                    }

                    if (skip)
                    {
                        continue;
                    }

                    var filePath = fn.Item1.Name;
                    var function = fn.Item2;

                    var    fileName = Path.GetFileName(filePath);
                    string target   = "Common";
                    if (fileName.Contains("Windows"))
                    {
                        target = "WindowsOnly";
                    }

                    var export = new XElement("Export", new XAttribute("name", fn.Item2.Name), new XAttribute("target", target), new XAttribute("source", fileName));
                    if (target == "WindowsOnly")
                    {
                        export.Add(new XAttribute("dllImportEx", ", CharSet = CharSet.Unicode"));
                    }
                    if (Config.IncludeLineNumbers)
                    {
                        export.Add(new XAttribute("line", function.Line));
                    }
                    var fnExtension = Config.ExportExtensions.FirstOrDefault(ed => ed.FunctionName == fn.Item2.Name);
                    if (fnExtension != null)
                    {
                        export.Add(fnExtension.Extensions);
                    }

                    var ccg         = HeaderFilePostProcessor.GetPostProcessor(fn.Item1.Name);
                    var codeComment = ccg.GetCodeCommentPreviousToLine(int.Parse(function.Line));

                    var descriptionElement = new XElement("Description", new XText(new XText(Environment.NewLine) + "      "), new XCData(Environment.NewLine + String.Join(Environment.NewLine, codeComment) + Environment.NewLine), new XText(Environment.NewLine + "     "));
                    export.Add(descriptionElement);

                    var parameters = new XElement("Parameters");
                    foreach (var arg in fn.Item2.Arguments.OrderBy(arg => int.Parse(arg.Line)))
                    {
                        var argTypeName = doc.GetTypeNameById(arg.Type);
                        var direction   = ParameterDirection.In;
                        direction = ccg.GetArgumentDirection(int.Parse(arg.Line));
                        if (direction != ParameterDirection.In && argTypeName.EndsWith('*'))
                        {
                            argTypeName = argTypeName.Substring(0, argTypeName.Length - 1);
                        }

                        var typeMap = Config.TypeMap.FirstOrDefault(tm => tm.From == argTypeName && (tm.FromDirection == null || tm.FromDirection == direction));
                        if (typeMap != null)
                        {
                            argTypeName = typeMap.To;
                            if (typeMap.ToDirection != null)
                            {
                                direction = typeMap.ToDirection.Value;
                            }
                        }

                        var argName = arg.Name;
                        switch (argName)
                        {
                        case "object":
                        case "ref":
                            argName = "@" + argName;
                            break;
                        }

                        var parameter = new XElement("Parameter", new XAttribute("type", argTypeName), new XAttribute("name", argName));

                        if (Config.IncludeLineNumbers)
                        {
                            parameter.Add(new XAttribute("line", arg.Line));
                        }

                        if (direction != ParameterDirection.In)
                        {
                            parameter.Add(new XAttribute("direction", direction.ToString()));
                        }

                        parameters.Add(parameter);
                    }
                    export.Add(parameters);

                    root.Add(export);
                }
            }


            externs.Save(Path.Combine(OutputDirectory, "ChakraExternDefinitions.xml"));

            Logger.Message("Generated Extern Definition");
        }