public IEnumerable <ProjectDependency> ResolveProjectDependencies(ProjectContext projectContext, HashSet <string> preResolvedProjects = null)
        {
            preResolvedProjects = preResolvedProjects ?? new HashSet <string>();

            var projectExports = projectContext.CreateExporter("_").GetDependencies();
            var possibleProjectDependencies =
                FindPossibleProjectDependencies(projectContext.ProjectFile.ProjectFilePath);

            var projectDependencies = new List <ProjectDependency>();

            foreach (var projectExport in projectExports)
            {
                var projectExportName = projectExport.Library.Identity.Name;
                ProjectDependency projectDependency;

                if (!possibleProjectDependencies.TryGetValue(projectExportName, out projectDependency))
                {
                    if (projectExport.Library.Identity.Type.Equals(LibraryType.Project) &&
                        !preResolvedProjects.Contains(projectExportName))
                    {
                        MigrationErrorCodes
                        .MIGRATE1014($"Unresolved project dependency ({projectExportName})").Throw();
                    }
                    else
                    {
                        continue;
                    }
                }

                projectDependencies.Add(projectDependency);
            }

            return(projectDependencies);
        }
Exemple #2
0
        private ProjectId AddProject(ProjectContext project)
        {
            // Create the framework specific project and add it to the workspace
            var projectInfo = ProjectInfo.Create(
                                ProjectId.CreateNewId(),
                                VersionStamp.Create(),
                                project.ProjectFile.Name + "+" + project.TargetFramework,
                                project.ProjectFile.Name,
                                LanguageNames.CSharp,
                                project.ProjectFile.ProjectFilePath);

            OnProjectAdded(projectInfo);

            // TODO: ctor argument?
            var configuration = "Debug";

            var compilationOptions = project.GetLanguageSpecificCompilerOptions(project.TargetFramework, configuration);

            var compilationSettings = ToCompilationSettings(compilationOptions, project.TargetFramework, project.ProjectFile.ProjectDirectory);

            OnParseOptionsChanged(projectInfo.Id, new CSharpParseOptions(compilationSettings.LanguageVersion, preprocessorSymbols: compilationSettings.Defines));

            OnCompilationOptionsChanged(projectInfo.Id, compilationSettings.CompilationOptions);

            foreach (var file in project.ProjectFile.Files.SourceFiles)
            {
                AddSourceFile(projectInfo, file);
            }

            var exporter = project.CreateExporter(configuration);

            foreach (var dependency in exporter.GetDependencies())
            {
                var projectDependency = dependency.Library as ProjectDescription;
                if (projectDependency != null)
                {
                    var projectDependencyContext = ProjectContext.Create(projectDependency.Project.ProjectFilePath, projectDependency.Framework);

                    var id = AddProject(projectDependencyContext);

                    OnProjectReferenceAdded(projectInfo.Id, new ProjectReference(id));
                }
                else
                {
                    foreach (var asset in dependency.CompilationAssemblies)
                    {
                        OnMetadataReferenceAdded(projectInfo.Id, GetMetadataReference(asset.ResolvedPath));
                    }
                }

                foreach (var file in dependency.SourceReferences)
                {
                    AddSourceFile(projectInfo, file);
                }
            }

            return projectInfo.Id;
        }
Exemple #3
0
        private static bool Compile(ProjectContext context, string configuration, string outputOptionValue, string intermediateOutputValue, bool buildProjectReferences, bool noHost)
        {
            // Set up Output Paths
            string outputPath             = GetOutputPath(context, configuration, outputOptionValue);
            string intermediateOutputPath = GetIntermediateOutputPath(context, configuration, intermediateOutputValue, outputOptionValue);

            Directory.CreateDirectory(outputPath);
            Directory.CreateDirectory(intermediateOutputPath);

            // Create the library exporter
            var exporter = context.CreateExporter(configuration);

            // Gather exports for the project
            var dependencies = exporter.GetDependencies().ToList();

            if (buildProjectReferences)
            {
                var projects = new Dictionary <string, ProjectDescription>();

                // Build project references
                foreach (var dependency in dependencies)
                {
                    var projectDependency = dependency.Library as ProjectDescription;

                    if (projectDependency != null && projectDependency.Project.Files.SourceFiles.Any())
                    {
                        projects[projectDependency.Identity.Name] = projectDependency;
                    }
                }

                foreach (var projectDependency in Sort(projects))
                {
                    // Skip compiling project dependencies since we've already figured out the build order
                    var compileResult = Command.Create("dotnet-compile",
                                                       $"--framework {projectDependency.Framework} " +
                                                       $"--configuration {configuration} " +
                                                       $"--output \"{outputPath}\" " +
                                                       $"--temp-output \"{intermediateOutputPath}\" " +
                                                       "--no-project-dependencies " +
                                                       (noHost ? "--no-host " : string.Empty) +
                                                       $"\"{projectDependency.Project.ProjectDirectory}\"")
                                        .ForwardStdOut()
                                        .ForwardStdErr()
                                        .Execute();

                    if (compileResult.ExitCode != 0)
                    {
                        return(false);
                    }
                }

                projects.Clear();
            }

            return(CompileProject(context, configuration, outputPath, intermediateOutputPath, dependencies, noHost));
        }
