| // Copyright 2020 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| package langserver |
| |
| import ( |
| "context" |
| "fmt" |
| "strings" |
| |
| fidlcommon "fidl-lsp/third_party/common" |
| "github.com/sourcegraph/go-lsp" |
| "github.com/sourcegraph/jsonrpc2" |
| |
| "fidl-lsp/analysis" |
| "fidl-lsp/state" |
| ) |
| |
| func (h *LangHandler) publishDiagnostics(ctx context.Context, conn *jsonrpc2.Conn, uri lsp.DocumentURI) { |
| diags, err := h.getDiagnosticsForLibraryWithFile(uri) |
| if err != nil { |
| h.log.Printf("error publishing diagnostics: %s\n", err) |
| return |
| } |
| |
| for fileURI, fileDiags := range diags { |
| h.Notify(ctx, conn, "textDocument/publishDiagnostics", lsp.PublishDiagnosticsParams{ |
| URI: fileURI, |
| Diagnostics: fileDiags, |
| }) |
| } |
| } |
| |
| func (h *LangHandler) getDiagnosticsForLibraryWithFile(uri lsp.DocumentURI) (map[lsp.DocumentURI][]lsp.Diagnostic, error) { |
| file, err := h.fs.File(state.FileID(uri)) |
| if err != nil { |
| return nil, fmt.Errorf("could not find file `%s`: %s", uri, err) |
| } |
| libraryName, err := state.LibraryOfFile(file) |
| if err != nil { |
| return nil, fmt.Errorf("could not find library name of file `%s`: %s", uri, err) |
| } |
| |
| diags, err := h.analyzer.DiagnosticsOnLibrary(fidlcommon.LibraryName(libraryName), state.FileID(uri)) |
| if err != nil { |
| return nil, fmt.Errorf("error getting diagnostics: %s", err) |
| } |
| |
| // Convert analysis.Diagnostics --> lsp.Diagnostics |
| lspDiags := make(map[lsp.DocumentURI][]lsp.Diagnostic) |
| for fileID, fileDiags := range diags { |
| fileURI := lsp.DocumentURI(fileID) |
| lspDiags[fileURI] = []lsp.Diagnostic{} |
| |
| for _, diag := range fileDiags { |
| var severity lsp.DiagnosticSeverity |
| message := diag.Message |
| |
| switch diag.Source { |
| case analysis.Fidlc: |
| diagType := strings.Split(diag.Category, "/")[1] |
| if diagType == "error" { |
| severity = lsp.Error |
| } else { |
| severity = lsp.Warning |
| } |
| case analysis.FidlLint: |
| severity = lsp.Warning |
| if len(diag.Suggestions) > 0 { |
| message = message + "; " + diag.Suggestions[0].Description |
| } |
| } |
| |
| lspDiags[fileURI] = append(lspDiags[fileURI], lsp.Diagnostic{ |
| Range: lsp.Range{ |
| Start: lsp.Position{Line: diag.StartLine - 1, Character: diag.StartChar}, |
| End: lsp.Position{Line: diag.EndLine - 1, Character: diag.EndChar}, |
| }, |
| Severity: severity, |
| Source: string(diag.Source), |
| Message: message, |
| }) |
| } |
| } |
| return lspDiags, nil |
| } |