Skip to content

Commit

Permalink
Merge pull request #4482 from zooba/issue-3829
Browse files Browse the repository at this point in the history
[WIP] Fixes #3829 Squiggles disappear when file is reopened
  • Loading branch information
zooba authored Jul 6, 2018
2 parents d4bd108 + b20ed43 commit 2401fff
Show file tree
Hide file tree
Showing 12 changed files with 149 additions and 156 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,19 @@ public void ProcessTaskComment(object sender, CommentEventArgs e) {
source = _source
};

bool found = false;
foreach (var kv in _taskCommentMap.MaybeEnumerate().OrderByDescending(kv => kv.Key.Length)) {
if (text.IndexOfOrdinal(kv.Key, ignoreCase: true) >= 0) {
d.code = kv.Key;
d.severity = kv.Value;
found = true;
break;
}
}

_onDiagnostic(d);
if (found) {
_onDiagnostic(d);
}
}

internal static DiagnosticSeverity GetSeverity(Severity severity) {
Expand Down
2 changes: 1 addition & 1 deletion Python/Product/Analysis/Parsing/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4965,7 +4965,7 @@ public override void Add(string message, SourceSpan span, int errorCode, Severit

public static TextReader ReadStreamWithEncoding(Stream stream, PythonLanguageVersion version) {
var defaultEncoding = version.Is3x() ? new UTF8Encoding(false) : DefaultEncoding;
return GetStreamReaderWithEncoding(stream, defaultEncoding, null);
return GetStreamReaderWithEncoding(stream, defaultEncoding, ErrorSink.Null);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,6 @@ sealed class OutOfProcProjectAnalyzer : IDisposable {

private bool _isDisposed;

// Moniker strings allow the task provider to distinguish between
// different sources of items for the same file.
private const string ParserTaskMoniker = "Parser";
internal const string UnresolvedImportMoniker = "UnresolvedImport";

private readonly Connection _connection;

internal OutOfProcProjectAnalyzer(Stream writer, Stream reader, Action<string> log) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ public ITextSnapshot AddSentSnapshot(ITextSnapshot sent) {

public bool UpdateLastReceivedParse(int version) {
lock (_lock) {
Trace("UpdateLastReceivedParse", version, _expectParse.ContainsKey(version));
Trace("UpdateLastReceivedParse", version, _expectParse.ContainsKey(version) ? "expected" : "unexpected");
var toRemove = _expectParse.Keys.TakeWhile(k => k < version).ToArray();
foreach (var i in toRemove) {
Debug.WriteLine($"Skipped parse for version {i}");
Expand All @@ -459,7 +459,7 @@ public bool UpdateLastReceivedParse(int version) {

public bool UpdateLastReceivedAnalysis(int version) {
lock (_lock) {
Trace("UpdateLastReceivedAnalysis", version, _expectAnalysis.ContainsKey(version));
Trace("UpdateLastReceivedAnalysis", version, _expectAnalysis.ContainsKey(version) ? "expected" : "unexpected");

var toRemove = _expectAnalysis.Keys.TakeWhile(k => k < version).ToArray();
foreach (var i in toRemove) {
Expand Down Expand Up @@ -748,7 +748,7 @@ private AnalysisLogWriter OpenTraceLog() {
);
}

private void Trace(string eventName, params object[] args) {
internal void Trace(string eventName, params object[] args) {
_traceLog?.Log(eventName, args);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ private static async Task<AnalysisEntry> AnalyzeBufferAsync(ITextView textView,
}

bool suppressErrorList = textView.Properties.ContainsProperty(SuppressErrorLists);
var entry = await vsAnalyzer.AnalyzeFileAsync(bufferInfo.DocumentUri, isTemporaryFile, suppressErrorList);
var entry = await vsAnalyzer.AnalyzeFileAsync(bufferInfo.DocumentUri, bufferInfo.Filename, isTemporaryFile, suppressErrorList);
if (entry != null && followDefaultEnvironment) {
entry.Properties[FollowDefaultEnvironment] = true;
}
Expand Down Expand Up @@ -300,7 +300,7 @@ private async Task DefaultInterpreterChanged() {
oldAnalyzer.Dispose();
}

var newEntry = await analyzer.AnalyzeFileAsync(bi.DocumentUri, true, bi.Buffer.Properties.ContainsProperty(SuppressErrorLists));
var newEntry = await analyzer.AnalyzeFileAsync(bi.DocumentUri, bi.Filename, true, bi.Buffer.Properties.ContainsProperty(SuppressErrorLists));
newEntry.Properties[FollowDefaultEnvironment] = true;
bi.TrySetAnalysisEntry(newEntry, null);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ protected override async Task OnNewAnalysis(PythonTextBufferInfo bi, AnalysisEnt
new List<TaskProviderItem> {
new TaskProviderItem(
Services.Site,
VsProjectAnalyzer.InvalidEncodingMoniker,
message,
span,
VSTASKPRIORITY.TP_NORMAL,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,10 @@ sealed class VsProjectAnalyzer : ProjectAnalyzer, IDisposable {
internal readonly HashSet<AnalysisEntry> _hasParseErrors = new HashSet<AnalysisEntry>();
internal readonly object _hasParseErrorsLock = new object();

private const string ParserTaskMoniker = "Parser";
internal const string UnresolvedImportMoniker = "UnresolvedImport";
internal const string ParserTaskMoniker = "Python (parser)";
internal const string AnalyzerTaskMoniker = "Python (analysis)";
internal const string InvalidEncodingMoniker = "InvalidEncoding";
internal const string TaskCommentMoniker = "Task comment";
internal bool _analysisComplete;

private AP.AnalysisOptions _analysisOptions;
Expand Down Expand Up @@ -526,9 +527,9 @@ public void Dispose() {

foreach (var path in _projectFiles.Keys) {
_services.ErrorTaskProvider?.Clear(path, ParserTaskMoniker);
_services.ErrorTaskProvider?.Clear(path, UnresolvedImportMoniker);
_services.ErrorTaskProvider?.Clear(path, AnalyzerTaskMoniker);
_services.ErrorTaskProvider?.Clear(path, InvalidEncodingMoniker);
_services.CommentTaskProvider?.Clear(path, ParserTaskMoniker);
_services.CommentTaskProvider?.Clear(path, TaskCommentMoniker);
}

Debug.WriteLine(String.Format("Disposing of parser {0}", _analysisProcess));
Expand Down Expand Up @@ -1033,9 +1034,9 @@ internal static void ConnectErrorList(PythonTextBufferInfo buffer) {
}

buffer.Services.ErrorTaskProvider?.AddBufferForErrorSource(buffer.Filename, ParserTaskMoniker, buffer.Buffer);
buffer.Services.ErrorTaskProvider?.AddBufferForErrorSource(buffer.Filename, UnresolvedImportMoniker, buffer.Buffer);
buffer.Services.ErrorTaskProvider?.AddBufferForErrorSource(buffer.Filename, AnalyzerTaskMoniker, buffer.Buffer);
buffer.Services.ErrorTaskProvider?.AddBufferForErrorSource(buffer.Filename, InvalidEncodingMoniker, buffer.Buffer);
buffer.Services.CommentTaskProvider?.AddBufferForErrorSource(buffer.Filename, ParserTaskMoniker, buffer.Buffer);
buffer.Services.CommentTaskProvider?.AddBufferForErrorSource(buffer.Filename, TaskCommentMoniker, buffer.Buffer);
buffer.Services.InvalidEncodingSquiggleProvider?.AddBuffer(buffer);
}

Expand All @@ -1047,9 +1048,9 @@ internal static void DisconnectErrorList(PythonTextBufferInfo buffer) {
// Use Maybe* variants, since if they haven't been created we don't need to
// remove our sources.
buffer.Services.MaybeErrorTaskProvider?.RemoveBufferForErrorSource(buffer.Filename, ParserTaskMoniker, buffer.Buffer);
buffer.Services.MaybeErrorTaskProvider?.RemoveBufferForErrorSource(buffer.Filename, UnresolvedImportMoniker, buffer.Buffer);
buffer.Services.MaybeErrorTaskProvider?.RemoveBufferForErrorSource(buffer.Filename, AnalyzerTaskMoniker, buffer.Buffer);
buffer.Services.MaybeErrorTaskProvider?.RemoveBufferForErrorSource(buffer.Filename, InvalidEncodingMoniker, buffer.Buffer);
buffer.Services.MaybeCommentTaskProvider?.RemoveBufferForErrorSource(buffer.Filename, ParserTaskMoniker, buffer.Buffer);
buffer.Services.MaybeCommentTaskProvider?.RemoveBufferForErrorSource(buffer.Filename, TaskCommentMoniker, buffer.Buffer);
buffer.Services.MaybeInvalidEncodingSquiggleProvider?.RemoveBuffer(buffer);
}

Expand All @@ -1073,9 +1074,9 @@ internal void BufferDetached(AnalysisEntry entry, ITextBuffer buffer) {

if (!entry.SuppressErrorList) {
_services.ErrorTaskProvider?.ClearErrorSource(entry.Path, ParserTaskMoniker);
_services.ErrorTaskProvider?.ClearErrorSource(entry.Path, UnresolvedImportMoniker);
_services.ErrorTaskProvider?.ClearErrorSource(entry.Path, AnalyzerTaskMoniker);
_services.ErrorTaskProvider?.ClearErrorSource(entry.Path, InvalidEncodingMoniker);
_services.CommentTaskProvider?.ClearErrorSource(entry.Path, ParserTaskMoniker);
_services.CommentTaskProvider?.ClearErrorSource(entry.Path, TaskCommentMoniker);
}

if (entry.IsTemporaryFile) {
Expand Down Expand Up @@ -1124,6 +1125,7 @@ internal async Task<AnalysisEntry> AnalyzeFileAsync(

internal async Task<AnalysisEntry> AnalyzeFileAsync(
Uri uri,
string path,
bool isTemporaryFile = false,
bool suppressErrorList = false
) {
Expand All @@ -1141,8 +1143,7 @@ internal async Task<AnalysisEntry> AnalyzeFileAsync(
return entry;
}

string path = null;
if (uri.IsFile) {
if (string.IsNullOrEmpty(path) && uri.IsFile) {
path = uri.LocalPath;
}

Expand Down Expand Up @@ -1535,54 +1536,43 @@ private void OnDiagnostics(AnalysisEntry entry, AP.DiagnosticsEvent diagnostics)
if (entry.Path == null) {
return;
}
bi?.Trace("OnDiagnostics", diagnostics.diagnostics?.Length ?? 0);

// Update the warn-on-launch state for this entry
var hasErrors = diagnostics.diagnostics.MaybeEnumerate()
.Any(d => d.source == "Python" && d.severity == LS.DiagnosticSeverity.Error);
.Any(d => d.severity == LS.DiagnosticSeverity.Error);

// Update the parser warnings/errors.
var errorTask = entry.SuppressErrorList ? null : _services.ErrorTaskProvider;
var commentTask = entry.SuppressErrorList ? null : _services.CommentTaskProvider;

if (errorTask != null) {
if (errorTask != null || commentTask != null) {
var pyErrors = diagnostics.diagnostics.MaybeEnumerate()
.Where(d => d.source == "Python")
.GroupBy(d => d.severity);
.GroupBy(d => d.source);

if (!pyErrors.Any()) {
errorTask.Clear(entry.Path, ParserTaskMoniker);
errorTask?.Clear(entry.Path, ParserTaskMoniker);
errorTask?.Clear(entry.Path, AnalyzerTaskMoniker);
commentTask?.Clear(entry.Path, TaskCommentMoniker);
} else {
var factory = new TaskProviderItemFactory(bi?.LocationTracker, diagnostics.version);
var items = pyErrors.SelectMany(ge => ge.Select(e => factory.FromDiagnostic(
_services.Site,
e,
ge.Key,
VSTASKCATEGORY.CAT_CODESENSE,
true
))).ToList();

errorTask.ReplaceItems(entry.Path, ParserTaskMoniker, items);
}
}

var commentTask = entry.SuppressErrorList ? null : _services.CommentTaskProvider;
if (commentTask != null) {
var comments = diagnostics.diagnostics.MaybeEnumerate()
.Where(d => d.source == "Task comment")
.GroupBy(d => d.severity);

if (!comments.Any()) {
commentTask.Clear(entry.Path, ParserTaskMoniker);
} else {
var factory = new TaskProviderItemFactory(bi?.LocationTracker, diagnostics.version);
var items = comments.SelectMany(ge => ge.Select(e => factory.FromDiagnostic(
_services.Site,
e,
ge.Key,
VSTASKCATEGORY.CAT_COMMENTS,
false
))).ToList();

commentTask.ReplaceItems(entry.Path, ParserTaskMoniker, items);
foreach (var g in pyErrors) {
Debug.Assert(g.Key == ParserTaskMoniker || g.Key == AnalyzerTaskMoniker || g.Key == TaskCommentMoniker, $"Unexpected source {g.Key}");

bool isComment = (g.Key == TaskCommentMoniker);
var items = g.Select(e => factory.FromDiagnostic(
_services.Site,
e,
isComment ? VSTASKCATEGORY.CAT_COMMENTS : VSTASKCATEGORY.CAT_CODESENSE,
!isComment
)).ToList();

if (isComment) {
commentTask?.ReplaceItems(entry.Path, g.Key, items);
} else {
errorTask?.ReplaceItems(entry.Path, g.Key, items);
}
}
}
}

Expand Down Expand Up @@ -1701,9 +1691,9 @@ internal async Task UnloadFileAsync(AnalysisEntry entry) {
bp.ClearBuffers();
} else {
_services.MaybeErrorTaskProvider?.ClearErrorSource(entry.Path, ParserTaskMoniker);
_services.MaybeErrorTaskProvider?.ClearErrorSource(entry.Path, UnresolvedImportMoniker);
_services.MaybeErrorTaskProvider?.ClearErrorSource(entry.Path, AnalyzerTaskMoniker);
_services.MaybeErrorTaskProvider?.ClearErrorSource(entry.Path, InvalidEncodingMoniker);
_services.MaybeCommentTaskProvider?.ClearErrorSource(entry.Path, ParserTaskMoniker);
_services.MaybeCommentTaskProvider?.ClearErrorSource(entry.Path, TaskCommentMoniker);
}
if (entry?.Path != null) {
_projectFiles.TryRemove(entry.Path, out _);
Expand Down
Loading

0 comments on commit 2401fff

Please sign in to comment.