/// <summary> /// Loads the <paramref name="registry"/> and Purges Generated Code given /// <paramref name="serviceManager"/>. /// </summary> /// <param name="serviceManager"></param> /// <param name="registry"></param> private void LoadAndPurgeGeneratedCode(CodeGenerationServiceManager serviceManager , out OrToolsSatGeneratedSyntaxTreeRegistry registry) { if (DebugMessagesSwitch) { Writer.WriteLine("Loading and purging registry."); } /* Should not need to re-load any ServiceManager Registries, * since this is done inherently by the SM itself. */ registry = serviceManager.Registry; if (!registry.Any()) { if (DebugMessagesSwitch) { Writer.WriteLine("There are no Registry entries."); } return; } // Work around output or reference parameters. var local = registry; var outputDirectory = local.OutputDirectory; var anUpdateOccurred = local.GoogleOrToolsVersion < GoogleOrToolsVersion; // Purge All if any of them are missing. bool ShouldPurgeRegistry(GeneratedSyntaxTreeDescriptor descriptor) { /* Easy Purge to make by Version first, followed closely by whether * any previously registered files have themselves disappeared. */ bool WhetherSomeFilesAreMissing() { var someFilesAreMissing = descriptor.GeneratedAssetKeys .Select(y => Path.Combine(outputDirectory, y.RenderGeneratedFileName())) .Any(filePath => !File.Exists(filePath)); return(someFilesAreMissing); } var should = anUpdateOccurred || WhetherSomeFilesAreMissing(); if (DebugMessagesSwitch) { Writer.WriteLine($"Should{(should ? " " : " not ")}purge generated code."); } return(should); } registry.PurgeWhere(ShouldPurgeRegistry); }
public void Generates_When_Google_OrTools_Version_Updates() { VerifySingleCodeGenerationPass(out var registry); // TODO: TBD: could almost inject some code into a generic handler... void VerifyRegistryAndUpdate() { Version Parse(string s) => Version.Parse(s); // We need an instance of the Service Manager for what we are about to do here. var serviceManager = new CodeGenerationServiceManager(registry.OutputDirectory, RegistryFileName); // The Version will surely have updated from '0.0.0' ... Remember, we also want it in Three Parts. serviceManager.Registry.GoogleOrToolsVersion = Parse("0.0.0"); serviceManager.TrySave(); } VerifyRegistryAndUpdate(); VerifySingleCodeGenerationPass(out var secondRegistry); VerifyDifferentRegistries(registry, secondRegistry); }
// ReSharper disable once MemberCanBeMadeStatic.Local private int?GenerateCode() { void EnsureDirectoryExists(string path) { if (Directory.Exists(path)) { return; } Directory.CreateDirectory(path); } try { string outputDirectory = OutputDirectoryVar; string generatedCodeRegistryFile = GeneratedCodeRegistryFileVar; EnsureDirectoryExists(outputDirectory); if (DebugMessagesSwitch) { Writer.WriteLine($"Output Directory is '{outputDirectory}', registry file name is '{generatedCodeRegistryFile}'."); } var serviceManager = new CodeGenerationServiceManager(outputDirectory, generatedCodeRegistryFile); LoadAndPurgeGeneratedCode(serviceManager, out var registry); Registry = registry; registry.AssumesTrue(x => ReferenceEquals(x, serviceManager.Registry)); // ReSharper disable once RedundantEmptyObjectOrCollectionInitializer var service = new SatParameterCodeGeneratorService { }; var descriptor = service.Descriptor; service.CodeGenerationVisitor.Visit(descriptor); var compilationUnits = service.CodeGenerationVisitor.CompilationUnits; if (DebugMessagesSwitch) { Writer.WriteLine( $"There are {compilationUnits.Count} potential new compilation units as compared" + $" to {registry.SelectMany(x => x.GeneratedAssetKeys).Count()} old ones." ); } // TODO: TBD: this is what we are really talking about... // TODO: TBD: we need to find an exact match, otherwise, we reject the current set and regenerate... // TODO: TBD: no need to go ad-hoc compiling any previously generated code... that is entirely unnecessary. var renderedCompilationUnits = compilationUnits.ToDictionary( x => x.Key , x => x.Value.NormalizeWhitespace().ToFullString() ); if (TryEvaluateCompilationUnits(registry, renderedCompilationUnits)) { if (DebugMessagesSwitch) { Writer.WriteLine( "Evaluation complete, there are" + $" {renderedCompilationUnits.Count} rendered compilation units." ); } var generatedDescriptor = GeneratedSyntaxTreeDescriptor.Create(); foreach (var(key, renderedCompilationUnit) in renderedCompilationUnits) { var filePath = Path.Combine(outputDirectory, key.RenderGeneratedFileName()); using (var fs = File.Open(filePath, FileMode.CreateNew, FileAccess.Write, FileShare.Read)) { using (var sw = new StreamWriter(fs)) { sw.WriteLine(renderedCompilationUnit); } } generatedDescriptor.GeneratedAssetKeys.Add(key); } registry.Add(generatedDescriptor); if (DebugMessagesSwitch) { Writer.WriteLine( "Service Manager Registry instance" + $" is{(ReferenceEquals(serviceManager.Registry, registry) ? " " : " not ")}the same." ); } if (DebugMessagesSwitch) { // TODO: TBD: do we need exposure of the SM Registry? Writer.WriteLine( $"There are {generatedDescriptor.GeneratedAssetKeys.Count} generated items and" + $" {serviceManager.Registry.SelectMany(x => x.GeneratedAssetKeys).Count()} total entries to save." ); } serviceManager.TrySave(); } } catch (Exception ex) { ReportException(ex); return(ErrorGeneratingCode); } return(null); }