Exemple #4
0
        public static ProjectContextSnapshot Create(ProjectContext context, string configuration, IEnumerable <string> currentSearchPaths)
        {
            var snapshot = new ProjectContextSnapshot();

            var allDependencyDiagnostics = new List <DiagnosticMessage>();

            allDependencyDiagnostics.AddRange(context.LibraryManager.GetAllDiagnostics());
            allDependencyDiagnostics.AddRange(DependencyTypeChangeFinder.Diagnose(context, currentSearchPaths));

            var diagnosticsLookup = allDependencyDiagnostics.ToLookup(d => d.Source);

            var allExports = context.CreateExporter(configuration)
                             .GetAllExports()
                             .ToDictionary(export => export.Library.Identity.Name);

            var allSourceFiles       = new List <string>(context.ProjectFile.Files.SourceFiles);
            var allFileReferences    = new List <string>();
            var allProjectReferences = new List <ProjectReferenceDescription>();
            var allDependencies      = new Dictionary <string, DependencyDescription>();

            // All exports are returned. When the same library name have a ReferenceAssembly type export and a Package type export
            // both will be listed as dependencies. Prefix "fx/" will be added to ReferenceAssembly type dependency.
            foreach (var export in allExports.Values)
            {
                allSourceFiles.AddRange(export.SourceReferences.Select(f => f.ResolvedPath));
                var diagnostics = diagnosticsLookup[export.Library].ToList();
                var description = DependencyDescription.Create(export.Library, diagnostics, allExports);
                allDependencies[description.Name] = description;

                var projectDescription = export.Library as ProjectDescription;
                if (projectDescription != null)
                {
                    if (projectDescription.Identity.Name != context.ProjectFile.Name)
                    {
                        allProjectReferences.Add(ProjectReferenceDescription.Create(projectDescription));
                    }
                }
                else
                {
                    allFileReferences.AddRange(export.CompilationAssemblies.Select(asset => asset.ResolvedPath));
                }
            }

            snapshot.RootDependency        = context.ProjectFile.Name;
            snapshot.TargetFramework       = context.TargetFramework;
            snapshot.SourceFiles           = allSourceFiles.Distinct(StringComparer.OrdinalIgnoreCase).OrderBy(path => path).ToList();
            snapshot.CompilerOptions       = context.GetLanguageSpecificCompilerOptions(context.TargetFramework, configuration);
            snapshot.ProjectReferences     = allProjectReferences.OrderBy(reference => reference.Name).ToList();
            snapshot.FileReferences        = allFileReferences.Distinct(StringComparer.OrdinalIgnoreCase).OrderBy(path => path).ToList();
            snapshot.DependencyDiagnostics = allDependencyDiagnostics;
            snapshot.Dependencies          = allDependencies;

            return(snapshot);
        }
        public static ProjectContextSnapshot Create(ProjectContext context, string configuration, IEnumerable<string> currentSearchPaths)
        {
            var snapshot = new ProjectContextSnapshot();

            var allDependencyDiagnostics = new List<DiagnosticMessage>();
            allDependencyDiagnostics.AddRange(context.LibraryManager.GetAllDiagnostics());
            allDependencyDiagnostics.AddRange(DependencyTypeChangeFinder.Diagnose(context, currentSearchPaths));

            var diagnosticsLookup = allDependencyDiagnostics.ToLookup(d => d.Source);

            var allExports = context.CreateExporter(configuration)
                                    .GetAllExports()
                                    .ToDictionary(export => export.Library.Identity.Name);

            var allSourceFiles = new List<string>(context.ProjectFile.Files.SourceFiles);
            var allFileReferences = new List<string>();
            var allProjectReferences = new List<ProjectReferenceDescription>();
            var allDependencies = new Dictionary<string, DependencyDescription>();

            // All exports are returned. When the same library name have a ReferenceAssembly type export and a Package type export
            // both will be listed as dependencies. Prefix "fx/" will be added to ReferenceAssembly type dependency.
            foreach (var export in allExports.Values)
            {
                allSourceFiles.AddRange(export.SourceReferences.Select(f => f.ResolvedPath));
                var diagnostics = diagnosticsLookup[export.Library].ToList();
                var description = DependencyDescription.Create(export.Library, diagnostics, allExports);
                allDependencies[description.Name] = description;

                var projectDescription = export.Library as ProjectDescription;
                if (projectDescription != null)
                {
                    if (projectDescription.Identity.Name != context.ProjectFile.Name)
                    { 
                        allProjectReferences.Add(ProjectReferenceDescription.Create(projectDescription));
                    }
                }
                else
                {
                    allFileReferences.AddRange(export.CompilationAssemblies.Select(asset => asset.ResolvedPath));
                }
            }

            snapshot.RootDependency = context.ProjectFile.Name;
            snapshot.TargetFramework = context.TargetFramework;
            snapshot.SourceFiles = allSourceFiles.Distinct(StringComparer.OrdinalIgnoreCase).OrderBy(path => path).ToList();
            snapshot.CompilerOptions = context.GetLanguageSpecificCompilerOptions(context.TargetFramework, configuration);
            snapshot.ProjectReferences = allProjectReferences.OrderBy(reference => reference.Name).ToList();
            snapshot.FileReferences = allFileReferences.Distinct(StringComparer.OrdinalIgnoreCase).OrderBy(path => path).ToList();
            snapshot.DependencyDiagnostics = allDependencyDiagnostics;
            snapshot.Dependencies = allDependencies;

            return snapshot;
        }
