예제 #1
0
        public ILibraryExport GetLibraryExport(ILibraryKey target)
        {
            // Did we even resolve this name, if not then do nothing
            if (!_resolvedPaths.ContainsKey(target.Name))
            {
                return(null);
            }

            // We can't use resolved paths since it might be different to the target framework
            // being passed in here. After we know this resolver is handling the
            // requested name, we can call back into the FrameworkResolver to figure out
            //  the specific path for the target framework

            string  path;
            Version version;

            var asmName = LibraryRange.GetAssemblyName(target.Name);

            if (FrameworkResolver.TryGetAssembly(asmName, target.TargetFramework, out path, out version))
            {
                return(new LibraryExport(new MetadataFileReference(asmName, path)));
            }

            return(null);
        }
    public IMetadataProjectReference CompileProject(
      ICompilationProject project,
      ILibraryKey target,
      Func<ILibraryExport> referenceResolver,
      Func<IList<ResourceDescriptor>> resourcesResolver)
    {
      var export = referenceResolver();
      if (export == null)
      {
          return null;
      }

      var incomingReferences = export.MetadataReferences;
      var incomingSourceReferences = export.SourceReferences;

      var compilationContext = _compiler.CompileProject(
        project,
        target,
        incomingReferences,
        incomingSourceReferences,
        resourcesResolver);

      if (compilationContext == null)
      {
        return null;
      }

      // Project reference
      return new FSharpProjectReference(compilationContext);
    }
예제 #3
0
        public IMetadataProjectReference GetProjectReference(
            Project project,
            ILibraryKey target,
            Func <ILibraryExport> referenceResolver,
            IList <IMetadataReference> outgoingReferences)
        {
            var export                   = referenceResolver();
            var incomingReferences       = export.MetadataReferences;
            var incomingSourceReferences = export.SourceReferences;

            var compliationContext = _compiler.CompileProject(
                project,
                target,
                incomingReferences,
                incomingSourceReferences,
                outgoingReferences);

            if (compliationContext == null)
            {
                return(null);
            }

            // Project reference
            return(new RoslynProjectReference(compliationContext));
        }
        public ILibraryExport GetLibraryExport(ILibraryKey target) {
            Project project;
            // Can't find a project file with the name so bail
            if (!_projectResolver.TryResolveProject(target.Name, out project)) {
                return null;
            }

            var targetFrameworkInformation = project.GetTargetFramework(target.TargetFramework);

            // This is the target framework defined in the project. If there were no target frameworks
            // defined then this is the targetFramework specified
            if (targetFrameworkInformation.FrameworkName != null) {
                target = target.ChangeTargetFramework(targetFrameworkInformation.FrameworkName);
            }

            var metadataReferences = new List<IMetadataReference>();
            var sourceReferences = new List<ISourceReference>();

            if (!string.IsNullOrEmpty(targetFrameworkInformation.AssemblyPath)) {
                var assemblyPath = ResolvePath(project, target.Configuration, targetFrameworkInformation.AssemblyPath);
                var pdbPath = ResolvePath(project, target.Configuration, targetFrameworkInformation.PdbPath);

                metadataReferences.Add(new CompiledProjectMetadataReference(project, assemblyPath, pdbPath));
            }
            else {
                var libraryManager = _serviceProvider.GetService<IOrchardLibraryManager>();

               return libraryManager.GetLibraryExport(target.Name, target.Aspect);
            }

            return new LibraryExport(metadataReferences, sourceReferences);
        }
예제 #5
0
        public ILibraryExport GetLibraryExport(ILibraryKey target)
        {
            PackageDescription description;

            if (!_packageDescriptions.TryGetValue(target.Name, out description))
            {
                return(null);
            }

            var references = new Dictionary <string, IMetadataReference>(StringComparer.OrdinalIgnoreCase);

            if (!TryPopulateMetadataReferences(description, target.TargetFramework, references))
            {
                return(null);
            }

            // REVIEW: This requires more design
            var sourceReferences = new List <ISourceReference>();

            foreach (var sharedSource in GetSharedSources(description, target.TargetFramework))
            {
                sourceReferences.Add(new SourceFileReference(sharedSource));
            }

            return(new LibraryExport(references.Values.ToList(), sourceReferences));
        }
        private CompilationModules GetCompileModules(ILibraryKey target)
        {
            // The only thing that matters is the runtime environment
            // when loading the compilation modules, so use that as the cache key
            var key = Tuple.Create(
                target.Name,
                _environment.RuntimeFramework,
                _environment.Configuration,
                "compilemodules");

            return(_cache.Get <CompilationModules>(key, _ => {
                var modules = new List <ICompileModule>();

                var childContext = _loadContextFactory.Create();

                var preprocessAssembly = childContext.Load(target.Name + "!preprocess");

                foreach (var preprocessType in preprocessAssembly.ExportedTypes)
                {
                    if (preprocessType.GetTypeInfo().ImplementedInterfaces.Contains(typeof(ICompileModule)))
                    {
                        var module = (ICompileModule)ActivatorUtilities.CreateInstance(_services, preprocessType);
                        modules.Add(module);
                    }
                }

                // We do this so that the load context is disposed when the cache entry
                // expires
                return new CompilationModules {
                    LoadContext = childContext,
                    Modules = modules,
                };
            }));
        }
