Example #1
0
        public CompilerOutput Compile()
        {
            var output = new CompilerOutput();

            var compilationUnit = IRBuilder.BuildCodeRepresentation(SourceCode, ExternalApi, out var compilationErrors);

            // ToDo: надо бы сделать какой то опциональный вывод лога со всеми данными из compilationUnit в этом месте
            // а еще лучше сделать какой-то визуализатор конечных нодов (особенно expression-ов), т.к. там дальше пойдет куча трасформаций и оптимизаций и без видения
            // графа очень сложно понять что происходит

            if (compilationUnit != null)
            {
                // Процесс генерации кода уже не должен валидировать исходный код (описываемый в структуре CompilationUnit)
                // Процесс генерации кода просто генерирует assembly код под target платформу (в данном случае это всегда udon assembly)
                // Все compile-time ошибки, которые могли быть должны быть обработаны ДО входа в этот метод.
                // В этом случае весь код, кроме вызова этого метода можно будет переиспользовать для анализаторов языка. Например сделать language server для подсветки кода
                // в vs code. Можно потом оформить библиотеку для создания CompilationUnit объекта отдельно и использовать ее тут же, просто послее нее будет вызываться эта генерация asm кода
                var code = (new CodeGenerator(compilationUnit, true)).GenerateCode();

                output.UdonAssemblyCode  = code.UdonAssemblyCode;
                output.DefaultHeapValues = code.DefaultHeapValues;

                return(output);
            }
            else
            {
                output.CompilationErrors = compilationErrors;
                return(output);
            }
        }
        private void UpdateDiagnostics(Uri documentUri, bool clear = false)
        {
            var diagnostics = new List <Diagnostic>();

            if (!clear)
            {
                var externalApi = _externalApiProvider.GetExternalApi();

                if (externalApi != null)
                {
                    var documentPath = documentUri.ToString();

                    IRBuilder.BuildCodeRepresentation(
                        _documentsSourceCode.GetDocumentSourceCode(documentPath).FullSourceCode,
                        externalApi,
                        out var compilationErrors
                        );

                    if (compilationErrors != null)
                    {
                        foreach (var compilationError in compilationErrors)
                        {
                            var diagnostic = new Diagnostic();

                            diagnostic.Severity = DiagnosticSeverity.Error;

                            diagnostic.Message = compilationError.Message;

                            diagnostic.Range = new OmniSharp.Extensions.LanguageServer.Protocol.Models.Range()
                            {
                                Start = new Position(compilationError.LineIdx, compilationError.CharInLineIdx),
                                End   = new Position(
                                    compilationError.LineIdxTo == null ? compilationError.LineIdx : compilationError.LineIdxTo.Value,
                                    compilationError.CharInLineIdxTo == null ? compilationError.CharInLineIdx : compilationError.CharInLineIdxTo.Value
                                    )
                            };

                            diagnostics.Add(diagnostic);
                        }
                    }
                }
                else
                {
                    var diagnostic = new Diagnostic();

                    diagnostic.Severity = DiagnosticSeverity.Error;

                    diagnostic.Message = "Doshik external Api cache was not found. Try to update doshik script from unity3d, that shoud rebuild cache";

                    diagnostic.Range = new OmniSharp.Extensions.LanguageServer.Protocol.Models.Range()
                    {
                        Start = new Position(0, 0),
                        End   = new Position(0, 0)
                    };

                    diagnostics.Add(diagnostic);
                }
            }

            _server.Document.PublishDiagnostics(new PublishDiagnosticsParams()
            {
                Uri = documentUri, Diagnostics = new Container <Diagnostic>(diagnostics)
            });
        }