Skip to content

Commit c8d2e5e

Browse files
committed
Refactoring of the builder
1 parent 0073fd3 commit c8d2e5e

File tree

5 files changed

+54
-55
lines changed

5 files changed

+54
-55
lines changed

ls/builder.go

+39-10
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ package ls
22

33
import (
44
"bytes"
5+
"runtime"
56
"strings"
67
"time"
78

9+
"github.com/arduino/arduino-cli/arduino/builder"
810
"github.com/arduino/arduino-cli/arduino/libraries"
911
"github.com/arduino/arduino-cli/executils"
1012
"github.com/arduino/arduino-language-server/streams"
@@ -85,17 +87,17 @@ func (handler *INOLanguageServer) rebuildEnvironmentLoop() {
8587
}
8688
}
8789

88-
func (handler *INOLanguageServer) generateBuildEnvironment(logger jsonrpc.FunctionLogger, buildPath *paths.Path) error {
89-
sketchDir := handler.sketchRoot
90-
fqbn := handler.config.SelectedBoard.Fqbn
90+
func (ls *INOLanguageServer) generateBuildEnvironment(logger jsonrpc.FunctionLogger) error {
91+
sketchDir := ls.sketchRoot
92+
fqbn := ls.config.SelectedBoard.Fqbn
9193

9294
// Export temporary files
9395
type overridesFile struct {
9496
Overrides map[string]string `json:"overrides"`
9597
}
9698
data := overridesFile{Overrides: map[string]string{}}
97-
for uri, trackedFile := range handler.trackedInoDocs {
98-
rel, err := paths.New(uri).RelFrom(handler.sketchRoot)
99+
for uri, trackedFile := range ls.trackedInoDocs {
100+
rel, err := paths.New(uri).RelFrom(ls.sketchRoot)
99101
if err != nil {
100102
return errors.WithMessage(err, "dumping tracked files")
101103
}
@@ -104,12 +106,12 @@ func (handler *INOLanguageServer) generateBuildEnvironment(logger jsonrpc.Functi
104106
var overridesJSON *paths.Path
105107
if jsonBytes, err := json.MarshalIndent(data, "", " "); err != nil {
106108
return errors.WithMessage(err, "dumping tracked files")
107-
} else if tmpFile, err := paths.WriteToTempFile(jsonBytes, nil, ""); err != nil {
109+
} else if tmp, err := paths.WriteToTempFile(jsonBytes, nil, ""); err != nil {
108110
return errors.WithMessage(err, "dumping tracked files")
109111
} else {
110-
// logger.Logf("Dumped overrides: %s", string(jsonBytes))
111-
overridesJSON = tmpFile
112-
defer tmpFile.Remove()
112+
logger.Logf("Dumped overrides: %s", string(jsonBytes))
113+
overridesJSON = tmp
114+
defer tmp.Remove()
113115
}
114116

115117
// XXX: do this from IDE or via gRPC
@@ -120,7 +122,7 @@ func (handler *INOLanguageServer) generateBuildEnvironment(logger jsonrpc.Functi
120122
"--only-compilation-database",
121123
"--clean",
122124
"--source-override", overridesJSON.String(),
123-
"--build-path", buildPath.String(),
125+
"--build-path", ls.buildPath.String(),
124126
"--format", "json",
125127
sketchDir.String(),
126128
}
@@ -153,5 +155,32 @@ func (handler *INOLanguageServer) generateBuildEnvironment(logger jsonrpc.Functi
153155
}
154156
logger.Logf("arduino-cli output: %s", cmdOutput)
155157

158+
// TODO: do canonicalization directly in `arduino-cli`
159+
canonicalizeCompileCommandsJSON(ls.buildPath)
160+
156161
return nil
157162
}
163+
164+
func canonicalizeCompileCommandsJSON(compileCommandsDir *paths.Path) {
165+
compileCommandsJSONPath := compileCommandsDir.Join("compile_commands.json")
166+
compileCommands, err := builder.LoadCompilationDatabase(compileCommandsJSONPath)
167+
if err != nil {
168+
panic("could not find compile_commands.json")
169+
}
170+
for i, cmd := range compileCommands.Contents {
171+
if len(cmd.Arguments) == 0 {
172+
panic("invalid empty argument field in compile_commands.json")
173+
}
174+
175+
// clangd requires full path to compiler (including extension .exe on Windows!)
176+
compilerPath := paths.New(cmd.Arguments[0]).Canonical()
177+
compiler := compilerPath.String()
178+
if runtime.GOOS == "windows" && strings.ToLower(compilerPath.Ext()) != ".exe" {
179+
compiler += ".exe"
180+
}
181+
compileCommands.Contents[i].Arguments[0] = compiler
182+
}
183+
184+
// Save back compile_commands.json with OS native file separator and extension
185+
compileCommands.SaveToFile()
186+
}

ls/ls.go

+12-42
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,11 @@ import (
66
"fmt"
77
"io"
88
"log"
9-
"runtime"
109
"strconv"
1110
"strings"
1211
"sync"
1312
"time"
1413

15-
"github.com/arduino/arduino-cli/arduino/builder"
1614
"github.com/arduino/arduino-cli/executils"
1715
"github.com/arduino/arduino-language-server/sourcemapper"
1816
"github.com/arduino/arduino-language-server/streams"
@@ -1062,20 +1060,21 @@ func (ls *INOLanguageServer) initializeWorkbench(logger jsonrpc.FunctionLogger,
10621060
currCppTextVersion := 0
10631061
if params != nil {
10641062
logger.Logf(" --> initialize(%s)", params.RootURI)
1065-
ls.lspInitializeParams = params
10661063
ls.sketchRoot = params.RootURI.AsPath()
10671064
ls.sketchName = ls.sketchRoot.Base()
1065+
ls.buildSketchCpp = ls.buildSketchRoot.Join(ls.sketchName + ".ino.cpp")
1066+
1067+
ls.lspInitializeParams = params
1068+
ls.lspInitializeParams.RootPath = ls.buildSketchRoot.String()
1069+
ls.lspInitializeParams.RootURI = lsp.NewDocumentURIFromPath(ls.buildSketchRoot)
10681070
} else {
10691071
logger.Logf(" --> RE-initialize()")
10701072
currCppTextVersion = ls.sketchMapper.CppText.Version
10711073
}
10721074

1073-
if err := ls.generateBuildEnvironment(logger, ls.buildPath); err != nil {
1075+
if err := ls.generateBuildEnvironment(logger); err != nil {
10741076
return err
10751077
}
1076-
ls.buildSketchCpp = ls.buildSketchRoot.Join(ls.sketchName + ".ino.cpp")
1077-
ls.lspInitializeParams.RootPath = ls.buildSketchRoot.String()
1078-
ls.lspInitializeParams.RootURI = lsp.NewDocumentURIFromPath(ls.buildSketchRoot)
10791078

10801079
if cppContent, err := ls.buildSketchCpp.ReadFile(); err == nil {
10811080
ls.sketchMapper = sourcemapper.CreateInoMapper(cppContent)
@@ -1084,13 +1083,12 @@ func (ls *INOLanguageServer) initializeWorkbench(logger jsonrpc.FunctionLogger,
10841083
return errors.WithMessage(err, "reading generated cpp file from sketch")
10851084
}
10861085

1087-
canonicalizeCompileCommandsJSON(ls.buildPath)
1088-
10891086
if params == nil {
10901087
// If we are restarting re-synchronize clangd
10911088
cppURI := lsp.NewDocumentURIFromPath(ls.buildSketchCpp)
10921089

1093-
logger.Logf("LS --> CL NOTIF textDocument/didSave:")
1090+
logger.Logf("Sending 'didSave' notification to Clangd")
1091+
10941092
didSaveParams := &lsp.DidSaveTextDocumentParams{
10951093
TextDocument: lsp.TextDocumentIdentifier{URI: cppURI},
10961094
Text: ls.sketchMapper.CppText.Text,
@@ -1099,6 +1097,8 @@ func (ls *INOLanguageServer) initializeWorkbench(logger jsonrpc.FunctionLogger,
10991097
logger.Logf(" error reinitilizing clangd:", err)
11001098
return err
11011099
}
1100+
1101+
logger.Logf("Sending 'didChange' notification to Clangd")
11021102
didChangeParams := &lsp.DidChangeTextDocumentParams{
11031103
TextDocument: lsp.VersionedTextDocumentIdentifier{
11041104
TextDocumentIdentifier: lsp.TextDocumentIdentifier{URI: cppURI},
@@ -1258,36 +1258,6 @@ func (ls *INOLanguageServer) CheckCppIncludesChanges() {
12581258
}
12591259
}
12601260

1261-
func canonicalizeCompileCommandsJSON(compileCommandsDir *paths.Path) map[string]bool {
1262-
// Open compile_commands.json and find the main cross-compiler executable
1263-
compileCommandsJSONPath := compileCommandsDir.Join("compile_commands.json")
1264-
compileCommands, err := builder.LoadCompilationDatabase(compileCommandsJSONPath)
1265-
if err != nil {
1266-
panic("could not find compile_commands.json")
1267-
}
1268-
compilers := map[string]bool{}
1269-
for i, cmd := range compileCommands.Contents {
1270-
if len(cmd.Arguments) == 0 {
1271-
panic("invalid empty argument field in compile_commands.json")
1272-
}
1273-
1274-
// clangd requires full path to compiler (including extension .exe on Windows!)
1275-
compilerPath := paths.New(cmd.Arguments[0]).Canonical()
1276-
compiler := compilerPath.String()
1277-
if runtime.GOOS == "windows" && strings.ToLower(compilerPath.Ext()) != ".exe" {
1278-
compiler += ".exe"
1279-
}
1280-
compileCommands.Contents[i].Arguments[0] = compiler
1281-
1282-
compilers[compiler] = true
1283-
}
1284-
1285-
// Save back compile_commands.json with OS native file separator and extension
1286-
compileCommands.SaveToFile()
1287-
1288-
return compilers
1289-
}
1290-
12911261
func (ls *INOLanguageServer) didClose(logger jsonrpc.FunctionLogger, inoDidClose *lsp.DidCloseTextDocumentParams) (*lsp.DidCloseTextDocumentParams, error) {
12921262
inoIdentifier := inoDidClose.TextDocument
12931263
if _, exist := ls.trackedInoDocs[inoIdentifier.URI.AsPath().String()]; exist {
@@ -1368,7 +1338,7 @@ func (ls *INOLanguageServer) didChange(logger jsonrpc.FunctionLogger, inoDidChan
13681338

13691339
cppChanges := []lsp.TextDocumentContentChangeEvent{}
13701340
for _, inoChange := range inoDidChangeParams.ContentChanges {
1371-
cppChangeRange, ok := ls.sketchMapper.InoToCppLSPRangeOk(inoDoc.URI, inoChange.Range)
1341+
cppChangeRange, ok := ls.sketchMapper.InoToCppLSPRangeOk(inoDoc.URI, *inoChange.Range)
13721342
if !ok {
13731343
return nil, errors.Errorf("invalid change range %s:%s", inoDoc.URI, inoChange.Range)
13741344
}
@@ -1394,7 +1364,7 @@ func (ls *INOLanguageServer) didChange(logger jsonrpc.FunctionLogger, inoDidChan
13941364
logger.Logf("New version:----------+\n" + ls.sketchMapper.CppText.Text + "\n----------------------")
13951365

13961366
cppChanges = append(cppChanges, lsp.TextDocumentContentChangeEvent{
1397-
Range: cppChangeRange,
1367+
Range: &cppChangeRange,
13981368
RangeLength: inoChange.RangeLength,
13991369
Text: inoChange.Text,
14001370
})

sourcemapper/ino.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ func unquoteCppString(str string) string {
210210
// It returns true if the change is "dirty", this happens when the change alters preprocessed lines
211211
// and a new preprocessing may be probably required.
212212
func (s *SketchMapper) ApplyTextChange(inoURI lsp.DocumentURI, inoChange lsp.TextDocumentContentChangeEvent) (dirty bool) {
213-
inoRange := inoChange.Range
213+
inoRange := *inoChange.Range
214214
cppRange, ok := s.InoToCppLSPRangeOk(inoURI, inoRange)
215215
if !ok {
216216
panic("Invalid sketch range " + inoURI.String() + ":" + inoRange.String())

sourcemapper/ino_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ func TestCreateSourceMaps(t *testing.T) {
5858
sourceMap.DebugLogAll()
5959

6060
sourceMap.ApplyTextChange(lsp.NewDocumentURIFromPath(sketch), lsp.TextDocumentContentChangeEvent{
61-
Range: lsp.Range{
61+
Range: &lsp.Range{
6262
Start: lsp.Position{Line: 3, Character: 0},
6363
End: lsp.Position{Line: 3, Character: 0},
6464
},

textutils/textutils.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
// ApplyLSPTextDocumentContentChangeEvent applies the LSP change in the given text
1010
func ApplyLSPTextDocumentContentChangeEvent(textDoc lsp.TextDocumentItem, changes []lsp.TextDocumentContentChangeEvent, version int) (lsp.TextDocumentItem, error) {
1111
for _, change := range changes {
12-
if t, err := ApplyTextChange(textDoc.Text, change.Range, change.Text); err == nil {
12+
if t, err := ApplyTextChange(textDoc.Text, *change.Range, change.Text); err == nil {
1313
textDoc.Text = t
1414
} else {
1515
return lsp.TextDocumentItem{}, err

0 commit comments

Comments
 (0)