public CompilationContext(UnityEditor.Compilation.Assembly assembly, GeneratedFileGuidCache cache, Dictionary <string, GhostCodeGen> genCache)
 {
     assemblyName          = assembly.name;
     assemblyNameGenerated = AssemblyNameGenerated(assembly.name);
     compilerCache         = cache;
     generatedAssembly     = default;
     generatedBatch        = default;
     isRuntimeAssembly     = !assembly.flags.HasFlag(AssemblyFlags.EditorAssembly) &&
                             !assembly.compiledAssemblyReferences.Any(a => a.EndsWith("nunit.framework.dll"));
     codeGenCache = genCache;
 }
        //Return true if the assembly folder is changed
        public bool FlushBatch(CompilationContext context)
        {
            var assemblyFolder = Path.Combine(kOutputFolderPath, context.assemblyNameGenerated);
            var assemblyEntry  = new GeneratedFileGuidCache.AssemblyEntry {
                files = new Dictionary <string, Guid>()
            };

            //Generate all the assembly guids and file entries
            foreach (var op in context.generatedBatch.m_PendingOperations)
            {
                var newGuid = GhostCompilerServiceUtils.ComputeGuidHashFor(op.Item2);
                assemblyEntry.files.Add(Path.GetFileName(op.Item1), newGuid);
            }
            context.generatedAssembly = assemblyEntry;

            if (_alwaysRegenerateAllFiles)
            {
                FileUtil.DeleteFileOrDirectory(assemblyFolder);
            }

            if (!Directory.Exists(assemblyFolder))
            {
                Directory.CreateDirectory(assemblyFolder);
                foreach (var op in context.generatedBatch.m_PendingOperations)
                {
                    var path = op.Item1;
                    File.WriteAllText(path, op.Item2);
                }
                return(true);
            }

            //Check for any changes (files added or content changed) in library/temp directory first
            //and compute the new contents guid
            if (!context.compilerCache.assemblies.TryGetValue(context.assemblyNameGenerated, out var cachedAssemblyInfo))
            {
                cachedAssemblyInfo       = new GeneratedFileGuidCache.AssemblyEntry();
                cachedAssemblyInfo.files = new Dictionary <string, Guid>();
                context.compilerCache.assemblies.Add(context.assemblyNameGenerated, cachedAssemblyInfo);
            }

            bool FileGuidChanged(string filename)
            {
                return(!cachedAssemblyInfo.files.TryGetValue(filename, out var guid) || guid != assemblyEntry.files[filename]);
            }

            bool ShouldFlushOpPredicate(Tuple <string, string> op)
            {
                return(!File.Exists(op.Item1) || FileGuidChanged(Path.GetFileName(op.Item1)));
            }

            //check for any files that need to be removed
            var toRemove = cachedAssemblyInfo.files.Select(pair => pair.Key)
                           .Where(f => !assemblyEntry.files.ContainsKey(f)).ToArray();

            var anyRemoved = toRemove.Length > 0;

            foreach (var f in toRemove)
            {
                var filePath = Path.Combine(context.outputFolder, f);
                FileUtil.DeleteFileOrDirectory(filePath);
                cachedAssemblyInfo.files.Remove(f);
            }

            bool anyWritten = false;

            foreach (var op in context.generatedBatch.m_PendingOperations.Where(ShouldFlushOpPredicate))
            {
                File.WriteAllText(op.Item1, op.Item2);
                anyWritten = true;
            }
            ;

            return(anyWritten || anyRemoved);
        }