public IMetadataProjectReference CompileProject(
      CompilationProjectContext projectContext,
      Func<LibraryExport> referenceResolver,
      Func<IList<ResourceDescriptor>> resourcesResolver)
        {
            var export = referenceResolver();
              if (export == null)
              {
              return null;
              }

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

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

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

              // Project reference
              return new FSharpProjectReference(compilationContext);
        }
        public CompiledProjectMetadataReference(CompilationProjectContext project, string assemblyPath, string pdbPath)
        {
            Name        = project.Target.Name;
            ProjectPath = project.ProjectFilePath;
            Path        = assemblyPath;

            _project      = project;
            _assemblyPath = assemblyPath;
            _pdbPath      = pdbPath;
        }
        public CompiledProjectMetadataReference(CompilationProjectContext project, string assemblyPath, string pdbPath)
        {
            Name = project.Target.Name;
            ProjectPath = project.ProjectFilePath;
            Path = assemblyPath;

            _project = project;
            _assemblyPath = assemblyPath;
            _pdbPath = pdbPath;
        }
예제 #4
0
   internal CompilationContext(
 CompilationProjectContext project,
 FSharpProjectInfo projectInfo,
 bool success,
 IEnumerable<FSharpDiagnosticMessage> messages,
 byte[] assembly,
 byte[] pdb,
 byte[] xml)
   {
       _project = project;
         ProjectInfo = projectInfo;
         Success = success;
         Diagnostics = messages.ToList();
         Assembly = assembly;
         Pdb = pdb;
         Xml = xml;
   }
예제 #5
0
 public DesignTimeProjectReference(CompilationProjectContext project, CompileResponse response)
 {
     _project = project;
     _response = response;
 }
예제 #6
0
        public CompilationContext CompileProject(
      CompilationProjectContext projectContext,
      IEnumerable<IMetadataReference> incomingReferences,
      IEnumerable<ISourceReference> incomingSourceReferences,
      Func<IList<ResourceDescriptor>> resourcesResolver)
        {
            var path = projectContext.ProjectDirectory;
              var name = projectContext.Target.Name;
              var projectInfo = GetProjectInfo(projectContext.ProjectFilePath);

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

            // Monitor the trigger {projectName}_BuildOutputs
            var buildOutputsName = name + "_BuildOutputs";

            _cacheContextAccessor.Current.Monitor(_namedDependencyProvider.GetNamedDependency(buildOutputsName));
            _cacheContextAccessor.Current.Monitor(_namedDependencyProvider.GetNamedDependency(name + "_Dependencies"));
              }

              Logger.TraceInformation("[{0}]: Compiling '{1}'", GetType().Name, name);
              var sw = Stopwatch.StartNew();

              CompilationContext context;
              using (new ResolveHooker())
              using (var files = new TempFiles())
              {
            var outFileName = $"{name}.dll";
            var outDir = files.CreateDir();
            var outFile = Path.Combine(outDir, outFileName);
            var args = new List<string>();
            args.Add("fsc.exe");
            args.Add($"--out:{outFile}");
            args.Add("--target:library");
            args.Add("--noframework");
            args.Add("--optimize-");
            args.Add("--debug");
            if (SupportsPdbGeneration)
              args.Add($"--pdb:{Path.ChangeExtension(outFile, ".pdb")}");
            args.Add($"--doc:{Path.ChangeExtension(outFile, ".xml")}");
            args.AddRange(projectInfo.Files);

            // These are the metadata references being used by your project.
            // Everything in your project.json is resolved and normailzed here:
            // - Project references
            // - Package references are turned into the appropriate assemblies
            // Each IMetadaReference maps to an assembly
            foreach (var reference in incomingReferences)
            {
              string fileName = null;
              var projectRef = reference as IMetadataProjectReference;
              if (projectRef != null)
              {
            var dir = files.CreateDir();
            projectRef.EmitAssembly(dir);
            fileName = Path.Combine(dir, $"{projectRef.Name}.dll");
              }

              var fileRef = reference as IMetadataFileReference;
              if (fileRef != null)
            fileName = fileRef.Path;
              else if (fileName == null)
            throw new Exception($"Unknown reference type {reference.GetType()}");

              args.Add($"-r:{fileName}");
            }

            //Console.WriteLine(string.Join(Environment.NewLine, args));
            var scs = new SimpleSourceCodeServices();
            var result = scs.Compile(args.ToArray());
            var errors = result.Item1.Select(FSharpDiagnosticMessage.CompilationMessage);
            var resultCode = result.Item2;

            //System.Diagnostics.Debugger.Launch();
            MemoryStream assembly = null;
            MemoryStream pdb = null;
            MemoryStream xml = null;
            if (resultCode == 0)
            {
              assembly = new MemoryStream();
              xml = new MemoryStream();

              using (var fs = File.OpenRead(outFile))
            fs.CopyTo(assembly);

              var pdbFile = Path.ChangeExtension(outFile, ".pdb");
              if (File.Exists(pdbFile))
              {
            pdb = new MemoryStream();
            using (var fs = File.OpenRead(pdbFile))
              fs.CopyTo(pdb);
              }

              var xmlFile = Path.ChangeExtension(outFile, ".xml");
              if (File.Exists(xmlFile))
              {
            xml = new MemoryStream();
            using (var fs = File.OpenRead(xmlFile))
              fs.CopyTo(xml);
              }
            }

            context = new CompilationContext(
              projectContext,
              projectInfo,
              resultCode == 0,
              errors,
              assembly?.ToArray(),
              pdb?.ToArray(),
              xml?.ToArray());

            assembly?.Dispose();
            pdb?.Dispose();
            xml?.Dispose();
              }

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

              return context;
        }
