/// <summary>
        /// Corresponds to CLI "headers" keyword. Converts given c# assemblies to corresponding c++ files.
        /// Combination of extract and generate keywords.
        /// </summary>
        public void Execute()
        {
            AssemblyCache assemblies = new AssemblyCache();

            // Create list of assemblies (enrolling masks when needed)
            foreach (string assemblyPath in Assemblies)
            {
                string assemblyName = Path.GetFileName(assemblyPath);
                if (!string.IsNullOrEmpty(assemblyName))
                {
                    string assemblyDirectory = string.IsNullOrEmpty(assemblyDirectory = Path.GetDirectoryName(assemblyPath))
                                                   ? Environment.CurrentDirectory
                                                   : Path.GetFullPath(assemblyDirectory);
                    assemblies.AddFiles(Directory.EnumerateFiles(assemblyDirectory, assemblyName));
                }
            }

            List <IDecl> declarations = new List <IDecl>();

            foreach (Assembly assembly in assemblies)
            {
                CommentNavigator.TryCreate(assembly, out CommentNavigator docNavigator);
                ProjectNavigator.TryCreate(ProjectPath, assembly, out ProjectNavigator projNavigator);

                List <Type> types = TypesExtractor.GetTypes(assembly, Types);
                List <Type> enums = TypesExtractor.GetEnums(assembly, Types);
                declarations.AddRange(types.Concat(enums)
                                      .Select(type => DeclarationConvertor.ToDecl(type, docNavigator, projNavigator)));
            }

            GeneratorSettingsProvider.PopulateFromFile(SettingsPath);
            var fileContentInfos = DeclConverter.ConvertSet(declarations);

            foreach (var hppFile in fileContentInfos)
            {
                var fullPath  = Path.Combine(OutputFolder, hppFile.FolderName, hppFile.FileName);
                var directory = Path.GetDirectoryName(fullPath);
                Directory.CreateDirectory(directory);

                if (File.Exists(fullPath))
                {
                    Console.ForegroundColor = ConsoleColor.DarkYellow;
                    Console.WriteLine($"Warning! File already exists. Overwriting: {hppFile.FolderName}/{hppFile.FileName}");
                    Console.ResetColor();
                }
                else
                {
                    Console.WriteLine($"Generated: {hppFile.FolderName}/{hppFile.FileName}");
                }

                File.WriteAllText(fullPath, hppFile.Content);
            }
        }
        /// <summary>
        /// Corresponds to CLI "extract" keyword. Converts assembly types to declarations.
        /// ExtractVerbOptions.ProjectPath has been introduced to add project structure info to declarations.
        /// </summary>
        public void Execute()
        {
            AssemblyCache assemblies = new AssemblyCache();

            // Create list of assemblies (enrolling masks when needed)
            foreach (string assemblyPath in Assemblies)
            {
                string assemblyName = Path.GetFileName(assemblyPath);
                if (!string.IsNullOrEmpty(assemblyName))
                {
                    string assemblyDirectory =
                        string.IsNullOrEmpty(assemblyDirectory = Path.GetDirectoryName(assemblyPath)) ?
                        Environment.CurrentDirectory :
                        Path.GetFullPath(assemblyDirectory);
                    assemblies.AddFiles(Directory.EnumerateFiles(assemblyDirectory, assemblyName));
                }
            }

            // When no assemblies provided, search inside working directory
            if (assemblies.IsEmpty)
            {
                assemblies.AddFiles(Directory.EnumerateFiles(Environment.CurrentDirectory, "*.dll"));
            }

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

            foreach (Assembly assembly in assemblies)
            {
                Console.Write("A> ");
                Console.WriteLine(assembly.Location);

                bool hasDocumentation = CommentNavigator.TryCreate(assembly, out CommentNavigator docNavigator);
                if (hasDocumentation)
                {
                    Console.Write("D> ");
                    Console.WriteLine(docNavigator.XmlLocation);
                }

                bool isProjectLocated = ProjectNavigator.TryCreate(ProjectPath, assembly, out ProjectNavigator projNavigator);
                if (isProjectLocated)
                {
                    Console.Write("P> ");
                    Console.WriteLine(projNavigator.Location);
                }

                List <Type> types = TypesExtractor.GetTypes(assembly, Types);

                foreach (Type type in types)
                {
                    TypeDecl decl = DeclarationConvertor.TypeToDecl(type, docNavigator, projNavigator);

                    string outputFolder = Path.Combine(OutputFolder, decl.Module.ModuleName.Replace('.', '\\'));
                    Directory.CreateDirectory(outputFolder);

                    string extension  = type.IsSubclassOf(typeof(Enum)) ? "clenum" : "cltype";
                    string outputFile = Path.Combine(outputFolder, $"{decl.Name}.{extension}");

                    Console.Write(type.FullName);
                    Console.Write(" => ");
                    Console.WriteLine(outputFile);

                    File.WriteAllText(outputFile, DeclarationSerializer.Serialize(decl));
                }

                List <Type> enums = TypesExtractor.GetEnums(assembly, Types);
                foreach (Type type in enums)
                {
                    EnumDecl decl = DeclarationConvertor.EnumToDecl(type, docNavigator, projNavigator);

                    string outputFolder = Path.Combine(OutputFolder, decl.Module.ModuleName.Replace('.', '\\'));
                    Directory.CreateDirectory(outputFolder);

                    string extension  = type.IsSubclassOf(typeof(Enum)) ? "clenum" : "cltype";
                    string outputFile = Path.Combine(outputFolder, $"{decl.Name}.{extension}");

                    Console.Write(type.FullName);
                    Console.Write(" => ");
                    Console.WriteLine(outputFile);

                    File.WriteAllText(outputFile, DeclarationSerializer.Serialize(decl));
                }
            }
        }
