Skip to content

Commit 37f3b38

Browse files
committed
Better handling of publishDiagnostics
1 parent 21d9a7c commit 37f3b38

File tree

1 file changed

+49
-67
lines changed

1 file changed

+49
-67
lines changed

Diff for: handler/handler.go

+49-67
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ type InoHandler struct {
6969
sketchMapper *sourcemapper.InoMapper
7070
sketchTrackedFilesCount int
7171
docs map[string]*lsp.TextDocumentItem
72-
inoDocsWithDiagnostics map[string]bool
72+
inoDocsWithDiagnostics map[lsp.DocumentURI]bool
7373

7474
config lsp.BoardConfig
7575
}
@@ -106,7 +106,7 @@ func (handler *InoHandler) waitClangdStart(msg string) {
106106
func NewInoHandler(stdio io.ReadWriteCloser, board lsp.Board) *InoHandler {
107107
handler := &InoHandler{
108108
docs: map[string]*lsp.TextDocumentItem{},
109-
inoDocsWithDiagnostics: map[string]bool{},
109+
inoDocsWithDiagnostics: map[lsp.DocumentURI]bool{},
110110
config: lsp.BoardConfig{
111111
SelectedBoard: board,
112112
},
@@ -975,6 +975,10 @@ func (handler *InoHandler) inoDocumentURIFromInoPath(inoPath string) (lsp.Docume
975975
}
976976

977977
func (handler *InoHandler) cpp2inoDocumentURI(cppURI lsp.DocumentURI, cppRange lsp.Range) (lsp.DocumentURI, lsp.Range, error) {
978+
// TODO: Split this function into 2
979+
// - Cpp2inoSketchDocumentURI: converts sketch (cppURI, cppRange) -> (inoURI, inoRange)
980+
// - Cpp2inoDocumentURI : converts non-sketch (cppURI) -> (inoURI) [range is the same]
981+
978982
// Sketchbook/Sketch/Sketch.ino <- build-path/sketch/Sketch.ino.cpp
979983
// Sketchbook/Sketch/AnotherTab.ino <- build-path/sketch/Sketch.ino.cpp (different section from above)
980984
// Sketchbook/Sketch/AnotherFile.cpp <- build-path/sketch/AnotherFile.cpp (1:1)
@@ -1011,9 +1015,11 @@ func (handler *InoHandler) cpp2inoDocumentURI(cppURI lsp.DocumentURI, cppRange l
10111015

10121016
rel, err := handler.buildSketchRoot.RelTo(cppPath)
10131017
if err == nil {
1014-
inoPath := handler.sketchRoot.JoinPath(rel)
1018+
inoPath := handler.sketchRoot.JoinPath(rel).String()
10151019
log.Printf(" URI: '%s' -> '%s'", cppPath, inoPath)
1016-
return lsp.NewDocumentURIFromPath(inoPath), cppRange, nil
1020+
inoURI, err := handler.inoDocumentURIFromInoPath(inoPath)
1021+
log.Printf(" as URI: '%s'", inoURI)
1022+
return inoURI, cppRange, err
10171023
}
10181024

10191025
log.Printf(" could not determine rel-path of '%s' in '%s': %s", cppPath, handler.buildSketchRoot, err)
@@ -1475,46 +1481,68 @@ func (handler *InoHandler) cpp2inoSymbolInformation(syms []lsp.SymbolInformation
14751481
}
14761482

14771483
func (handler *InoHandler) cpp2inoDiagnostics(cppDiags *lsp.PublishDiagnosticsParams) ([]*lsp.PublishDiagnosticsParams, error) {
1484+
inoDiagsParam := map[lsp.DocumentURI]*lsp.PublishDiagnosticsParams{}
14781485

1479-
if len(cppDiags.Diagnostics) == 0 {
1480-
// If we receive the empty diagnostic on the preprocessed sketch,
1481-
// just return an empty diagnostic array.
1482-
if cppDiags.URI.AsPath().EquivalentTo(handler.buildSketchCpp) {
1483-
return []*lsp.PublishDiagnosticsParams{}, nil
1484-
}
1485-
1486-
inoURI, _, err := handler.cpp2inoDocumentURI(cppDiags.URI, lsp.NilRange)
1487-
return []*lsp.PublishDiagnosticsParams{
1488-
{
1486+
cppURI := cppDiags.URI
1487+
isSketch := cppURI.AsPath().EquivalentTo(handler.buildSketchCpp)
1488+
if isSketch {
1489+
for inoURI := range handler.inoDocsWithDiagnostics {
1490+
inoDiagsParam[inoURI] = &lsp.PublishDiagnosticsParams{
14891491
URI: inoURI,
14901492
Diagnostics: []lsp.Diagnostic{},
1491-
},
1492-
}, err
1493+
}
1494+
}
1495+
handler.inoDocsWithDiagnostics = map[lsp.DocumentURI]bool{}
1496+
} else {
1497+
inoURI, _, err := handler.cpp2inoDocumentURI(cppURI, lsp.NilRange)
1498+
if err != nil {
1499+
return nil, err
1500+
}
1501+
inoDiagsParam[inoURI] = &lsp.PublishDiagnosticsParams{
1502+
URI: inoURI,
1503+
Diagnostics: []lsp.Diagnostic{},
1504+
}
14931505
}
14941506

1495-
convertedDiagnostics := map[lsp.DocumentURI]*lsp.PublishDiagnosticsParams{}
14961507
for _, cppDiag := range cppDiags.Diagnostics {
1497-
inoURI, inoRange, err := handler.cpp2inoDocumentURI(cppDiags.URI, cppDiag.Range)
1508+
inoURI, inoRange, err := handler.cpp2inoDocumentURI(cppURI, cppDiag.Range)
14981509
if err != nil {
14991510
return nil, err
15001511
}
1512+
if inoURI.String() == sourcemapper.NotInoURI.String() {
1513+
continue
1514+
}
15011515

1502-
inoDiagParam, created := convertedDiagnostics[inoURI]
1516+
inoDiagParam, created := inoDiagsParam[inoURI]
15031517
if !created {
15041518
inoDiagParam = &lsp.PublishDiagnosticsParams{
15051519
URI: inoURI,
15061520
Diagnostics: []lsp.Diagnostic{},
15071521
}
1508-
convertedDiagnostics[inoURI] = inoDiagParam
1522+
inoDiagsParam[inoURI] = inoDiagParam
15091523
}
15101524

15111525
inoDiag := cppDiag
15121526
inoDiag.Range = inoRange
15131527
inoDiagParam.Diagnostics = append(inoDiagParam.Diagnostics, inoDiag)
1528+
1529+
if isSketch {
1530+
handler.inoDocsWithDiagnostics[inoURI] = true
1531+
1532+
// If we have an "undefined reference" in the .ino code trigger a
1533+
// check for newly created symbols (that in turn may trigger a
1534+
// new arduino-preprocessing of the sketch).
1535+
if inoDiag.Code == "undeclared_var_use_suggest" ||
1536+
inoDiag.Code == "undeclared_var_use" ||
1537+
inoDiag.Code == "ovl_no_viable_function_in_call" ||
1538+
inoDiag.Code == "pp_file_not_found" {
1539+
handler.buildSketchSymbolsCheck = true
1540+
}
1541+
}
15141542
}
15151543

15161544
inoDiagParams := []*lsp.PublishDiagnosticsParams{}
1517-
for _, v := range convertedDiagnostics {
1545+
for _, v := range inoDiagsParam {
15181546
inoDiagParams = append(inoDiagParams, v)
15191547
}
15201548
return inoDiagParams, nil
@@ -1603,34 +1631,9 @@ func (handler *InoHandler) FromClangd(ctx context.Context, connection *jsonrpc2.
16031631
if err != nil {
16041632
return nil, err
16051633
}
1606-
cleanUpInoDiagnostics := false
1607-
if len(inoDiagnostics) == 0 {
1608-
cleanUpInoDiagnostics = true
1609-
}
16101634

16111635
// Push back to IDE the converted diagnostics
1612-
inoDocsWithDiagnostics := map[string]bool{}
16131636
for _, inoDiag := range inoDiagnostics {
1614-
if inoDiag.URI.String() == sourcemapper.NotInoURI.String() {
1615-
cleanUpInoDiagnostics = true
1616-
continue
1617-
}
1618-
1619-
// If we have an "undefined reference" in the .ino code trigger a
1620-
// check for newly created symbols (that in turn may trigger a
1621-
// new arduino-preprocessing of the sketch).
1622-
if inoDiag.URI.Ext() == ".ino" {
1623-
inoDocsWithDiagnostics[inoDiag.URI.Canonical()] = true
1624-
cleanUpInoDiagnostics = true
1625-
for _, diag := range inoDiag.Diagnostics {
1626-
if diag.Code == "undeclared_var_use_suggest" ||
1627-
diag.Code == "undeclared_var_use" ||
1628-
diag.Code == "ovl_no_viable_function_in_call" ||
1629-
diag.Code == "pp_file_not_found" {
1630-
handler.buildSketchSymbolsCheck = true
1631-
}
1632-
}
1633-
}
16341637

16351638
log.Printf(prefix+"to IDE: publishDiagnostics(%s):", inoDiag.URI)
16361639
for _, diag := range inoDiag.Diagnostics {
@@ -1640,27 +1643,6 @@ func (handler *InoHandler) FromClangd(ctx context.Context, connection *jsonrpc2.
16401643
return nil, err
16411644
}
16421645
}
1643-
1644-
if cleanUpInoDiagnostics {
1645-
// Remove diagnostics from all .ino where there are no errors coming from clang
1646-
for sourcePath := range handler.inoDocsWithDiagnostics {
1647-
if inoDocsWithDiagnostics[sourcePath] {
1648-
// skip if we already sent updated diagnostics
1649-
continue
1650-
}
1651-
// otherwise clear previous diagnostics
1652-
msg := lsp.PublishDiagnosticsParams{
1653-
URI: lsp.NewDocumentURI(sourcePath),
1654-
Diagnostics: []lsp.Diagnostic{},
1655-
}
1656-
log.Printf(prefix+"to IDE: publishDiagnostics(%s):", msg.URI)
1657-
if err := handler.StdioConn.Notify(ctx, "textDocument/publishDiagnostics", msg); err != nil {
1658-
return nil, err
1659-
}
1660-
}
1661-
1662-
handler.inoDocsWithDiagnostics = inoDocsWithDiagnostics
1663-
}
16641646
return nil, err
16651647

16661648
case *lsp.ApplyWorkspaceEditParams:

0 commit comments

Comments
 (0)