private AssemblyReference LoadAssembly(string name, CSharpCompilation compilation) { using (var codeStream = new MemoryStream()) { #if DEBUG using (var symbolStream = new MemoryStream()) { var compilationResult = compilation.Emit(codeStream, symbolStream); string pdbFile = Path.Combine(Utilities.AssemblyPath, $"{name}.pdb"); if (File.Exists(pdbFile)) { File.Delete(pdbFile); } File.WriteAllBytes(pdbFile, symbolStream.ToArray()); #else { var compilationResult = compilation.Emit(codeStream); #endif if (compilationResult.Success) { codeStream.Seek(0, SeekOrigin.Begin); CollectableAssemblyContext assemblyContext = new CollectableAssemblyContext(); AssemblyReference assembly = assemblyContext.LoadFromStream(codeStream); return(assembly); } else { Logging.LogError(LogType.Bot, "Failed to compile script"); foreach (var error in compilationResult.Diagnostics) { Logging.LogError(LogType.Bot, "{0}", error.ToString()); } } } } return(null); }
public bool TryCompile(string script, CompilerOptions compilerOptions, out AssemblyReference assembly) { assembly = null; try { Logging.Log(LogType.Bot, LogLevel.Info, $"Attempting to compile script {script}"); if (m_cache.IsCached(script)) { Logging.Log(LogType.Bot, LogLevel.Info, $"Found cached script fetching assembly"); assembly = m_cache.GetCachedAssembly(script); return(true); } if (!File.Exists(script)) { Logging.Log(LogType.Bot, LogLevel.Error, $"Failed to find script {script} aborting compilation"); return(false); } string scriptName = Path.GetFileNameWithoutExtension(script); bool success = false; IEnumerable <PortableExecutableReference> references = null; success = Utilities.TryCatch(() => references = compilerOptions.Assemblies.Select(asm => FindAndCreateReference(asm, compilerOptions)).Where(result => result != null), "Failed to create meta data from assembly"); if (!success) { return(false); } SyntaxTree[] syntax = null; Utilities.TryCatch(() => syntax = new SyntaxTree[] { ParseSyntax(script) }, $"Failed to parse syntax of script {script}"); if (!success) { return(false); } CSharpCompilation compilation = CSharpCompilation.Create(scriptName, syntax, references, compilerOptions.Options); AssemblyReference compiledAssembly = LoadAssembly(scriptName, compilation); assembly = compiledAssembly; if (compiledAssembly.IsLoaded) { Logging.LogInfo(LogType.Bot, $"Compilation of script {script} successful."); Logging.LogInfo(LogType.Bot, $"Attempting to load reference Assemblies."); if (TryLoadingReferences(references)) { Logging.LogInfo(LogType.Bot, $"Compilation of script {script} successful."); m_cache.CacheAssembly(script, compiledAssembly); return(true); } else { Logging.LogError(LogType.Bot, $"Script {script} has a reference library that was not loaded. Unloading script assembly."); compiledAssembly.Unload(); } } } catch (Exception ex) { Logging.LogException(LogType.Bot, ex, "Failed to compiled script"); } return(false); }
public bool TryCompile(string script, out AssemblyReference assembly) { return(TryCompile(script, CompilerOptions.Default, out assembly)); }