private bool TryAddReferenceToKnownProject( ProjectId id, string projectReferencePath, ImmutableArray <string> aliases, ResolvedReferencesBuilder builder) { if (_projectMap.TryGetIdsByProjectPath(projectReferencePath, out var projectReferenceIds)) { foreach (var projectReferenceId in projectReferenceIds) { // Don't add a reference if the project already has a reference on us. Otherwise, it will cause a circularity. if (ProjectReferenceExists(to: id, from: projectReferenceId)) { return(false); } var outputRefFilePath = _projectMap.GetOutputRefFilePathById(projectReferenceId); var outputFilePath = _projectMap.GetOutputFilePathById(projectReferenceId); if (builder.Contains(outputRefFilePath) || builder.Contains(outputFilePath)) { var newProjectReference = CreateProjectReference(from: id, to: projectReferenceId, aliases); builder.SwapMetadataReferenceForProjectReference(newProjectReference, outputRefFilePath, outputFilePath); return(true); } } } return(false); }
private async Task <bool> TryLoadAndAddReferenceAsync(ProjectId id, string projectReferencePath, ImmutableArray <string> aliases, ResolvedReferencesBuilder builder, CancellationToken cancellationToken) { var projectReferenceInfos = await LoadProjectInfosFromPathAsync(projectReferencePath, _discoveredProjectOptions, cancellationToken).ConfigureAwait(false); // Find the project reference info whose output we have a metadata reference for. ProjectInfo projectReferenceInfo = null; foreach (var info in projectReferenceInfos) { if (builder.Contains(info.OutputFilePath) || builder.Contains(info.OutputRefFilePath)) { projectReferenceInfo = info; break; } } if (projectReferenceInfo == null) { return(false); } if (!ProjectReferenceExists(to: id, from: projectReferenceInfo)) { var newProjectReference = CreateProjectReference(from: id, to: projectReferenceInfo.Id, aliases); builder.SwapMetadataReferenceForProjectReference(newProjectReference, projectReferenceInfo.OutputRefFilePath, projectReferenceInfo.OutputFilePath); } else { // This project already has a reference on us. Don't introduce a circularity by referencing it. // However, if the project's output doesn't exist on disk, we need to remove from our list of // metadata references to avoid failures later. Essentially, the concern here is that the metadata // reference is an UnresolvedMetadataReference, which will throw when we try to create a // Compilation with it. if (!File.Exists(projectReferenceInfo.OutputRefFilePath)) { builder.Remove(projectReferenceInfo.OutputRefFilePath); } if (!File.Exists(projectReferenceInfo.OutputFilePath)) { builder.Remove(projectReferenceInfo.OutputFilePath); } } // Note that we return true even if we don't actually add a reference due to a circularity because, // in that case, we've still handled everything. return(true); }
private async Task <bool> TryLoadAndAddReferenceAsync(ProjectId id, string projectReferencePath, ImmutableArray <string> aliases, ResolvedReferencesBuilder builder, CancellationToken cancellationToken) { var projectReferenceInfos = await LoadProjectInfosFromPathAsync(projectReferencePath, _discoveredProjectOptions, cancellationToken).ConfigureAwait(false); if (projectReferenceInfos.IsEmpty) { return(false); } // Find the project reference info whose output we have a metadata reference for. ProjectInfo projectReferenceInfo = null; foreach (var info in projectReferenceInfos) { if (builder.Contains(info.OutputFilePath) || builder.Contains(info.OutputRefFilePath)) { projectReferenceInfo = info; break; } } if (projectReferenceInfo == null) { // We didn't find the project reference info that matches any of our metadata references. // In this case, we'll go ahead and use the first project reference info that was found, // but report a warning because this likely means that either a metadata reference path // or a project output path is incorrect. projectReferenceInfo = projectReferenceInfos[0]; _diagnosticReporter.Report(new ProjectDiagnostic( WorkspaceDiagnosticKind.Warning, string.Format(WorkspaceMSBuildResources.Found_project_reference_without_a_matching_metadata_reference_0, projectReferencePath), id)); } if (!ProjectReferenceExists(to: id, from: projectReferenceInfo)) { var newProjectReference = CreateProjectReference(from: id, to: projectReferenceInfo.Id, aliases); builder.SwapMetadataReferenceForProjectReference(newProjectReference, projectReferenceInfo.OutputRefFilePath, projectReferenceInfo.OutputFilePath); } else { // This project already has a reference on us. Don't introduce a circularity by referencing it. // However, if the project's output doesn't exist on disk, we need to remove from our list of // metadata references to avoid failures later. Essentially, the concern here is that the metadata // reference is an UnresolvedMetadataReference, which will throw when we try to create a // Compilation with it. if (!File.Exists(projectReferenceInfo.OutputRefFilePath)) { builder.Remove(projectReferenceInfo.OutputRefFilePath); } if (!File.Exists(projectReferenceInfo.OutputFilePath)) { builder.Remove(projectReferenceInfo.OutputFilePath); } } // Note that we return true even if we don't actually add a reference due to a circularity because, // in that case, we've still handled everything. return(true); }