@@ -12,6 +12,8 @@ import (
1212 "strings"
1313 "time"
1414
15+ "github.com/bcmi-labs/arduino-language-server/handler/sourcemapper"
16+ "github.com/bcmi-labs/arduino-language-server/handler/textutils"
1517 "github.com/pkg/errors"
1618 lsp "github.com/sourcegraph/go-lsp"
1719 "github.com/sourcegraph/jsonrpc2"
@@ -70,12 +72,11 @@ type InoHandler struct {
7072
7173// FileData gathers information on a .ino source file.
7274type FileData struct {
73- sourceText string
74- sourceURI lsp.DocumentURI
75- targetURI lsp.DocumentURI
76- sourceLineMap map [int ]int
77- targetLineMap map [int ]int
78- version int
75+ sourceText string
76+ sourceURI lsp.DocumentURI
77+ targetURI lsp.DocumentURI
78+ sourceMap * sourcemapper.InoMapper
79+ version int
7980}
8081
8182// StopClangd closes the connection to the clangd process.
@@ -240,13 +241,11 @@ func (handler *InoHandler) createFileData(ctx context.Context, sourceURI lsp.Doc
240241 }
241242
242243 targetURI := pathToURI (targetPath )
243- sourceLineMap , targetLineMap := createSourceMaps (bytes .NewReader (targetBytes ))
244244 data := & FileData {
245245 sourceText ,
246246 sourceURI ,
247247 targetURI ,
248- sourceLineMap ,
249- targetLineMap ,
248+ sourcemapper .CreateInoMapper (bytes .NewReader (targetBytes )),
250249 version ,
251250 }
252251 handler .data [sourceURI ] = data
@@ -262,7 +261,7 @@ func (handler *InoHandler) updateFileData(ctx context.Context, data *FileData, c
262261 if rang == nil {
263262 newSourceText = change .Text
264263 } else {
265- newSourceText , err = applyTextChange (data .sourceText , * rang , change .Text )
264+ newSourceText , err = textutils . ApplyTextChange (data .sourceText , * rang , change .Text )
266265 if err != nil {
267266 return err
268267 }
@@ -277,35 +276,28 @@ func (handler *InoHandler) updateFileData(ctx context.Context, data *FileData, c
277276 }
278277 } else {
279278 // Fallback: try to apply a multi-line update
280- targetStartLine := data .targetLineMap [rang .Start .Line ]
281- targetEndLine := data .targetLineMap [rang .End .Line ]
282279 data .sourceText = newSourceText
283- updateSourceMaps (data .sourceLineMap , data .targetLineMap , rang .End .Line - rang .Start .Line , rang .Start .Line , change .Text )
284- rang .Start .Line = targetStartLine
285- rang .End .Line = targetEndLine
280+ data .sourceMap .Update (rang .End .Line - rang .Start .Line , rang .Start .Line , change .Text )
281+ * rang = data .sourceMap .InoToCppRange (* rang )
286282 return nil
287283 }
288284 }
289285
290- sourceLineMap , targetLineMap := createSourceMaps (bytes .NewReader (targetBytes ))
291286 data .sourceText = newSourceText
292- data .sourceLineMap = sourceLineMap
293- data .targetLineMap = targetLineMap
287+ data .sourceMap = sourcemapper .CreateInoMapper (bytes .NewReader (targetBytes ))
294288
295289 change .Text = string (targetBytes )
296290 change .Range = nil
297291 change .RangeLength = 0
298292 } else {
299293 // Apply an update to a single line both to the source and the target text
300- targetLine := data .targetLineMap [rang .Start .Line ]
301- data .sourceText , err = applyTextChange (data .sourceText , * rang , change .Text )
294+ data .sourceText , err = textutils .ApplyTextChange (data .sourceText , * rang , change .Text )
302295 if err != nil {
303296 return err
304297 }
305- updateSourceMaps ( data .sourceLineMap , data . targetLineMap , 0 , rang .Start .Line , change .Text )
298+ data .sourceMap . Update ( 0 , rang .Start .Line , change .Text )
306299
307- rang .Start .Line = targetLine
308- rang .End .Line = targetLine
300+ * rang = data .sourceMap .InoToCppRange (* rang )
309301 }
310302 return nil
311303}
@@ -391,7 +383,7 @@ func (handler *InoHandler) ino2cppDidChangeTextDocumentParams(ctx context.Contex
391383func (handler * InoHandler ) ino2cppTextDocumentPositionParams (params * lsp.TextDocumentPositionParams ) error {
392384 handler .ino2cppTextDocumentIdentifier (& params .TextDocument )
393385 if data , ok := handler .data [params .TextDocument .URI ]; ok {
394- targetLine := data .targetLineMap [ params .Position .Line ]
386+ targetLine := data .sourceMap . InoToCppLine ( params .Position .Line )
395387 params .Position .Line = targetLine
396388 return nil
397389 }
@@ -401,12 +393,10 @@ func (handler *InoHandler) ino2cppTextDocumentPositionParams(params *lsp.TextDoc
401393func (handler * InoHandler ) ino2cppCodeActionParams (params * lsp.CodeActionParams ) error {
402394 handler .ino2cppTextDocumentIdentifier (& params .TextDocument )
403395 if data , ok := handler .data [params .TextDocument .URI ]; ok {
404- params .Range .Start .Line = data .targetLineMap [params .Range .Start .Line ]
405- params .Range .End .Line = data .targetLineMap [params .Range .End .Line ]
396+ params .Range = data .sourceMap .InoToCppRange (params .Range )
406397 for index := range params .Context .Diagnostics {
407398 r := & params .Context .Diagnostics [index ].Range
408- r .Start .Line = data .targetLineMap [r .Start .Line ]
409- r .End .Line = data .targetLineMap [r .End .Line ]
399+ * r = data .sourceMap .InoToCppRange (* r )
410400 }
411401 return nil
412402 }
@@ -416,8 +406,7 @@ func (handler *InoHandler) ino2cppCodeActionParams(params *lsp.CodeActionParams)
416406func (handler * InoHandler ) ino2cppDocumentRangeFormattingParams (params * lsp.DocumentRangeFormattingParams ) error {
417407 handler .ino2cppTextDocumentIdentifier (& params .TextDocument )
418408 if data , ok := handler .data [params .TextDocument .URI ]; ok {
419- params .Range .Start .Line = data .targetLineMap [params .Range .Start .Line ]
420- params .Range .End .Line = data .targetLineMap [params .Range .End .Line ]
409+ params .Range = data .sourceMap .InoToCppRange (params .Range )
421410 return nil
422411 }
423412 return unknownURI (params .TextDocument .URI )
@@ -426,7 +415,7 @@ func (handler *InoHandler) ino2cppDocumentRangeFormattingParams(params *lsp.Docu
426415func (handler * InoHandler ) ino2cppDocumentOnTypeFormattingParams (params * lsp.DocumentOnTypeFormattingParams ) error {
427416 handler .ino2cppTextDocumentIdentifier (& params .TextDocument )
428417 if data , ok := handler .data [params .TextDocument .URI ]; ok {
429- params .Position .Line = data .targetLineMap [ params .Position .Line ]
418+ params .Position .Line = data .sourceMap . InoToCppLine ( params .Position .Line )
430419 return nil
431420 }
432421 return unknownURI (params .TextDocument .URI )
@@ -435,7 +424,7 @@ func (handler *InoHandler) ino2cppDocumentOnTypeFormattingParams(params *lsp.Doc
435424func (handler * InoHandler ) ino2cppRenameParams (params * lsp.RenameParams ) error {
436425 handler .ino2cppTextDocumentIdentifier (& params .TextDocument )
437426 if data , ok := handler .data [params .TextDocument .URI ]; ok {
438- params .Position .Line = data .targetLineMap [ params .Position .Line ]
427+ params .Position .Line = data .sourceMap . InoToCppLine ( params .Position .Line )
439428 return nil
440429 }
441430 return unknownURI (params .TextDocument .URI )
@@ -467,13 +456,9 @@ func (handler *InoHandler) ino2cppWorkspaceEdit(origEdit *lsp.WorkspaceEdit) *ls
467456 if data , ok := handler .data [lsp .DocumentURI (uri )]; ok {
468457 newValue := make ([]lsp.TextEdit , len (edit ))
469458 for index := range edit {
470- r := edit [index ].Range
471459 newValue [index ] = lsp.TextEdit {
472460 NewText : edit [index ].NewText ,
473- Range : lsp.Range {
474- Start : lsp.Position {Line : data .targetLineMap [r .Start .Line ], Character : r .Start .Character },
475- End : lsp.Position {Line : data .targetLineMap [r .End .Line ], Character : r .End .Character },
476- },
461+ Range : data .sourceMap .InoToCppRange (edit [index ].Range ),
477462 }
478463 }
479464 newEdit .Changes [string (data .targetURI )] = newValue
@@ -577,9 +562,7 @@ func (handler *InoHandler) cpp2inoCompletionList(list *lsp.CompletionList, uri l
577562 for _ , item := range list .Items {
578563 if ! strings .HasPrefix (item .InsertText , "_" ) {
579564 if item .TextEdit != nil {
580- r := & item .TextEdit .Range
581- r .Start .Line = data .sourceLineMap [r .Start .Line ]
582- r .End .Line = data .sourceLineMap [r .End .Line ]
565+ item .TextEdit .Range = data .sourceMap .CppToInoRange (item .TextEdit .Range )
583566 }
584567 newItems = append (newItems , item )
585568 }
@@ -592,9 +575,7 @@ func (handler *InoHandler) cpp2inoCodeAction(codeAction *CodeAction, uri lsp.Doc
592575 codeAction .Edit = handler .cpp2inoWorkspaceEdit (codeAction .Edit )
593576 if data , ok := handler .data [uri ]; ok {
594577 for index := range codeAction .Diagnostics {
595- r := & codeAction .Diagnostics [index ].Range
596- r .Start .Line = data .sourceLineMap [r .Start .Line ]
597- r .End .Line = data .sourceLineMap [r .End .Line ]
578+ codeAction .Diagnostics [index ].Range = data .sourceMap .CppToInoRange (codeAction .Diagnostics [index ].Range )
598579 }
599580 }
600581}
@@ -614,13 +595,9 @@ func (handler *InoHandler) cpp2inoWorkspaceEdit(origEdit *lsp.WorkspaceEdit) *ls
614595 if data , ok := handler .data [lsp .DocumentURI (uri )]; ok {
615596 newValue := make ([]lsp.TextEdit , len (edit ))
616597 for index := range edit {
617- r := edit [index ].Range
618598 newValue [index ] = lsp.TextEdit {
619599 NewText : edit [index ].NewText ,
620- Range : lsp.Range {
621- Start : lsp.Position {Line : data .sourceLineMap [r .Start .Line ], Character : r .Start .Character },
622- End : lsp.Position {Line : data .sourceLineMap [r .End .Line ], Character : r .End .Character },
623- },
600+ Range : data .sourceMap .CppToInoRange (edit [index ].Range ),
624601 }
625602 }
626603 newEdit .Changes [string (data .sourceURI )] = newValue
@@ -635,31 +612,27 @@ func (handler *InoHandler) cpp2inoHover(hover *Hover, uri lsp.DocumentURI) {
635612 if data , ok := handler .data [uri ]; ok {
636613 r := hover .Range
637614 if r != nil {
638- r .Start .Line = data .sourceLineMap [r .Start .Line ]
639- r .End .Line = data .sourceLineMap [r .End .Line ]
615+ * r = data .sourceMap .CppToInoRange (* r )
640616 }
641617 }
642618}
643619
644620func (handler * InoHandler ) cpp2inoLocation (location * lsp.Location ) {
645621 if data , ok := handler .data [location .URI ]; ok {
646622 location .URI = data .sourceURI
647- location .Range .Start .Line = data .sourceLineMap [location .Range .Start .Line ]
648- location .Range .End .Line = data .sourceLineMap [location .Range .End .Line ]
623+ location .Range = data .sourceMap .CppToInoRange (location .Range )
649624 }
650625}
651626
652627func (handler * InoHandler ) cpp2inoDocumentHighlight (highlight * lsp.DocumentHighlight , uri lsp.DocumentURI ) {
653628 if data , ok := handler .data [uri ]; ok {
654- highlight .Range .Start .Line = data .sourceLineMap [highlight .Range .Start .Line ]
655- highlight .Range .End .Line = data .sourceLineMap [highlight .Range .End .Line ]
629+ highlight .Range = data .sourceMap .CppToInoRange (highlight .Range )
656630 }
657631}
658632
659633func (handler * InoHandler ) cpp2inoTextEdit (edit * lsp.TextEdit , uri lsp.DocumentURI ) {
660634 if data , ok := handler .data [uri ]; ok {
661- edit .Range .Start .Line = data .sourceLineMap [edit .Range .Start .Line ]
662- edit .Range .End .Line = data .sourceLineMap [edit .Range .End .Line ]
635+ edit .Range = data .sourceMap .CppToInoRange (edit .Range )
663636 }
664637}
665638
@@ -672,8 +645,7 @@ func (handler *InoHandler) cpp2inoDocumentSymbols(origSymbols []DocumentSymbol,
672645 symbolIdx := make (map [string ]* DocumentSymbol )
673646 for i := 0 ; i < len (origSymbols ); i ++ {
674647 symbol := & origSymbols [i ]
675- symbol .Range .Start .Line = data .sourceLineMap [symbol .Range .Start .Line ]
676- symbol .Range .End .Line = data .sourceLineMap [symbol .Range .End .Line ]
648+ symbol .Range = data .sourceMap .CppToInoRange (symbol .Range )
677649
678650 duplicate := false
679651 other , duplicate := symbolIdx [symbol .Name ]
@@ -686,8 +658,7 @@ func (handler *InoHandler) cpp2inoDocumentSymbols(origSymbols []DocumentSymbol,
686658 }
687659 }
688660
689- symbol .SelectionRange .Start .Line = data .sourceLineMap [symbol .SelectionRange .Start .Line ]
690- symbol .SelectionRange .End .Line = data .sourceLineMap [symbol .SelectionRange .End .Line ]
661+ symbol .SelectionRange = data .sourceMap .CppToInoRange (symbol .SelectionRange )
691662 symbol .Children = handler .cpp2inoDocumentSymbols (symbol .Children , uri )
692663 symbolIdx [symbol .Name ] = symbol
693664 }
@@ -776,9 +747,9 @@ func (handler *InoHandler) cpp2inoPublishDiagnosticsParams(params *lsp.PublishDi
776747 newDiagnostics := make ([]lsp.Diagnostic , 0 , len (params .Diagnostics ))
777748 for index := range params .Diagnostics {
778749 r := & params .Diagnostics [index ].Range
779- if startLine , ok := data .sourceLineMap [ r .Start .Line ] ; ok {
750+ if startLine , ok := data .sourceMap . CppToInoLineOk ( r .Start .Line ) ; ok {
780751 r .Start .Line = startLine
781- r .End .Line = data .sourceLineMap [ r .End .Line ]
752+ r .End .Line = data .sourceMap . CppToInoLine ( r .End .Line )
782753 newDiagnostics = append (newDiagnostics , params .Diagnostics [index ])
783754 }
784755 }
0 commit comments