diff --git a/src/Analysis/Engine/Impl/Definitions/Diagnostic.cs b/src/Analysis/Engine/Impl/Definitions/Diagnostic.cs index fc3657320..bff9e11de 100644 --- a/src/Analysis/Engine/Impl/Definitions/Diagnostic.cs +++ b/src/Analysis/Engine/Impl/Definitions/Diagnostic.cs @@ -48,7 +48,7 @@ public class Diagnostic { } public enum DiagnosticSeverity : int { - Unspecified = 0, + Suppressed = 0, Error = 1, Warning = 2, Information = 3, diff --git a/src/Analysis/Engine/Impl/DependencyResolution/PathResolverSnapshot.cs b/src/Analysis/Engine/Impl/DependencyResolution/PathResolverSnapshot.cs index c1f69c132..66d4c7fee 100644 --- a/src/Analysis/Engine/Impl/DependencyResolution/PathResolverSnapshot.cs +++ b/src/Analysis/Engine/Impl/DependencyResolution/PathResolverSnapshot.cs @@ -69,6 +69,7 @@ private PathResolverSnapshot(PythonLanguageVersion pythonLanguageVersion, string public IEnumerable GetAllModuleNames() => GetModuleNames(_roots.Prepend(_nonRooted).Append(_builtins)); public IEnumerable GetInterpreterModuleNames() => GetModuleNames(_roots.Skip(_userRootsCount).Append(_builtins)); + public IEnumerable GetRootPaths() => _roots.Select(r => r.Name); private static IEnumerable GetModuleNames(IEnumerable roots) => roots .SelectMany(r => r.TraverseBreadthFirst(n => n.IsModule ? Enumerable.Empty() : n.Children)) diff --git a/src/Analysis/Engine/Impl/PythonAnalyzer.cs b/src/Analysis/Engine/Impl/PythonAnalyzer.cs index 982fde416..5694a89ee 100644 --- a/src/Analysis/Engine/Impl/PythonAnalyzer.cs +++ b/src/Analysis/Engine/Impl/PythonAnalyzer.cs @@ -68,7 +68,7 @@ public partial class PythonAnalyzer : IPythonAnalyzer, IDisposable { public static async Task CreateAsync(IPythonInterpreterFactory factory, CancellationToken token = default) { var analyzer = new PythonAnalyzer(factory); try { - await analyzer.ReloadModulesAsync(token).ConfigureAwait(false); + await analyzer.ReloadModulesAsync(false, token).ConfigureAwait(false); } catch(Exception) { analyzer.Dispose(); throw; @@ -140,7 +140,9 @@ private void ReloadModulePaths(in IEnumerable rootPaths) { /// This method should be called on the analysis thread and is usually invoked /// when the interpreter signals that it's modules have changed. /// - public async Task ReloadModulesAsync(CancellationToken token = default) { + public Task ReloadModulesAsync(CancellationToken token = default) => ReloadModulesAsync(true, token); + + private async Task ReloadModulesAsync(bool reScanRoots, CancellationToken token) { if (!_reloadLock.Wait(0)) { // If we don't lock immediately, wait for the current reload to // complete and then return. @@ -156,6 +158,11 @@ public async Task ReloadModulesAsync(CancellationToken token = default) { InterpreterFactory.NotifyImportNamesChanged(); // Now initialize the interpreter Interpreter.Initialize(this); + // Rescan roots for modules if requested + if (reScanRoots) { + ReloadModulePaths(CurrentPathResolver.GetRootPaths()); + } + // Reload importable modules Modules.Reload(); // Load known types from the selected interpreter @@ -760,7 +767,7 @@ public void AnalyzeQueuedEntries(CancellationToken cancel) { if (_builtinModule == null) { Debug.Fail("Used analyzer without reloading modules"); - ReloadModulesAsync(cancel).WaitAndUnwrapExceptions(); + ReloadModulesAsync(true, cancel).WaitAndUnwrapExceptions(); } var ddg = new DDG(); diff --git a/src/Analysis/Engine/Test/LanguageServerTests.cs b/src/Analysis/Engine/Test/LanguageServerTests.cs index 974499161..f8e7ee28e 100644 --- a/src/Analysis/Engine/Test/LanguageServerTests.cs +++ b/src/Analysis/Engine/Test/LanguageServerTests.cs @@ -298,7 +298,7 @@ public async Task ParseIndentationDiagnostics() { DiagnosticSeverity.Error, DiagnosticSeverity.Warning, DiagnosticSeverity.Information, - DiagnosticSeverity.Unspecified + DiagnosticSeverity.Suppressed }) { // For now, these options have to be configured directly s.ParseQueue.InconsistentIndentation = tc; @@ -317,7 +317,7 @@ await s.DidChangeTextDocument(new DidChangeTextDocumentParams { await s.WaitForCompleteAnalysisAsync(CancellationToken.None); var messages = GetDiagnostics(diags, mod).ToArray(); - if (tc == DiagnosticSeverity.Unspecified) { + if (tc == DiagnosticSeverity.Suppressed) { messages.Should().BeEmpty(); } else { messages.Should().OnlyContain($"{tc};inconsistent whitespace;Python;2;0;1"); @@ -359,7 +359,7 @@ public async Task DiagnosticsSettingChange() { await s.SendDidChangeConfiguration(newSettings); await s.WaitForCompleteAnalysisAsync(CancellationToken.None); - GetDiagnostics(diags, u).Where(st => !st.StartsWith($"{DiagnosticSeverity.Unspecified}")).Should().BeEmpty(); + GetDiagnostics(diags, u).Where(st => !st.StartsWith($"{DiagnosticSeverity.Suppressed}")).Should().BeEmpty(); } } diff --git a/src/LanguageServer/Core/Impl/Definitions/ServerSettings.cs b/src/LanguageServer/Core/Impl/Definitions/ServerSettings.cs index 982446351..b73ce2a8a 100644 --- a/src/LanguageServer/Core/Impl/Definitions/ServerSettings.cs +++ b/src/LanguageServer/Core/Impl/Definitions/ServerSettings.cs @@ -48,7 +48,7 @@ public void SetErrorSeverityOptions(string[] errors, string[] warnings, string[] _map[x] = DiagnosticSeverity.Error; } foreach (var x in disabled) { - _map[x] = DiagnosticSeverity.Unspecified; + _map[x] = DiagnosticSeverity.Suppressed; } this.errors = errors; diff --git a/src/LanguageServer/Core/Impl/Implementation/DiagnosticsErrorSink.cs b/src/LanguageServer/Core/Impl/Implementation/DiagnosticsErrorSink.cs index ec40f3c22..f06a585ea 100644 --- a/src/LanguageServer/Core/Impl/Implementation/DiagnosticsErrorSink.cs +++ b/src/LanguageServer/Core/Impl/Implementation/DiagnosticsErrorSink.cs @@ -72,18 +72,18 @@ public void ProcessTaskComment(object sender, CommentEventArgs e) { internal static DiagnosticSeverity GetSeverity(Severity severity) { switch (severity) { - case Severity.Ignore: return DiagnosticSeverity.Unspecified; + case Severity.Ignore: return DiagnosticSeverity.Suppressed; case Severity.Information: return DiagnosticSeverity.Information; case Severity.Warning: return DiagnosticSeverity.Warning; case Severity.Error: return DiagnosticSeverity.Error; case Severity.FatalError: return DiagnosticSeverity.Error; - default: return DiagnosticSeverity.Unspecified; + default: return DiagnosticSeverity.Suppressed; } } internal static Severity GetSeverity(DiagnosticSeverity severity) { switch (severity) { - case DiagnosticSeverity.Unspecified: return Severity.Ignore; + case DiagnosticSeverity.Suppressed: return Severity.Ignore; case DiagnosticSeverity.Information: return Severity.Information; case DiagnosticSeverity.Warning: return Severity.Warning; case DiagnosticSeverity.Error: return Severity.Error; diff --git a/src/LanguageServer/Impl/LanguageServer.cs b/src/LanguageServer/Impl/LanguageServer.cs index 7c09d1cd2..bbba9bb4f 100644 --- a/src/LanguageServer/Impl/LanguageServer.cs +++ b/src/LanguageServer/Impl/LanguageServer.cs @@ -423,7 +423,7 @@ private void PublishPendingDiagnostics() { foreach (var kvp in list) { var parameters = new PublishDiagnosticsParams { uri = kvp.Key, - diagnostics = kvp.Value.Where(d => d.severity != DiagnosticSeverity.Unspecified).ToArray() + diagnostics = kvp.Value.Where(d => d.severity != DiagnosticSeverity.Suppressed).ToArray() }; _rpc.NotifyWithParameterObjectAsync("textDocument/publishDiagnostics", parameters).DoNotWait(); } diff --git a/src/PTVS/Microsoft.PythonTools.Analyzer/Impl/Intellisense/AnalysisProtocol.cs b/src/PTVS/Microsoft.PythonTools.Analyzer/Impl/Intellisense/AnalysisProtocol.cs index 46873b01a..5d642465b 100644 --- a/src/PTVS/Microsoft.PythonTools.Analyzer/Impl/Intellisense/AnalysisProtocol.cs +++ b/src/PTVS/Microsoft.PythonTools.Analyzer/Impl/Intellisense/AnalysisProtocol.cs @@ -59,8 +59,6 @@ public sealed class InitializeRequest : Request { public bool analyzeAllFiles; [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool traceLogging; - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public bool liveLinting; } public sealed class InterpreterInfo { @@ -824,6 +822,8 @@ public sealed class SetAnalysisOptionsRequest : Request { public sealed class AnalysisOptions { public Severity indentationInconsistencySeverity; + public bool enableUnresolvedImportWarning; + public bool enableUseBeforeDefWarning; public Dictionary commentTokens; public Dictionary analysisLimits; public LS.MessageType? traceLevel; diff --git a/src/PTVS/Microsoft.PythonTools.Analyzer/Impl/Intellisense/OutOfProcProjectAnalyzer.cs b/src/PTVS/Microsoft.PythonTools.Analyzer/Impl/Intellisense/OutOfProcProjectAnalyzer.cs index f1346fbf9..1fb3a6b15 100644 --- a/src/PTVS/Microsoft.PythonTools.Analyzer/Impl/Intellisense/OutOfProcProjectAnalyzer.cs +++ b/src/PTVS/Microsoft.PythonTools.Analyzer/Impl/Intellisense/OutOfProcProjectAnalyzer.cs @@ -269,8 +269,7 @@ await _server.Initialize(new LS.InitializeParams { }, capabilities = new LS.ClientCapabilities { python = new LS.PythonClientCapabilities { - manualFileLoad = !request.analyzeAllFiles, - liveLinting = request.liveLinting + manualFileLoad = !request.analyzeAllFiles }, textDocument = new LS.TextDocumentClientCapabilities { completion = new LS.TextDocumentClientCapabilities.CompletionCapabilities { @@ -1559,9 +1558,35 @@ private Response SetAnalysisOptions(AP.SetAnalysisOptionsRequest request) { _server.ParseQueue.TaskCommentMap = Options.commentTokens; _server.Analyzer.SetTypeStubPaths(Options.typeStubPaths ?? Enumerable.Empty()); + SetErrorMessagesSeverity(); + return new Response(); } + private void SetErrorMessagesSeverity() { + var serverSettings = new LS.ServerSettings(); + var warnings = new List(); + var disabled = new List(); + + if (Options.enableUnresolvedImportWarning) { + warnings.Add(ErrorMessages.UnresolvedImportCode); + } else { + disabled.Add(ErrorMessages.UnresolvedImportCode); + } + + if (Options.enableUseBeforeDefWarning) { + warnings.Add(ErrorMessages.UseBeforeDefCode); + } else { + disabled.Add(ErrorMessages.UseBeforeDefCode); + } + + serverSettings.analysis.SetErrorSeverityOptions(Array.Empty(), warnings.ToArray(), Array.Empty(), disabled.ToArray()); + + _server.DidChangeConfiguration(new LS.DidChangeConfigurationParams { + settings = serverSettings + }, CancellationToken.None).DoNotWait(); + } + public AP.AnalysisOptions Options { get; set; } @@ -1570,7 +1595,7 @@ private void AnalysisQueue_Complete(object sender, EventArgs e) { } private void OnModulesChanged(object sender, EventArgs args) { - _server.DidChangeConfiguration(new LS.DidChangeConfigurationParams(), CancellationToken.None).DoNotWait(); + _server.ReloadModulesAsync(CancellationToken.None).DoNotWait(); } private void OnFileChanged(AP.FileChangedEvent e) { @@ -1653,7 +1678,7 @@ private void OnPublishDiagnostics(object sender, LS.PublishDiagnosticsEventArgs new AP.DiagnosticsEvent { documentUri = e.uri, version = e._version ?? -1, - diagnostics = e.diagnostics?.ToArray() + diagnostics = e.diagnostics?.Where(d => d.severity != DiagnosticSeverity.Suppressed).ToArray() } ).DoNotWait(); } diff --git a/src/PTVS/Microsoft.PythonTools.Analyzer/Impl/python-language-server-ptvs.nuspec b/src/PTVS/Microsoft.PythonTools.Analyzer/Impl/python-language-server-ptvs.nuspec index 280da818c..7ed8aeb6c 100644 --- a/src/PTVS/Microsoft.PythonTools.Analyzer/Impl/python-language-server-ptvs.nuspec +++ b/src/PTVS/Microsoft.PythonTools.Analyzer/Impl/python-language-server-ptvs.nuspec @@ -23,7 +23,7 @@ - +