예제 #7
0
        public async Task <CompileResponse> Compile(string projectPath, ILibraryKey library)
        {
            var contexts = await _projectContexts.Task;

            int contextId;

            if (!contexts.TryGetValue(projectPath, out contextId))
            {
                // This should never happen
                throw new InvalidOperationException();
            }

            var obj = new JObject();

            obj["Name"]            = library.Name;
            obj["Configuration"]   = library.Configuration;
            obj["TargetFramework"] = library.TargetFramework.ToString();
            obj["Aspect"]          = library.Aspect;
            obj["Version"]         = 1;

            _queue.Send(new DesignTimeMessage
            {
                HostId      = "Application",
                MessageType = "GetCompiledAssembly",
                Payload     = obj,
                ContextId   = contextId
            });

            return(await _compileResponses.GetOrAdd(contextId, _ => new TaskCompletionSource <CompileResponse>()).Task);
        }
예제 #8
0
        public async Task<CompileResponse> Compile(string projectPath, ILibraryKey library)
        {
            var contexts = await _projectContexts.Task;

            int contextId;
            if (!contexts.TryGetValue(projectPath, out contextId))
            {
                // This should never happen
                throw new InvalidOperationException();
            }

            var obj = new JObject();
            obj["Name"] = library.Name;
            obj["Configuration"] = library.Configuration;
            obj["TargetFramework"] = library.TargetFramework.ToString();
            obj["Aspect"] = library.Aspect;
            obj["Version"] = 1;

            _queue.Send(new DesignTimeMessage
            {
                HostId = "Application",
                MessageType = "GetCompiledAssembly",
                Payload = obj,
                ContextId = contextId
            });

            return await _compileResponses.GetOrAdd(contextId, _ => new TaskCompletionSource<CompileResponse>()).Task;
        }
예제 #9
0
        public async Task<CompileResponse> Compile(string projectPath, ILibraryKey library)
        {
            var contexts = await _projectContexts.Task;

            int contextId;
            if (!contexts.TryGetValue(projectPath, out contextId))
            {
                // This should never happen
                throw new InvalidOperationException();
            }

            _queue.Send(new DesignTimeMessage
            {
                HostId = "Application",
                MessageType = "GetCompiledAssembly",
                Payload = JToken.FromObject(new LibraryKey
                {
                    Name = library.Name,
                    Configuration = library.Configuration,
                    TargetFramework = library.TargetFramework.ToString(),
                    Aspect = library.Aspect
                }),
                ContextId = contextId
            });

            return await _compileResponses.GetOrAdd(contextId, _ => new TaskCompletionSource<CompileResponse>()).Task;
        }
        public IMetadataProjectReference GetProjectReference(
            Project project,
            ILibraryKey target,
            Func<ILibraryExport> referenceResolver)
        {
            var export = referenceResolver();
            if (export == null)
            {
                return null;
            }

            var incomingReferences = export.MetadataReferences;
            var incomingSourceReferences = export.SourceReferences;

            var compliationContext = _compiler.CompileProject(
                project,
                target,
                incomingReferences,
                incomingSourceReferences);

            if (compliationContext == null)
            {
                return null;
            }

            // Project reference
            return new RoslynProjectReference(compliationContext);
        }
예제 #11
0
        public async Task<CompileResponse> Compile(string projectPath, ILibraryKey library)
        {
            var contexts = await _projectContexts.Task.ConfigureAwait(false);

            int contextId;
            if (!contexts.TryGetValue(projectPath, out contextId))
            {
                // This should never happen
                throw new InvalidOperationException();
            }

            _queue.Send(new GetCompiledAssemblyMessage
            {
                Name = library.Name,
                Configuration = library.Configuration,
                TargetFramework = library.TargetFramework,
                Aspect = library.Aspect,
                ContextId = contextId
            });

            _watcher.WatchProject(projectPath);

            var task = _compileResponses.GetOrAdd(contextId, _ => new TaskCompletionSource<CompileResponse>()).Task;
            return await task.ConfigureAwait(false);
        }
예제 #12
0
 public static ILibraryKey ChangeName(this ILibraryKey target, string name)
 {
     return(new LibraryKey {
         Name = name,
         TargetFramework = target.TargetFramework,
         Configuration = target.Configuration,
         Aspect = target.Aspect,
     });
 }
