|
15 | 15 |
|
16 | 16 | namespace Microsoft.VisualStudio.Razor.LanguageClient.Cohost;
|
17 | 17 |
|
| 18 | +[Export(typeof(IProjectCapabilityListener))] |
18 | 19 | [Export(typeof(IIncompatibleProjectNotifier))]
|
19 | 20 | [method: ImportingConstructor]
|
20 | 21 | internal sealed class IncompatibleProjectNotifier(
|
21 |
| - IProjectCapabilityResolver projectCapabilityResolver, |
22 |
| - ILoggerFactory loggerFactory) : IIncompatibleProjectNotifier |
| 22 | + ILoggerFactory loggerFactory) : IIncompatibleProjectNotifier, IProjectCapabilityListener |
23 | 23 | {
|
24 |
| - private readonly IProjectCapabilityResolver _projectCapabilityResolver = projectCapabilityResolver; |
25 | 24 | private readonly ILogger _logger = loggerFactory.GetOrCreateLogger<IncompatibleProjectNotifier>();
|
26 | 25 |
|
| 26 | + private readonly HashSet<string> _frameworkProjects = new(PathUtilities.OSSpecificPathComparer); |
| 27 | + |
27 | 28 | public void NotifyMiscFilesDocument(TextDocument textDocument)
|
28 | 29 | {
|
29 | 30 | _logger.Log(LogLevel.Error, $"{WorkspacesSR.FormatIncompatibleProject_MiscFiles(Path.GetFileName(textDocument.FilePath))}");
|
30 | 31 | }
|
31 | 32 |
|
32 | 33 | public void NotifyMissingDocument(Project project, string filePath)
|
33 | 34 | {
|
34 |
| - // When this document was opened, we will have checked if it was a .NET Framework project. If so, then we can avoid |
35 |
| - // notifying the user because they are not using the LSP editor, even though we get the odd request. |
36 |
| - // If this check returns a false positive, the fallout is only one log message, so nothing to be concerned about. |
37 |
| - if (_projectCapabilityResolver.TryGetCachedCapabilityMatch(project.FilePath.AssumeNotNull(), WellKnownProjectCapabilities.DotNetCoreCSharp, out var isMatch) && !isMatch) |
| 35 | + // When this document was opened, we will have checked if it was a .NET Framework project, and we listened for that below. |
| 36 | + // Since this method is only called when we receive an LSP request for a document, and LSP only works on open documents, |
| 37 | + // we know that the capability check must have happened before this method was called, so our cache is as up to date as |
| 38 | + // possible for the specific file being asked about. |
| 39 | + lock (_frameworkProjects) |
38 | 40 | {
|
39 |
| - return; |
| 41 | + if (_frameworkProjects.Contains(project.FilePath.AssumeNotNull())) |
| 42 | + { |
| 43 | + // This project doesn't have the .NET Core C# capability, so it's a .NET Framework project and we don't want |
| 44 | + // to notify the user, as those projects use a different editor. |
| 45 | + return; |
| 46 | + } |
40 | 47 | }
|
41 | 48 |
|
42 | 49 | _logger.Log(LogLevel.Error, $"{(
|
43 | 50 | project.AdditionalDocuments.Any(d => d.FilePath is not null && d.FilePath.IsRazorFilePath())
|
44 | 51 | ? WorkspacesSR.FormatIncompatibleProject_NotAnAdditionalFile(Path.GetFileName(filePath), project.Name)
|
45 | 52 | : WorkspacesSR.FormatIncompatibleProject_NoAdditionalFiles(Path.GetFileName(filePath), project.Name))}");
|
46 | 53 | }
|
| 54 | + |
| 55 | + public void OnProjectCapabilityMatched(string projectFilePath, string capability, bool isMatch) |
| 56 | + { |
| 57 | + // We only track the .NET Core capability |
| 58 | + if (capability != WellKnownProjectCapabilities.DotNetCoreCSharp) |
| 59 | + { |
| 60 | + return; |
| 61 | + } |
| 62 | + |
| 63 | + lock (_frameworkProjects) |
| 64 | + { |
| 65 | + if (isMatch) |
| 66 | + { |
| 67 | + // The project is a .NET Core project, so we don't care, but just in case it used to be .NET Framework, |
| 68 | + // let's clean up. |
| 69 | + _frameworkProjects.Remove(projectFilePath); |
| 70 | + } |
| 71 | + else |
| 72 | + { |
| 73 | + // The project is not a .NET Core project, so add it to our list of framework projects. |
| 74 | + _frameworkProjects.Add(projectFilePath); |
| 75 | + } |
| 76 | + } |
| 77 | + } |
47 | 78 | }
|
0 commit comments