@@ -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 },
@@ -731,7 +731,7 @@ func startClangd(compileCommandsDir, sketchCpp *paths.Path, compilers map[string
731731func (handler * InoHandler ) didOpen (inoDidOpen * lsp.DidOpenTextDocumentParams ) (* lsp.DidOpenTextDocumentParams , error ) {
732732 // Add the TextDocumentItem in the tracked files list
733733 inoItem := inoDidOpen .TextDocument
734- handler .docs [inoItem .URI .Canonical ()] = & inoItem
734+ handler .docs [inoItem .URI .AsPath (). String ()] = & inoItem
735735
736736 // If we are tracking a .ino...
737737 if inoItem .URI .Ext () == ".ino" {
@@ -752,8 +752,8 @@ func (handler *InoHandler) didOpen(inoDidOpen *lsp.DidOpenTextDocumentParams) (*
752752
753753func (handler * InoHandler ) didClose (inoDidClose * lsp.DidCloseTextDocumentParams ) (* lsp.DidCloseTextDocumentParams , error ) {
754754 inoIdentifier := inoDidClose .TextDocument
755- if _ , exist := handler .docs [inoIdentifier .URI .Canonical ()]; exist {
756- delete (handler .docs , inoIdentifier .URI .Canonical ())
755+ if _ , exist := handler .docs [inoIdentifier .URI .AsPath (). String ()]; exist {
756+ delete (handler .docs , inoIdentifier .URI .AsPath (). String ())
757757 } else {
758758 log .Printf (" didClose of untracked document: %s" , inoIdentifier .URI )
759759 return nil , unknownURI (inoIdentifier .URI )
@@ -789,8 +789,9 @@ func (handler *InoHandler) ino2cppTextDocumentItem(inoItem lsp.TextDocumentItem)
789789 cppItem .Version = handler .sketchMapper .CppText .Version
790790 } else {
791791 cppItem .LanguageID = inoItem .LanguageID
792- cppItem .Text = handler .docs [inoItem .URI .Canonical ()].Text
793- cppItem .Version = handler .docs [inoItem .URI .Canonical ()].Version
792+ inoPath := inoItem .URI .AsPath ().String ()
793+ cppItem .Text = handler .docs [inoPath ].Text
794+ cppItem .Version = handler .docs [inoPath ].Version
794795 }
795796
796797 return cppItem , nil
@@ -799,7 +800,7 @@ func (handler *InoHandler) ino2cppTextDocumentItem(inoItem lsp.TextDocumentItem)
799800func (handler * InoHandler ) didChange (ctx context.Context , req * lsp.DidChangeTextDocumentParams ) (* lsp.DidChangeTextDocumentParams , error ) {
800801 doc := req .TextDocument
801802
802- trackedDoc , ok := handler .docs [doc .URI .Canonical ()]
803+ trackedDoc , ok := handler .docs [doc .URI .AsPath (). String ()]
803804 if ! ok {
804805 return nil , unknownURI (doc .URI )
805806 }
@@ -974,6 +975,10 @@ func (handler *InoHandler) inoDocumentURIFromInoPath(inoPath string) (lsp.Docume
974975}
975976
976977func (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+
977982 // Sketchbook/Sketch/Sketch.ino <- build-path/sketch/Sketch.ino.cpp
978983 // Sketchbook/Sketch/AnotherTab.ino <- build-path/sketch/Sketch.ino.cpp (different section from above)
979984 // Sketchbook/Sketch/AnotherFile.cpp <- build-path/sketch/AnotherFile.cpp (1:1)
@@ -1010,9 +1015,11 @@ func (handler *InoHandler) cpp2inoDocumentURI(cppURI lsp.DocumentURI, cppRange l
10101015
10111016 rel , err := handler .buildSketchRoot .RelTo (cppPath )
10121017 if err == nil {
1013- inoPath := handler .sketchRoot .JoinPath (rel )
1018+ inoPath := handler .sketchRoot .JoinPath (rel ). String ()
10141019 log .Printf (" URI: '%s' -> '%s'" , cppPath , inoPath )
1015- return lsp .NewDocumentURIFromPath (inoPath ), cppRange , nil
1020+ inoURI , err := handler .inoDocumentURIFromInoPath (inoPath )
1021+ log .Printf (" as URI: '%s'" , inoURI )
1022+ return inoURI , cppRange , err
10161023 }
10171024
10181025 log .Printf (" could not determine rel-path of '%s' in '%s': %s" , cppPath , handler .buildSketchRoot , err )
@@ -1405,7 +1412,7 @@ func (handler *InoHandler) cpp2inoTextEdit(cppURI lsp.DocumentURI, cppEdit lsp.T
14051412}
14061413
14071414func (handler * InoHandler ) cpp2inoDocumentSymbols (cppSymbols []lsp.DocumentSymbol , inoRequestedURI lsp.DocumentURI ) []lsp.DocumentSymbol {
1408- inoRequested := inoRequestedURI .Canonical ()
1415+ inoRequested := inoRequestedURI .AsPath (). String ()
14091416 log .Printf (" filtering for requested ino file: %s" , inoRequested )
14101417 if inoRequestedURI .Ext () != ".ino" || len (cppSymbols ) == 0 {
14111418 return cppSymbols
@@ -1474,46 +1481,68 @@ func (handler *InoHandler) cpp2inoSymbolInformation(syms []lsp.SymbolInformation
14741481}
14751482
14761483func (handler * InoHandler ) cpp2inoDiagnostics (cppDiags * lsp.PublishDiagnosticsParams ) ([]* lsp.PublishDiagnosticsParams , error ) {
1484+ inoDiagsParam := map [lsp.DocumentURI ]* lsp.PublishDiagnosticsParams {}
14771485
1478- if len (cppDiags .Diagnostics ) == 0 {
1479- // If we receive the empty diagnostic on the preprocessed sketch,
1480- // just return an empty diagnostic array.
1481- if cppDiags .URI .AsPath ().EquivalentTo (handler .buildSketchCpp ) {
1482- return []* lsp.PublishDiagnosticsParams {}, nil
1483- }
1484-
1485- inoURI , _ , err := handler .cpp2inoDocumentURI (cppDiags .URI , lsp .NilRange )
1486- return []* lsp.PublishDiagnosticsParams {
1487- {
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 {
14881491 URI : inoURI ,
14891492 Diagnostics : []lsp.Diagnostic {},
1490- },
1491- }, 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+ }
14921505 }
14931506
1494- convertedDiagnostics := map [lsp.DocumentURI ]* lsp.PublishDiagnosticsParams {}
14951507 for _ , cppDiag := range cppDiags .Diagnostics {
1496- inoURI , inoRange , err := handler .cpp2inoDocumentURI (cppDiags . URI , cppDiag .Range )
1508+ inoURI , inoRange , err := handler .cpp2inoDocumentURI (cppURI , cppDiag .Range )
14971509 if err != nil {
14981510 return nil , err
14991511 }
1512+ if inoURI .String () == sourcemapper .NotInoURI .String () {
1513+ continue
1514+ }
15001515
1501- inoDiagParam , created := convertedDiagnostics [inoURI ]
1516+ inoDiagParam , created := inoDiagsParam [inoURI ]
15021517 if ! created {
15031518 inoDiagParam = & lsp.PublishDiagnosticsParams {
15041519 URI : inoURI ,
15051520 Diagnostics : []lsp.Diagnostic {},
15061521 }
1507- convertedDiagnostics [inoURI ] = inoDiagParam
1522+ inoDiagsParam [inoURI ] = inoDiagParam
15081523 }
15091524
15101525 inoDiag := cppDiag
15111526 inoDiag .Range = inoRange
15121527 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+ }
15131542 }
15141543
15151544 inoDiagParams := []* lsp.PublishDiagnosticsParams {}
1516- for _ , v := range convertedDiagnostics {
1545+ for _ , v := range inoDiagsParam {
15171546 inoDiagParams = append (inoDiagParams , v )
15181547 }
15191548 return inoDiagParams , nil
@@ -1602,34 +1631,9 @@ func (handler *InoHandler) FromClangd(ctx context.Context, connection *jsonrpc2.
16021631 if err != nil {
16031632 return nil , err
16041633 }
1605- cleanUpInoDiagnostics := false
1606- if len (inoDiagnostics ) == 0 {
1607- cleanUpInoDiagnostics = true
1608- }
16091634
16101635 // Push back to IDE the converted diagnostics
1611- inoDocsWithDiagnostics := map [string ]bool {}
16121636 for _ , inoDiag := range inoDiagnostics {
1613- if inoDiag .URI .String () == sourcemapper .NotInoURI .String () {
1614- cleanUpInoDiagnostics = true
1615- continue
1616- }
1617-
1618- // If we have an "undefined reference" in the .ino code trigger a
1619- // check for newly created symbols (that in turn may trigger a
1620- // new arduino-preprocessing of the sketch).
1621- if inoDiag .URI .Ext () == ".ino" {
1622- inoDocsWithDiagnostics [inoDiag .URI .Canonical ()] = true
1623- cleanUpInoDiagnostics = true
1624- for _ , diag := range inoDiag .Diagnostics {
1625- if diag .Code == "undeclared_var_use_suggest" ||
1626- diag .Code == "undeclared_var_use" ||
1627- diag .Code == "ovl_no_viable_function_in_call" ||
1628- diag .Code == "pp_file_not_found" {
1629- handler .buildSketchSymbolsCheck = true
1630- }
1631- }
1632- }
16331637
16341638 log .Printf (prefix + "to IDE: publishDiagnostics(%s):" , inoDiag .URI )
16351639 for _ , diag := range inoDiag .Diagnostics {
@@ -1639,27 +1643,6 @@ func (handler *InoHandler) FromClangd(ctx context.Context, connection *jsonrpc2.
16391643 return nil , err
16401644 }
16411645 }
1642-
1643- if cleanUpInoDiagnostics {
1644- // Remove diagnostics from all .ino where there are no errors coming from clang
1645- for sourcePath := range handler .inoDocsWithDiagnostics {
1646- if inoDocsWithDiagnostics [sourcePath ] {
1647- // skip if we already sent updated diagnostics
1648- continue
1649- }
1650- // otherwise clear previous diagnostics
1651- msg := lsp.PublishDiagnosticsParams {
1652- URI : lsp .NewDocumentURI (sourcePath ),
1653- Diagnostics : []lsp.Diagnostic {},
1654- }
1655- log .Printf (prefix + "to IDE: publishDiagnostics(%s):" , msg .URI )
1656- if err := handler .StdioConn .Notify (ctx , "textDocument/publishDiagnostics" , msg ); err != nil {
1657- return nil , err
1658- }
1659- }
1660-
1661- handler .inoDocsWithDiagnostics = inoDocsWithDiagnostics
1662- }
16631646 return nil , err
16641647
16651648 case * lsp.ApplyWorkspaceEditParams :
0 commit comments