예제 #13
0
 public static ILibraryKey ChangeTargetFramework(this ILibraryKey target, FrameworkName targetFramework)
 {
     return(new LibraryKey {
         Name = target.Name,
         TargetFramework = targetFramework,
         Configuration = target.Configuration,
         Aspect = target.Aspect,
     });
 }
예제 #14
0
 public static ILibraryKey ChangeAspect(this ILibraryKey target, string aspect)
 {
     return(new LibraryKey {
         Name = target.Name,
         TargetFramework = target.TargetFramework,
         Configuration = target.Configuration,
         Aspect = aspect,
     });
 }
        public IMetadataProjectReference GetProjectReference(
            Project project,
            ILibraryKey target,
            Func<ILibraryExport> referenceResolver)
        {
            // The target framework and configuration are assumed to be correct
            // in the design time process
            var task = _compiler.Compile(project.ProjectDirectory, target);

            return new DesignTimeProjectReference(project, task.Result);
        }
예제 #16
0
        public ILibraryExport GetLibraryExport(ILibraryKey target)
        {
            string assemblyPath;

            if (_resolvedPaths.TryGetValue(target.Name, out assemblyPath))
            {
                return(new LibraryExport(new MetadataFileReference(target.Name, assemblyPath)));
            }

            return(null);
        }
        public IMetadataProjectReference GetProjectReference(
            Project project,
            ILibraryKey target,
            Func <ILibraryExport> referenceResolver)
        {
            // The target framework and configuration are assumed to be correct
            // in the design time process
            var task = _compiler.Compile(project.ProjectDirectory, target);

            return(new DesignTimeProjectReference(project, task.Result));
        }
예제 #18
0
        public IMetadataProjectReference GetProjectReference(
            Project project,
            ILibraryKey libraryKey,
            Func <ILibraryExport> referenceResolver,
            IList <IMetadataReference> outgoingReferences)
        {
            var export                   = referenceResolver();
            var incomingReferences       = export.MetadataReferences;
            var incomingSourceReferences = export.SourceReferences;

            return(new CscProjectReference(project, libraryKey.TargetFramework, libraryKey.Configuration, incomingReferences, incomingSourceReferences));
        }
        public IMetadataProjectReference GetProjectReference(
            Project project, 
            ILibraryKey libraryKey,
            Func<ILibraryExport> referenceResolver,
            IList<IMetadataReference> outgoingReferences)
        {
            var export = referenceResolver();
            var incomingReferences = export.MetadataReferences;
            var incomingSourceReferences = export.SourceReferences;

            return new CscProjectReference(project, libraryKey.TargetFramework, libraryKey.Configuration, incomingReferences, incomingSourceReferences);
        }
예제 #20
0
        public IMetadataProjectReference GetProjectReference(
            Project project,
            ILibraryKey target,
            Func <ILibraryExport> referenceResolver,
            IList <IMetadataReference> outgoingReferences)
        {
            // The target framework and configuration are assumed to be correct
            // in the design time process
            var task = _compiler.Compile(project.ProjectDirectory, target);

            foreach (var embeddedReference in task.Result.EmbeddedReferences)
            {
                outgoingReferences.Add(new EmbeddedMetadataReference(embeddedReference.Key, embeddedReference.Value));
            }

            return(new DesignTimeProjectReference(project, task.Result));
        }
예제 #21
0
        public static ILibraryExport GetExportsRecursive(
            ICache cache,
            ILibraryManager manager,
            ILibraryExportProvider libraryExportProvider,
            ILibraryKey target,
            bool dependenciesOnly)
        {
            return(GetExportsRecursive(cache, manager, libraryExportProvider, target, libraryInformation =>
            {
                if (dependenciesOnly)
                {
                    return !string.Equals(target.Name, libraryInformation.Name);
                }

                return true;
            }));
        }
예제 #22
0
        public static ILibraryExport GetExportsRecursive(
            ICache cache,
            ILibraryManager manager,
            ILibraryExportProvider libraryExportProvider,
            ILibraryKey target,
            bool dependenciesOnly)
        {
            return GetExportsRecursive(cache, manager, libraryExportProvider, target, libraryInformation =>
            {
                if (dependenciesOnly)
                {
                    return !string.Equals(target.Name, libraryInformation.Name);
                }

                return true;
            });
        }
        public IMetadataProjectReference GetProjectReference(
            Project project,
            ILibraryKey target,
            Func<ILibraryExport> referenceResolver,
            IList<IMetadataReference> outgoingReferences)
        {
            // The target framework and configuration are assumed to be correct
            // in the design time process
            var task = _compiler.Compile(project.ProjectDirectory, target);

            foreach (var embeddedReference in task.Result.EmbeddedReferences)
            {
                outgoingReferences.Add(new EmbeddedMetadataReference(embeddedReference.Key, embeddedReference.Value));
            }

            return new DesignTimeProjectReference(project, task.Result);
        }
