@@ -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) {
106106func 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
977977func (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
14771483func (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