예제 #7
0
        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;
        }
예제 #8
0
        private IList<SyntaxTree> GetSyntaxTrees(CompilationProjectContext project,
                                                 IEnumerable<string> sourceFiles,
                                                 IEnumerable<ISourceReference> sourceReferences,
                                                 CSharpParseOptions parseOptions,
                                                 bool isMainAspect)
        {
            var trees = new List<SyntaxTree>();

            var dirs = new HashSet<string>();

            if (isMainAspect) {
                dirs.Add(project.ProjectDirectory);
            }

            foreach (var sourcePath in sourceFiles) {
                _watcher.WatchFile(sourcePath);

                var syntaxTree = CreateSyntaxTree(sourcePath, parseOptions);

                trees.Add(syntaxTree);
            }

            foreach (var sourceFileReference in sourceReferences.OfType<ISourceFileReference>()) {
                var sourcePath = sourceFileReference.Path;

                _watcher.WatchFile(sourcePath);

                var syntaxTree = CreateSyntaxTree(sourcePath, parseOptions);

                trees.Add(syntaxTree);
            }

            // Watch all directories
            var ctx = _cacheContextAccessor.Current;

            foreach (var d in dirs) {
                ctx?.Monitor(new FileWriteTimeCacheDependency(d));

                // TODO: Make the file watcher hand out cache dependencies as well
                _watcher.WatchDirectory(d, ".cs");
            }

            return trees;
        }
예제 #9
0
        private static CSharpCompilation ApplyVersionInfo(CSharpCompilation compilation, CompilationProjectContext project,
            CSharpParseOptions parseOptions)
        {
            const string assemblyFileVersionName = "System.Reflection.AssemblyFileVersionAttribute";
            const string assemblyVersionName = "System.Reflection.AssemblyVersionAttribute";
            const string assemblyInformationalVersion = "System.Reflection.AssemblyInformationalVersionAttribute";

            var assemblyAttributes = compilation.Assembly.GetAttributes();

            var foundAssemblyFileVersion = false;
            var foundAssemblyVersion = false;
            var foundAssemblyInformationalVersion = false;

            foreach (var assembly in assemblyAttributes) {
                string attributeName = assembly.AttributeClass.ToString();

                if (string.Equals(attributeName, assemblyFileVersionName, StringComparison.Ordinal)) {
                    foundAssemblyFileVersion = true;
                }
                else if (string.Equals(attributeName, assemblyVersionName, StringComparison.Ordinal)) {
                    foundAssemblyVersion = true;
                }
                else if (string.Equals(attributeName, assemblyInformationalVersion, StringComparison.Ordinal)) {
                    foundAssemblyInformationalVersion = true;
                }
            }

            var versionAttributes = new StringBuilder();
            if (!foundAssemblyFileVersion) {
                versionAttributes.AppendLine($"[assembly:{assemblyFileVersionName}(\"{project.AssemblyFileVersion}\")]");
            }

            if (!foundAssemblyVersion) {
                versionAttributes.AppendLine($"[assembly:{assemblyVersionName}(\"{RemovePrereleaseTag(project.Version)}\")]");
            }

            if (!foundAssemblyInformationalVersion) {
                versionAttributes.AppendLine($"[assembly:{assemblyInformationalVersion}(\"{project.Version}\")]");
            }

            if (versionAttributes.Length != 0) {
                compilation = compilation.AddSyntaxTrees(new[]
                {
                    CSharpSyntaxTree.ParseText(versionAttributes.ToString(), parseOptions)
                });
            }

            return compilation;
        }
        public IMetadataProjectReference CompileProject(
            CompilationProjectContext projectContext,
            Func<LibraryExport> referenceResolver,
            Func<IList<ResourceDescriptor>> resourcesResolver)
        {
            List<DiagnosticResult> diagnosticResults = new List<DiagnosticResult>();

            var module = new PostSharpCompilerModule(_services, _workingDirectory);

            var export = referenceResolver();
            if (export == null)
            {
                return null;
            }

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

            var processedIncomingReferences = new List<IMetadataReference>(incomingReferences.Count);

            foreach ( var reference in incomingReferences )
            {
                
                var projectReference = reference as IMetadataProjectReference;
                if ( projectReference != null )
                {
                    // If we have a PostSharpProjectReference, we have to compile it using EmitAssembly and replace the reference by a MetadataFileReference.
                    string referencePath = Path.Combine(_workingDirectory, projectReference.Name + ".dll");
                    if (!File.Exists(referencePath))
                    {
                        DiagnosticResult diagnostics = projectReference.EmitAssembly(_workingDirectory);
                        diagnosticResults.Add(diagnostics);
                    }

                    processedIncomingReferences.Add(new MetadataFileReference(projectReference.Name, referencePath));

                }
                else
                {
                    processedIncomingReferences.Add(reference);
                }

                
            }

            var compilationContext = _compiler.CompileProject(
                projectContext,
                processedIncomingReferences,
                incomingSourceReferences,
                resourcesResolver);

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

            compilationContext.Modules.Add(module);

            // Project reference
            return new PostSharpProjectReference( new RoslynProjectReference(compilationContext), diagnosticResults, _workingDirectory );
        }