예제 #24
0
        public ILibraryExport GetLibraryExport(ILibraryKey target)
        {
            Project project;

            // Can't find a project file with the name so bail
            if (!_projectResolver.TryResolveProject(target.Name, out project))
            {
                return(null);
            }

            var targetFrameworkInformation = project.GetTargetFramework(target.TargetFramework);

            // This is the target framework defined in the project. If there were no target frameworks
            // defined then this is the targetFramework specified
            if (targetFrameworkInformation.FrameworkName != null)
            {
                target = target.ChangeTargetFramework(targetFrameworkInformation.FrameworkName);
            }

            var metadataReferences = new List <IMetadataReference>();
            var sourceReferences   = new List <ISourceReference>();

            if (!string.IsNullOrEmpty(targetFrameworkInformation.AssemblyPath))
            {
                var assemblyPath = ResolvePath(project, target.Configuration, targetFrameworkInformation.AssemblyPath);
                var pdbPath      = ResolvePath(project, target.Configuration, targetFrameworkInformation.PdbPath);

                metadataReferences.Add(new CompiledProjectMetadataReference(project, assemblyPath, pdbPath));
            }
            else
            {
                var libraryManager = _serviceProvider.GetService <IOrchardLibraryManager>();

                return(libraryManager.GetLibraryExport(target.Name, target.Aspect));
            }

            return(new LibraryExport(metadataReferences, sourceReferences));
        }
예제 #25
0
        public ILibraryExport GetLibraryExport(ILibraryKey target)
        {
            Project project;

            // Can't find a project file with the name so bail
            if (!_projectResolver.TryResolveProject(target.Name, out project))
            {
                return(null);
            }

            Logger.TraceInformation("[{0}]: GetLibraryExport({1}, {2}, {3}, {4})", GetType().Name, target.Name, target.TargetFramework, target.Configuration, target.Aspect);

            var targetFrameworkInformation = project.GetTargetFramework(target.TargetFramework);

            // This is the target framework defined in the project. If there were no target frameworks
            // defined then this is the targetFramework specified
            if (targetFrameworkInformation.FrameworkName != null)
            {
                target = target.ChangeTargetFramework(targetFrameworkInformation.FrameworkName);
            }

            var key = Tuple.Create(
                target.Name,
                target.TargetFramework,
                target.Configuration,
                target.Aspect);

            var cache = (ICache)_serviceProvider.GetService(typeof(ICache));

            return(cache.Get <ILibraryExport>(key, ctx =>
            {
                // Get the composite library export provider
                var exportProvider = (ILibraryExportProvider)_serviceProvider.GetService(typeof(ILibraryExportProvider));
                var libraryManager = (ILibraryManager)_serviceProvider.GetService(typeof(ILibraryManager));

                var metadataReferences = new List <IMetadataReference>();
                var sourceReferences = new List <ISourceReference>();

                if (!string.IsNullOrEmpty(targetFrameworkInformation.AssemblyPath))
                {
                    var assemblyPath = ResolvePath(project, target.Configuration, targetFrameworkInformation.AssemblyPath);
                    var pdbPath = ResolvePath(project, target.Configuration, targetFrameworkInformation.PdbPath);

                    metadataReferences.Add(new CompiledProjectMetadataReference(project, assemblyPath, pdbPath));
                }
                else
                {
                    var provider = project.LanguageServices?.ProjectReferenceProvider ?? Project.DefaultLanguageService;

                    // Find the default project exporter
                    var projectReferenceProvider = _projectReferenceProviders.GetOrAdd(provider, typeInfo =>
                    {
                        return LanguageServices.CreateService <IProjectReferenceProvider>(_serviceProvider, _projectLoadContext.Value, typeInfo);
                    });

                    Logger.TraceInformation("[{0}]: GetProjectReference({1}, {2}, {3}, {4})", provider.TypeName, target.Name, target.TargetFramework, target.Configuration, target.Aspect);

                    // Get the exports for the project dependencies
                    var projectExport = new Lazy <ILibraryExport>(() => ProjectExportProviderHelper.GetExportsRecursive(
                                                                      cache,
                                                                      libraryManager,
                                                                      exportProvider,
                                                                      target,
                                                                      dependenciesOnly: true));

                    // Resolve the project export
                    IMetadataProjectReference projectReference = projectReferenceProvider.GetProjectReference(
                        project,
                        target,
                        () => projectExport.Value);

                    metadataReferences.Add(projectReference);

                    // Shared sources
                    foreach (var sharedFile in project.Files.SharedFiles)
                    {
                        sourceReferences.Add(new SourceFileReference(sharedFile));
                    }
                }

                return new LibraryExport(metadataReferences, sourceReferences);
            }));
        }