Exemple #6
0
        public static AssemblyLoadContext CreateLoadContext(
            [NotNull] this ProjectContext context,
            [NotNull] string runtimeIdentifier,
            [NotNull] string configuration,
            [CanBeNull] string outputPath = null)
        {
            var exporter   = context.CreateExporter(configuration);
            var assemblies = new Dictionary <AssemblyName, string>(AssemblyNameComparer.OrdinalIgnoreCase);
            var dllImports = new Dictionary <string, string>();

            var fallbacks = DependencyContext.Default.RuntimeGraph.FirstOrDefault(f => f.Runtime.Equals(runtimeIdentifier));

            if (fallbacks == null)
            {
                throw new InvalidOperationException($"Failed to load runtime fallback graph for: {runtimeIdentifier}");
            }

            foreach (var export in exporter.GetAllExports())
            {
                var group = SelectGroup(export.RuntimeAssemblyGroups, fallbacks);

                // TODO: Handle resource assemblies
                if (group != null)
                {
                    foreach (var asset in group.Assets)
                    {
                        // REVIEW: Should we use the following?
                        // AssemblyLoadContext.GetAssemblyName(asset.ResolvedPath);
                        var assemblyName = new AssemblyName(asset.Name);
                        assemblies[assemblyName] = asset.ResolvedPath;
                    }
                }

                group = SelectGroup(export.NativeLibraryGroups, fallbacks);

                if (group != null)
                {
                    foreach (var asset in group.Assets)
                    {
                        dllImports[asset.Name] = asset.ResolvedPath;
                    }
                }
            }

            return(new DesignTimeProjectLoadContext(
                       assemblies,
                       dllImports,

                       // Add the project's output directory path to ensure project-to-project references get located
                       new[] { context.GetOutputPaths(configuration, outputPath: outputPath).CompilationOutputPath }));
        }
Exemple #7
0
        public IEnumerable <TemplatePackage> GetInstalledTemplates()
        {
            if (_templatesProjectContext.LockFile == null)
            {
                RestoreTemplatePackages();
                ReloadTemplatesProject();
            }

            var templatePackages = _templatesProjectContext.LockFile.PackageLibraries;
            var exporter         = _templatesProjectContext.CreateExporter("Debug");
            var packages         = exporter.GetAllExports().Select(e => e.Library).OfType <PackageDescription>();

            foreach (var package in packages)
            {
                var manifestFile = package.Library.Files.SingleOrDefault(f => f == "templates\\templates.json");

                // TODO: Handle other packages turning up in lock file due to template packages having dependencies
                if (manifestFile != null)
                {
                    var templatePackage = new TemplatePackage {
                        Id = package.Identity.Name, Version = package.Identity.Version.ToString()
                    };

                    var manifestFilePath = Path.Combine(package.Path, manifestFile).Replace('\\', Path.DirectorySeparatorChar);
                    var manifest         = JObject.Parse(File.ReadAllText(manifestFilePath));

                    var projectTemplates = manifest["projectTemplates"].Children <JProperty>();

                    var templates = projectTemplates.Select(c =>
                                                            new Template
                    {
                        Name    = c.Value["title"].ToString(),
                        Package = templatePackage,
                        Files   = package.Library.Files
                                  .Where(f => f.StartsWith("templates\\" + c.Name + "\\"))
                                  .Select(f => new TemplateFile
                        {
                            SourcePath = Path.Combine(package.Path, f).Replace('\\', Path.DirectorySeparatorChar),
                            DestPath   = f.Substring(("templates\\" + c.Name + "\\files\\").Length)
                        })
                                  .ToList(),
                        Path = c.Name
                    });

                    templatePackage.Templates = templates.ToList();

                    yield return(templatePackage);
                }
            }
        }
