Skip to content

Commit df0957d

Browse files
committed
Return errors instead of panics to make the code more idiomatic
1 parent d508afb commit df0957d

File tree

6 files changed

+65
-28
lines changed

6 files changed

+65
-28
lines changed

Diff for: internal/ls/definition.go

+10-5
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
package ls
22

33
import (
4+
"fmt"
45
"github.com/microsoft/typescript-go/internal/ast"
56
"github.com/microsoft/typescript-go/internal/astnav"
67
"github.com/microsoft/typescript-go/internal/core"
78
"github.com/microsoft/typescript-go/internal/scanner"
89
)
910

10-
func (l *LanguageService) ProvideDefinitions(fileName string, position int) []Location {
11-
program, file := l.getProgramAndFile(fileName)
11+
func (l *LanguageService) ProvideDefinitions(fileName string, position int) ([]Location, error) {
12+
program, file, err := l.getProgramAndFile(fileName)
13+
if err != nil {
14+
return nil, fmt.Errorf("failed to get program and file: %w", err)
15+
}
16+
1217
node := astnav.GetTouchingPropertyName(file, position)
1318
if node.Kind == ast.KindSourceFile {
14-
return nil
19+
return nil, nil
1520
}
1621

1722
checker := program.GetTypeChecker()
@@ -33,7 +38,7 @@ func (l *LanguageService) ProvideDefinitions(fileName string, position int) []Lo
3338
Range: core.NewTextRange(pos, loc.End()),
3439
})
3540
}
36-
return locations
41+
return locations, nil
3742
}
38-
return nil
43+
return nil, nil
3944
}

Diff for: internal/ls/diagnostics.go

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
package ls
22

33
import (
4+
"fmt"
45
"slices"
56

67
"github.com/microsoft/typescript-go/internal/ast"
78
)
89

