code/Kingdom.OrTools.Sat.CodeGeneration.Tool/Managers/CodeGenerationConsoleManager.cs
/// <summary>
/// We need to Evaluate a further and much more in depth Purge opportunity given the
/// <paramref name="registry"/> and set of <paramref name="renderedCompilationUnits"/>.
/// </summary>
/// <param name="registry"></param>
/// <param name="renderedCompilationUnits"></param>
/// <returns></returns>
We need to Evaluate a further and much more in depth Purge opportunity given the
and set of .
We need to Evaluate a further and much more in depth Purge opportunity given the and set of .
private bool TryEvaluateCompilationUnits(OrToolsSatGeneratedSyntaxTreeRegistry registry
            , IRenderedCompilationUnitDictionary renderedCompilationUnits)
        {
            bool StringEquals(string a, string b, StringComparison comparisonType)
                => !(a == null || b == null)
                   && string.Equals(a.Trim(), b.Trim(), comparisonType);
            bool TryDecomposeCompilationUnitSyntaxPair(CompilationUnitSyntaxPair pair
                , out string generatedCode) => !IsNullOrEmpty(generatedCode = pair.Value);
            bool ThereAreCodeGenerationInconsistencies(GeneratedSyntaxTreeDescriptor _)
            {
                var outputDirectory = registry.OutputDirectory;
                var filePaths = Directory.EnumerateFiles(outputDirectory, $"*{g}{cs}", TopDirectoryOnly);
                var streamFactories = filePaths.Select(filePath => (Func<Stream>)(
                    () => File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)
                ));
                foreach (var streamFactory in streamFactories)
                {
                    string baselineGeneratedCode;
                    using (var fs = streamFactory.Invoke())
                    {
                        using (var sr = new StreamReader(fs))
                        {
                            baselineGeneratedCode = sr.ReadToEndAsync().Result;
                        }
                    }
                    if (renderedCompilationUnits.Any(
                        pair => TryDecomposeCompilationUnitSyntaxPair(pair, out var x)
                                && StringEquals(x, baselineGeneratedCode, Ordinal)))
                    {
                        continue;
                    }
                    if (DebugMessagesSwitch)
                    {
                        Writer.WriteLine("Generated code inconsistencies discovered, purge required.");
                    }
                    return true;
                }
                if (DebugMessagesSwitch)
                {
                    Writer.WriteLine("Generated code found to be consistent, purge not required.");
                }
                return false;
            }
            var areNonePreviouslyGenerated = !registry.SelectMany(x => x.GeneratedAssetKeys).Any();
            var areObviouslyDifferent = registry.SelectMany(x => x.GeneratedAssetKeys).Count() != renderedCompilationUnits.Count;
            var thereAreCodeGenerationInconsistencies = registry.Any(ThereAreCodeGenerationInconsistencies);
            var shouldPurge = areNonePreviouslyGenerated || areObviouslyDifferent || thereAreCodeGenerationInconsistencies;
            registry.PurgeWhere(_ => shouldPurge);
            return shouldPurge;
        }
private bool TryEvaluateCompilationUnits ( OrToolsSatGeneratedSyntaxTreeRegistry registry , IRenderedCompilationUnitDictionary renderedCompilationUnits ) { bool StringEquals ( string a , string b , StringComparison comparisonType ) => ! ( a == null || b == null ) && string . Equals ( a . Trim ( ) , b . Trim ( ) , comparisonType ) ; bool TryDecomposeCompilationUnitSyntaxPair ( CompilationUnitSyntaxPair pair , out string generatedCode ) => ! IsNullOrEmpty ( generatedCode = pair . Value ) ; bool ThereAreCodeGenerationInconsistencies ( GeneratedSyntaxTreeDescriptor _ ) { var outputDirectory = registry . OutputDirectory ; var filePaths = Directory . EnumerateFiles ( outputDirectory , $" * { g } { cs } " , TopDirectoryOnly ) ; var streamFactories = filePaths . Select ( filePath => ( Func < Stream > ) ( ( ) => File . Open ( filePath , FileMode . Open , FileAccess . Read , FileShare . Read ) ) ) ; foreach ( var streamFactory in streamFactories ) { string baselineGeneratedCode ; using ( var fs = streamFactory . Invoke ( ) ) { using ( var sr = new StreamReader ( fs ) ) { baselineGeneratedCode = sr . ReadToEndAsync ( ) . Result ; } } if ( renderedCompilationUnits . Any ( pair => TryDecomposeCompilationUnitSyntaxPair ( pair , out var x ) && StringEquals ( x , baselineGeneratedCode , Ordinal ) ) ) { continue ; } if ( DebugMessagesSwitch ) { Writer . WriteLine ( " " ) ; } return true ; } if ( DebugMessagesSwitch ) { Writer . WriteLine ( " " ) ; } return false ; } var areNonePreviouslyGenerated = ! registry . SelectMany ( x => x . GeneratedAssetKeys ) . Any ( ) ; var areObviouslyDifferent = registry . SelectMany ( x => x . GeneratedAssetKeys ) . Count ( ) != renderedCompilationUnits . Count ; var thereAreCodeGenerationInconsistencies = registry . Any ( ThereAreCodeGenerationInconsistencies ) ; var shouldPurge = areNonePreviouslyGenerated || areObviouslyDifferent || thereAreCodeGenerationInconsistencies ; registry . PurgeWhere ( _ => shouldPurge ) ; return shouldPurge ; }
We need to Evaluate a further and much more in depth Purge opportunity given the
and set of .
We need to Evaluate a further and much more in depth Purge opportunity given the and set of .
// Pretty sure we want to do an Ordinal comparison here. But this is a function of the Invocation. // This is a bit involved, but this gains us sufficient accounting of Generated Code. // Obtain any Previously Existing Baseline Generated Code in the form of a Stream Factory. // Which has the added benefit of deferring Stream operations until we absolutely need them. /* And which also defers the actual delegate formation given the nature of the LINQ
                     * provider. Performance may vary from OS to OS, from Run-time to Run-time. */ // Do this operation Once and Only Once for the breadth of the candidate set of Generated Code. // Continue when Code Generation Consistency checks can be verified. // Otherwise, break, we know the set to be Inconsistent, i.e. re-Generation required. // If everything checked out, All Consistent, then we are Clear to Bypass Code Generation.
None
registry
OrToolsSatGeneratedSyntaxTreeRegistry
None
renderedCompilationUnits
IRenderedCompilationUnitDictionary
None