예제 #26
0
        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;
        }
        public ILibraryExport GetLibraryExport(ILibraryKey target)
        {
            // Did we even resolve this name, if not then do nothing
            if (!_resolvedPaths.ContainsKey(target.Name))
            {
                return null;
            }

            // We can't use resolved paths since it might be different to the target framework
            // being passed in here. After we know this resolver is handling the
            // requested name, we can call back into the FrameworkResolver to figure out
            //  the specific path for the target framework

            string path;
            Version version;

            if (FrameworkResolver.TryGetAssembly(target.Name, target.TargetFramework, out path, out version))
            {
                return new LibraryExport(target.Name, path);
            }

            return null;
        }
예제 #28
0
        public ILibraryExport GetLibraryExport(ILibraryKey target)
        {
            Project project;
            // Can't find a project file with the name so bail
            if (!_projectResolver.TryResolveProject(target.Name, out project))
            {
                return null;
            }

            Trace.TraceInformation("[{0}]: GetLibraryExport({1}, {2}, {3}, {4})", GetType().Name, target.Name, target.TargetFramework, target.Configuration, target.Aspect);

            var targetFrameworkInformation = project.GetTargetFramework(target.TargetFramework);

            // This is the target framework defined in the project. If there were no target frameworks
            // defined then this is the targetFramework specified
            if (targetFrameworkInformation.FrameworkName != null)
            {
                target = target.ChangeTargetFramework(targetFrameworkInformation.FrameworkName);
            }

            var key = Tuple.Create(
                target.Name,
                target.TargetFramework,
                target.Configuration,
                target.Aspect);

            var cache = (ICache)_serviceProvider.GetService(typeof(ICache));

            return cache.Get<ILibraryExport>(key, ctx =>
            {
                // Get the composite library export provider
                var exportProvider = (ILibraryExportProvider)_serviceProvider.GetService(typeof(ILibraryExportProvider));
                var libraryManager = (ILibraryManager)_serviceProvider.GetService(typeof(ILibraryManager));

                var metadataReferences = new List<IMetadataReference>();
                var sourceReferences = new List<ISourceReference>();

                if (!string.IsNullOrEmpty(targetFrameworkInformation.AssemblyPath))
                {
                    var assemblyPath = ResolvePath(project, target.Configuration, targetFrameworkInformation.AssemblyPath);
                    var pdbPath = ResolvePath(project, target.Configuration, targetFrameworkInformation.PdbPath);

                    metadataReferences.Add(new CompiledProjectMetadataReference(project, assemblyPath, pdbPath));
                }
                else
                {
                    // Find the default project exporter
                    var projectReferenceProvider = _projectReferenceProviders.GetOrAdd(project.LanguageServices.ProjectReferenceProvider, typeInfo =>
                    {
                        return LanguageServices.CreateService<IProjectReferenceProvider>(_serviceProvider, _projectLoadContext.Value, typeInfo);
                    });

                    Trace.TraceInformation("[{0}]: GetProjectReference({1}, {2}, {3}, {4})", project.LanguageServices.ProjectReferenceProvider.TypeName, target.Name, target.TargetFramework, target.Configuration, target.Aspect);

                    // Get the exports for the project dependencies
                    var projectExport = new Lazy<ILibraryExport>(() => ProjectExportProviderHelper.GetExportsRecursive(
                        cache,
                        libraryManager,
                        exportProvider,
                        target,
                        dependenciesOnly: true));

                    // Resolve the project export
                    IMetadataProjectReference projectReference = projectReferenceProvider.GetProjectReference(
                        project,
                        target,
                        () => projectExport.Value,
                        metadataReferences);

                    metadataReferences.Add(projectReference);

                    // Shared sources
                    foreach (var sharedFile in project.SharedFiles)
                    {
                        sourceReferences.Add(new SourceFileReference(sharedFile));
                    }
                }

                return new LibraryExport(metadataReferences, sourceReferences);
            });
        }
예제 #29
0
 public ILibraryExport GetLibraryExport(ILibraryKey target)
 {
     return _libraryExporters.Select(r => r.GetLibraryExport(target))
                                      .FirstOrDefault(export => export != null);
 }
예제 #30
0
        public ILibraryExport GetLibraryExport(ILibraryKey target)
        {
            string assemblyPath;
            if (_resolvedPaths.TryGetValue(target.Name, out assemblyPath))
            {
                return new LibraryExport(new MetadataFileReference(target.Name, assemblyPath));
            }

            return null;
        }
