private List <ClassDefinition> BuildClassDefinitions() { string[] udonSharpDataAssets = AssetDatabase.FindAssets($"t:{typeof(UdonSharpProgramAsset).Name}"); List <UdonSharpProgramAsset> udonSharpPrograms = new List <UdonSharpProgramAsset>(); foreach (string dataGuid in udonSharpDataAssets) { udonSharpPrograms.Add(AssetDatabase.LoadAssetAtPath <UdonSharpProgramAsset>(AssetDatabase.GUIDToAssetPath(dataGuid))); } List <ClassDefinition> classDefinitions = new List <ClassDefinition>(); foreach (UdonSharpProgramAsset udonSharpProgram in udonSharpPrograms) { if (udonSharpProgram.sourceCsScript == null) { continue; } string sourcePath = AssetDatabase.GetAssetPath(udonSharpProgram.sourceCsScript); string programSource = UdonSharpUtils.ReadFileTextSync(sourcePath); ResolverContext resolver = new ResolverContext(); SymbolTable classSymbols = new SymbolTable(resolver, null); classSymbols.OpenSymbolTable(); LabelTable classLabels = new LabelTable(); SyntaxTree tree = CSharpSyntaxTree.ParseText(programSource); ClassVisitor classVisitor = new ClassVisitor(resolver, classSymbols, classLabels); try { classVisitor.Visit(tree.GetRoot()); } catch (System.Exception e) { UdonSharpUtils.LogBuildError($"{e.GetType()}: {e.Message}", sourcePath.Replace("/", "\\"), 0, 0); return(null); } classSymbols.CloseSymbolTable(); classVisitor.classDefinition.classScript = udonSharpProgram.sourceCsScript; classDefinitions.Add(classVisitor.classDefinition); } return(classDefinitions); }
private static string HashSourceFile(MonoScript script) { string scriptPath = AssetDatabase.GetAssetPath(script); string scriptText = ""; try { scriptText = UdonSharpUtils.ReadFileTextSync(scriptPath); } catch (System.Exception e) { scriptText = Random.value.ToString(); Debug.Log(e); } return(UdonSharpUtils.HashString(scriptText)); }
public CompilationModule(UdonSharpProgramAsset sourceAsset) { programAsset = sourceAsset; resolver = new ResolverContext(); moduleSymbols = new SymbolTable(resolver, null); moduleLabels = new LabelTable(); fieldsWithInitializers = new HashSet <FieldDeclarationSyntax>(); if (programAsset.sourceCsScript == null) { throw new System.ArgumentException($"Asset '{AssetDatabase.GetAssetPath(programAsset)}' does not have a valid program source to compile from"); } sourceCode = UdonSharpUtils.ReadFileTextSync(AssetDatabase.GetAssetPath(programAsset.sourceCsScript)); settings = UdonSharpSettings.GetSettings(); }
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 = UdonSharpUtils.ReadFileTextSync(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) { compiledClassDefinition = classDefinitions.Find(e => e.userClassType == visitor.visitorContext.behaviourUserType); 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); }