Beispiel #1
0
        public CompileTaskResult Compile(List <ClassDefinition> classDefinitions)
        {
            programAsset.compileErrors.Clear();

            Microsoft.CodeAnalysis.SyntaxTree tree = CSharpSyntaxTree.ParseText(sourceCode);

            CompileTaskResult result = new CompileTaskResult();

            result.programAsset = programAsset;

            int errorCount = 0;

            foreach (Diagnostic diagnostic in tree.GetDiagnostics())
            {
                if (diagnostic.Severity == DiagnosticSeverity.Error)
                {
                    errorCount++;

                    LinePosition linePosition = diagnostic.Location.GetLineSpan().StartLinePosition;

                    CompileError error = new CompileError();
                    error.script   = programAsset.sourceCsScript;
                    error.errorStr = $"error {diagnostic.Descriptor.Id}: {diagnostic.GetMessage()}";
                    error.lineIdx  = linePosition.Line;
                    error.charIdx  = linePosition.Character;

                    result.compileErrors.Add(error);
                }
            }

            if (errorCount > 0)
            {
                return(result);
            }

            moduleSymbols.OpenSymbolTable();

            UdonSharpFieldVisitor fieldVisitor = new UdonSharpFieldVisitor(fieldsWithInitializers);

            fieldVisitor.Visit(tree.GetRoot());

            MethodVisitor methodVisitor = new MethodVisitor(resolver, moduleSymbols, moduleLabels);

            methodVisitor.Visit(tree.GetRoot());

            ClassDebugInfo debugInfo = null;

            if (settings == null || settings.buildDebugInfo)
            {
                debugInfo = new ClassDebugInfo(sourceCode, settings == null || settings.includeInlineCode);
            }

            ASTVisitor visitor = new ASTVisitor(resolver, moduleSymbols, moduleLabels, methodVisitor.definedMethods, classDefinitions, debugInfo);

            try
            {
                visitor.Visit(tree.GetRoot());
                visitor.VerifyIntegrity();
            }
            catch (System.Exception e)
            {
                SyntaxNode currentNode = visitor.visitorContext.currentNode;

                string logMessage = "";

                if (currentNode != null)
                {
                    FileLinePositionSpan lineSpan = currentNode.GetLocation().GetLineSpan();

                    CompileError error = new CompileError();
                    error.script   = programAsset.sourceCsScript;
                    error.errorStr = $"{e.GetType()}: {e.Message}";
                    error.lineIdx  = lineSpan.StartLinePosition.Line;
                    error.charIdx  = lineSpan.StartLinePosition.Character;

                    result.compileErrors.Add(error);
                }
                else
                {
                    logMessage = e.ToString();
                    Debug.LogException(e);
                }
#if UDONSHARP_DEBUG
                Debug.LogException(e);
                Debug.LogError(e.StackTrace);
#endif

                programAsset.compileErrors.Add(logMessage);

                errorCount++;
            }

            if (errorCount > 0)
            {
                return(result);
            }

            moduleSymbols.CloseSymbolTable();

            if (errorCount == 0)
            {
                compiledClassDefinition = classDefinitions.Find(e => e.userClassType == visitor.visitorContext.behaviourUserType);

                string dataBlock = BuildHeapDataBlock();
                string codeBlock = visitor.GetCompiledUasm();

                result.compiledAssembly = dataBlock + codeBlock;
                result.symbolCount      = (uint)(moduleSymbols.GetAllUniqueChildSymbols().Count + visitor.GetExternStrCount());

                programAsset.behaviourIDHeapVarName = visitor.GetIDHeapVarName();

                programAsset.fieldDefinitions = visitor.visitorContext.localFieldDefinitions;

                if (debugInfo != null)
                {
                    debugInfo.FinalizeDebugInfo();
                }

                programAsset.debugInfo = debugInfo;
            }

            return(result);
        }