public static IList<IMetadataEmbeddedReference> GetRequiredEmbeddedReferences(CompilationContext context) { var assemblyNeutralTypes = context.MetadataReferences.OfType<IMetadataEmbeddedReference>() .ToDictionary(r => r.Name); // No assembly neutral types so do nothing if (assemblyNeutralTypes.Count == 0) { return _emptyList; } // Walk the assembly neutral references and embed anything that we use // directly or indirectly var results = GetUsedReferences(context, assemblyNeutralTypes); // REVIEW: This should probably by driven by a property in the project metadata if (results.Count == 0) { // If nothing outgoing from this assembly, treat it like a carrier assembly // and embed everyting foreach (var a in assemblyNeutralTypes.Keys) { results.Add(a); } } return results.Select(name => assemblyNeutralTypes[name]) .ToList(); }
public SyntaxNode Generate(CompilationContext context, ISettings settings) { // Create the root node and add usings, header, pragma var r4mvcNode = SyntaxFactory.CompilationUnit() .WithUsings("System.CodeDom.Compiler", "System.Diagnostics", "Microsoft.AspNet.Mvc") .WithHeader(_headerText) .WithPragmaCodes(false, pramaCodes); var controllers = _controllerRewriter.RewriteControllers(context.Compilation, R4MvcFileName); var generatedControllers = _controllerGenerator.GenerateControllers(context.Compilation, controllers).ToImmutableArray(); var staticFileNode = _staticFileGenerator.GenerateStaticFiles(settings); // add the dummy class using in the derived controller partial class var r4Namespace = SyntaxNodeHelpers.CreateNamespace(settings.R4MvcNamespace).WithDummyClass(); // create static MVC class and add controller fields var mvcStaticClass = SyntaxNodeHelpers.CreateClass(settings.HelpersPrefix, null, SyntaxKind.PublicKeyword, SyntaxKind.StaticKeyword, SyntaxKind.PartialKeyword) .WithAttributes(SyntaxNodeHelpers.CreateGeneratedCodeAttribute(), SyntaxNodeHelpers.CreateDebugNonUserCodeAttribute()) .WithControllerFields(controllers); r4mvcNode = r4mvcNode.AddMembers(generatedControllers.Cast<MemberDeclarationSyntax>().ToArray()) .AddMembers(staticFileNode) .AddMembers(r4Namespace) .AddMembers(mvcStaticClass) .NormalizeWhitespace() .WithPragmaCodes(true, pramaCodes); // NOTE reenable pragma codes after normalizing whitespace or it doesn't place on newline return r4mvcNode; }
public AfterCompileContext(CompilationContext context, IEnumerable<Diagnostic> emitDiagnostics) { _context = context; var diagnostics = new List<Diagnostic>(context.Diagnostics); diagnostics.AddRange(emitDiagnostics); Diagnostics = diagnostics; }
private static HashSet<string> GetUsedReferences(CompilationContext context, Dictionary<string, IMetadataEmbeddedReference> assemblies) { var results = new HashSet<string>(); byte[] metadataBuffer = null; // First we need to emit just the metadata for this compilation using (var metadataStream = new MemoryStream()) { var result = context.Compilation.Emit(metadataStream); if (!result.Success) { // We failed to emit metadata so do nothing since we're probably // going to fail compilation anyways return results; } // Store the buffer and close the stream metadataBuffer = metadataStream.ToArray(); } var stack = new Stack<Tuple<string, byte[]>>(); stack.Push(Tuple.Create((string)null, metadataBuffer)); while (stack.Count > 0) { var top = stack.Pop(); var assemblyName = top.Item1; if (!string.IsNullOrEmpty(assemblyName) && !results.Add(assemblyName)) { // Skip the reference if saw it already continue; } var buffer = top.Item2; foreach (var reference in GetReferences(buffer)) { IMetadataEmbeddedReference embeddedReference; if (assemblies.TryGetValue(reference, out embeddedReference)) { stack.Push(Tuple.Create(reference, embeddedReference.Contents)); } } } return results; }
private static IList<ResourceDescription> GetResources(CompilationContext context) { var resxProvider = new ResxResourceProvider(); var embeddedResourceProvider = new EmbeddedResourceProvider(); var resourceProvider = new CompositeResourceProvider(new IResourceProvider[] { resxProvider, embeddedResourceProvider }); var sw = Stopwatch.StartNew(); Logger.TraceInformation("[{0}]: Generating resources for {1}", nameof(CompilationContext), context.Project.Name); var resources = resourceProvider.GetResources(context.Project); sw.Stop(); Logger.TraceInformation("[{0}]: Generated resources for {1} in {2}ms", nameof(CompilationContext), context.Project.Name, sw.ElapsedMilliseconds); return resources; }
public RoslynProjectReference(CompilationContext compilationContext) { CompilationContext = compilationContext; MetadataReference = compilationContext.Compilation.ToMetadataReference(embedInteropTypes: compilationContext.Project.EmbedInteropTypes); Name = compilationContext.Project.Name; }
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; }
private void ApplyStrongNameSettings(CompilationContext compilationContext) { var keyFile = Environment.GetEnvironmentVariable(EnvironmentNames.BuildKeyFile) ?? compilationContext.Compilation.Options.CryptoKeyFile; if (!string.IsNullOrEmpty(keyFile) && !RuntimeEnvironmentHelper.IsMono) { #if DNX451 var delaySignString = Environment.GetEnvironmentVariable(EnvironmentNames.BuildDelaySign); var delaySign = delaySignString == null ? compilationContext.Compilation.Options.DelaySign : string.Equals(delaySignString, "true", StringComparison.OrdinalIgnoreCase) || string.Equals(delaySignString, "1", StringComparison.OrdinalIgnoreCase); var strongNameProvider = new DesktopStrongNameProvider( ImmutableArray.Create(compilationContext.Project.ProjectDirectory)); var newOptions = compilationContext.Compilation.Options .WithStrongNameProvider(strongNameProvider) .WithCryptoKeyFile(keyFile) .WithDelaySign(delaySign); compilationContext.Compilation = compilationContext.Compilation.WithOptions(newOptions); #else var diag = Diagnostic.Create( RoslynDiagnostics.StrongNamingNotSupported, null); compilationContext.Diagnostics.Add(diag); #endif } // If both CryptoPublicKey and CryptoKeyFile compilation will fail so we don't need a check if (compilationContext.Compilation.Options.CryptoPublicKey != null) { var options = compilationContext.Compilation.Options .WithCryptoPublicKey(compilationContext.Compilation.Options.CryptoPublicKey); compilationContext.Compilation = compilationContext.Compilation.WithOptions(options); } }
public CompilationContext CompileProject( Project project, ILibraryKey target, IEnumerable<IMetadataReference> incomingReferences, IEnumerable<ISourceReference> incomingSourceReferences, IList<IMetadataReference> outgoingReferences) { var path = project.ProjectDirectory; var name = project.Name; var isMainAspect = string.IsNullOrEmpty(target.Aspect); var isPreprocessAspect = string.Equals(target.Aspect, "preprocess", StringComparison.OrdinalIgnoreCase); if (!string.IsNullOrEmpty(target.Aspect)) { name += "!" + target.Aspect; } _watcher.WatchProject(path); _watcher.WatchFile(project.ProjectFilePath); if (_cacheContextAccessor.Current != null) { _cacheContextAccessor.Current.Monitor(new FileWriteTimeCacheDependency(project.ProjectFilePath)); if (isMainAspect) { // Monitor the trigger {projectName}_BuildOutputs var buildOutputsName = project.Name + "_BuildOutputs"; _cacheContextAccessor.Current.Monitor(_namedDependencyProvider.GetNamedDependency(buildOutputsName)); } } var exportedReferences = incomingReferences.Select(ConvertMetadataReference); Trace.TraceInformation("[{0}]: Compiling '{1}'", GetType().Name, name); var sw = Stopwatch.StartNew(); var compilationSettings = project.GetCompilerOptions(target.TargetFramework, target.Configuration) .ToCompilationSettings(target.TargetFramework); var sourceFiles = Enumerable.Empty<String>(); if (isMainAspect) { sourceFiles = project.SourceFiles; } else if (isPreprocessAspect) { sourceFiles = project.PreprocessSourceFiles; } var parseOptions = new CSharpParseOptions(languageVersion: compilationSettings.LanguageVersion, preprocessorSymbols: compilationSettings.Defines); IList<SyntaxTree> trees = GetSyntaxTrees( project, 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); var aniSw = Stopwatch.StartNew(); Trace.TraceInformation("[{0}]: Scanning '{1}' for assembly neutral interfaces", GetType().Name, name); var assemblyNeutralWorker = new AssemblyNeutralWorker(compilation, embeddedReferences); assemblyNeutralWorker.FindTypeCompilations(compilation.Assembly.GlobalNamespace); assemblyNeutralWorker.OrderTypeCompilations(); var assemblyNeutralTypeDiagnostics = assemblyNeutralWorker.GenerateTypeCompilations(); assemblyNeutralWorker.Generate(); aniSw.Stop(); Trace.TraceInformation("[{0}]: Found {1} assembly neutral interfaces for '{2}' in {3}ms", GetType().Name, assemblyNeutralWorker.TypeCompilations.Count(), name, aniSw.ElapsedMilliseconds); foreach (var t in assemblyNeutralWorker.TypeCompilations) { outgoingReferences.Add(new EmbeddedMetadataReference(t)); } var newCompilation = assemblyNeutralWorker.Compilation; newCompilation = ApplyVersionInfo(newCompilation, project, parseOptions); var compilationContext = new CompilationContext(newCompilation, incomingReferences.Concat(outgoingReferences).ToList(), assemblyNeutralTypeDiagnostics, project); var modules = new List<ICompileModule>(); if (isMainAspect && project.PreprocessSourceFiles.Any()) { try { modules = GetCompileModules(target).Modules; } 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); } Trace.TraceError("[{0}]: Failed loading meta assembly '{1}'", GetType().Name, name); } else { Trace.TraceError("[{0}]: Failed loading meta assembly '{1}':\n {2}", GetType().Name, name, ex); } } } if (modules.Count > 0) { var precompSw = Stopwatch.StartNew(); foreach (var module in modules) { module.BeforeCompile(compilationContext); } precompSw.Stop(); Trace.TraceInformation("[{0}]: Compile modules ran in in {1}ms", GetType().Name, precompSw.ElapsedMilliseconds); } sw.Stop(); Trace.TraceInformation("[{0}]: Compiled '{1}' in {2}ms", GetType().Name, name, sw.ElapsedMilliseconds); return compilationContext; }
private static IList<ResourceDescription> GetResources(CompilationContext context) { var resxProvider = new ResxResourceProvider(); var embeddedResourceProvider = new EmbeddedResourceProvider(); var resourceProvider = new CompositeResourceProvider(new IResourceProvider[] { resxProvider, embeddedResourceProvider }); var sw = Stopwatch.StartNew(); Trace.TraceInformation("[{0}]: Generating resources for {1}", nameof(CompilationContext), context.Project.Name); var resources = resourceProvider.GetResources(context.Project); sw.Stop(); Trace.TraceInformation("[{0}]: Generated resources for {1} in {2}ms", nameof(CompilationContext), context.Project.Name, sw.ElapsedMilliseconds); sw = Stopwatch.StartNew(); Trace.TraceInformation("[{0}]: Resolving required assembly neutral references for {1}", nameof(CompilationContext), context.Project.Name); var embeddedReferences = EmbeddedReferencesHelper.GetRequiredEmbeddedReferences(context); resources.AddEmbeddedReferences(embeddedReferences); Trace.TraceInformation("[{0}]: Resolved {1} required assembly neutral references for {2} in {3}ms", nameof(CompilationContext), embeddedReferences.Count, context.Project.Name, sw.ElapsedMilliseconds); sw.Stop(); return resources; }
private void ApplyStrongNameSettings(CompilationContext compilationContext) { // This is temporary, eventually we'll want a project.json feature for this var keyFile = Environment.GetEnvironmentVariable(EnvironmentNames.BuildKeyFile); if(!string.IsNullOrEmpty(keyFile)) { #if DNX451 var delaySignString = Environment.GetEnvironmentVariable(EnvironmentNames.BuildDelaySign); var delaySign = !string.IsNullOrEmpty(delaySignString) && ( string.Equals(delaySignString, "true", StringComparison.OrdinalIgnoreCase) || string.Equals(delaySignString, "1", StringComparison.OrdinalIgnoreCase)); var strongNameProvider = new DesktopStrongNameProvider(); var newOptions = compilationContext.Compilation.Options .WithStrongNameProvider(strongNameProvider) .WithCryptoKeyFile(keyFile) .WithDelaySign(delaySign); compilationContext.Compilation = compilationContext.Compilation.WithOptions(newOptions); #else var diag = Diagnostic.Create( RoslynDiagnostics.StrongNamingNotSupported, null); compilationContext.Diagnostics.Add(diag); #endif } }
public CompilationContext CompileProject( ICompilationProject project, ILibraryKey target, IEnumerable <IMetadataReference> incomingReferences, IEnumerable <ISourceReference> incomingSourceReferences, Func <IList <ResourceDescriptor> > resourcesResolver) { var path = project.ProjectDirectory; var name = project.Name; var isMainAspect = string.IsNullOrEmpty(target.Aspect); var isPreprocessAspect = string.Equals(target.Aspect, "preprocess", StringComparison.OrdinalIgnoreCase); if (!string.IsNullOrEmpty(target.Aspect)) { name += "!" + target.Aspect; } _watcher.WatchProject(path); _watcher.WatchFile(project.ProjectFilePath); if (_cacheContextAccessor.Current != null) { _cacheContextAccessor.Current.Monitor(new FileWriteTimeCacheDependency(project.ProjectFilePath)); if (isMainAspect) { // Monitor the trigger {projectName}_BuildOutputs var buildOutputsName = project.Name + "_BuildOutputs"; _cacheContextAccessor.Current.Monitor(_namedDependencyProvider.GetNamedDependency(buildOutputsName)); } _cacheContextAccessor.Current.Monitor(_namedDependencyProvider.GetNamedDependency(project.Name + "_Dependencies")); } var exportedReferences = incomingReferences.Select(ConvertMetadataReference); Logger.TraceInformation("[{0}]: Compiling '{1}'", GetType().Name, name); var sw = Stopwatch.StartNew(); var compilationSettings = project.GetCompilerOptions(target.TargetFramework, target.Configuration) .ToCompilationSettings(target.TargetFramework); var sourceFiles = Enumerable.Empty <String>(); if (isMainAspect) { sourceFiles = project.Files.SourceFiles; } else if (isPreprocessAspect) { sourceFiles = project.Files.PreprocessSourceFiles; } var parseOptions = new CSharpParseOptions(languageVersion: compilationSettings.LanguageVersion, preprocessorSymbols: compilationSettings.Defines); IList <SyntaxTree> trees = GetSyntaxTrees( project, 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, project, parseOptions); var compilationContext = new CompilationContext( compilation, project, target.TargetFramework, target.Configuration, incomingReferences, () => resourcesResolver() .Select(res => new ResourceDescription( res.Name, res.StreamFactory, isPublic: true)) .ToList()); // Apply strong-name settings ApplyStrongNameSettings(compilationContext); if (isMainAspect && project.Files.PreprocessSourceFiles.Any()) { try { var modules = GetCompileModules(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 static IList <IMetadataEmbeddedReference> GetRequiredEmbeddedReferences(CompilationContext context) { var assemblyNeutralTypes = context.MetadataReferences.OfType <IMetadataEmbeddedReference>() .ToDictionary(r => r.Name); // No assembly neutral types so do nothing if (assemblyNeutralTypes.Count == 0) { return(_emptyList); } // Walk the assembly neutral references and embed anything that we use // directly or indirectly var results = GetUsedReferences(context, assemblyNeutralTypes); // REVIEW: This should probably by driven by a property in the project metadata if (results.Count == 0) { // If nothing outgoing from this assembly, treat it like a carrier assembly // and embed everyting foreach (var a in assemblyNeutralTypes.Keys) { results.Add(a); } } return(results.Select(name => assemblyNeutralTypes[name]) .ToList()); }