Example #1
0
        private static void TickCompile()
        {
            if (CurrentJob == null) return;
            
            if (!CurrentJob.Task.IsCompleted)
            {
                CompilationContext.CompilePhase currentPhase = CurrentJob.Context.CurrentPhase;
                float phaseProgress = CurrentJob.Context.PhaseProgress;

                float totalProgress = (phaseProgress / (int) CompilationContext.CompilePhase.Count) +
                                      ((int) currentPhase / (float)(int)CompilationContext.CompilePhase.Count);
                
                UdonSharpUtils.ShowAsyncProgressBar($"U#: {currentPhase}", totalProgress);
                return;
            }

            if (!CurrentJob.CompileOptions.DisableLogging)
            {
                foreach (var diagnostic in CurrentJob.Context.Diagnostics)
                {
                    string filePath = "";
                    if (diagnostic.Location != null)
                        filePath = CurrentJob.Context.TranslateLocationToFileName(diagnostic.Location);
                    LinePosition? linePosition = diagnostic.Location?.GetLineSpan().StartLinePosition;

                    int line = (linePosition?.Line ?? 0) + 1;
                    int character = (linePosition?.Character ?? 0) + 1;

                    string fileStr = $"{filePath ?? "Unknown File"}({line},{character})";

                    string logStr = $"{fileStr}: {diagnostic.Message}";

                    switch (diagnostic.Severity)
                    {
                        case DiagnosticSeverity.Error:
                            UdonSharpUtils.LogBuildError(diagnostic.Message, filePath, line, character);
                            break;
                        case DiagnosticSeverity.Warning:
                            UdonSharpUtils.LogWarning(logStr);
                            break;
                        case DiagnosticSeverity.Log:
                            UdonSharpUtils.Log(logStr);
                            break;
                    }
                }
            }
            
            // Translate the diagnostic types and apply them to the cache, todo: consider merging the two structures
            UdonSharpEditorCache.CompileDiagnostic[] diagnostics = new UdonSharpEditorCache.CompileDiagnostic[CurrentJob.Context.Diagnostics.Count];
            CompilationContext.CompileDiagnostic[] compileDiagnostics = CurrentJob.Context.Diagnostics.ToArray();

            for (int i = 0; i < diagnostics.Length; ++i)
            {
                LinePosition diagLine = compileDiagnostics[i]?.Location?.GetLineSpan().StartLinePosition ?? LinePosition.Zero;
                
                diagnostics[i] = new UdonSharpEditorCache.CompileDiagnostic()
                {
                    severity = compileDiagnostics[i].Severity,
                    message = compileDiagnostics[i].Message,
                    file = CurrentJob.Context.TranslateLocationToFileName(compileDiagnostics[i].Location) ?? "",
                    line = diagLine.Line,
                    character = diagLine.Character,
                };
            }

            UdonSharpEditorCache.Instance.LastCompileDiagnostics = diagnostics;
            
            if (CurrentJob.Task.IsFaulted)
            {
                UdonSharpUtils.LogError("internal compiler error, dumping exceptions. Please report to Merlin");

                if (CurrentJob.Task.Exception != null)
                {
                    foreach (Exception innerException in CurrentJob.Task.Exception.InnerExceptions)
                    {
                        UdonSharpUtils.LogError(innerException);
                    }
                }

                CleanupCompile();
                return;
            }

            if (CurrentJob.Context.ErrorCount > 0)
            {
                CleanupCompile();
                return;
            }
                
            foreach (ModuleBinding rootBinding in CurrentJob.Context.ModuleBindings)
            {
                if (rootBinding.programAsset == null) 
                    continue;
                
                rootBinding.programAsset.ApplyProgram();
                
                UdonSharpEditorCache.Instance.SetUASMStr(rootBinding.programAsset, rootBinding.assembly);
                
                rootBinding.programAsset.CompiledVersion = UdonSharpProgramVersion.CurrentVersion;
                EditorUtility.SetDirty(rootBinding.programAsset);
            }
            
            try
            {
                UdonSharpEditorCache.Instance.RehashAllScripts();
                UdonSharpEditorManager.RunPostBuildSceneFixup();
            }
            catch (Exception e)
            {
                UdonSharpUtils.LogError($"Exception while running post build fixup:\n{e}");
                CleanupCompile();
                return;
            }

            UdonSharpEditorCache.Instance.LastBuildType = CurrentJob.CompileOptions.IsEditorBuild
                ? UdonSharpEditorCache.DebugInfoType.Editor
                : UdonSharpEditorCache.DebugInfoType.Client;
            
            int scriptCount = CurrentJob.Context.ModuleBindings.Count(e => e.programAsset != null);
            UdonSharpUtils.Log($"Compile of {scriptCount} script{(scriptCount != 1 ? "s" : "")} finished in {CurrentJob.CompileTimer.Elapsed:mm\\:ss\\.fff}");
            
            CleanupCompile();

            if (_compileQueued)
            {
                Compile(_queuedOptions);
                _compileQueued = false;
                _queuedOptions = null;
            }
        }