9-
func (l *LanguageService) GetDocumentDiagnostics(fileName string) []*ast.Diagnostic {
10-
program, file := l.getProgramAndFile(fileName)
10+
func (l *LanguageService) GetDocumentDiagnostics(fileName string) ([]*ast.Diagnostic, error) {
11+
program, file, err := l.getProgramAndFile(fileName)
12+
if err != nil {
13+
return nil, fmt.Errorf("failed to get program and file for diagnostics: %w", err)
14+
}
1115
syntaxDiagnostics := program.GetSyntacticDiagnostics(file)
1216
semanticDiagnostics := program.GetSemanticDiagnostics(file)
13-
return slices.Concat(syntaxDiagnostics, semanticDiagnostics)
17+
return slices.Concat(syntaxDiagnostics, semanticDiagnostics), nil
1418
}

Diff for: internal/ls/hover.go

+10-5
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,28 @@
11
package ls
22

33
import (
4+
"fmt"
5+
46
"github.com/microsoft/typescript-go/internal/ast"
57
"github.com/microsoft/typescript-go/internal/astnav"
68
)
79

8-
func (l *LanguageService) ProvideHover(fileName string, position int) string {
9-
program, file := l.getProgramAndFile(fileName)
10+
func (l *LanguageService) ProvideHover(fileName string, position int) (string, error) {
11+
program, file, err := l.getProgramAndFile(fileName)
12+
if err != nil {
13+
return "", fmt.Errorf("failed to get program and file for hover: %w", err)
14+
}
1015
node := astnav.GetTouchingPropertyName(file, position)
1116
if node.Kind == ast.KindSourceFile {
1217
// Avoid giving quickInfo for the sourceFile as a whole.
13-
return ""
18+
return "", nil
1419
}
1520

1621
checker := program.GetTypeChecker()
1722
if symbol := checker.GetSymbolAtLocation(node); symbol != nil {
1823
if t := checker.GetTypeOfSymbolAtLocation(symbol, node); t != nil {
19-
return checker.TypeToString(t)
24+
return checker.TypeToString(t), nil
2025
}
2126
}
22-
return ""
27+
return "", nil
2328
}

Diff for: internal/ls/languageservice.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package ls
22

33
import (
4+
"fmt"
5+
46
"github.com/microsoft/typescript-go/internal/ast"
57
"github.com/microsoft/typescript-go/internal/compiler"
68
"github.com/microsoft/typescript-go/internal/core"
@@ -55,11 +57,11 @@ func (l *LanguageService) GetProgram() *compiler.Program {
5557
return l.host.GetProgram()
5658
}
5759

58-
func (l *LanguageService) getProgramAndFile(fileName string) (*compiler.Program, *ast.SourceFile) {
60+
func (l *LanguageService) getProgramAndFile(fileName string) (*compiler.Program, *ast.SourceFile, error) {
5961
program := l.GetProgram()
6062
file := program.GetSourceFile(fileName)
6163
if file == nil {
62-
panic("file not found")
64+
return nil, nil, fmt.Errorf("file not found")
6365
}
64-
return program, file
66+
return program, file, nil
6567
}

Diff for: internal/lsp/converters.go

+18-9
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,18 @@ func (c *converters) fromLspRange(textRange lsproto.Range, fileName string) (cor
3434
if scriptInfo == nil {
3535
return core.TextRange{}, fmt.Errorf("no script info found for %s", fileName)
3636
}
37-
return core.NewTextRange(
38-
lineAndCharacterToPosition(textRange.Start, scriptInfo.LineMap()),
39-
lineAndCharacterToPosition(textRange.End, scriptInfo.LineMap()),
40-
), nil
37+
38+
startPos, err := lineAndCharacterToPosition(textRange.Start, scriptInfo.LineMap())
39+
if err != nil {
40+
return core.TextRange{}, fmt.Errorf("error converting start position: %w", err)
41+
}
42+
43+
endPos, err := lineAndCharacterToPosition(textRange.End, scriptInfo.LineMap())
44+
if err != nil {
45+
return core.TextRange{}, fmt.Errorf("error converting end position: %w", err)
46+
}
47+
48+
return core.NewTextRange(startPos, endPos), nil
4149
}
4250

4351
func (c *converters) fromLspTextChange(change *lsproto.TextDocumentContentChangePartial, fileName string) (ls.TextChange, error) {
@@ -124,7 +132,7 @@ func (c *converters) lineAndCharacterToPosition(lineAndCharacter lsproto.Positio
124132
if scriptInfo == nil {
125133
return 0, fmt.Errorf("no script info found for %s", fileName)
126134
}
127-
return lineAndCharacterToPosition(lineAndCharacter, scriptInfo.LineMap()), nil
135+
return lineAndCharacterToPosition(lineAndCharacter, scriptInfo.LineMap())
128136
}
129137

130138
func languageKindToScriptKind(languageID lsproto.LanguageKind) core.ScriptKind {
@@ -188,19 +196,20 @@ func fileNameToDocumentUri(fileName string) lsproto.DocumentUri {
188196
return lsproto.DocumentUri("file://" + fileName)
189197
}
190198

191-
func lineAndCharacterToPosition(lineAndCharacter lsproto.Position, lineMap []core.TextPos) int {
199+
func lineAndCharacterToPosition(lineAndCharacter lsproto.Position, lineMap []core.TextPos) (int, error) {
192200
line := int(lineAndCharacter.Line)
193201
offset := int(lineAndCharacter.Character)
194202

195203
if line < 0 || line >= len(lineMap) {
196-
panic(fmt.Sprintf("bad line number. Line: %d, lineMap length: %d", line, len(lineMap)))
204+
return 0, fmt.Errorf("bad line number. Line: %d, lineMap length: %d", line, len(lineMap))
197205
}
198206

199207
res := int(lineMap[line]) + offset
200208
if line < len(lineMap)-1 && res >= int(lineMap[line+1]) {
201-
panic("resulting position is out of bounds")
209+
return 0, fmt.Errorf("resulting position is out of bounds")
202210
}
203-
return res
211+
212+
return res, nil
204213
}
205214

206215
func positionToLineAndCharacter(position int, lineMap []core.TextPos) lsproto.Position {

Diff for: internal/lsp/server.go

+15-3
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,11 @@ func (s *Server) handleDidClose(req *lsproto.RequestMessage) error {
303303
func (s *Server) handleDocumentDiagnostic(req *lsproto.RequestMessage) error {
304304
params := req.Params.(*lsproto.DocumentDiagnosticParams)
305305
file, project := s.getFileAndProject(params.TextDocument.Uri)
306-
diagnostics := project.LanguageService().GetDocumentDiagnostics(file.FileName())
306+
diagnostics, err := project.LanguageService().GetDocumentDiagnostics(file.FileName())
307+
if err != nil {
308+
return s.sendError(req.ID, err)
309+
}
310+
307311
lspDiagnostics := make([]lsproto.Diagnostic, len(diagnostics))
308312
for i, diag := range diagnostics {
309313
if lspDiagnostic, err := s.converters.toLspDiagnostic(diag); err != nil {
@@ -330,7 +334,11 @@ func (s *Server) handleHover(req *lsproto.RequestMessage) error {
330334
return s.sendError(req.ID, err)
331335
}
332336

333-
hoverText := project.LanguageService().ProvideHover(file.FileName(), pos)
337+
hoverText, err := project.LanguageService().ProvideHover(file.FileName(), pos)
338+
if err != nil {
339+
return s.sendError(req.ID, err)
340+
}
341+
334342
return s.sendResult(req.ID, &lsproto.Hover{
335343
Contents: lsproto.MarkupContentOrMarkedStringOrMarkedStrings{
336344
MarkupContent: &lsproto.MarkupContent{
@@ -349,7 +357,11 @@ func (s *Server) handleDefinition(req *lsproto.RequestMessage) error {
349357
return s.sendError(req.ID, err)
350358
}
351359

352-
locations := project.LanguageService().ProvideDefinitions(file.FileName(), pos)
360+
locations, err := project.LanguageService().ProvideDefinitions(file.FileName(), pos)
361+
if err != nil {
362+
return s.sendError(req.ID, err)
363+
}
364+
353365
lspLocations := make([]lsproto.Location, len(locations))
354366
for i, loc := range locations {
355367
if lspLocation, err := s.converters.toLspLocation(loc); err != nil {

0 commit comments

Comments
 (0)