예제 #31
0
        public static ILibraryExport GetExportsRecursive(
            ICache cache,
            ILibraryManager manager,
            ILibraryExportProvider libraryExportProvider,
            ILibraryKey target,
            Func <ILibraryInformation, bool> include)
        {
            var dependencyStopWatch = Stopwatch.StartNew();

            Logger.TraceInformation("[{0}]: Resolving references for '{1}' {2}", typeof(ProjectExportProviderHelper).Name, target.Name, target.Aspect);

            var references       = new Dictionary <string, IMetadataReference>(StringComparer.OrdinalIgnoreCase);
            var sourceReferences = new Dictionary <string, ISourceReference>(StringComparer.OrdinalIgnoreCase);

            // Walk the dependency tree and resolve the library export for all references to this project
            var queue     = new Queue <Node>();
            var processed = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            var rootNode = new Node
            {
                Library = manager.GetLibraryInformation(target.Name, target.Aspect)
            };

            queue.Enqueue(rootNode);

            while (queue.Count > 0)
            {
                var node = queue.Dequeue();

                // Skip it if we've already seen it
                if (!processed.Add(node.Library.Name))
                {
                    continue;
                }

                if (include(node.Library))
                {
                    var libraryExport = libraryExportProvider.GetLibraryExport(target
                                                                               .ChangeName(node.Library.Name)
                                                                               .ChangeAspect(null));

                    if (libraryExport != null)
                    {
                        if (node.Parent == rootNode)
                        {
                            // Only export sources from first level dependencies
                            ProcessExport(cache, libraryExport, references, sourceReferences);
                        }
                        else
                        {
                            // Skip source exports from anything else
                            ProcessExport(cache, libraryExport, references, sourceReferences: null);
                        }
                    }
                }

                foreach (var dependency in node.Library.Dependencies)
                {
                    var childNode = new Node
                    {
                        Library = manager.GetLibraryInformation(dependency, null),
                        Parent  = node
                    };

                    queue.Enqueue(childNode);
                }
            }

            dependencyStopWatch.Stop();
            Logger.TraceInformation("[{0}]: Resolved {1} references for '{2}' in {3}ms",
                                    typeof(ProjectExportProviderHelper).Name,
                                    references.Count,
                                    target.Name,
                                    dependencyStopWatch.ElapsedMilliseconds);

            return(new LibraryExport(
                       references.Values.ToList(),
                       sourceReferences.Values.ToList()));
        }
예제 #32
0
        public CompilationContext CompileProject(
            Project project,
            ILibraryKey target,
            IEnumerable <IMetadataReference> incomingReferences,
            IEnumerable <ISourceReference> incomingSourceReferences)
        {
            var path = project.ProjectDirectory;
            var name = project.Name.TrimStart('/');

            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);

            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);

            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);
                }

                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);
        }
예제 #33
0
        private CompilationModules GetCompileModules(ILibraryKey target)
        {
            // The only thing that matters is the runtime environment
            // when loading the compilation modules, so use that as the cache key
            var key = Tuple.Create(
                target.Name,
                _environment.RuntimeFramework,
                _environment.Configuration,
                "compilemodules");

            return _cache.Get<CompilationModules>(key, _ => {
                var modules = new List<ICompileModule>();

                var childContext = _loadContextFactory.Create(_services);

                var preprocessAssembly = childContext.Load(target.Name + "!preprocess");

                foreach (var preprocessType in preprocessAssembly.ExportedTypes) {
                    if (preprocessType.GetTypeInfo().ImplementedInterfaces.Contains(typeof(ICompileModule))) {
                        var module = (ICompileModule)ActivatorUtilities.CreateInstance(_services, preprocessType);
                        modules.Add(module);
                    }
                }

                // We do this so that the load context is disposed when the cache entry
                // expires
                return new CompilationModules {
                    LoadContext = childContext,
                    Modules = modules,
                };
            });
        }
예제 #34
0
        public static ILibraryExport GetExportsRecursive(
            ICache cache,
            ILibraryManager manager,
            ILibraryExportProvider libraryExportProvider,
            ILibraryKey target,
            Func<ILibraryInformation, bool> include)
        {
            var dependencyStopWatch = Stopwatch.StartNew();
            Logger.TraceInformation("[{0}]: Resolving references for '{1}' {2}", typeof(ProjectExportProviderHelper).Name, target.Name, target.Aspect);

            var references = new Dictionary<string, IMetadataReference>(StringComparer.OrdinalIgnoreCase);
            var sourceReferences = new Dictionary<string, ISourceReference>(StringComparer.OrdinalIgnoreCase);

            // Walk the dependency tree and resolve the library export for all references to this project
            var stack = new Queue<Node>();
            var processed = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

            var rootNode = new Node
            {
                Library = manager.GetLibraryInformation(target.Name, target.Aspect)
            };

            stack.Enqueue(rootNode);

            while (stack.Count > 0)
            {
                var node = stack.Dequeue();

                // Skip it if we've already seen it
                if (!processed.Add(node.Library.Name))
                {
                    continue;
                }

                if (include(node.Library))
                {
                    var libraryExport = libraryExportProvider.GetLibraryExport(target
                        .ChangeName(node.Library.Name)
                        .ChangeAspect(null));

                    if (libraryExport != null)
                    {
                        if (node.Parent == rootNode)
                        {
                            // Only export sources from first level dependencies
                            ProcessExport(cache, libraryExport, references, sourceReferences);
                        }
                        else
                        {
                            // Skip source exports from anything else
                            ProcessExport(cache, libraryExport, references, sourceReferences: null);
                        }
                    }
                }

                foreach (var dependency in node.Library.Dependencies)
                {
                    var childNode = new Node
                    {
                        Library = manager.GetLibraryInformation(dependency, null),
                        Parent = node
                    };

                    stack.Enqueue(childNode);
                }
            }

            dependencyStopWatch.Stop();
            Logger.TraceInformation("[{0}]: Resolved {1} references for '{2}' in {3}ms",
                                  typeof(ProjectExportProviderHelper).Name,
                                  references.Count,
                                  target.Name,
                                  dependencyStopWatch.ElapsedMilliseconds);

            return new LibraryExport(
                references.Values.ToList(),
                sourceReferences.Values.ToList());
        }
