Skip to content

Commit 5b10b0f

Browse files
committed
feat: lsp diagnostics #29
1 parent 659302e commit 5b10b0f

4 files changed

+60
-13
lines changed

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
# Changelog
22

3-
## v0.0.13-next
3+
## v0.0.13
44

55
- lsp: semantic syntax highlighting #28
6+
- lsp: diagnostics #29
67

78
## v0.0.12
89

langsrv/handler-text-document-did-change.go

+5-8
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package langsrv
33
import (
44
"github.com/tliron/glsp"
55
protocol "github.com/tliron/glsp/protocol_3_16"
6-
"github.com/vknabel/lithia/parser"
76
)
87

98
func textDocumentDidChange(context *glsp.Context, params *protocol.DidChangeTextDocumentParams) error {
@@ -12,26 +11,24 @@ func textDocumentDidChange(context *glsp.Context, params *protocol.DidChangeText
1211
for _, event := range params.ContentChanges {
1312
switch e := event.(type) {
1413
case protocol.TextDocumentContentChangeEvent:
15-
langserver.server.Log.Infof("from: %s", text)
1614
text = text[:e.Range.Start.IndexIn(text)] + e.Text + text[e.Range.End.IndexIn(text):]
17-
langserver.server.Log.Infof("to: %s", text)
1815
case protocol.TextDocumentContentChangeEventWhole:
1916
text = e.Text
2017
}
2118
}
2219
entry.item.Text = text
2320
fileParser, errs := entry.parser.Parse("default-module", string(params.TextDocument.URI), text)
2421
if len(errs) > 0 {
25-
// TODO: syntax errors
26-
return parser.NewGroupedSyntaxError(errs)
22+
publishSyntaxErrorDiagnostics(context, params.TextDocument.URI, uint32(params.TextDocument.Version), errs)
23+
return nil
2724
}
2825
sourceFile, errs := fileParser.ParseSourceFile()
2926
if len(errs) > 0 {
30-
// TODO: syntax errors
31-
return parser.NewGroupedSyntaxError(errs)
27+
publishSyntaxErrorDiagnostics(context, params.TextDocument.URI, uint32(params.TextDocument.Version), errs)
28+
return nil
3229
}
33-
langserver.server.Log.Infof("%s: %s", params.TextDocument.URI, text)
3430
langserver.documentCache.documents[params.TextDocument.URI].fileParser = fileParser
3531
langserver.documentCache.documents[params.TextDocument.URI].sourceFile = sourceFile
32+
publishSyntaxErrorDiagnostics(context, params.TextDocument.URI, uint32(params.TextDocument.Version), nil)
3633
return nil
3734
}

langsrv/handler-text-document-did-open.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,20 @@ func textDocumentDidOpen(context *glsp.Context, params *protocol.DidOpenTextDocu
1010
lithiaParser := parser.NewParser()
1111
fileParser, errs := lithiaParser.Parse("default-module", string(params.TextDocument.URI), params.TextDocument.Text)
1212
if len(errs) > 0 {
13-
// TODO: syntax errors
14-
return parser.NewGroupedSyntaxError(errs)
13+
publishSyntaxErrorDiagnostics(context, params.TextDocument.URI, uint32(params.TextDocument.Version), errs)
14+
return nil
1515
}
1616
sourceFile, errs := fileParser.ParseSourceFile()
1717
if len(errs) > 0 {
18-
// TODO: syntax errors
19-
return parser.NewGroupedSyntaxError(errs)
18+
publishSyntaxErrorDiagnostics(context, params.TextDocument.URI, uint32(params.TextDocument.Version), errs)
19+
return nil
2020
}
2121
langserver.documentCache.documents[params.TextDocument.URI] = &textDocumentEntry{
2222
item: params.TextDocument,
2323
parser: lithiaParser,
2424
fileParser: fileParser,
2525
sourceFile: sourceFile,
2626
}
27+
publishSyntaxErrorDiagnostics(context, params.TextDocument.URI, uint32(params.TextDocument.Version), nil)
2728
return nil
2829
}

langsrv/publish-diagnostics.go

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package langsrv
2+
3+
import (
4+
"github.com/tliron/glsp"
5+
protocol "github.com/tliron/glsp/protocol_3_16"
6+
"github.com/vknabel/lithia/parser"
7+
)
8+
9+
func publishSyntaxErrorDiagnostics(context *glsp.Context, textDocumentURI protocol.URI, version uint32, errs []parser.SyntaxError) {
10+
diagnostics := make([]protocol.Diagnostic, len(errs))
11+
for i, err := range errs {
12+
diagnostics[i] = syntaxErrorToDiagnostic(err)
13+
}
14+
15+
versionRef := version
16+
context.Notify(protocol.ServerTextDocumentPublishDiagnostics, protocol.PublishDiagnosticsParams{
17+
URI: textDocumentURI,
18+
Version: &versionRef,
19+
Diagnostics: diagnostics,
20+
})
21+
}
22+
23+
func syntaxErrorToDiagnostic(err parser.SyntaxError) protocol.Diagnostic {
24+
return protocol.Diagnostic{
25+
Source: &lsName,
26+
Range: rangeFromSourceLocation(err.SourceLocation),
27+
Severity: newSeverityRef(protocol.DiagnosticSeverityError),
28+
Message: err.Message,
29+
}
30+
}
31+
32+
func rangeFromSourceLocation(location parser.SourceLocation) protocol.Range {
33+
return protocol.Range{
34+
Start: protocol.Position{
35+
Line: location.Node.StartPoint().Row,
36+
Character: location.Node.StartPoint().Column,
37+
},
38+
End: protocol.Position{
39+
Line: location.Node.EndPoint().Row,
40+
Character: location.Node.EndPoint().Column,
41+
},
42+
}
43+
}
44+
45+
func newSeverityRef(sev protocol.DiagnosticSeverity) *protocol.DiagnosticSeverity {
46+
severity := sev
47+
return &severity
48+
}

0 commit comments

Comments
 (0)