Skip to content

Commit e485484

Browse files
committed
Fixed concurrency and improved checks for sketch-rebuild trigger
1 parent 2a31a25 commit e485484

File tree

1 file changed

+47
-28
lines changed

1 file changed

+47
-28
lines changed

Diff for: handler/handler.go

+47-28
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)