@@ -58,6 +58,7 @@ type InoHandler struct {
5858 buildSketchCpp * paths.Path
5959 buildSketchCppVersion int
6060 buildSketchSymbols []lsp.DocumentSymbol
61+ buildSketchSymbolsCanary string
6162 buildSketchSymbolsLoad bool
6263 buildSketchSymbolsCheck bool
6364 rebuildSketchDeadline * time.Time
@@ -448,13 +449,14 @@ func (handler *InoHandler) HandleMessageFromIDE(ctx context.Context, conn *jsonr
448449 }
449450 if err == nil && handler .buildSketchSymbolsLoad {
450451 handler .buildSketchSymbolsLoad = false
452+ handler .buildSketchSymbolsCheck = false
451453 log .Println (prefix + "Queued resfreshing document symbols" )
452- go handler .refreshCppDocumentSymbols ()
454+ go handler .LoadCppDocumentSymbols ()
453455 }
454456 if err == nil && handler .buildSketchSymbolsCheck {
455457 handler .buildSketchSymbolsCheck = false
456458 log .Println (prefix + "Queued check document symbols" )
457- go handler .checkCppDocumentSymbols ()
459+ go handler .CheckCppDocumentSymbols ()
458460 }
459461 if err != nil {
460462 // Exit the process and trigger a restart by the client in case of a severe error
@@ -563,31 +565,32 @@ func (handler *InoHandler) initializeWorkbench(ctx context.Context, params *lsp.
563565 }
564566 }
565567
568+ handler .buildSketchSymbolsLoad = true
566569 return nil
567570}
568571
569- func (handler * InoHandler ) refreshCppDocumentSymbols () error {
572+ func (handler * InoHandler ) refreshCppDocumentSymbols (prefix string ) error {
570573 // Query source code symbols
571574 cppURI := lsp .NewDocumentURIFromPath (handler .buildSketchCpp )
572575 log .Printf (prefix + "requesting documentSymbol for %s" , cppURI )
573576
577+ handler .dataRUnlock (prefix )
574578 result , err := lsp .SendRequest (context .Background (), handler .ClangdConn , "textDocument/documentSymbol" , & lsp.DocumentSymbolParams {
575579 TextDocument : lsp.TextDocumentIdentifier {URI : cppURI },
576580 })
577- handler .dataLock (prefix )
578- defer handler .dataUnlock (prefix )
581+ handler .dataRLock (prefix )
579582
580583 if err != nil {
581584 log .Printf (prefix + "error: %s" , err )
582585 return errors .WithMessage (err , "quering source code symbols" )
583586 }
584- result = handler .transformClangdResult ("textDocument/documentSymbol" , cppURI , lsp .NilURI , result )
585587
586- symbols , ok := result .([] lsp.DocumentSymbol )
587- if ! ok {
588- log .Printf (prefix + "error: invalid response from clangd" )
589- return errors .New ("invalid response from clangd" )
588+ symbolResult , ok := result .(* lsp.DocumentSymbolArrayOrSymbolInformationArray )
589+ if ! ok || symbolResult . DocumentSymbolArray == nil {
590+ log .Printf (prefix + "error: expected DocumenSymbol array from clangd" )
591+ return errors .New ("expected array from clangd" )
590592 }
593+ symbols := * symbolResult .DocumentSymbolArray
591594
592595 // Filter non-functions symbols
593596 i := 0
@@ -600,30 +603,47 @@ func (handler *InoHandler) refreshCppDocumentSymbols() error {
600603 }
601604 symbols = symbols [:i ]
602605
606+ canary := ""
603607 for _ , symbol := range symbols {
604608 log .Printf (prefix + " symbol: %s %s %s" , symbol .Kind , symbol .Name , symbol .Range )
609+ if symbolText , err := textutils .ExtractRange (handler .sketchMapper .CppText .Text , symbol .Range ); err != nil {
610+ log .Printf (prefix + " > invalid range: %s" , err )
611+ canary += "/"
612+ } else if end := strings .Index (symbolText , "{" ); end != - 1 {
613+ log .Printf (prefix + " TRIMMED> %s" , symbolText [:end ])
614+ canary += symbolText [:end ]
615+ } else {
616+ log .Printf (prefix + " > %s" , symbolText )
617+ canary += symbolText
618+ }
605619 }
606620 handler .buildSketchSymbols = symbols
621+ handler .buildSketchSymbolsCanary = canary
607622 return nil
608623}
609624
610- func (handler * InoHandler ) checkCppDocumentSymbols () error {
611- prefix := "LS --- "
625+ func (handler * InoHandler ) LoadCppDocumentSymbols () error {
626+ prefix := "SYLD--- "
627+ defer log .Printf (prefix + "(done)" )
628+ handler .dataRLock (prefix )
629+ defer handler .dataRUnlock (prefix )
630+ return handler .refreshCppDocumentSymbols (prefix )
631+ }
632+
633+ func (handler * InoHandler ) CheckCppDocumentSymbols () error {
634+ prefix := "SYCK--- "
635+ defer log .Printf (prefix + "(done)" )
636+ handler .dataRLock (prefix )
637+ defer handler .dataRUnlock (prefix )
638+
612639 oldSymbols := handler .buildSketchSymbols
613- if err := handler .refreshCppDocumentSymbols (); err != nil {
640+ canary := handler .buildSketchSymbolsCanary
641+ if err := handler .refreshCppDocumentSymbols (prefix ); err != nil {
614642 return err
615643 }
616- if len (oldSymbols ) != len (handler .buildSketchSymbols ) {
617- log .Println (prefix + "new symbols detected, triggering sketch rebuild!" )
644+ if len (oldSymbols ) != len (handler .buildSketchSymbols ) || canary != handler . buildSketchSymbolsCanary {
645+ log .Println (prefix + "function symbols change detected, triggering sketch rebuild!" )
618646 handler .scheduleRebuildEnvironment ()
619- return nil
620- }
621- for i , old := range oldSymbols {
622- if newName := handler .buildSketchSymbols [i ].Name ; old .Name != newName {
623- log .Printf (prefix + "symbols changed, triggering sketch rebuild: '%s' -> '%s'" , old .Name , newName )
624- handler .scheduleRebuildEnvironment ()
625- return nil
626- }
627647 }
628648 return nil
629649}
@@ -697,9 +717,6 @@ func (handler *InoHandler) didOpen(inoDidOpen *lsp.DidOpenTextDocumentParams) (*
697717 if handler .sketchTrackedFilesCount != 1 {
698718 return nil , nil
699719 }
700-
701- // trigger a documentSymbol load
702- handler .buildSketchSymbolsLoad = true
703720 }
704721
705722 cppItem , err := handler .ino2cppTextDocumentItem (inoItem )
@@ -778,7 +795,7 @@ func (handler *InoHandler) didChange(ctx context.Context, req *lsp.DidChangeText
778795 // and trigger arduino-preprocessing + clangd restart.
779796 dirty := false
780797 for _ , sym := range handler .buildSketchSymbols {
781- if sym .Range .Overlaps (cppRange ) {
798+ if sym .SelectionRange .Overlaps (cppRange ) {
782799 dirty = true
783800 log .Println ("--! DIRTY CHANGE detected using symbol tables, force sketch rebuild!" )
784801 break
@@ -1577,7 +1594,9 @@ func (handler *InoHandler) FromClangd(ctx context.Context, connection *jsonrpc2.
15771594 inoDocsWithDiagnostics [inoDiag .URI .Canonical ()] = true
15781595 cleanUpInoDiagnostics = true
15791596 for _ , diag := range inoDiag .Diagnostics {
1580- if diag .Code == "undeclared_var_use_suggest" || diag .Code == "undeclared_var_use" {
1597+ if diag .Code == "undeclared_var_use_suggest" ||
1598+ diag .Code == "undeclared_var_use" ||
1599+ diag .Code == "ovl_no_viable_function_in_call" {
15811600 handler .buildSketchSymbolsCheck = true
15821601 }
15831602 }
0 commit comments