Skip to content

Commit

Permalink
Merge pull request #9605 from drewnoakes/lang-svc-modernisation
Browse files Browse the repository at this point in the history
Language service tidying
  • Loading branch information
drewnoakes authored Nov 28, 2024
2 parents 32c88de + c6e60ad commit fc09b4a
Show file tree
Hide file tree
Showing 19 changed files with 373 additions and 488 deletions.
2 changes: 2 additions & 0 deletions spelling.dic
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ bstr
cmdid
combobox
commandbar
cshtml
csproj
debuggable
debugsettings
Expand Down Expand Up @@ -52,6 +53,7 @@ proj
projectsystem
projitems
readonly
refactorings
referencesource
renamer
resw
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,6 @@ public async ValueTask RestartAsync(CancellationToken cancellationToken)
{
WriteToOutputWindow(VSResources.HotReloadRestartInProgress, cancellationToken);


if (_callback is IProjectHotReloadSessionCallback2 callBack2)
{
await callBack2.RestartProjectAsync(_isRunningUnderDebugger, cancellationToken);
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -4,57 +4,50 @@
using Microsoft.VisualStudio.LanguageServices.ProjectSystem;
using Microsoft.VisualStudio.ProjectSystem.VS;

namespace Microsoft.VisualStudio.ProjectSystem.LanguageServices.Handlers
namespace Microsoft.VisualStudio.ProjectSystem.LanguageServices.Handlers;

/// <summary>
/// Handles <c>AdditionalFiles</c> items during design-time builds.
/// </summary>
[Export(typeof(IWorkspaceUpdateHandler))]
[PartCreationPolicy(CreationPolicy.NonShared)]
[method: ImportingConstructor]
internal class AdditionalFilesItemHandler(UnconfiguredProject project) : IWorkspaceUpdateHandler, ICommandLineHandler
{
/// <summary>
/// Handles <c>AdditionalFiles</c> items during design-time builds.
/// </summary>
[Export(typeof(IWorkspaceUpdateHandler))]
[PartCreationPolicy(CreationPolicy.NonShared)]
internal class AdditionalFilesItemHandler : IWorkspaceUpdateHandler, ICommandLineHandler
{
// WORKAROUND: To avoid Roslyn throwing when we add duplicate additional files, we remember what
// sent to them and avoid sending on duplicates.
// See: https://github.com/dotnet/project-system/issues/2230
// WORKAROUND: To avoid Roslyn throwing when we add duplicate additional files, we remember what
// sent to them and avoid sending on duplicates.
// See: https://github.com/dotnet/project-system/issues/2230

private readonly UnconfiguredProject _project;
private readonly HashSet<string> _paths = new(StringComparers.Paths);
private readonly HashSet<string> _paths = new(StringComparers.Paths);

[ImportingConstructor]
public AdditionalFilesItemHandler(UnconfiguredProject project)
public void Handle(IWorkspaceProjectContext context, IComparable version, BuildOptions added, BuildOptions removed, ContextState state, IManagedProjectDiagnosticOutputService logger)
{
foreach (CommandLineSourceFile additionalFile in removed.AdditionalFiles)
{
_project = project;
string fullPath = project.MakeRooted(additionalFile.Path);

RemoveFromContextIfPresent(fullPath);
}

public void Handle(IWorkspaceProjectContext context, IComparable version, BuildOptions added, BuildOptions removed, ContextState state, IManagedProjectDiagnosticOutputService logger)
foreach (CommandLineSourceFile additionalFile in added.AdditionalFiles)
{
foreach (CommandLineSourceFile additionalFile in removed.AdditionalFiles)
{
string fullPath = _project.MakeRooted(additionalFile.Path);
string fullPath = project.MakeRooted(additionalFile.Path);

RemoveFromContextIfPresent(context, fullPath, logger);
}

foreach (CommandLineSourceFile additionalFile in added.AdditionalFiles)
{
string fullPath = _project.MakeRooted(additionalFile.Path);

AddToContextIfNotPresent(context, fullPath, state.IsActiveEditorContext, logger);
}
AddToContextIfNotPresent(fullPath);
}

private void AddToContextIfNotPresent(IWorkspaceProjectContext context, string fullPath, bool isActiveContext, IManagedProjectDiagnosticOutputService logger)
void AddToContextIfNotPresent(string fullPath)
{
if (!_paths.Contains(fullPath))
{
logger.WriteLine("Adding additional file '{0}'", fullPath);
context.AddAdditionalFile(fullPath, folderNames: [], isActiveContext);
context.AddAdditionalFile(fullPath, folderNames: [], state.IsActiveEditorContext);
bool added = _paths.Add(fullPath);
Assumes.True(added);
}
}

private void RemoveFromContextIfPresent(IWorkspaceProjectContext context, string fullPath, IManagedProjectDiagnosticOutputService logger)
void RemoveFromContextIfPresent(string fullPath)
{
if (_paths.Contains(fullPath))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,39 @@
using Microsoft.VisualStudio.LanguageServices.ProjectSystem;
using Microsoft.VisualStudio.ProjectSystem.VS;

namespace Microsoft.VisualStudio.ProjectSystem.LanguageServices.Handlers
namespace Microsoft.VisualStudio.ProjectSystem.LanguageServices.Handlers;

/// <summary>
/// Handles changes to the &lt;EditorConfigFiles/&gt; items during design-time builds.
/// </summary>
[Export(typeof(IWorkspaceUpdateHandler))]
[PartCreationPolicy(CreationPolicy.NonShared)]
[method: ImportingConstructor]
internal class AnalyzerConfigItemHandler(UnconfiguredProject project) : IWorkspaceUpdateHandler, ICommandLineHandler
{
/// <summary>
/// Handles changes to the &lt;EditorConfigFiles/&gt; items during design-time builds.
/// </summary>
[Export(typeof(IWorkspaceUpdateHandler))]
[PartCreationPolicy(CreationPolicy.NonShared)]
internal class AnalyzerConfigItemHandler : IWorkspaceUpdateHandler, ICommandLineHandler
{
// WORKAROUND: To avoid Roslyn throwing when we add duplicate additional files, we remember what
// sent to them and avoid sending on duplicates.
// See: https://github.com/dotnet/project-system/issues/2230
// WORKAROUND: To avoid Roslyn throwing when we add duplicate additional files, we remember what
// sent to them and avoid sending on duplicates.
// See: https://github.com/dotnet/project-system/issues/2230

private readonly UnconfiguredProject _project;
private readonly HashSet<string> _paths = new(StringComparers.Paths);
private readonly HashSet<string> _paths = new(StringComparers.Paths);

[ImportingConstructor]
public AnalyzerConfigItemHandler(UnconfiguredProject project)
public void Handle(IWorkspaceProjectContext context, IComparable version, BuildOptions added, BuildOptions removed, ContextState state, IManagedProjectDiagnosticOutputService logger)
{
foreach (string analyzerConfigFile in removed.AnalyzerConfigFiles)
{
_project = project;
string fullPath = project.MakeRooted(analyzerConfigFile);

RemoveFromContextIfPresent(fullPath);
}

public void Handle(IWorkspaceProjectContext context, IComparable version, BuildOptions added, BuildOptions removed, ContextState state, IManagedProjectDiagnosticOutputService logger)
foreach (string analyzerConfigFile in added.AnalyzerConfigFiles)
{
foreach (string analyzerConfigFile in removed.AnalyzerConfigFiles)
{
string fullPath = _project.MakeRooted(analyzerConfigFile);
string fullPath = project.MakeRooted(analyzerConfigFile);

RemoveFromContextIfPresent(context, fullPath, logger);
}

foreach (string analyzerConfigFile in added.AnalyzerConfigFiles)
{
string fullPath = _project.MakeRooted(analyzerConfigFile);

AddToContextIfNotPresent(context, fullPath, logger);
}
AddToContextIfNotPresent(fullPath);
}

private void AddToContextIfNotPresent(IWorkspaceProjectContext context, string fullPath, IManagedProjectDiagnosticOutputService logger)
void AddToContextIfNotPresent(string fullPath)
{
if (!_paths.Contains(fullPath))
{
Expand All @@ -53,7 +46,7 @@ private void AddToContextIfNotPresent(IWorkspaceProjectContext context, string f
}
}

private void RemoveFromContextIfPresent(IWorkspaceProjectContext context, string fullPath, IManagedProjectDiagnosticOutputService logger)
void RemoveFromContextIfPresent(string fullPath)
{
if (_paths.Contains(fullPath))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,46 +4,39 @@
using Microsoft.VisualStudio.LanguageServices.ProjectSystem;
using Microsoft.VisualStudio.ProjectSystem.VS;

namespace Microsoft.VisualStudio.ProjectSystem.LanguageServices.Handlers
namespace Microsoft.VisualStudio.ProjectSystem.LanguageServices.Handlers;

/// <summary>
/// Handles changes to the &lt;Analyzer/&gt; item during design-time builds.
/// </summary>
[Export(typeof(IWorkspaceUpdateHandler))]
[PartCreationPolicy(CreationPolicy.NonShared)]
[method: ImportingConstructor]
internal class AnalyzerItemHandler(UnconfiguredProject project) : IWorkspaceUpdateHandler, ICommandLineHandler
{
/// <summary>
/// Handles changes to the &lt;Analyzer/&gt; item during design-time builds.
/// </summary>
[Export(typeof(IWorkspaceUpdateHandler))]
[PartCreationPolicy(CreationPolicy.NonShared)]
internal class AnalyzerItemHandler : IWorkspaceUpdateHandler, ICommandLineHandler
{
// WORKAROUND: To avoid Roslyn throwing when we add duplicate analyzers, we remember what
// sent to them and avoid sending on duplicates.
// See: https://github.com/dotnet/project-system/issues/2230
// WORKAROUND: To avoid Roslyn throwing when we add duplicate analyzers, we remember what
// sent to them and avoid sending on duplicates.
// See: https://github.com/dotnet/project-system/issues/2230

private readonly UnconfiguredProject _project;
private readonly HashSet<string> _paths = new(StringComparers.Paths);
private readonly HashSet<string> _paths = new(StringComparers.Paths);

[ImportingConstructor]
public AnalyzerItemHandler(UnconfiguredProject project)
public void Handle(IWorkspaceProjectContext context, IComparable version, BuildOptions added, BuildOptions removed, ContextState state, IManagedProjectDiagnosticOutputService logger)
{
foreach (CommandLineAnalyzerReference analyzer in removed.AnalyzerReferences)
{
_project = project;
string fullPath = project.MakeRooted(analyzer.FilePath);

RemoveFromContextIfPresent(fullPath);
}

public void Handle(IWorkspaceProjectContext context, IComparable version, BuildOptions added, BuildOptions removed, ContextState state, IManagedProjectDiagnosticOutputService logger)
foreach (CommandLineAnalyzerReference analyzer in added.AnalyzerReferences)
{
foreach (CommandLineAnalyzerReference analyzer in removed.AnalyzerReferences)
{
string fullPath = _project.MakeRooted(analyzer.FilePath);
string fullPath = project.MakeRooted(analyzer.FilePath);

RemoveFromContextIfPresent(context, fullPath, logger);
}

foreach (CommandLineAnalyzerReference analyzer in added.AnalyzerReferences)
{
string fullPath = _project.MakeRooted(analyzer.FilePath);

AddToContextIfNotPresent(context, fullPath, logger);
}
AddToContextIfNotPresent(fullPath);
}

private void AddToContextIfNotPresent(IWorkspaceProjectContext context, string fullPath, IManagedProjectDiagnosticOutputService logger)
void AddToContextIfNotPresent(string fullPath)
{
if (!_paths.Contains(fullPath))
{
Expand All @@ -54,7 +47,7 @@ private void AddToContextIfNotPresent(IWorkspaceProjectContext context, string f
}
}

private void RemoveFromContextIfPresent(IWorkspaceProjectContext context, string fullPath, IManagedProjectDiagnosticOutputService logger)
void RemoveFromContextIfPresent(string fullPath)
{
if (_paths.Contains(fullPath))
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,32 @@
// Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE.md file in the project root for more information.

using Microsoft.VisualStudio.Composition;
using Microsoft.VisualStudio.LanguageServices.ProjectSystem;
using Microsoft.VisualStudio.ProjectSystem.LanguageServices.FSharp;

namespace Microsoft.VisualStudio.ProjectSystem.LanguageServices.Handlers
namespace Microsoft.VisualStudio.ProjectSystem.LanguageServices.Handlers;

/// <summary>
/// An indirection that sends design-time build results in the form of command-line arguments to the F# language-service.
/// </summary>
/// <remarks>
/// This indirection is needed because Microsoft.VisualStudio.ProjectSystem.FSharp does not have InternalsVisibleTo access to Roslyn.
/// </remarks>
[Export(typeof(IWorkspaceUpdateHandler))]
[method: ImportingConstructor]
internal class CommandLineNotificationHandler(UnconfiguredProject project) : IWorkspaceUpdateHandler, ICommandLineHandler
{
/// <summary>
/// An indirection that sends design-time build results in the form of command-line arguments to the F# language-service.
/// </summary>
/// <remarks>
/// This indirection is needed because Microsoft.VisualStudio.ProjectSystem.FSharp does not have InternalsVisibleTo access to Roslyn.
/// See <see cref="FSharpCommandLineParserService.HandleCommandLineNotifications"/> for an example of this export.
/// </remarks>
[Export(typeof(IWorkspaceUpdateHandler))]
internal class CommandLineNotificationHandler : IWorkspaceUpdateHandler, ICommandLineHandler
{
[ImportingConstructor]
public CommandLineNotificationHandler(UnconfiguredProject project)
{
// See FSharpCommandLineParserService.HandleCommandLineNotifications for an example of this export
CommandLineNotifications = new OrderPrecedenceImportCollection<Action<string?, BuildOptions, BuildOptions>>(projectCapabilityCheckProvider: project);
}

/// <remarks>
/// See <see cref="FSharpCommandLineParserService.HandleCommandLineNotifications"/> for an export.
/// </remarks>
[ImportMany]
public OrderPrecedenceImportCollection<Action<string?, BuildOptions, BuildOptions>> CommandLineNotifications { get; }
[ImportMany]
public OrderPrecedenceImportCollection<Action<string?, BuildOptions, BuildOptions>> CommandLineNotifications { get; } = new(projectCapabilityCheckProvider: project);

public void Handle(IWorkspaceProjectContext context, IComparable version, BuildOptions added, BuildOptions removed, ContextState state, IManagedProjectDiagnosticOutputService logger)
public void Handle(IWorkspaceProjectContext context, IComparable version, BuildOptions added, BuildOptions removed, ContextState state, IManagedProjectDiagnosticOutputService logger)
{
foreach (Action<string?, BuildOptions, BuildOptions> value in CommandLineNotifications.ExtensionValues())
{
foreach (Lazy<Action<string?, BuildOptions, BuildOptions>, IOrderPrecedenceMetadataView> value in CommandLineNotifications)
{
value.Value(context.BinOutputPath, added, removed);
}
value(context.BinOutputPath, added, removed);
}
}
}
Loading

0 comments on commit fc09b4a

Please sign in to comment.