提交 34fa72b5 编写于 作者: K Kevin Pilch-Bisson

Use ResolveMetadataReferences and ResolveAnalyzerReferences in DPL

Use the resolved references in DPL.  This is necessary because VB adds mscorlib to the set of
resolved references implicitly.

Fixes #14433 and #14584
上级 7e871dfa
......@@ -4,6 +4,7 @@
using System.Threading;
using Microsoft.VisualStudio.Shell.Interop;
using Roslyn.Utilities;
using Microsoft.CodeAnalysis.Host;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem
{
......@@ -25,8 +26,7 @@ int IVsSolutionEvents.OnAfterOpenSolution(object pUnkReserved, int fNewSolution)
if (IsDeferredSolutionLoadEnabled())
{
var deferredProjectWorkspaceService = _workspaceServices.GetService<IDeferredProjectWorkspaceService>();
LoadSolutionFromMSBuildAsync(deferredProjectWorkspaceService, _solutionParsingCancellationTokenSource.Token).FireAndForget();
LoadSolutionFromMSBuildAsync(_solutionParsingCancellationTokenSource.Token).FireAndForget();
}
return VSConstants.S_OK;
......
......@@ -34,14 +34,13 @@ int IVsSolutionLoadEvents.OnBeforeOpenSolution(string pszSolutionFilename)
}
private async Task LoadSolutionFromMSBuildAsync(
IDeferredProjectWorkspaceService deferredProjectWorkspaceService,
CancellationToken cancellationToken)
{
AssertIsForeground();
InitializeOutputPane();
// Continue on the UI thread for these operations, since we are touching the VisualStudioWorkspace, etc.
await PopulateWorkspaceFromDeferredProjectInfoAsync(deferredProjectWorkspaceService, cancellationToken).ConfigureAwait(true);
await PopulateWorkspaceFromDeferredProjectInfoAsync(cancellationToken).ConfigureAwait(true);
}
[Conditional("DEBUG")]
......@@ -104,7 +103,6 @@ int IVsSolutionLoadEvents.OnAfterBackgroundSolutionLoadComplete()
}
private async Task PopulateWorkspaceFromDeferredProjectInfoAsync(
IDeferredProjectWorkspaceService deferredProjectWorkspaceService,
CancellationToken cancellationToken)
{
// NOTE: We need to check cancellationToken after each await, in case the user has
......@@ -127,6 +125,7 @@ int IVsSolutionLoadEvents.OnAfterBackgroundSolutionLoadComplete()
if (solutionConfig != null)
{
// Capture the context so that we come back on the UI thread, and do the actual project creation there.
var deferredProjectWorkspaceService = _workspaceServices.GetService<IDeferredProjectWorkspaceService>();
projectInfos = await deferredProjectWorkspaceService.GetDeferredProjectInfoForConfigurationAsync(
$"{solutionConfig.Name}|{solutionConfig.PlatformName}",
cancellationToken).ConfigureAwait(true);
......@@ -139,11 +138,13 @@ int IVsSolutionLoadEvents.OnAfterBackgroundSolutionLoadComplete()
OutputToOutputWindow($"Creating projects - start");
start = DateTimeOffset.UtcNow;
var targetPathsToProjectPaths = BuildTargetPathMap(projectInfos);
var analyzerAssemblyLoader = _workspaceServices.GetRequiredService<IAnalyzerService>().GetLoader();
foreach (var projectFilename in projectInfos.Keys)
{
cancellationToken.ThrowIfCancellationRequested();
GetOrCreateProjectFromArgumentsAndReferences(
workspaceProjectContextFactory,
analyzerAssemblyLoader,
projectFilename,
projectInfos,
targetPathsToProjectPaths);
......@@ -185,6 +186,7 @@ private void OutputToOutputWindow(string message)
private AbstractProject GetOrCreateProjectFromArgumentsAndReferences(
IWorkspaceProjectContextFactory workspaceProjectContextFactory,
IAnalyzerAssemblyLoader analyzerAssemblyLoader,
string projectFilename,
IReadOnlyDictionary<string, DeferredProjectInformation> allProjectInfos,
IReadOnlyDictionary<string, string> targetPathsToProjectPaths)
......@@ -263,6 +265,7 @@ private void OutputToOutputWindow(string message)
hierarchy: null,
binOutputPath: outputPath);
project = (AbstractProject)projectContext;
projectContext.SetOptions(projectInfo.CommandLineArguments.Join(" "));
foreach (var sourceFile in commandLineArguments.SourceFiles)
......@@ -287,6 +290,7 @@ private void OutputToOutputWindow(string message)
{
referencedProject = GetOrCreateProjectFromArgumentsAndReferences(
workspaceProjectContextFactory,
analyzerAssemblyLoader,
projectReferencePath,
allProjectInfos,
targetPathsToProjectPaths);
......@@ -322,22 +326,31 @@ private void OutputToOutputWindow(string message)
}
}
foreach (var reference in commandLineArguments.MetadataReferences)
foreach (var reference in commandLineArguments.ResolveMetadataReferences(project.CurrentCompilationOptions.MetadataReferenceResolver))
{
// References that don't exist on disk will come back prepended with "Unresolved: ". We'll strip that off
// and still add them, so that if they appear, we'll load them (maybe they are outputs of other parts of the build).
const string unresolved = "Unresolved: ";
var path = reference.Display;
if (path.StartsWith(unresolved))
{
path = path.Substring(unresolved.Length);
}
string possibleProjectReference;
if (targetPathsToProjectPaths.TryGetValue(reference.Reference, out possibleProjectReference) &&
if (targetPathsToProjectPaths.TryGetValue(path, out possibleProjectReference) &&
addedProjectReferences.Contains(possibleProjectReference))
{
// We already added a P2P reference for this, we don't need to add the file reference too.
continue;
}
projectContext.AddMetadataReference(reference.Reference, reference.Properties);
projectContext.AddMetadataReference(path, reference.Properties);
}
foreach (var reference in commandLineArguments.AnalyzerReferences)
foreach (var reference in commandLineArguments.ResolveAnalyzerReferences(analyzerAssemblyLoader))
{
var path = reference.FilePath;
var path = reference.FullPath;
if (!PathUtilities.IsAbsolute(path))
{
path = PathUtilities.CombineAbsoluteAndRelativePaths(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册