예제 #35
0
 public ILibraryExport GetLibraryExport(ILibraryKey target)
 {
     return(_libraryExporters.Select(r => r.GetLibraryExport(target))
            .FirstOrDefault(export => export != null));
 }
예제 #36
0
        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.TrimStart('/');

            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 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 fsproj = GetProjectInfo(path);

      _watcher.WatchProject(path);
      _watcher.WatchFile(project.ProjectFilePath);
      _watcher.WatchFile(fsproj.ProjectFilePath);
      foreach (var f in fsproj.Files)
        _watcher.WatchFile(f);

      if (_cacheContextAccessor.Current != null)
      {
        _cacheContextAccessor.Current.Monitor(new FileWriteTimeCacheDependency(fsproj.ProjectFilePath));

        // Monitor the trigger {projectName}_BuildOutputs
        var buildOutputsName = project.Name + "_BuildOutputs";

        _cacheContextAccessor.Current.Monitor(_namedDependencyProvider.GetNamedDependency(buildOutputsName));
        _cacheContextAccessor.Current.Monitor(_namedDependencyProvider.GetNamedDependency(project.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")}");

        foreach (var source in fsproj.Files)
          args.Add(source);

        // 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(FSharpCompilationMessage.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(
          project,
          fsproj,
          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;
    }
예제 #38
0
        public ILibraryExport GetLibraryExport(ILibraryKey target)
        {
            PackageDescription description;
            if (!_packageDescriptions.TryGetValue(target.Name, out description))
            {
                return null;
            }

            var references = new Dictionary<string, IMetadataReference>(StringComparer.OrdinalIgnoreCase);

            if (!TryPopulateMetadataReferences(description, target.TargetFramework, references))
            {
                return null;
            }

            // REVIEW: This requires more design
            var sourceReferences = new List<ISourceReference>();

            foreach (var sharedSource in GetSharedSources(description, target.TargetFramework))
            {
                sourceReferences.Add(new SourceFileReference(sharedSource));
            }

            return new LibraryExport(references.Values.ToList(), sourceReferences);
        }
        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 fsproj = GetProjectInfo(path);

            _watcher.WatchProject(path);
            _watcher.WatchFile(project.ProjectFilePath);
            _watcher.WatchFile(fsproj.ProjectFilePath);
            foreach (var f in fsproj.Files)
            {
                _watcher.WatchFile(f);
            }

            if (_cacheContextAccessor.Current != null)
            {
                _cacheContextAccessor.Current.Monitor(new FileWriteTimeCacheDependency(fsproj.ProjectFilePath));

                // Monitor the trigger {projectName}_BuildOutputs
                var buildOutputsName = project.Name + "_BuildOutputs";

                _cacheContextAccessor.Current.Monitor(_namedDependencyProvider.GetNamedDependency(buildOutputsName));
                _cacheContextAccessor.Current.Monitor(_namedDependencyProvider.GetNamedDependency(project.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")}");

                    foreach (var source in fsproj.Files)
                    {
                        args.Add(source);
                    }

                    // 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(FSharpCompilationMessage.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(
                        project,
                        fsproj,
                        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);
        }
예제 #40
0
        public ILibraryExport GetLibraryExport(ILibraryKey target)
        {
            Project project;
            // Can't find a project file with the name so bail
            if (!_projectResolver.TryResolveProject(target.Name, out project))
            {
                return null;
            }

            Logger.TraceInformation("[{0}]: GetLibraryExport({1}, {2}, {3}, {4})", GetType().Name, target.Name, target.TargetFramework, target.Configuration, target.Aspect);

            var targetFrameworkInformation = project.GetTargetFramework(target.TargetFramework);

            // This is the target framework defined in the project. If there were no target frameworks
            // defined then this is the targetFramework specified
            if (targetFrameworkInformation.FrameworkName != null)
            {
                target = target.ChangeTargetFramework(targetFrameworkInformation.FrameworkName);
            }

            var key = Tuple.Create(
                target.Name,
                target.TargetFramework,
                target.Configuration,
                target.Aspect);

            var cache = (ICache)_serviceProvider.GetService(typeof(ICache));
            var cacheContextAccessor = (ICacheContextAccessor)_serviceProvider.GetService(typeof(ICacheContextAccessor));
            var namedCacheDependencyProvider = (INamedCacheDependencyProvider)_serviceProvider.GetService(typeof(INamedCacheDependencyProvider));
            var loadContextFactory = (IAssemblyLoadContextFactory)_serviceProvider.GetService(typeof(IAssemblyLoadContextFactory));

            return cache.Get<ILibraryExport>(key, ctx =>
            {
                var metadataReferences = new List<IMetadataReference>();
                var sourceReferences = new List<ISourceReference>();

                if (!string.IsNullOrEmpty(targetFrameworkInformation.AssemblyPath))
                {
                    var assemblyPath = ResolvePath(project, target.Configuration, targetFrameworkInformation.AssemblyPath);
                    var pdbPath = ResolvePath(project, target.Configuration, targetFrameworkInformation.PdbPath);

                    metadataReferences.Add(new CompiledProjectMetadataReference(project, assemblyPath, pdbPath));
                }
                else
                {
                    var provider = project.CompilerServices?.ProjectCompiler ?? Project.DefaultCompiler;

                    // Find the default project exporter
                    var projectCompiler = _projectCompilers.GetOrAdd(provider, typeInfo =>
                    {
                        return CompilerServices.CreateService<IProjectCompiler>(_serviceProvider, _projectLoadContext.Value, typeInfo);
                    });

                    Logger.TraceInformation("[{0}]: GetProjectReference({1}, {2}, {3}, {4})", provider.TypeName, target.Name, target.TargetFramework, target.Configuration, target.Aspect);

                    // Get the exports for the project dependencies
                    var projectExport = new Lazy<ILibraryExport>(() =>
                    {
                        // TODO: Cache?
                        var context = new ApplicationHostContext(_serviceProvider,
                                                                project.ProjectDirectory,
                                                                packagesDirectory: null,
                                                                configuration: target.Configuration,
                                                                targetFramework: target.TargetFramework,
                                                                cache: cache,
                                                                cacheContextAccessor: cacheContextAccessor,
                                                                namedCacheDependencyProvider: namedCacheDependencyProvider,
                                                                loadContextFactory: loadContextFactory);

                        context.DependencyWalker.Walk(project.Name, project.Version, target.TargetFramework);

                        return ProjectExportProviderHelper.GetExportsRecursive(
                          cache,
                          context.LibraryManager,
                          context.LibraryExportProvider,
                          target,
                          dependenciesOnly: true);
                    });

                    // Resolve the project export
                    IMetadataProjectReference projectReference = projectCompiler.CompileProject(
                        project,
                        target,
                        () => projectExport.Value,
                        () => CompositeResourceProvider.Default.GetResources(project));

                    metadataReferences.Add(projectReference);

                    // Shared sources
                    foreach (var sharedFile in project.Files.SharedFiles)
                    {
                        sourceReferences.Add(new SourceFileReference(sharedFile));
                    }
                }

                return new LibraryExport(metadataReferences, sourceReferences);
            });
        }
예제 #41
0
        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));

                // 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.GetCompilationSettings(
                target.TargetFramework,
                target.Configuration);

            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.AsImmutable());

            IList <SyntaxTree> trees = GetSyntaxTrees(
                project,
                sourceFiles,
                incomingSourceReferences,
                parseOptions);

            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>();


            using (var childContext = _loadContextFactory.Create())
            {
                if (isMainAspect && project.PreprocessSourceFiles.Any())
                {
                    try
                    {
                        var preprocessAssembly = childContext.Load(project.Name + "!preprocess");
                        foreach (var preprocessType in preprocessAssembly.ExportedTypes)
                        {
                            if (preprocessType.GetTypeInfo().ImplementedInterfaces.Contains(typeof(ICompileModule)))
                            {
                                var module = (ICompileModule)ActivatorUtilities.CreateInstance(_services, preprocessType);
                                modules.Add(module);
                            }
                        }
                    }
                    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);
                        }
                    }
                }

                foreach (var module in modules)
                {
                    module.BeforeCompile(compilationContext);
                }
            }

            sw.Stop();
            Trace.TraceInformation("[{0}]: Compiled '{1}' in {2}ms", GetType().Name, name, sw.ElapsedMilliseconds);

            return(compilationContext);
        }