internal/lsp: clear diagnostics for files on close, even with errors

Change-Id: I7230d560c57455c53200f4d8f2702fbbdd3f5e51
Reviewed-on: https://go-review.googlesource.com/c/tools/+/184162
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
diff --git a/internal/lsp/text_synchronization.go b/internal/lsp/text_synchronization.go
index fdb424c..4cd8853 100644
--- a/internal/lsp/text_synchronization.go
+++ b/internal/lsp/text_synchronization.go
@@ -116,6 +116,14 @@
 	if err := view.SetContent(ctx, uri, nil); err != nil {
 		return err
 	}
+	clear := []span.URI{uri} // by default, clear the closed URI
+	defer func() {
+		for _, uri := range clear {
+			if err := s.publishDiagnostics(ctx, view, uri, []source.Diagnostic{}); err != nil {
+				s.session.Logger().Errorf(ctx, "failed to clear diagnostics for %s: %v", uri, err)
+			}
+		}
+	}()
 	// If the current file was the only open file for its package,
 	// clear out all diagnostics for the package.
 	f, err := view.GetFile(ctx, uri)
@@ -126,6 +134,7 @@
 	// For non-Go files, don't return any diagnostics.
 	gof, ok := f.(source.GoFile)
 	if !ok {
+		s.session.Logger().Errorf(ctx, "closing a non-Go file, no diagnostics to clear")
 		return nil
 	}
 	pkg := gof.GetPackage(ctx)
@@ -133,27 +142,13 @@
 		s.session.Logger().Errorf(ctx, "no package available for %s", uri)
 		return nil
 	}
-	reports := make(map[span.URI][]source.Diagnostic)
-	clearDiagnostics := true
 	for _, filename := range pkg.GetFilenames() {
-		uri := span.NewURI(filename)
-		reports[uri] = []source.Diagnostic{}
-		if span.CompareURI(uri, gof.URI()) == 0 {
-			continue
+		// If other files from this package are open, don't clear.
+		if s.session.IsOpen(span.NewURI(filename)) {
+			clear = nil
+			return nil
 		}
-		// If other files from this package are open.
-		if s.session.IsOpen(uri) {
-			clearDiagnostics = false
-		}
-	}
-	// We still have open files for this package, so don't clear diagnostics.
-	if !clearDiagnostics {
-		return nil
-	}
-	for uri, diagnostics := range reports {
-		if err := s.publishDiagnostics(ctx, view, uri, diagnostics); err != nil {
-			s.session.Logger().Errorf(ctx, "failed to clear diagnostics for %s: %v", uri, err)
-		}
+		clear = append(clear, span.FileURI(filename))
 	}
 	return nil
 }