internal static void Internal_OnEvent(EventType type) { switch (type) { case EventType.CompileBegin: CompilationBegin?.Invoke(); break; case EventType.CompileStarted: CompilationStarted?.Invoke(); break; case EventType.CompileEndGood: CompilationEnd?.Invoke(true); CompilationSuccess?.Invoke(); break; case EventType.CompileEndFailed: CompilationEnd?.Invoke(false); CompilationFailed?.Invoke(); break; case EventType.ReloadCalled: ScriptsReloadCalled?.Invoke(); break; case EventType.ReloadBegin: ScriptsReloadBegin?.Invoke(); break; case EventType.ReloadEnd: ScriptsReloadEnd?.Invoke(); break; } }
private async Task recompileAsync(Type targetType, string changedFile) { if (targetType == null || isCompiling || referenceBuilder is EmptyTypeReferenceBuilder) { return; } isCompiling = true; try { while (!checkFileReady(changedFile)) { Thread.Sleep(10); } Logger.Log($@"Recompiling {Path.GetFileName(targetType.Name)}...", LoggingTarget.Runtime, LogLevel.Important); CompilationStarted?.Invoke(); foreach (string f in await referenceBuilder.GetReferencedFiles(targetType, changedFile).ConfigureAwait(false)) { requiredFiles.Add(f); } var assemblies = await referenceBuilder.GetReferencedAssemblies(targetType, changedFile).ConfigureAwait(false); using (var pdbStream = new MemoryStream()) using (var peStream = new MemoryStream()) { var compilationResult = createCompilation(targetType, requiredFiles, assemblies).Emit(peStream, pdbStream); if (compilationResult.Success) { peStream.Seek(0, SeekOrigin.Begin); pdbStream.Seek(0, SeekOrigin.Begin); CompilationFinished?.Invoke( Assembly.Load(peStream.ToArray(), pdbStream.ToArray()).GetModules()[0].GetTypes().LastOrDefault(t => t.FullName == targetType.FullName) ); } else { var exceptions = new List <Exception>(); foreach (var diagnostic in compilationResult.Diagnostics) { if (diagnostic.Severity < DiagnosticSeverity.Error) { continue; } exceptions.Add(new InvalidOperationException(diagnostic.ToString())); } throw new AggregateException(exceptions.ToArray()); } } } catch (Exception ex) { CompilationFailed?.Invoke(ex); } finally { isCompiling = false; } }
private void recompile() { if (assemblies == null) { assemblies = new HashSet <string>(); foreach (var ass in AppDomain.CurrentDomain.GetAssemblies().Where(a => !a.IsDynamic)) { assemblies.Add(ass.Location); } } assemblies.Add(typeof(JetBrains.Annotations.NotNullAttribute).Assembly.Location); var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary); // ReSharper disable once RedundantExplicitArrayCreation this doesn't compile when the array is empty var parseOptions = new CSharpParseOptions(preprocessorSymbols: new string[] { #if DEBUG "DEBUG", #endif #if TRACE "TRACE", #endif #if RELEASE "RELEASE", #endif }, languageVersion: LanguageVersion.CSharp7_3); var references = assemblies.Select(a => MetadataReference.CreateFromFile(a)); while (!checkFileReady(lastTouchedFile)) { Thread.Sleep(10); } Logger.Log($@"Recompiling {Path.GetFileName(checkpointObject.GetType().Name)}...", LoggingTarget.Runtime, LogLevel.Important); CompilationStarted?.Invoke(); // ensure we don't duplicate the dynamic suffix. string assemblyNamespace = checkpointObject.GetType().Assembly.GetName().Name.Replace(".Dynamic", ""); string assemblyVersion = $"{++currentVersion}.0.*"; string dynamicNamespace = $"{assemblyNamespace}.Dynamic"; var compilation = CSharpCompilation.Create( dynamicNamespace, requiredFiles.Select(file => CSharpSyntaxTree.ParseText(File.ReadAllText(file), parseOptions, file)) // Compile the assembly with a new version so that it replaces the existing one .Append(CSharpSyntaxTree.ParseText($"using System.Reflection; [assembly: AssemblyVersion(\"{assemblyVersion}\")]", parseOptions)) , references, options ); using (var ms = new MemoryStream()) { var compilationResult = compilation.Emit(ms); if (compilationResult.Success) { ms.Seek(0, SeekOrigin.Begin); CompilationFinished?.Invoke( Assembly.Load(ms.ToArray()).GetModules()[0].GetTypes().LastOrDefault(t => t.FullName == checkpointObject.GetType().FullName) ); } else { foreach (var diagnostic in compilationResult.Diagnostics) { if (diagnostic.Severity < DiagnosticSeverity.Error) { continue; } CompilationFailed?.Invoke(new Exception(diagnostic.ToString())); } } } }
private async Task recompileAsync(Type targetType, string changedFile) { if (targetType == null || isCompiling) { return; } isCompiling = true; try { while (!checkFileReady(changedFile)) { Thread.Sleep(10); } Logger.Log($@"Recompiling {Path.GetFileName(targetType.Name)}...", LoggingTarget.Runtime, LogLevel.Important); CompilationStarted?.Invoke(); var newRequiredFiles = await referenceBuilder.GetReferencedFiles(targetType, changedFile); foreach (var f in newRequiredFiles) { requiredFiles.Add(f); } var requiredAssemblies = await referenceBuilder.GetReferencedAssemblies(targetType, changedFile); var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary); // ReSharper disable once RedundantExplicitArrayCreation this doesn't compile when the array is empty var parseOptions = new CSharpParseOptions(preprocessorSymbols: new string[] { #if DEBUG "DEBUG", #endif #if TRACE "TRACE", #endif #if RELEASE "RELEASE", #endif }, languageVersion: LanguageVersion.Latest); var references = requiredAssemblies.Where(a => !string.IsNullOrEmpty(a)) .Select(a => MetadataReference.CreateFromFile(a)); // ensure we don't duplicate the dynamic suffix. string assemblyNamespace = targetType.Assembly.GetName().Name?.Replace(".Dynamic", ""); string assemblyVersion = $"{++currentVersion}.0.*"; string dynamicNamespace = $"{assemblyNamespace}.Dynamic"; var compilation = CSharpCompilation.Create( dynamicNamespace, requiredFiles.Select(file => CSharpSyntaxTree.ParseText(File.ReadAllText(file), parseOptions, file)) // Compile the assembly with a new version so that it replaces the existing one .Append(CSharpSyntaxTree.ParseText($"using System.Reflection; [assembly: AssemblyVersion(\"{assemblyVersion}\")]", parseOptions)), references, options ); using (var ms = new MemoryStream()) { var compilationResult = compilation.Emit(ms); if (compilationResult.Success) { ms.Seek(0, SeekOrigin.Begin); CompilationFinished?.Invoke( Assembly.Load(ms.ToArray()).GetModules()[0].GetTypes().LastOrDefault(t => t.FullName == targetType.FullName) ); } else { var exceptions = new List <Exception>(); foreach (var diagnostic in compilationResult.Diagnostics) { if (diagnostic.Severity < DiagnosticSeverity.Error) { continue; } exceptions.Add(new InvalidOperationException(diagnostic.ToString())); } throw new AggregateException(exceptions.ToArray()); } } } catch (Exception ex) { CompilationFailed?.Invoke(ex); } finally { isCompiling = false; } }
internal void TriggerCompilationStart(CSharpCompilation compilation) => CompilationStarted?.Invoke(this, compilation);