public int Compile(List <ClassDefinition> classDefinitions) { if (programAsset.sourceCsScript == null) { throw new System.ArgumentException($"Asset '{AssetDatabase.GetAssetPath(programAsset)}' does not have a valid program source to compile from"); } Profiler.BeginSample("Compile Module"); programAsset.compileErrors.Clear(); sourceCode = File.ReadAllText(AssetDatabase.GetAssetPath(programAsset.sourceCsScript)); Profiler.BeginSample("Parse AST"); SyntaxTree tree = CSharpSyntaxTree.ParseText(sourceCode); Profiler.EndSample(); int errorCount = 0; string errorString = ""; foreach (Diagnostic diagnostic in tree.GetDiagnostics()) { if (diagnostic.Severity == DiagnosticSeverity.Error) { errorCount++; LinePosition linePosition = diagnostic.Location.GetLineSpan().StartLinePosition; errorString = UdonSharpUtils.LogBuildError($"error {diagnostic.Descriptor.Id}: {diagnostic.GetMessage()}", AssetDatabase.GetAssetPath(programAsset.sourceCsScript).Replace("/", "\\"), linePosition.Line, linePosition.Character); programAsset.compileErrors.Add(errorString); } } if (errorCount > 0) { ErrorCount = errorCount; Profiler.EndSample(); return(errorCount); } Profiler.BeginSample("Visit"); UdonSharpFieldVisitor fieldVisitor = new UdonSharpFieldVisitor(fieldsWithInitializers); fieldVisitor.Visit(tree.GetRoot()); MethodVisitor methodVisitor = new MethodVisitor(resolver, moduleSymbols, moduleLabels); methodVisitor.Visit(tree.GetRoot()); UdonSharpSettings settings = UdonSharpSettings.GetSettings(); 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(); logMessage = UdonSharpUtils.LogBuildError($"{e.GetType()}: {e.Message}", AssetDatabase.GetAssetPath(programAsset.sourceCsScript).Replace("/", "\\"), lineSpan.StartLinePosition.Line, lineSpan.StartLinePosition.Character); } else { logMessage = e.ToString(); Debug.LogException(e); } programAsset.compileErrors.Add(logMessage); errorCount++; } Profiler.EndSample(); if (errorCount == 0) { Profiler.BeginSample("Build assembly"); string dataBlock = BuildHeapDataBlock(); string codeBlock = visitor.GetCompiledUasm(); programAsset.SetUdonAssembly(dataBlock + codeBlock); Profiler.EndSample(); Profiler.BeginSample("Assemble Program"); programAsset.AssembleCsProgram((uint)(moduleSymbols.GetAllUniqueChildSymbols().Count + visitor.GetExternStrCount())); Profiler.EndSample(); programAsset.behaviourIDHeapVarName = visitor.GetIDHeapVarName(); programAsset.fieldDefinitions = visitor.visitorContext.localFieldDefinitions; if (debugInfo != null) { debugInfo.FinalizeDebugInfo(); } programAsset.debugInfo = debugInfo; } Profiler.EndSample(); return(errorCount); }
public CompileTaskResult Compile(List <ClassDefinition> classDefinitions) { programAsset.compileErrors.Clear(); 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); }