Beispiel #1
0
        /// <summary>
        /// Adds a project to an existing Roslyn workspace.
        /// </summary>
        /// <param name="analyzer">The Buildalyzer project analyzer.</param>
        /// <param name="workspace">A Roslyn workspace.</param>
        /// <param name="addProjectReferences">
        /// <c>true</c> to add projects to the workspace for project references that exist in the same
        /// <see cref="AnalyzerManager" />.
        /// </param>
        /// <returns>The newly added Roslyn project.</returns>
        public static Project AddToWorkspace(this ProjectAnalyzer analyzer, AdhocWorkspace workspace, bool addProjectReferences = false)
        {
            if (analyzer == null)
            {
                throw new ArgumentNullException(nameof(analyzer));
            }

            if (workspace == null)
            {
                throw new ArgumentNullException(nameof(workspace));
            }

            // Get or create an ID for this project
            var projectGuid = analyzer.CompiledProject?.GetPropertyValue("ProjectGuid");
            var projectId   = !string.IsNullOrEmpty(projectGuid) &&
                              Guid.TryParse(analyzer.CompiledProject?.GetPropertyValue("ProjectGuid"), out var projectIdGuid)
                                        ? ProjectId.CreateFromSerialized(projectIdGuid)
                                        : ProjectId.CreateNewId();

            // Create and add the project
            var projectInfo = GetProjectInfo(analyzer, workspace, projectId);
            var solution    = workspace.CurrentSolution.AddProject(projectInfo);

            // Check if this project is referenced by any other projects in the workspace
            foreach (var existingProject in solution.Projects.ToArray())
            {
                if (!existingProject.Id.Equals(projectId) &&
                    analyzer.Manager.Projects.TryGetValue(existingProject.FilePath, out var existingAnalyzer) &&
                    (existingAnalyzer.GetProjectReferences()?.Contains(analyzer.ProjectFilePath) ?? false))
                {
                    // Add the reference to the existing project
                    var projectReference = new ProjectReference(projectId);
                    solution = solution.AddProjectReference(existingProject.Id, projectReference);
                }
            }

            // Apply solution changes
            if (!workspace.TryApplyChanges(solution))
            {
                throw new InvalidOperationException("Could not apply workspace solution changes");
            }

            // Add any project references not already added
            if (addProjectReferences)
            {
                foreach (var referencedAnalyzer in GetReferencedAnalyzerProjects(analyzer))
                {
                    // Check if the workspace contains the project inside the loop since adding one might also add this one due to transitive references
                    if (!workspace.CurrentSolution.Projects.Any(x => x.FilePath == referencedAnalyzer.ProjectFilePath))
                    {
                        AddToWorkspace(referencedAnalyzer, workspace, addProjectReferences);
                    }
                }
            }

            // Find and return this project
            return(workspace.CurrentSolution.GetProject(projectId));
        }
Beispiel #2
0
        /// <summary>
        /// Gets a Roslyn workspace for the analyzed project.
        /// </summary>
        /// <param name="analyzer">The Buildalyzer project analyzer.</param>
        /// <param name="addProjectReferences"><c>true</c> to add projects to the workspace for project references that exist in the same <see cref="AnalyzerManager"/>.</param>
        /// <returns>A Roslyn workspace.</returns>
        public static AdhocWorkspace GetWorkspace(this ProjectAnalyzer analyzer, bool addProjectReferences = false)
        {
            if (analyzer == null)
            {
                throw new ArgumentNullException(nameof(analyzer));
            }
            AdhocWorkspace workspace = new AdhocWorkspace();

            AddToWorkspace(analyzer, workspace, addProjectReferences);
            return(workspace);
        }
        public ProjectAnalyzer GetProject(string projectFilePath)
        {
            if (projectFilePath == null)
            {
                throw new ArgumentNullException(nameof(projectFilePath));
            }

            // Normalize as .sln uses backslash regardless of OS the sln is created on
            projectFilePath = projectFilePath.Replace('\\', Path.DirectorySeparatorChar);
            projectFilePath = ValidatePath(projectFilePath, true);
            if (_projects.TryGetValue(projectFilePath, out ProjectAnalyzer project))
            {
                return(project);
            }
            project = new ProjectAnalyzer(this, projectFilePath);
            _projects.Add(projectFilePath, project);
            return(project);
        }
Beispiel #4
0
        private static ProjectInfo GetProjectInfo(ProjectAnalyzer analyzer, AdhocWorkspace workspace, ProjectId projectId)
        {
            string      projectName  = Path.GetFileNameWithoutExtension(analyzer.ProjectFilePath);
            string      languageName = GetLanguageName(analyzer.ProjectFilePath);
            ProjectInfo projectInfo  = ProjectInfo.Create(
                projectId,
                VersionStamp.Create(),
                projectName,
                projectName,
                languageName,
                filePath: analyzer.ProjectFilePath,
                outputFilePath: analyzer.CompiledProject?.GetPropertyValue("TargetPath"),
                documents: GetDocuments(analyzer, projectId),
                projectReferences: GetExistingProjectReferences(analyzer, workspace),
                metadataReferences: GetMetadataReferences(analyzer),
                compilationOptions: CreateCompilationOptions(analyzer.Project, languageName));

            return(projectInfo);
        }
Beispiel #5
0
 private static IEnumerable <ProjectAnalyzer> GetReferencedAnalyzerProjects(ProjectAnalyzer analyzer) =>
 analyzer.GetProjectReferences()
 ?.Select(x => analyzer.Manager.Projects.TryGetValue(x, out ProjectAnalyzer a) ? a : null)
Beispiel #6
0
 private static IEnumerable <ProjectReference> GetExistingProjectReferences(ProjectAnalyzer analyzer, AdhocWorkspace workspace) =>
 analyzer.GetProjectReferences()
 ?.Select(x => workspace.CurrentSolution.Projects.FirstOrDefault(y => y.FilePath == x))
 .Where(x => x != null)
 .Select(x => new ProjectReference(x.Id))
 ?? Array.Empty <ProjectReference>();