public CompilationContext(CSharpCompilation compilation, CompilationProjectContext compilationContext, IEnumerable<IMetadataReference> incomingReferences, Func<IList<ResourceDescriptor>> resourcesResolver) { Project = compilationContext; Modules = new List<ICompileModule>(); _resourcesResolver = resourcesResolver; var projectContext = new ProjectContext { Name = compilationContext.Target.Name, ProjectDirectory = compilationContext.ProjectDirectory, ProjectFilePath = compilationContext.ProjectFilePath, TargetFramework = compilationContext.Target.TargetFramework, Version = compilationContext.Version?.ToString(), Configuration = compilationContext.Target.Configuration }; _beforeCompileContext = new BeforeCompileContext( compilation, projectContext, ResolveResources, () => new List<Diagnostic>(), () => new List<IMetadataReference>(incomingReferences) ); }
public CompilationContext(CSharpCompilation compilation, CompilationProjectContext compilationContext, IEnumerable <IMetadataReference> incomingReferences, Func <IList <ResourceDescription> > resourcesResolver) { Project = compilationContext; Modules = new List <ICompileModule>(); _resourcesResolver = resourcesResolver; var projectContext = new ProjectContext { Name = compilationContext.Target.Name, ProjectDirectory = compilationContext.ProjectDirectory, ProjectFilePath = compilationContext.ProjectFilePath, TargetFramework = compilationContext.Target.TargetFramework, Version = compilationContext.Version?.ToString(), Configuration = compilationContext.Target.Configuration }; _beforeCompileContext = new BeforeCompileContext { Compilation = compilation, ProjectContext = projectContext, Resources = new LazyList <ResourceDescription>(ResolveResources), Diagnostics = new List <Diagnostic>(), MetadataReferences = new List <IMetadataReference>(incomingReferences) }; }
public IMetadataProjectReference CompileProject( CompilationProjectContext projectContext, Func <LibraryExport> referenceResolver, Func <IList <ResourceDescriptor> > resourcesResolver) { var export = referenceResolver(); if (export == null) { return(null); } var incomingReferences = export.MetadataReferences; var incomingSourceReferences = export.SourceReferences; var compliationContext = _compiler.CompileProject( projectContext, incomingReferences, incomingSourceReferences, resourcesResolver); if (compliationContext == null) { return(null); } // Project reference return(new RoslynProjectReference(compliationContext)); }
public IMetadataProjectReference CompileProject( CompilationProjectContext projectContext, Func<LibraryExport> referenceResolver, Func<IList<ResourceDescriptor>> resourcesResolver) { var export = referenceResolver(); if (export == null) { return null; } var incomingReferences = export.MetadataReferences; var incomingSourceReferences = export.SourceReferences; var compliationContext = _compiler.CompileProject( projectContext, incomingReferences, incomingSourceReferences, resourcesResolver); if (compliationContext == null) { return null; } // Project reference return new RoslynProjectReference(compliationContext); }
public void FlowsProjectPropertiesIntoAssembly() { const string testName = "Test name"; const string testTitle = "Test title"; const string testDescription = "Test description"; const string testCopyright = "Test copyright"; const string testAssemblyFileVersion = "1.2.3.4"; const string testVersion = "1.2.3-rc1"; const string testFrameworkName = "DNX,Version=v4.5.1"; // Arrange var compilationProjectContext = new CompilationProjectContext( new CompilationTarget(testName, new FrameworkName(testFrameworkName), string.Empty, string.Empty), string.Empty, string.Empty, testTitle, testDescription, testCopyright, testVersion, new Version(testAssemblyFileVersion), false, new CompilationFiles( new List<string> { }, new List<string> { }), new Mock<ICompilerOptions>().Object); var compiler = new RoslynCompiler( new Mock<ICache>().Object, new Mock<ICacheContextAccessor>().Object, new Mock<INamedCacheDependencyProvider>().Object, new Mock<IAssemblyLoadContext>().Object, new Mock<IApplicationEnvironment>().Object, new Mock<IServiceProvider>().Object); var metadataReference = new Mock<IRoslynMetadataReference>(); metadataReference .Setup(reference => reference.MetadataReference) .Returns(MetadataReference.CreateFromFile(typeof(object).Assembly.Location)); // Act var compilationContext = compiler.CompileProject( compilationProjectContext, new List<IMetadataReference> { metadataReference.Object }, new List<ISourceReference> { }, () => new List<ResourceDescriptor> { }); // Assert var expectedAttributes = new Dictionary<string, string> { [typeof(AssemblyTitleAttribute).FullName] = testTitle, [typeof(AssemblyDescriptionAttribute).FullName] = testDescription, [typeof(AssemblyCopyrightAttribute).FullName] = testCopyright, [typeof(AssemblyFileVersionAttribute).FullName] = testAssemblyFileVersion, [typeof(AssemblyVersionAttribute).FullName] = testVersion.Substring(0, testVersion.IndexOf('-')), [typeof(AssemblyInformationalVersionAttribute).FullName] = testVersion, }; var compilationAttributes = compilationContext.Compilation.Assembly.GetAttributes(); Assert.All(compilationAttributes, compilationAttribute => expectedAttributes[compilationAttribute.AttributeClass.ToString()].Equals( compilationAttribute.ConstructorArguments.First().Value)); }
public IMetadataProjectReference CompileProject( CompilationProjectContext projectContext, Func <LibraryExport> referenceResolver, Func <IList <ResourceDescriptor> > resourcesResolver) { List <DiagnosticResult> diagnosticResults = new List <DiagnosticResult>(); var module = new PostSharpCompilerModule(_services, _workingDirectory); var export = referenceResolver(); if (export == null) { return(null); } var incomingReferences = export.MetadataReferences; var incomingSourceReferences = export.SourceReferences; var processedIncomingReferences = new List <IMetadataReference>(incomingReferences.Count); foreach (var reference in incomingReferences) { var projectReference = reference as IMetadataProjectReference; if (projectReference != null) { // If we have a PostSharpProjectReference, we have to compile it using EmitAssembly and replace the reference by a MetadataFileReference. string referencePath = Path.Combine(_workingDirectory, projectReference.Name + ".dll"); if (!File.Exists(referencePath)) { DiagnosticResult diagnostics = projectReference.EmitAssembly(_workingDirectory); diagnosticResults.Add(diagnostics); } processedIncomingReferences.Add(new MetadataFileReference(projectReference.Name, referencePath)); } else { processedIncomingReferences.Add(reference); } } var compilationContext = _compiler.CompileProject( projectContext, processedIncomingReferences, incomingSourceReferences, resourcesResolver); if (compilationContext == null) { return(null); } compilationContext.Modules.Add(module); // Project reference return(new PostSharpProjectReference(new RoslynProjectReference(compilationContext), diagnosticResults, _workingDirectory)); }
public IMetadataProjectReference CompileProject( CompilationProjectContext projectContext, Func <LibraryExport> referenceResolver, Func <IList <ResourceDescriptor> > resourcesResolver) { // The target framework and configuration are assumed to be correct // in the design time process var task = _compiler.Compile(projectContext.ProjectDirectory, projectContext.Target); return(new DesignTimeProjectReference(projectContext, task.Result)); }
public IMetadataProjectReference CompileProject( CompilationProjectContext projectContext, Func<LibraryExport> referenceResolver, Func<IList<ResourceDescriptor>> resourcesResolver) { // The target framework and configuration are assumed to be correct // in the design time process var task = _compiler.Compile(projectContext.ProjectDirectory, projectContext.Target); return new DesignTimeProjectReference(projectContext, task.Result); }
private static void PrepareCompilation(ICompilerOptions compilerOptions, out RoslynCompiler compiler, out CompilationProjectContext projectContext) { var cacheContextAccessor = new FakeCacheContextAccessor { Current = new CacheContext(null, (d) => { }) }; compiler = new RoslynCompiler(null, cacheContextAccessor, new FakeNamedDependencyProvider(), null, null, null); var compilationTarget = new CompilationTarget("test", new FrameworkName(".NET Framework, Version=4.0"), "Release", null); projectContext = new CompilationProjectContext( compilationTarget, Directory.GetCurrentDirectory(), "project.json", "title", "description", "copyright", "1.0.0", new System.Version(1, 0), false, new CompilationFiles(Enumerable.Empty<string>(), Enumerable.Empty<string>()), compilerOptions); }
private static void PrepareCompilation(ICompilerOptions compilerOptions, out RoslynCompiler compiler, out CompilationProjectContext projectContext) { var cacheContextAccessor = new FakeCacheContextAccessor { Current = new CacheContext(null, (d) => { }) }; compiler = new RoslynCompiler(null, cacheContextAccessor, new FakeNamedDependencyProvider(), null, null, null); var compilationTarget = new CompilationTarget("test", new FrameworkName(".NET Framework, Version=4.0"), "Release", null); projectContext = new CompilationProjectContext( compilationTarget, Directory.GetCurrentDirectory(), "project.json", "title", "description", "copyright", "1.0.0", new System.Version(1, 0), false, new CompilationFiles(Enumerable.Empty <string>(), Enumerable.Empty <string>()), compilerOptions); }
private IList <SyntaxTree> GetSyntaxTrees(CompilationProjectContext project, IEnumerable <string> sourceFiles, IEnumerable <ISourceReference> sourceReferences, CSharpParseOptions parseOptions, bool isMainAspect) { var trees = new List <SyntaxTree>(); var dirs = new HashSet <string>(); if (isMainAspect) { dirs.Add(project.ProjectDirectory); } foreach (var sourcePath in sourceFiles) { _watcher.WatchFile(sourcePath); var syntaxTree = CreateSyntaxTree(sourcePath, parseOptions); trees.Add(syntaxTree); } foreach (var sourceFileReference in sourceReferences.OfType <ISourceFileReference>()) { var sourcePath = sourceFileReference.Path; _watcher.WatchFile(sourcePath); var syntaxTree = CreateSyntaxTree(sourcePath, parseOptions); trees.Add(syntaxTree); } // Watch all directories var ctx = _cacheContextAccessor.Current; foreach (var d in dirs) { ctx.Monitor(new FileWriteTimeCacheDependency(d)); // TODO: Make the file watcher hand out cache dependencies as well _watcher.WatchDirectory(d, ".cs"); } return(trees); }
internal CompilationContext( CompilationProjectContext project, FSharpProjectInfo projectInfo, bool success, IEnumerable <FSharpDiagnosticMessage> messages, byte[] assembly, byte[] pdb, byte[] xml) { _project = project; ProjectInfo = projectInfo; Success = success; Diagnostics = messages.ToList(); Assembly = assembly; Pdb = pdb; Xml = xml; }
private static CompilationContext Compile(FakeCompilerOptions compilerOptions, CompilationTarget target) { var cacheContextAccessor = new FakeCacheContextAccessor { Current = new CacheContext(null, (d) => { }) }; var compilationProjectContext = new CompilationProjectContext( target, Directory.GetCurrentDirectory(), "project.json", TestTitle, TestDescription, TestCopyright, TestVersion, Version.Parse(TestAssemblyFileVersion), false, new CompilationFiles( new List <string> { }, new List <string> { }), compilerOptions); var compiler = new RoslynCompiler(null, cacheContextAccessor, new FakeNamedDependencyProvider(), null, null, null); var assembly = typeof(object).GetTypeInfo().Assembly; var metadataReference = new FakeMetadataReference() { MetadataReference = MetadataReference.CreateFromFile((string)assembly.GetType().GetProperty("Location").GetValue(assembly)) }; var compilationContext = compiler.CompileProject( compilationProjectContext, new List <IMetadataReference> { metadataReference }, new List <ISourceReference> { }, () => new List <ResourceDescriptor>(), "Debug"); return(compilationContext); }
private static CompilationContext Compile(FakeCompilerOptions compilerOptions, CompilationTarget target) { var cacheContextAccessor = new FakeCacheContextAccessor {Current = new CacheContext(null, (d) => { })}; var compilationProjectContext = new CompilationProjectContext( target, Directory.GetCurrentDirectory(), "project.json", TestTitle, TestDescription, TestCopyright, TestVersion, Version.Parse(TestAssemblyFileVersion), false, new CompilationFiles( new List<string> {}, new List<string> {}), compilerOptions); var compiler = new RoslynCompiler(null, cacheContextAccessor, new FakeNamedDependencyProvider(), null, null, null); var assembly = typeof (object).GetTypeInfo().Assembly; var metadataReference = new FakeMetadataReference() { MetadataReference = MetadataReference.CreateFromFile((string)assembly.GetType().GetProperty("Location").GetValue(assembly)) }; var compilationContext = compiler.CompileProject( compilationProjectContext, new List<IMetadataReference> { metadataReference }, new List<ISourceReference> {}, () => new List<ResourceDescriptor>(), "Debug"); return compilationContext; }
public void FlowsProjectPropertiesIntoAssembly() { const string testName = "Test name"; const string testTitle = "Test title"; const string testDescription = "Test description"; const string testCopyright = "Test copyright"; const string testAssemblyFileVersion = "1.2.3.4"; const string testVersion = "1.2.3-rc1"; const string testFrameworkName = "DNX,Version=v4.5.1"; // Arrange var compilationProjectContext = new CompilationProjectContext( new CompilationTarget(testName, new FrameworkName(testFrameworkName), string.Empty, string.Empty), string.Empty, string.Empty, testTitle, testDescription, testCopyright, testVersion, new Version(testAssemblyFileVersion), false, new CompilationFiles( new List <string> { }, new List <string> { }), new Mock <ICompilerOptions>().Object); var compiler = new RoslynCompiler( new Mock <ICache>().Object, new Mock <ICacheContextAccessor>().Object, new Mock <INamedCacheDependencyProvider>().Object, new Mock <IAssemblyLoadContext>().Object, new Mock <IApplicationEnvironment>().Object, new Mock <IServiceProvider>().Object); var metadataReference = new Mock <IRoslynMetadataReference>(); metadataReference .Setup(reference => reference.MetadataReference) .Returns(MetadataReference.CreateFromFile(typeof(object).Assembly.Location)); // Act var compilationContext = compiler.CompileProject( compilationProjectContext, new List <IMetadataReference> { metadataReference.Object }, new List <ISourceReference> { }, () => new List <ResourceDescriptor> { }); // Assert var expectedAttributes = new Dictionary <string, string> { [typeof(AssemblyTitleAttribute).FullName] = testTitle, [typeof(AssemblyDescriptionAttribute).FullName] = testDescription, [typeof(AssemblyCopyrightAttribute).FullName] = testCopyright, [typeof(AssemblyFileVersionAttribute).FullName] = testAssemblyFileVersion, [typeof(AssemblyVersionAttribute).FullName] = testVersion.Substring(0, testVersion.IndexOf('-')), [typeof(AssemblyInformationalVersionAttribute).FullName] = testVersion, }; var compilationAttributes = compilationContext.Compilation.Assembly.GetAttributes(); Assert.All(compilationAttributes, compilationAttribute => expectedAttributes[compilationAttribute.AttributeClass.ToString()].Equals( compilationAttribute.ConstructorArguments.First().Value)); }
public CompilationContext CompileProject( CompilationProjectContext projectContext, IEnumerable <IMetadataReference> incomingReferences, IEnumerable <ISourceReference> incomingSourceReferences, Func <IList <ResourceDescriptor> > resourcesResolver) { var path = projectContext.ProjectDirectory; var name = projectContext.Target.Name; var projectInfo = GetProjectInfo(projectContext.ProjectFilePath); if (_cacheContextAccessor.Current != null) { _cacheContextAccessor.Current.Monitor(new FileWriteTimeCacheDependency(projectContext.ProjectFilePath)); // Monitor the trigger {projectName}_BuildOutputs var buildOutputsName = name + "_BuildOutputs"; _cacheContextAccessor.Current.Monitor(_namedDependencyProvider.GetNamedDependency(buildOutputsName)); _cacheContextAccessor.Current.Monitor(_namedDependencyProvider.GetNamedDependency(name + "_Dependencies")); } Logger.TraceInformation("[{0}]: Compiling '{1}'", GetType().Name, name); var sw = Stopwatch.StartNew(); CompilationContext context; using (new ResolveHooker()) using (var files = new TempFiles()) { var outFileName = $"{name}.dll"; var outDir = files.CreateDir(); var outFile = Path.Combine(outDir, outFileName); var args = new List <string>(); args.Add("fsc.exe"); args.Add($"--out:{outFile}"); args.Add("--target:library"); args.Add("--noframework"); args.Add("--optimize-"); args.Add("--debug"); if (SupportsPdbGeneration) { args.Add($"--pdb:{Path.ChangeExtension(outFile, ".pdb")}"); } args.Add($"--doc:{Path.ChangeExtension(outFile, ".xml")}"); args.AddRange(projectInfo.Files); // These are the metadata references being used by your project. // Everything in your project.json is resolved and normailzed here: // - Project references // - Package references are turned into the appropriate assemblies // Each IMetadaReference maps to an assembly foreach (var reference in incomingReferences) { string fileName = null; var projectRef = reference as IMetadataProjectReference; if (projectRef != null) { var dir = files.CreateDir(); projectRef.EmitAssembly(dir); fileName = Path.Combine(dir, $"{projectRef.Name}.dll"); } var fileRef = reference as IMetadataFileReference; if (fileRef != null) { fileName = fileRef.Path; } else if (fileName == null) { throw new Exception($"Unknown reference type {reference.GetType()}"); } args.Add($"-r:{fileName}"); } //Console.WriteLine(string.Join(Environment.NewLine, args)); var scs = new SimpleSourceCodeServices(); var result = scs.Compile(args.ToArray()); var errors = result.Item1.Select(FSharpDiagnosticMessage.CompilationMessage); var resultCode = result.Item2; //System.Diagnostics.Debugger.Launch(); MemoryStream assembly = null; MemoryStream pdb = null; MemoryStream xml = null; if (resultCode == 0) { assembly = new MemoryStream(); xml = new MemoryStream(); using (var fs = File.OpenRead(outFile)) fs.CopyTo(assembly); var pdbFile = Path.ChangeExtension(outFile, ".pdb"); if (File.Exists(pdbFile)) { pdb = new MemoryStream(); using (var fs = File.OpenRead(pdbFile)) fs.CopyTo(pdb); } var xmlFile = Path.ChangeExtension(outFile, ".xml"); if (File.Exists(xmlFile)) { xml = new MemoryStream(); using (var fs = File.OpenRead(xmlFile)) fs.CopyTo(xml); } } context = new CompilationContext( projectContext, projectInfo, resultCode == 0, errors, assembly?.ToArray(), pdb?.ToArray(), xml?.ToArray()); assembly?.Dispose(); pdb?.Dispose(); xml?.Dispose(); } sw.Stop(); Logger.TraceInformation("[{0}]: Compiled '{1}' in {2}ms", GetType().Name, name, sw.ElapsedMilliseconds); return(context); }
public CompilationContext CompileProject( CompilationProjectContext projectContext, IEnumerable<IMetadataReference> incomingReferences, IEnumerable<ISourceReference> incomingSourceReferences, Func<IList<ResourceDescriptor>> resourcesResolver) { var path = projectContext.ProjectDirectory; var name = projectContext.Target.Name.TrimStart('/'); var isMainAspect = string.IsNullOrEmpty(projectContext.Target.Aspect); var isPreprocessAspect = string.Equals(projectContext.Target.Aspect, "preprocess", StringComparison.OrdinalIgnoreCase); if (!string.IsNullOrEmpty(projectContext.Target.Aspect)) { name += "!" + projectContext.Target.Aspect; } _watcher.WatchProject(path); _watcher.WatchFile(projectContext.ProjectFilePath); if (_cacheContextAccessor.Current != null) { _cacheContextAccessor.Current.Monitor(new FileWriteTimeCacheDependency(projectContext.ProjectFilePath)); if (isMainAspect) { // Monitor the trigger {projectName}_BuildOutputs var buildOutputsName = projectContext.Target.Name + "_BuildOutputs"; _cacheContextAccessor.Current.Monitor(_namedDependencyProvider.GetNamedDependency(buildOutputsName)); } _cacheContextAccessor.Current.Monitor(_namedDependencyProvider.GetNamedDependency(projectContext.Target.Name + "_Dependencies")); } var exportedReferences = incomingReferences.Select(ConvertMetadataReference); Logger.TraceInformation("[{0}]: Compiling '{1}'", GetType().Name, name); var sw = Stopwatch.StartNew(); var compilationSettings = projectContext.CompilerOptions.ToCompilationSettings( projectContext.Target.TargetFramework); var sourceFiles = Enumerable.Empty<String>(); if (isMainAspect) { sourceFiles = projectContext.Files.SourceFiles; } else if (isPreprocessAspect) { sourceFiles = projectContext.Files.PreprocessSourceFiles; } var parseOptions = new CSharpParseOptions(languageVersion: compilationSettings.LanguageVersion, preprocessorSymbols: compilationSettings.Defines); IList<SyntaxTree> trees = GetSyntaxTrees( projectContext, sourceFiles, incomingSourceReferences, parseOptions, isMainAspect); var embeddedReferences = incomingReferences.OfType<IMetadataEmbeddedReference>() .ToDictionary(a => a.Name, ConvertMetadataReference); var references = new List<MetadataReference>(); references.AddRange(exportedReferences); var compilation = CSharpCompilation.Create( name, trees, references, compilationSettings.CompilationOptions); compilation = ApplyVersionInfo(compilation, projectContext, parseOptions); var compilationContext = new CompilationContext( compilation, projectContext, incomingReferences, () => resourcesResolver() .Select(res => new ResourceDescription( res.Name, res.StreamFactory, isPublic: true)) .ToList()); // Apply strong-name settings ApplyStrongNameSettings(compilationContext); if (isMainAspect && projectContext.Files.PreprocessSourceFiles.Any()) { try { var modules = GetCompileModules(projectContext.Target).Modules; foreach (var m in modules) { compilationContext.Modules.Add(m); } } catch (Exception ex) { var compilationException = ex.InnerException as RoslynCompilationException; if (compilationException != null) { // Add diagnostics from the precompile step foreach (var diag in compilationException.Diagnostics) { compilationContext.Diagnostics.Add(diag); } Logger.TraceError("[{0}]: Failed loading meta assembly '{1}'", GetType().Name, name); } else { Logger.TraceError("[{0}]: Failed loading meta assembly '{1}':\n {2}", GetType().Name, name, ex); } } } if (compilationContext.Modules.Count > 0) { var precompSw = Stopwatch.StartNew(); foreach (var module in compilationContext.Modules) { module.BeforeCompile(compilationContext.BeforeCompileContext); } precompSw.Stop(); Logger.TraceInformation("[{0}]: Compile modules ran in in {1}ms", GetType().Name, precompSw.ElapsedMilliseconds); } sw.Stop(); Logger.TraceInformation("[{0}]: Compiled '{1}' in {2}ms", GetType().Name, name, sw.ElapsedMilliseconds); return compilationContext; }
public DesignTimeProjectReference(CompilationProjectContext project, CompileResponse response) { _project = project; _response = response; }
private static CSharpCompilation ApplyVersionInfo(CSharpCompilation compilation, CompilationProjectContext project, CSharpParseOptions parseOptions) { const string assemblyFileVersionName = "System.Reflection.AssemblyFileVersionAttribute"; const string assemblyVersionName = "System.Reflection.AssemblyVersionAttribute"; const string assemblyInformationalVersion = "System.Reflection.AssemblyInformationalVersionAttribute"; var assemblyAttributes = compilation.Assembly.GetAttributes(); var foundAssemblyFileVersion = false; var foundAssemblyVersion = false; var foundAssemblyInformationalVersion = false; foreach (var assembly in assemblyAttributes) { string attributeName = assembly.AttributeClass.ToString(); if (string.Equals(attributeName, assemblyFileVersionName, StringComparison.Ordinal)) { foundAssemblyFileVersion = true; } else if (string.Equals(attributeName, assemblyVersionName, StringComparison.Ordinal)) { foundAssemblyVersion = true; } else if (string.Equals(attributeName, assemblyInformationalVersion, StringComparison.Ordinal)) { foundAssemblyInformationalVersion = true; } } var versionAttributes = new StringBuilder(); if (!foundAssemblyFileVersion) { versionAttributes.AppendLine($"[assembly:{assemblyFileVersionName}(\"{project.AssemblyFileVersion}\")]"); } if (!foundAssemblyVersion) { versionAttributes.AppendLine($"[assembly:{assemblyVersionName}(\"{RemovePrereleaseTag(project.Version)}\")]"); } if (!foundAssemblyInformationalVersion) { versionAttributes.AppendLine($"[assembly:{assemblyInformationalVersion}(\"{project.Version}\")]"); } if (versionAttributes.Length != 0) { compilation = compilation.AddSyntaxTrees(new[] { CSharpSyntaxTree.ParseText(versionAttributes.ToString(), parseOptions) }); } return compilation; }
private IList<SyntaxTree> GetSyntaxTrees(CompilationProjectContext project, IEnumerable<string> sourceFiles, IEnumerable<ISourceReference> sourceReferences, CSharpParseOptions parseOptions, bool isMainAspect) { var trees = new List<SyntaxTree>(); var dirs = new HashSet<string>(); if (isMainAspect) { dirs.Add(project.ProjectDirectory); } foreach (var sourcePath in sourceFiles) { _watcher.WatchFile(sourcePath); var syntaxTree = CreateSyntaxTree(sourcePath, parseOptions); trees.Add(syntaxTree); } foreach (var sourceFileReference in sourceReferences.OfType<ISourceFileReference>()) { var sourcePath = sourceFileReference.Path; _watcher.WatchFile(sourcePath); var syntaxTree = CreateSyntaxTree(sourcePath, parseOptions); trees.Add(syntaxTree); } // Watch all directories var ctx = _cacheContextAccessor.Current; foreach (var d in dirs) { ctx?.Monitor(new FileWriteTimeCacheDependency(d)); // TODO: Make the file watcher hand out cache dependencies as well _watcher.WatchDirectory(d, ".cs"); } return trees; }
private static CSharpCompilation ApplyProjectInfo(CSharpCompilation compilation, CompilationProjectContext project, CSharpParseOptions parseOptions) { var projectAttributes = new Dictionary <string, string>(StringComparer.Ordinal) { [typeof(AssemblyTitleAttribute).FullName] = EscapeCharacters(project.Title), [typeof(AssemblyDescriptionAttribute).FullName] = EscapeCharacters(project.Description), [typeof(AssemblyCopyrightAttribute).FullName] = EscapeCharacters(project.Copyright), [typeof(AssemblyFileVersionAttribute).FullName] = EscapeCharacters(project.AssemblyFileVersion.ToString()), [typeof(AssemblyVersionAttribute).FullName] = EscapeCharacters(RemovePrereleaseTag(project.Version)), [typeof(AssemblyInformationalVersionAttribute).FullName] = EscapeCharacters(project.Version) }; var assemblyAttributes = compilation.Assembly.GetAttributes() .Select(assemblyAttribute => assemblyAttribute.AttributeClass.ToString()); var newAttributes = string.Join(Environment.NewLine, projectAttributes .Where(projectAttribute => projectAttribute.Value != null && !assemblyAttributes.Contains(projectAttribute.Key)) .Select(projectAttribute => $"[assembly:{projectAttribute.Key}(\"{projectAttribute.Value}\")]")); if (!string.IsNullOrWhiteSpace(newAttributes)) { compilation = compilation.AddSyntaxTrees(new[] { CSharpSyntaxTree.ParseText(newAttributes, parseOptions, path: $"{nameof(ApplyProjectInfo)}.cs", encoding: Encoding.UTF8) }); } return(compilation); }
private static CSharpCompilation ApplyProjectInfo(CSharpCompilation compilation, CompilationProjectContext project, CSharpParseOptions parseOptions) { var projectAttributes = new Dictionary<string, string>(StringComparer.Ordinal) { [typeof(AssemblyTitleAttribute).FullName] = EscapeCharacters(project.Title), [typeof(AssemblyDescriptionAttribute).FullName] = EscapeCharacters(project.Description), [typeof(AssemblyCopyrightAttribute).FullName] = EscapeCharacters(project.Copyright), [typeof(AssemblyFileVersionAttribute).FullName] = EscapeCharacters(project.AssemblyFileVersion.ToString()), [typeof(AssemblyVersionAttribute).FullName] = EscapeCharacters(RemovePrereleaseTag(project.Version)), [typeof(AssemblyInformationalVersionAttribute).FullName] = EscapeCharacters(project.Version) }; var assemblyAttributes = compilation.Assembly.GetAttributes() .Select(assemblyAttribute => assemblyAttribute.AttributeClass.ToString()); var newAttributes = string.Join(Environment.NewLine, projectAttributes .Where(projectAttribute => projectAttribute.Value != null && !assemblyAttributes.Contains(projectAttribute.Key)) .Select(projectAttribute => $"[assembly:{projectAttribute.Key}(\"{projectAttribute.Value}\")]")); if (!string.IsNullOrWhiteSpace(newAttributes)) { compilation = compilation.AddSyntaxTrees(new[] { CSharpSyntaxTree.ParseText(newAttributes, parseOptions, path: $"{nameof(ApplyProjectInfo)}.cs", encoding: Encoding.UTF8) }); } return compilation; }
public CompilationContext CompileProject( CompilationProjectContext projectContext, IEnumerable<IMetadataReference> incomingReferences, IEnumerable<ISourceReference> incomingSourceReferences, Func<IList<ResourceDescriptor>> resourcesResolver) { var path = projectContext.ProjectDirectory; var name = projectContext.Target.Name; var isMainAspect = string.IsNullOrEmpty(projectContext.Target.Aspect); var isPreprocessAspect = string.Equals(projectContext.Target.Aspect, "preprocess", StringComparison.OrdinalIgnoreCase); if (!string.IsNullOrEmpty(projectContext.Target.Aspect)) { name += "!" + projectContext.Target.Aspect; } if (_cacheContextAccessor.Current != null) { _cacheContextAccessor.Current.Monitor(new FileWriteTimeCacheDependency(projectContext.ProjectFilePath)); if (isMainAspect) { // Monitor the trigger {projectName}_BuildOutputs var buildOutputsName = projectContext.Target.Name + "_BuildOutputs"; _cacheContextAccessor.Current.Monitor(_namedDependencyProvider.GetNamedDependency(buildOutputsName)); } _cacheContextAccessor.Current.Monitor(_namedDependencyProvider.GetNamedDependency(projectContext.Target.Name + "_Dependencies")); } var exportedReferences = incomingReferences .Select(reference => reference.ConvertMetadataReference(_assemblyMetadataFactory)); Logger.TraceInformation("[{0}]: Compiling '{1}'", GetType().Name, name); var sw = Stopwatch.StartNew(); var compilationSettings = projectContext.CompilerOptions.ToCompilationSettings( projectContext.Target.TargetFramework, projectContext.ProjectDirectory); var sourceFiles = Enumerable.Empty<string>(); if (isMainAspect) { sourceFiles = projectContext.Files.SourceFiles; } else if (isPreprocessAspect) { sourceFiles = projectContext.Files.PreprocessSourceFiles; } var parseOptions = new CSharpParseOptions(languageVersion: compilationSettings.LanguageVersion, preprocessorSymbols: compilationSettings.Defines); var trees = GetSyntaxTrees( projectContext, sourceFiles, incomingSourceReferences, parseOptions, isMainAspect); var references = new List<MetadataReference>(); references.AddRange(exportedReferences); if (isPreprocessAspect) { compilationSettings.CompilationOptions = compilationSettings.CompilationOptions.WithOutputKind(OutputKind.DynamicallyLinkedLibrary); } var compilation = CSharpCompilation.Create( name, trees, references, compilationSettings.CompilationOptions); compilation = ApplyProjectInfo(compilation, projectContext, parseOptions); var compilationContext = new CompilationContext( compilation, projectContext, incomingReferences, resourcesResolver); ValidateSigningOptions(compilationContext); AddStrongNameProvider(compilationContext); if (isMainAspect && projectContext.Files.PreprocessSourceFiles.Any()) { try { var modules = GetCompileModules(projectContext.Target).Modules; foreach (var m in modules) { compilationContext.Modules.Add(m); } } catch (Exception ex) when (ex.InnerException is RoslynCompilationException) { var compilationException = ex.InnerException as RoslynCompilationException; // Add diagnostics from the precompile step foreach (var diag in compilationException.Diagnostics) { compilationContext.Diagnostics.Add(diag); } } } if (compilationContext.Modules.Count > 0) { var precompSw = Stopwatch.StartNew(); foreach (var module in compilationContext.Modules) { module.BeforeCompile(compilationContext.BeforeCompileContext); } precompSw.Stop(); Logger.TraceInformation("[{0}]: Compile modules ran in in {1}ms", GetType().Name, precompSw.ElapsedMilliseconds); } sw.Stop(); Logger.TraceInformation("[{0}]: Compiled '{1}' in {2}ms", GetType().Name, name, sw.ElapsedMilliseconds); return compilationContext; }
private static CSharpCompilation ApplyVersionInfo(CSharpCompilation compilation, CompilationProjectContext project, CSharpParseOptions parseOptions) { const string assemblyFileVersionName = "System.Reflection.AssemblyFileVersionAttribute"; const string assemblyVersionName = "System.Reflection.AssemblyVersionAttribute"; const string assemblyInformationalVersion = "System.Reflection.AssemblyInformationalVersionAttribute"; var assemblyAttributes = compilation.Assembly.GetAttributes(); var foundAssemblyFileVersion = false; var foundAssemblyVersion = false; var foundAssemblyInformationalVersion = false; foreach (var assembly in assemblyAttributes) { string attributeName = assembly.AttributeClass.ToString(); if (string.Equals(attributeName, assemblyFileVersionName, StringComparison.Ordinal)) { foundAssemblyFileVersion = true; } else if (string.Equals(attributeName, assemblyVersionName, StringComparison.Ordinal)) { foundAssemblyVersion = true; } else if (string.Equals(attributeName, assemblyInformationalVersion, StringComparison.Ordinal)) { foundAssemblyInformationalVersion = true; } } var versionAttributes = new StringBuilder(); if (!foundAssemblyFileVersion) { versionAttributes.AppendLine($"[assembly:{assemblyFileVersionName}(\"{project.AssemblyFileVersion}\")]"); } if (!foundAssemblyVersion) { versionAttributes.AppendLine($"[assembly:{assemblyVersionName}(\"{RemovePrereleaseTag(project.Version)}\")]"); } if (!foundAssemblyInformationalVersion) { versionAttributes.AppendLine($"[assembly:{assemblyInformationalVersion}(\"{project.Version}\")]"); } if (versionAttributes.Length != 0) { compilation = compilation.AddSyntaxTrees(new[] { CSharpSyntaxTree.ParseText(versionAttributes.ToString(), parseOptions) }); } return(compilation); }
public CompilationContext CompileProject( CompilationProjectContext projectContext, IEnumerable <IMetadataReference> incomingReferences, IEnumerable <ISourceReference> incomingSourceReferences, Func <IList <ResourceDescriptor> > resourcesResolver) { var path = projectContext.ProjectDirectory; var name = projectContext.Target.Name; var isMainAspect = string.IsNullOrEmpty(projectContext.Target.Aspect); var isPreprocessAspect = string.Equals(projectContext.Target.Aspect, "preprocess", StringComparison.OrdinalIgnoreCase); if (!string.IsNullOrEmpty(projectContext.Target.Aspect)) { name += "!" + projectContext.Target.Aspect; } _watcher.WatchProject(path); _watcher.WatchFile(projectContext.ProjectFilePath); if (_cacheContextAccessor.Current != null) { _cacheContextAccessor.Current.Monitor(new FileWriteTimeCacheDependency(projectContext.ProjectFilePath)); if (isMainAspect) { // Monitor the trigger {projectName}_BuildOutputs var buildOutputsName = projectContext.Target.Name + "_BuildOutputs"; _cacheContextAccessor.Current.Monitor(_namedDependencyProvider.GetNamedDependency(buildOutputsName)); } _cacheContextAccessor.Current.Monitor(_namedDependencyProvider.GetNamedDependency(projectContext.Target.Name + "_Dependencies")); } var exportedReferences = incomingReferences .Select(reference => reference.ConvertMetadataReference(_assemblyMetadataFactory)); Logger.TraceInformation("[{0}]: Compiling '{1}'", GetType().Name, name); var sw = Stopwatch.StartNew(); var compilationSettings = projectContext.CompilerOptions.ToCompilationSettings( projectContext.Target.TargetFramework); var sourceFiles = Enumerable.Empty <string>(); if (isMainAspect) { sourceFiles = projectContext.Files.SourceFiles; } else if (isPreprocessAspect) { sourceFiles = projectContext.Files.PreprocessSourceFiles; } var parseOptions = new CSharpParseOptions(languageVersion: compilationSettings.LanguageVersion, preprocessorSymbols: compilationSettings.Defines); var trees = GetSyntaxTrees( projectContext, sourceFiles, incomingSourceReferences, parseOptions, isMainAspect); var references = new List <MetadataReference>(); references.AddRange(exportedReferences); var compilation = CSharpCompilation.Create( name, trees, references, compilationSettings.CompilationOptions); compilation = ApplyVersionInfo(compilation, projectContext, parseOptions); var compilationContext = new CompilationContext( compilation, projectContext, incomingReferences, resourcesResolver); // Apply strong-name settings ApplyStrongNameSettings(compilationContext); if (isMainAspect && projectContext.Files.PreprocessSourceFiles.Any()) { try { var modules = GetCompileModules(projectContext.Target).Modules; foreach (var m in modules) { compilationContext.Modules.Add(m); } } catch (Exception ex) when(ex.InnerException is RoslynCompilationException) { var compilationException = ex.InnerException as RoslynCompilationException; // Add diagnostics from the precompile step foreach (var diag in compilationException.Diagnostics) { compilationContext.Diagnostics.Add(diag); } } } if (compilationContext.Modules.Count > 0) { var precompSw = Stopwatch.StartNew(); foreach (var module in compilationContext.Modules) { module.BeforeCompile(compilationContext.BeforeCompileContext); } precompSw.Stop(); Logger.TraceInformation("[{0}]: Compile modules ran in in {1}ms", GetType().Name, precompSw.ElapsedMilliseconds); } sw.Stop(); Logger.TraceInformation("[{0}]: Compiled '{1}' in {2}ms", GetType().Name, name, sw.ElapsedMilliseconds); return(compilationContext); }