public virtual void AfterCompile(AfterCompileContext context) { Console.WriteLine("*** Running PostSharp on {0}", context.Compilation.AssemblyName); try { if ( context.Diagnostics == null ) { context.Diagnostics = new List<Diagnostic>(); } // Do not execute our module if the compilation failed. if (context.Diagnostics.Any(d => d.Severity == DiagnosticSeverity.Error)) { return; } Stopwatch stopwatch = Stopwatch.StartNew(); // Copy dll and pdb streams to a temp directory. string inputAssemblyPath = Path.Combine(_inputDirectory, context.ProjectContext.Name + ".dll"); string outputAssemblyPath = Path.Combine(_outputDirectory, context.ProjectContext.Name + ".dll"); string inputSymbolPath; string outputSymbolPath; List<Task> tasks = new List<Task>(); try { tasks.Add(Task.Run(() => { using (FileStream assemblyStream = File.Create(inputAssemblyPath)) { context.AssemblyStream.Seek(0, SeekOrigin.Begin); context.AssemblyStream.CopyTo(assemblyStream); } })); if (context.SymbolStream != null) { inputSymbolPath = Path.Combine(_inputDirectory, context.ProjectContext.Name + ".pdb"); outputSymbolPath = Path.Combine(_outputDirectory, context.ProjectContext.Name + ".pdb"); tasks.Add(Task.Run(() => { using (FileStream symbolStream = File.Create(inputSymbolPath)) { context.SymbolStream.Seek(0, SeekOrigin.Begin); context.SymbolStream.CopyTo(symbolStream); } })); } else { inputSymbolPath = null; outputSymbolPath = null; } // Configure PostSharp build client. this.BuildClient.InputAssembly = inputAssemblyPath; this.BuildClient.Projects = new[] { "default" }; this.BuildClient.Properties["Configuration"] = context.ProjectContext.Configuration; this.BuildClient.Properties["DnxProjectFullPath"] = context.ProjectContext.ProjectFilePath; this.BuildClient.Properties["Platform"] = context.ProjectContext.TargetFramework.FullName; this.BuildClient.Properties["Output"] = outputAssemblyPath; this.BuildClient.Properties["ReferenceDirectory"] = context.ProjectContext.ProjectDirectory; this.BuildClient.Properties["Language"] = "C#"; this.BuildClient.TargetPlatform = IntPtr.Size == 8 ? "4.0-x64" : "4.0-x86"; this.BuildClient.Host = HostKind.PipeServer; string postsharpDllPath = null; // Resolving dependencies. StringBuilder referenceBuilder = new StringBuilder(); foreach (MetadataReference reference in context.Compilation.References) { if (referenceBuilder.Length > 0) { referenceBuilder.Append(";"); } PortableExecutableReference portableExecutableReference; if ( (portableExecutableReference = reference as PortableExecutableReference ) != null) { if (portableExecutableReference.FilePath != null) { // We have a reference to a file on disk. referenceBuilder.Append(portableExecutableReference.FilePath); if (string.Equals(Path.GetFileName(portableExecutableReference.FilePath), "PostSharp.dll", StringComparison.OrdinalIgnoreCase)) { postsharpDllPath = portableExecutableReference.FilePath; } continue; } } context.Diagnostics.Add(Diagnostic.Create(Diagnostics.UnsupportedReference, null, reference.Display, reference.GetType().Name)); } // If we didn't find PostSharp.dll, we fail because we don't know where to find the compiler. if (postsharpDllPath == null) { context.Diagnostics.Add(Diagnostic.Create(Diagnostics.CannotFindPostSharpDll, null)); return; } FileVersionInfo postsharpVersion = FileVersionInfo.GetVersionInfo(postsharpDllPath); FileVersionInfo expectedVersion = FileVersionInfo.GetVersionInfo(typeof(BuildClient).Assembly.Location); if (postsharpVersion.FileVersion != expectedVersion.FileVersion ) { context.Diagnostics.Add(Diagnostic.Create(Diagnostics.PostSharpDllVersionMismatch, null, postsharpDllPath, postsharpVersion.FileVersion, expectedVersion.FileVersion)); return; } this.BuildClient.ArchiveFile = Path.GetFullPath( Path.Combine(Path.GetDirectoryName(postsharpDllPath), "..\\..\\tools\\PostSharp-Tools.exe") ); this.BuildClient.Properties["ResolvedReferences"] = referenceBuilder.ToString(); Task.WaitAll(tasks.ToArray()); // Execute custom logic. this.BeforePostCompile(); if (!this.BuildClient.Execute(CancellationToken.None)) return; using (Stream outputAssemblyStream = File.OpenRead(outputAssemblyPath)) { context.AssemblyStream = new MemoryStream(); outputAssemblyStream.CopyTo(context.AssemblyStream); } if (outputSymbolPath != null) { context.SymbolStream = new MemoryStream(); using (Stream symbolAssemblyStream = File.OpenRead(outputSymbolPath)) { context.SymbolStream = new MemoryStream(); symbolAssemblyStream.CopyTo(context.AssemblyStream); } } } finally { foreach (Diagnostic diagnostic in this._logAdapter.Diagnostics) { context.Diagnostics.Add(diagnostic); } } } catch ( Exception e ) { context.Diagnostics.Add(Diagnostic.Create(Diagnostics.UnhandledException, null, e.GetType().Name, e.ToString())); } }
public Assembly Load(AssemblyName assemblyName, IAssemblyLoadContext loadContext) { using (var pdbStream = new MemoryStream()) using (var assemblyStream = new MemoryStream()) { var afterCompileContext = new AfterCompileContext { ProjectContext = CompilationContext.ProjectContext, Compilation = CompilationContext.Compilation, AssemblyStream = assemblyStream, SymbolStream = pdbStream }; EmitResult emitResult = null; // If assembly is not a satelite assembly or if assembly culture is neutral, then do not generate a resources assembly. if (!string.Equals(Path.GetExtension(assemblyName.Name), ".resources") || ResourcesHelper.IsResourceNeutralCulture(assemblyName)) { var resourcesForCulture = ResourcesForCulture.GetResourcesForCulture(assemblyName.CultureName ?? string.Empty, CompilationContext.Resources); if (resourcesForCulture == null) { // No resources is fine for a main assembly resourcesForCulture = Enumerable.Empty <ResourceDescriptor>(); } var resources = resourcesForCulture .Select(res => new ResourceDescription(res.Name, res.StreamFactory, isPublic: true)); Logger.TraceInformation("[{0}]: Emitting assembly for {1}", GetType().Name, Name); var sw = Stopwatch.StartNew(); bool emitPdb; var emitOptions = GetEmitOptions(out emitPdb); emitResult = CompilationContext.Compilation.Emit(assemblyStream, pdbStream: emitPdb ? pdbStream : null, manifestResources: resources, options: emitOptions); sw.Stop(); Logger.TraceInformation("[{0}]: Emitted {1} in {2}ms", GetType().Name, Name, sw.ElapsedMilliseconds); foreach (var m in CompilationContext.Modules) { m.AfterCompile(afterCompileContext); } } else { var resourcesForCulture = ResourcesForCulture.GetResourcesForCulture(assemblyName.CultureName ?? string.Empty, CompilationContext.Resources); if (resourcesForCulture == null) { return(null); } afterCompileContext.SymbolStream = null; emitResult = EmitResourceAssembly(assemblyName, resourcesForCulture, afterCompileContext.Compilation.Options, afterCompileContext.AssemblyStream); } afterCompileContext.Diagnostics = CompilationContext.Diagnostics.Concat(emitResult.Diagnostics).ToList(); if (!emitResult.Success || afterCompileContext.Diagnostics.Any(RoslynDiagnosticUtilities.IsError)) { throw new RoslynCompilationException(afterCompileContext.Diagnostics, CompilationContext.ProjectContext.TargetFramework); } Assembly assembly = null; // If this is null it'll fail anyways, just don't blow up with // a null reference if (afterCompileContext.AssemblyStream != null) { afterCompileContext.AssemblyStream.Position = 0; } if (afterCompileContext.SymbolStream == null || afterCompileContext.SymbolStream.Length == 0) { assembly = loadContext.LoadStream(afterCompileContext.AssemblyStream, assemblySymbols: null); } else { afterCompileContext.SymbolStream.Position = 0; assembly = loadContext.LoadStream(afterCompileContext.AssemblyStream, afterCompileContext.SymbolStream); } return(assembly); } }
public void AfterCompile(AfterCompileContext context) { }
public void AfterCompile(AfterCompileContext context) { Console.WriteLine("Hello After Compile"); }
public DiagnosticResult EmitAssembly(string outputPath) { var resources = Enumerable.Empty <ResourceDescription>(); var diagnosticsResult = EmitResources(outputPath, out resources); if (diagnosticsResult != null) { return(diagnosticsResult); } var assemblyPath = Path.Combine(outputPath, Name + ".dll"); var pdbPath = Path.Combine(outputPath, Name + ".pdb"); var xmlDocPath = Path.Combine(outputPath, Name + ".xml"); // REVIEW: Memory bloat? using (var xmlDocStream = new MemoryStream()) using (var pdbStream = new MemoryStream()) using (var assemblyStream = new MemoryStream()) using (var win32resStream = CompilationContext.Compilation.CreateDefaultWin32Resources( versionResource: true, noManifest: false, manifestContents: null, iconInIcoFormat: null)) { // The default win32resStream extracted from compilation represents a Win32 applicaiton manifest. // It enables the assmebly information to be viewed in Windows Explorer. Logger.TraceInformation("[{0}]: Emitting assembly for {1}", GetType().Name, Name); var sw = Stopwatch.StartNew(); bool emitPdb; var emitOptions = GetEmitOptions(out emitPdb).WithPdbFilePath(pdbPath); var emitResult = CompilationContext.Compilation.Emit( assemblyStream, pdbStream: emitPdb ? pdbStream : null, xmlDocumentationStream: xmlDocStream, win32Resources: win32resStream, manifestResources: resources, options: emitOptions); sw.Stop(); Logger.TraceInformation("[{0}]: Emitted {1} in {2}ms", GetType().Name, Name, sw.ElapsedMilliseconds); var diagnostics = CompilationContext.Diagnostics.Concat( emitResult.Diagnostics); var afterCompileContext = new AfterCompileContext { ProjectContext = CompilationContext.ProjectContext, Compilation = CompilationContext.Compilation, Diagnostics = new List <Diagnostic>(diagnostics), AssemblyStream = assemblyStream, SymbolStream = pdbStream, XmlDocStream = xmlDocStream }; foreach (var m in CompilationContext.Modules) { m.AfterCompile(afterCompileContext); } if (!emitResult.Success || afterCompileContext.Diagnostics.Any(RoslynDiagnosticUtilities.IsError)) { return(CreateDiagnosticResult(emitResult.Success, afterCompileContext.Diagnostics, CompilationContext.ProjectContext.TargetFramework)); } // Ensure there's an output directory Directory.CreateDirectory(outputPath); if (afterCompileContext.AssemblyStream != null) { afterCompileContext.AssemblyStream.Position = 0; using (var assemblyFileStream = File.Create(assemblyPath)) { afterCompileContext.AssemblyStream.CopyTo(assemblyFileStream); } } if (afterCompileContext.XmlDocStream != null) { afterCompileContext.XmlDocStream.Position = 0; using (var xmlDocFileStream = File.Create(xmlDocPath)) { afterCompileContext.XmlDocStream.CopyTo(xmlDocFileStream); } } if (afterCompileContext.SymbolStream != null && afterCompileContext.SymbolStream.Length > 0) { afterCompileContext.SymbolStream.Position = 0; using (var pdbFileStream = File.Create(pdbPath)) { afterCompileContext.SymbolStream.CopyTo(pdbFileStream); } } return(CreateDiagnosticResult(emitResult.Success, afterCompileContext.Diagnostics, CompilationContext.ProjectContext.TargetFramework)); } }
public Assembly Load(IAssemblyLoadContext loadContext) { using (var pdbStream = new MemoryStream()) using (var assemblyStream = new MemoryStream()) { IList <ResourceDescription> resources = CompilationContext.Resources; Logger.TraceInformation("[{0}]: Emitting assembly for {1}", GetType().Name, Name); var sw = Stopwatch.StartNew(); EmitResult emitResult = null; if (_supportsPdbGeneration.Value) { emitResult = CompilationContext.Compilation.Emit(assemblyStream, pdbStream: pdbStream, manifestResources: resources); } else { Logger.TraceWarning("PDB generation is not supported on this platform"); emitResult = CompilationContext.Compilation.Emit(assemblyStream, manifestResources: resources); } sw.Stop(); Logger.TraceInformation("[{0}]: Emitted {1} in {2}ms", GetType().Name, Name, sw.ElapsedMilliseconds); var diagnostics = CompilationContext.Diagnostics.Concat( emitResult.Diagnostics); var afterCompileContext = new AfterCompileContext { ProjectContext = CompilationContext.ProjectContext, Compilation = CompilationContext.Compilation, AssemblyStream = assemblyStream, SymbolStream = pdbStream, Diagnostics = new List <Diagnostic>(diagnostics) }; foreach (var m in CompilationContext.Modules) { m.AfterCompile(afterCompileContext); } if (!emitResult.Success || afterCompileContext.Diagnostics.Any(RoslynDiagnosticUtilities.IsError)) { throw new RoslynCompilationException(afterCompileContext.Diagnostics, CompilationContext.ProjectContext.TargetFramework); } Assembly assembly = null; // If this is null it'll fail anyways, just don't blow up with // a null reference if (afterCompileContext.AssemblyStream != null) { afterCompileContext.AssemblyStream.Position = 0; } if (afterCompileContext.SymbolStream == null || afterCompileContext.SymbolStream.Length == 0) { assembly = loadContext.LoadStream(afterCompileContext.AssemblyStream, assemblySymbols: null); } else { afterCompileContext.SymbolStream.Position = 0; assembly = loadContext.LoadStream(afterCompileContext.AssemblyStream, afterCompileContext.SymbolStream); } return(assembly); } }
public Assembly Load(AssemblyName assemblyName, IAssemblyLoadContext loadContext) { using (var pdbStream = new MemoryStream()) using (var assemblyStream = new MemoryStream()) { var afterCompileContext = new AfterCompileContext { ProjectContext = CompilationContext.ProjectContext, Compilation = CompilationContext.Compilation, AssemblyStream = assemblyStream, SymbolStream = pdbStream }; EmitResult emitResult = null; // If assembly is not a satelite assembly or if assembly culture is neutral, then do not generate a resources assembly. if (!string.Equals(Path.GetExtension(assemblyName.Name), ".resources") || ResourcesHelper.IsResourceNeutralCulture(assemblyName)) { var resourcesForCulture = ResourcesForCulture.GetResourcesForCulture(assemblyName.CultureName ?? string.Empty, CompilationContext.Resources); if (resourcesForCulture == null) { // No resources is fine for a main assembly resourcesForCulture = Enumerable.Empty<ResourceDescriptor>(); } var resources = resourcesForCulture .Select(res => new ResourceDescription(res.Name, res.StreamFactory, isPublic: true)); Logger.TraceInformation("[{0}]: Emitting assembly for {1}", GetType().Name, Name); var sw = Stopwatch.StartNew(); bool emitPdb; var emitOptions = GetEmitOptions(out emitPdb); emitResult = CompilationContext.Compilation.Emit(assemblyStream, pdbStream: emitPdb ? pdbStream : null, manifestResources: resources, options: emitOptions); sw.Stop(); Logger.TraceInformation("[{0}]: Emitted {1} in {2}ms", GetType().Name, Name, sw.ElapsedMilliseconds); foreach (var m in CompilationContext.Modules) { m.AfterCompile(afterCompileContext); } } else { var resourcesForCulture = ResourcesForCulture.GetResourcesForCulture(assemblyName.CultureName ?? string.Empty, CompilationContext.Resources); if (resourcesForCulture == null) { return null; } afterCompileContext.SymbolStream = null; emitResult = EmitResourceAssembly(assemblyName, resourcesForCulture, afterCompileContext.Compilation.Options, afterCompileContext.AssemblyStream); } afterCompileContext.Diagnostics = CompilationContext.Diagnostics.Concat(emitResult.Diagnostics).ToList(); if (!emitResult.Success || afterCompileContext.Diagnostics.Any(RoslynDiagnosticUtilities.IsError)) { throw new RoslynCompilationException(afterCompileContext.Diagnostics, CompilationContext.ProjectContext.TargetFramework); } Assembly assembly = null; // If this is null it'll fail anyways, just don't blow up with // a null reference if (afterCompileContext.AssemblyStream != null) { afterCompileContext.AssemblyStream.Position = 0; } if (afterCompileContext.SymbolStream == null || afterCompileContext.SymbolStream.Length == 0) { assembly = loadContext.LoadStream(afterCompileContext.AssemblyStream, assemblySymbols: null); } else { afterCompileContext.SymbolStream.Position = 0; assembly = loadContext.LoadStream(afterCompileContext.AssemblyStream, afterCompileContext.SymbolStream); } return assembly; } }
public DiagnosticResult EmitAssembly(string outputPath) { var resources = Enumerable.Empty<ResourceDescription>(); var diagnosticsResult = EmitResources(outputPath, out resources); if (diagnosticsResult != null) { return diagnosticsResult; } var assemblyPath = Path.Combine(outputPath, Name + ".dll"); var pdbPath = Path.Combine(outputPath, Name + ".pdb"); var xmlDocPath = Path.Combine(outputPath, Name + ".xml"); // REVIEW: Memory bloat? using (var xmlDocStream = new MemoryStream()) using (var pdbStream = new MemoryStream()) using (var assemblyStream = new MemoryStream()) using (var win32resStream = CompilationContext.Compilation.CreateDefaultWin32Resources( versionResource: true, noManifest: false, manifestContents: null, iconInIcoFormat: null)) { // The default win32resStream extracted from compilation represents a Win32 applicaiton manifest. // It enables the assmebly information to be viewed in Windows Explorer. Logger.TraceInformation("[{0}]: Emitting assembly for {1}", GetType().Name, Name); var sw = Stopwatch.StartNew(); bool emitPdb; var emitOptions = GetEmitOptions(out emitPdb).WithPdbFilePath(pdbPath); var emitResult = CompilationContext.Compilation.Emit( assemblyStream, pdbStream: emitPdb ? pdbStream : null, xmlDocumentationStream: xmlDocStream, win32Resources: win32resStream, manifestResources: resources, options: emitOptions); sw.Stop(); Logger.TraceInformation("[{0}]: Emitted {1} in {2}ms", GetType().Name, Name, sw.ElapsedMilliseconds); var diagnostics = CompilationContext.Diagnostics.Concat( emitResult.Diagnostics); var afterCompileContext = new AfterCompileContext { ProjectContext = CompilationContext.ProjectContext, Compilation = CompilationContext.Compilation, Diagnostics = new List<Diagnostic>(diagnostics), AssemblyStream = assemblyStream, SymbolStream = pdbStream, XmlDocStream = xmlDocStream }; foreach (var m in CompilationContext.Modules) { m.AfterCompile(afterCompileContext); } if (!emitResult.Success || afterCompileContext.Diagnostics.Any(RoslynDiagnosticUtilities.IsError)) { return CreateDiagnosticResult(emitResult.Success, afterCompileContext.Diagnostics, CompilationContext.ProjectContext.TargetFramework); } // Ensure there's an output directory Directory.CreateDirectory(outputPath); if (afterCompileContext.AssemblyStream != null) { afterCompileContext.AssemblyStream.Position = 0; using (var assemblyFileStream = File.Create(assemblyPath)) { afterCompileContext.AssemblyStream.CopyTo(assemblyFileStream); } } if (afterCompileContext.XmlDocStream != null) { afterCompileContext.XmlDocStream.Position = 0; using (var xmlDocFileStream = File.Create(xmlDocPath)) { afterCompileContext.XmlDocStream.CopyTo(xmlDocFileStream); } } if (afterCompileContext.SymbolStream != null && afterCompileContext.SymbolStream.Length > 0) { afterCompileContext.SymbolStream.Position = 0; using (var pdbFileStream = File.Create(pdbPath)) { afterCompileContext.SymbolStream.CopyTo(pdbFileStream); } } return CreateDiagnosticResult(emitResult.Success, afterCompileContext.Diagnostics, CompilationContext.ProjectContext.TargetFramework); } }
public Assembly Load(IAssemblyLoadContext loadContext) { using (var pdbStream = new MemoryStream()) using (var assemblyStream = new MemoryStream()) { IList<ResourceDescription> resources = CompilationContext.Resources; Logger.TraceInformation("[{0}]: Emitting assembly for {1}", GetType().Name, Name); var sw = Stopwatch.StartNew(); EmitResult emitResult = null; if (_supportsPdbGeneration.Value) { emitResult = CompilationContext.Compilation.Emit(assemblyStream, pdbStream: pdbStream, manifestResources: resources); } else { Logger.TraceWarning("PDB generation is not supported on this platform"); emitResult = CompilationContext.Compilation.Emit(assemblyStream, manifestResources: resources); } sw.Stop(); Logger.TraceInformation("[{0}]: Emitted {1} in {2}ms", GetType().Name, Name, sw.ElapsedMilliseconds); var diagnostics = CompilationContext.Diagnostics.Concat( emitResult.Diagnostics); var afterCompileContext = new AfterCompileContext { ProjectContext = CompilationContext.ProjectContext, Compilation = CompilationContext.Compilation, AssemblyStream = assemblyStream, SymbolStream = pdbStream, Diagnostics = new List<Diagnostic>(diagnostics) }; foreach (var m in CompilationContext.Modules) { m.AfterCompile(afterCompileContext); } if (!emitResult.Success || afterCompileContext.Diagnostics.Any(RoslynDiagnosticUtilities.IsError)) { throw new RoslynCompilationException(afterCompileContext.Diagnostics, CompilationContext.ProjectContext.TargetFramework); } Assembly assembly = null; // If this is null it'll fail anyways, just don't blow up with // a null reference if (afterCompileContext.AssemblyStream != null) { afterCompileContext.AssemblyStream.Position = 0; } if (afterCompileContext.SymbolStream == null || afterCompileContext.SymbolStream.Length == 0) { assembly = loadContext.LoadStream(afterCompileContext.AssemblyStream, assemblySymbols: null); } else { afterCompileContext.SymbolStream.Position = 0; assembly = loadContext.LoadStream(afterCompileContext.AssemblyStream, afterCompileContext.SymbolStream); } return assembly; } }
public void AfterCompile(AfterCompileContext context) { Console.WriteLine("Done CompileInjectorModule"); }