Exemple #8
0
        public ProjectInfo(ProjectContext context,
                           string configuration,
                           IEnumerable <string> currentSearchPaths)
        {
            var allExports     = context.CreateExporter(configuration).GetAllExports().ToList();
            var allDiagnostics = context.LibraryManager.GetAllDiagnostics();

            Context       = context;
            Configuration = configuration;

            var allSourceFiles    = new List <string>(context.ProjectFile.Files.SourceFiles);
            var allFileReferences = new List <string>();

            foreach (var export in allExports)
            {
                allSourceFiles.AddRange(export.SourceReferences);
                allFileReferences.AddRange(export.CompilationAssemblies.Select(asset => asset.ResolvedPath));
            }

            SourceFiles           = allSourceFiles.Distinct(StringComparer.OrdinalIgnoreCase).OrderBy(path => path).ToList();
            CompilationAssembiles = allFileReferences.Distinct(StringComparer.OrdinalIgnoreCase).OrderBy(path => path).ToList();

            var allProjectReferences = new List <ProjectReferenceDescription>();

            var allDependencyDiagnostics = new List <DiagnosticMessage>();

            allDependencyDiagnostics.AddRange(context.LibraryManager.GetAllDiagnostics());
            allDependencyDiagnostics.AddRange(DependencyTypeChangeFinder.Diagnose(Context, currentSearchPaths));

            var diagnosticsLookup = allDependencyDiagnostics.ToLookup(d => d.Source);

            Dependencies = new Dictionary <string, DependencyDescription>();

            foreach (var library in context.LibraryManager.GetLibraries())
            {
                var diagnostics = diagnosticsLookup[library].ToList();
                var description = DependencyDescription.Create(library, diagnostics);
                Dependencies[description.Name] = description;

                if (library is ProjectDescription && library.Identity.Name != context.ProjectFile.Name)
                {
                    allProjectReferences.Add(ProjectReferenceDescription.Create((ProjectDescription)library));
                }
            }

            DependencyDiagnostics = allDependencyDiagnostics;
            ProjectReferences     = allProjectReferences.OrderBy(reference => reference.Name).ToList();
        }
        public static ProjectContextSnapshot Create(ProjectContext context, string configuration, IEnumerable<string> currentSearchPaths)
        {
            var snapshot = new ProjectContextSnapshot();
            
            var allDependencyDiagnostics = new List<DiagnosticMessage>();
            allDependencyDiagnostics.AddRange(context.LibraryManager.GetAllDiagnostics());
            allDependencyDiagnostics.AddRange(DependencyTypeChangeFinder.Diagnose(context, currentSearchPaths));

            var diagnosticsLookup = allDependencyDiagnostics.ToLookup(d => d.Source);

            var allSourceFiles = new List<string>(context.ProjectFile.Files.SourceFiles);
            var allFileReferences = new List<string>();
            var allProjectReferences = new List<ProjectReferenceDescription>();
            var allDependencies = new Dictionary<string, DependencyDescription>();
            
            foreach (var export in context.CreateExporter(configuration).GetDependencies())
            {
                allSourceFiles.AddRange(export.SourceReferences);
                allFileReferences.AddRange(export.CompilationAssemblies.Select(asset => asset.ResolvedPath));

                var library = export.Library;
                var diagnostics = diagnosticsLookup[library].ToList();
                var description = DependencyDescription.Create(library, diagnostics);
                allDependencies[description.Name] = description;

                var projectDescription = library as ProjectDescription;

                if (projectDescription != null)
                {
                    allProjectReferences.Add(ProjectReferenceDescription.Create(projectDescription));
                }
            }

            snapshot.RootDependency = context.ProjectFile.Name;
            snapshot.TargetFramework = context.TargetFramework;
            snapshot.SourceFiles = allSourceFiles.Distinct(StringComparer.OrdinalIgnoreCase).OrderBy(path => path).ToList();
            snapshot.CompilerOptions = context.ProjectFile.GetCompilerOptions(context.TargetFramework, configuration);
            snapshot.ProjectReferences = allProjectReferences.OrderBy(reference => reference.Name).ToList();
            snapshot.FileReferences = allFileReferences.Distinct(StringComparer.OrdinalIgnoreCase).OrderBy(path => path).ToList();
            snapshot.DependencyDiagnostics = allDependencyDiagnostics;
            snapshot.Dependencies = allDependencies;

            return snapshot;
        }