Esempio n. 1
0
        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;
            }
        }
 public static void UpdateApplication([CanBeNull] Type[] updatedTypes) => CompilationFinished?.Invoke(updatedTypes);
Esempio n. 3
0
        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;
            }
        }