Example #3
0
        public void Smoke()
        {
            using (var context = new TemporalMongoUnitTestContext(this))
            {
                // Root of the C# source code of the DataCentric module
                string srcRootFolder = Path.Combine(context.TestFolderPath, "..\\..\\..");
                string libFolder     = Path.Combine(srcRootFolder, "DataCentric.Test\\bin\\Debug\\netcoreapp2.1"); // TODO - support Linux and release modes
                var    options       = new ExtractCommand
                {
                    Assemblies   = Directory.GetFiles(libFolder, "*.dll"),
                    OutputFolder = context.TestFolderPath,
                    Types        = new List <string>(),
                    ProjectPath  = srcRootFolder
                };

                AssemblyCache assemblies = new AssemblyCache();

                // Create list of assemblies (enrolling masks when needed)
                foreach (string assemblyPath in options.Assemblies)
                {
                    string assemblyName = Path.GetFileName(assemblyPath);
                    if (!string.IsNullOrEmpty(assemblyName))
                    {
                        string assemblyDirectory =
                            string.IsNullOrEmpty(assemblyDirectory = Path.GetDirectoryName(assemblyPath))
                                ? Environment.CurrentDirectory
                                : Path.GetFullPath(assemblyDirectory);
                        assemblies.AddFiles(Directory.EnumerateFiles(assemblyDirectory, assemblyName));
                    }
                }

                List <IDecl> declarations = new List <IDecl>();

                foreach (Assembly assembly in assemblies)
                {
                    CommentNavigator.TryCreate(assembly, out CommentNavigator docNavigator);
                    ProjectNavigator.TryCreate(options.ProjectPath, assembly, out ProjectNavigator projNavigator);

                    List <Type> types = TypesExtractor.GetTypes(assembly, options.Types);
                    List <Type> enums = TypesExtractor.GetEnums(assembly, options.Types);
                    declarations.AddRange(types.Concat(enums)
                                          .Select(type => DeclarationConvertor.ToDecl(type, docNavigator, projNavigator)));
                }

                var converted = DeclarationToPythonConverter.ConvertSet(declarations);

                var result = new Dictionary <string, string>();
                foreach (var file in converted)
                {
                    if (file.FolderName == null)
                    {
                        result[$"{file.FileName}"] = file.Content;
                    }
                    else
                    {
                        result[$"{file.FolderName}/{file.FileName}"] = file.Content;
                    }
                }

                // Record the contents of a selected list of generated files
                // for the purposes of approval testing
                var approvalTestFiles = new List <string>
                {
                    "job_status",
                    "job",
                    "job_key",
                    "zone",
                    "zone_key"
                };

                // Record approval test output
                foreach (var file in result.OrderBy(f => f.Key))
                {
                    string[] tokens   = file.Key.Split('/');
                    string   fileName = tokens[tokens.Length - 1].Split('.')[0];

                    if (approvalTestFiles.Contains(fileName))
                    {
                        context.Log.Verify(file.Key, file.Value);
                    }
                }

                // Enable to generate files on disk
                if (false)
                {
                    foreach (var file in result)
                    {
                        var fullPath  = Path.Combine(options.OutputFolder, file.Key);
                        var directory = Path.GetDirectoryName(fullPath);
                        Directory.CreateDirectory(directory);

                        File.WriteAllText(fullPath, file.Value);
                    }
                }
            }
        }