private bool CompileAssemblies(IEnumerable <UnityEditor.Compilation.Assembly> assemblies, List <string> excludeTypes = null) { var compiler = new GhostCompiler(_generatedFileCache, _generateCacheFilename); compiler.Generate(assemblies, new GhostCompilerOptions { tempOutputFolderPath = _settings.tempOutputFolderPath, alwaysGenerateFiles = _settings.alwaysGenerateFiles, excludeTypes = excludeTypes != null ? new HashSet <string>(excludeTypes) : null }); if (compiler.buildErrors != 0) { return(false); } bool anyChanges = false; try { var sync = new GhostCompilerFolderSync(_generatedFileCache, new SyncOptions { sourceFolder = _settings.tempOutputFolderPath, destFolder = _settings.outputFolder }); anyChanges = sync.SyncFolders(); changedAssemblies.Clear(); changesFlags = ChangesFlags.None; } catch (Exception e) { Debug.LogException(e); } if (anyChanges) { // This will trigger another compilation, we ignore marking assembly csharp dirty during that // compilation since the changes are most likely just caused by generated code // This prevents the next domain reload from triggering code gen - since no assemblies changed ignoreAssemblyCSharpNextCompilation = true; AssetDatabase.Refresh(); } return(anyChanges); }
private void OnUpdate() { if (_codegenTemplatesAssemblies.Length == 0) { RetrieveTemplatesFoldersAndRegisterWatcher(); } if (_loadCustomOverrides) { LoadCustomGhostSnapshotValueTypes(); } if (foldersToDelete.Count != 0) { foreach (var f in foldersToDelete) { GhostCompilerServiceUtils.DebugLog( $"Deleting generated folder {f}. Error in code generated files"); if (!AssetDatabase.DeleteAsset(f)) { GhostCompilerServiceUtils.DeleteFileOrDirectory(f); } } foldersToDelete.Clear(); AssetDatabase.Refresh(); } if (System.Threading.Interlocked.Exchange(ref _templateChangeCount, 0) != 0) { //If either a recompilation is in progress or if we already scheduled a delay regeneration don't do it again //Also avoid scheduling something while transitioning in between modes if (_settings.autoRecompile && changesFlags == ChangesFlags.None && !EditorApplication.isCompiling) { System.Threading.Interlocked.Increment(ref _regenerateChangeCount); } changesFlags |= ChangesFlags.TemplatesChanged; } if (System.Threading.Interlocked.Exchange(ref _regenerateChangeCount, 0) != 0) { RegenerateAllChanges(); } }
private void OnAssemblyCompilationFinished(string assemblyName, CompilerMessage[] messages) { //Don't track those. They are going to be regenerated because their "parent" did if (assemblyName.Contains(".Generated")) { return; } if (messages != null && messages.Any(msg => msg.type == CompilerMessageType.Error)) { //Don't mark the assembly has changed yet but Assembly-CSharp need special treatment if (Path.GetFileName(assemblyName).StartsWith("Assembly-CSharp")) { var generatedAssemblyCSharpFiles = Path.Combine(_settings.outputFolder, "Assembly-CSharp.Generated"); if (!Directory.Exists(generatedAssemblyCSharpFiles)) { return; } //Special case for Assembly-CSharp and Assembly-CSharp-Editor //If there are errors in some code-generated files, delete the generated folder if (messages.Any(msg => msg.type == CompilerMessageType.Error && msg.file.Contains(generatedAssemblyCSharpFiles))) { foldersToDelete.Add(generatedAssemblyCSharpFiles); } } return; } if (ignoreAssemblyCSharpNextCompilation && Path.GetFileName(assemblyName).StartsWith("Assembly-CSharp")) { GhostCompilerServiceUtils.DebugLog($"Assembly {assemblyName} changes ignored"); return; } //Mark the assembly as changed if it is not a ."Generated" one GhostCompilerServiceUtils.DebugLog($"Assembly {assemblyName} added to the changelist"); changesFlags |= ChangesFlags.AssembliesChanged; changedAssemblies.Add(Path.GetFileNameWithoutExtension(assemblyName)); }