@@ -58,6 +58,7 @@ type InoHandler struct {
58
58
buildSketchCpp * paths.Path
59
59
buildSketchCppVersion int
60
60
buildSketchSymbols []lsp.DocumentSymbol
61
+ buildSketchSymbolsCanary string
61
62
buildSketchSymbolsLoad bool
62
63
buildSketchSymbolsCheck bool
63
64
rebuildSketchDeadline * time.Time
@@ -448,13 +449,14 @@ func (handler *InoHandler) HandleMessageFromIDE(ctx context.Context, conn *jsonr
448
449
}
449
450
if err == nil && handler .buildSketchSymbolsLoad {
450
451
handler .buildSketchSymbolsLoad = false
452
+ handler .buildSketchSymbolsCheck = false
451
453
log .Println (prefix + "Queued resfreshing document symbols" )
452
- go handler .refreshCppDocumentSymbols ()
454
+ go handler .LoadCppDocumentSymbols ()
453
455
}
454
456
if err == nil && handler .buildSketchSymbolsCheck {
455
457
handler .buildSketchSymbolsCheck = false
456
458
log .Println (prefix + "Queued check document symbols" )
457
- go handler .checkCppDocumentSymbols ()
459
+ go handler .CheckCppDocumentSymbols ()
458
460
}
459
461
if err != nil {
460
462
// 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.
563
565
}
564
566
}
565
567
568
+ handler .buildSketchSymbolsLoad = true
566
569
return nil
567
570
}
568
571
569
- func (handler * InoHandler ) refreshCppDocumentSymbols () error {
572
+ func (handler * InoHandler ) refreshCppDocumentSymbols (prefix string ) error {
570
573
// Query source code symbols
571
574
cppURI := lsp .NewDocumentURIFromPath (handler .buildSketchCpp )
572
575
log .Printf (prefix + "requesting documentSymbol for %s" , cppURI )
573
576
577
+ handler .dataRUnlock (prefix )
574
578
result , err := lsp .SendRequest (context .Background (), handler .ClangdConn , "textDocument/documentSymbol" , & lsp.DocumentSymbolParams {
575
579
TextDocument : lsp.TextDocumentIdentifier {URI : cppURI },
576
580
})
577
- handler .dataLock (prefix )
578
- defer handler .dataUnlock (prefix )
581
+ handler .dataRLock (prefix )
579
582
580
583
if err != nil {
581
584
log .Printf (prefix + "error: %s" , err )
582
585
return errors .WithMessage (err , "quering source code symbols" )
583
586
}
584
- result = handler .transformClangdResult ("textDocument/documentSymbol" , cppURI , lsp .NilURI , result )
585
587
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" )
590
592
}
593
+ symbols := * symbolResult .DocumentSymbolArray
591
594
592
595
// Filter non-functions symbols
593
596
i := 0
@@ -600,30 +603,47 @@ func (handler *InoHandler) refreshCppDocumentSymbols() error {
600
603
}
601
604
symbols = symbols [:i ]
602
605
606
+ canary := ""
603
607
for _ , symbol := range symbols {
604
608
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
+ }
605
619
}
606
620
handler .buildSketchSymbols = symbols
621
+ handler .buildSketchSymbolsCanary = canary
607
622
return nil
608
623
}
609
624
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
+
612
639
oldSymbols := handler .buildSketchSymbols
613
- if err := handler .refreshCppDocumentSymbols (); err != nil {
640
+ canary := handler .buildSketchSymbolsCanary
641
+ if err := handler .refreshCppDocumentSymbols (prefix ); err != nil {
614
642
return err
615
643
}
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!" )
618
646
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
- }
627
647
}
628
648
return nil
629
649
}
@@ -697,9 +717,6 @@ func (handler *InoHandler) didOpen(inoDidOpen *lsp.DidOpenTextDocumentParams) (*
697
717
if handler .sketchTrackedFilesCount != 1 {
698
718
return nil , nil
699
719
}
700
-
701
- // trigger a documentSymbol load
702
- handler .buildSketchSymbolsLoad = true
703
720
}
704
721
705
722
cppItem , err := handler .ino2cppTextDocumentItem (inoItem )
@@ -778,7 +795,7 @@ func (handler *InoHandler) didChange(ctx context.Context, req *lsp.DidChangeText
778
795
// and trigger arduino-preprocessing + clangd restart.
779
796
dirty := false
780
797
for _ , sym := range handler .buildSketchSymbols {
781
- if sym .Range .Overlaps (cppRange ) {
798
+ if sym .SelectionRange .Overlaps (cppRange ) {
782
799
dirty = true
783
800
log .Println ("--! DIRTY CHANGE detected using symbol tables, force sketch rebuild!" )
784
801
break
@@ -1577,7 +1594,9 @@ func (handler *InoHandler) FromClangd(ctx context.Context, connection *jsonrpc2.
1577
1594
inoDocsWithDiagnostics [inoDiag .URI .Canonical ()] = true
1578
1595
cleanUpInoDiagnostics = true
1579
1596
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" {
1581
1600
handler .buildSketchSymbolsCheck = true
1582
1601
}
1583
1602
}
0 commit comments