blob: 0b8a7fddeda4f435bfbf130e9462c8d6b598642f [file] [log] [blame]
// 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 analysis
import (
"encoding/json"
"fmt"
"os/exec"
"fidl-lsp/state"
)
// DiagnosticsOnLibrary retrieves the cached diagnostics for `lib`.
func (a *Analyzer) DiagnosticsOnLibrary(lib LibraryName) (map[state.EditorFile][]Diagnostic, error) {
if _, ok := a.libs[lib]; !ok {
return nil, fmt.Errorf("could not find library `%s`", lib)
}
return a.libs[lib].diags, nil
}
type fidlLintSuggestion struct {
Description string
}
type FidlcTool string
const (
Fidlc FidlcTool = "fidlc"
FidlLint = "fidl-lint"
)
// Diagnostic represents an {error, warning, lint} deserialized from the JSON
// output of fidlc or fidl-lint.
type Diagnostic struct {
Source FidlcTool
Category string
Message string
Path string
StartLine int `json:"start_line"`
StartChar int `json:"start_char"`
EndLine int `json:"end_line"`
EndChar int `json:"end_char"`
Suggestions []fidlLintSuggestion
}
func (a *Analyzer) fidlcDiagsFromStderr(stderr []byte) (map[state.EditorFile][]Diagnostic, error) {
// Deserialize stderr into []Diagnostic
var diags []Diagnostic
if err := json.Unmarshal(stderr, &diags); err != nil {
return nil, fmt.Errorf("could not deserialize fidlc diagnostics: `%s`", err)
}
fileToDiags := make(map[state.EditorFile][]Diagnostic)
for i := range diags {
editorFile, err := a.inputFileToEditorFile(diags[i].Path)
if err != nil {
continue
}
if _, ok := fileToDiags[editorFile]; !ok {
fileToDiags[editorFile] = []Diagnostic{}
}
diags[i].Source = Fidlc
fileToDiags[editorFile] = append(fileToDiags[editorFile], diags[i])
}
return fileToDiags, nil
}
func (a *Analyzer) runFidlLint(path string) (map[state.EditorFile][]Diagnostic, error) {
// TODO: return early with an error if we got status code != 0 or 1?
// Otherwise, ignore err: we expect this to fail with status code 1 if there
// are any lints from fidl-lint.
out, _ := exec.Command(fidlLintPath, "--format=json", path).Output()
// Deserialize stdout into []fidlLint
var diags []Diagnostic
if err := json.Unmarshal(out, &diags); err != nil {
return nil, fmt.Errorf("error deserializing fidl-lint output: %s", err)
}
fileToDiags := make(map[state.EditorFile][]Diagnostic)
for i := range diags {
editorFile, err := a.inputFileToEditorFile(diags[i].Path)
if err != nil {
continue
}
if _, ok := fileToDiags[editorFile]; !ok {
fileToDiags[editorFile] = []Diagnostic{}
}
diags[i].Source = FidlLint
fileToDiags[editorFile] = append(fileToDiags[editorFile], diags[i])
}
return fileToDiags, nil
}