feat: Add simple diagnostics; Improvements

This commit is contained in:
Myzel394 2024-07-28 13:36:29 +02:00
parent da4577ac22
commit 184cf63411
No known key found for this signature in database
GPG Key ID: DEC4AAB876F73185
5 changed files with 121 additions and 30 deletions

35
common/errors.go Normal file
View File

@ -0,0 +1,35 @@
package common
import (
"fmt"
)
type ParserError interface {}
type OptionAlreadyExistsError struct {
Option string
FoundOnLine uint32
}
func (e OptionAlreadyExistsError) Error() string {
return fmt.Sprintf("Option %s already exists", e.Option)
}
type OptionUnknownError struct {
Option string
}
func (e OptionUnknownError) Error() string {
return fmt.Sprintf("Option '%s' does not exist", e.Option)
}
type MalformedLineError struct {
Line string
}
func (e MalformedLineError) Error() string {
return fmt.Sprintf("Malformed line: %s", e.Line)
}
type LineNotFoundError struct {}
func (e LineNotFoundError) Error() string {
return "Line not found"
}

View File

@ -1,7 +1,6 @@
package common
import (
"fmt"
"regexp"
"strings"
)
@ -34,29 +33,6 @@ type SimpleConfigParser struct {
Options SimpleConfigOptions
}
type OptionAlreadyExistsError struct {
Option string
}
func (e OptionAlreadyExistsError) Error() string {
return fmt.Sprintf("Option %s already exists", e.Option)
}
type OptionUnknownError struct {
Option string
}
func (e OptionUnknownError) Error() string {
return fmt.Sprintf("Option '%s' does not exist", e.Option)
}
type MalformedLineError struct {
Line string
}
func (e MalformedLineError) Error() string {
return fmt.Sprintf("Malformed line: %s", e.Line)
}
type LineNotFoundError struct {}
func (e LineNotFoundError) Error() string {
return "Line not found"
}
func (p *SimpleConfigParser) AddLine(line string, lineNumber int) error {
parts := strings.SplitN(line, p.Options.Separator, 2)
@ -83,6 +59,7 @@ func (p *SimpleConfigParser) AddLine(line string, lineNumber int) error {
if _, exists := p.Lines[option]; exists {
return OptionAlreadyExistsError{
Option: option,
FoundOnLine: uint32(lineNumber),
}
}
@ -118,6 +95,22 @@ func (p *SimpleConfigParser) UpsertOption(option string, value string) {
}
}
func (p *SimpleConfigParser) GetOption(option string) (SimpleConfigLine, error) {
if _, exists := p.Lines[option]; exists {
return p.Lines[option], nil
}
return SimpleConfigLine{
Value: "",
Position: SimpleConfigPosition{
Line: 0,
},
},
OptionUnknownError{
Option: option,
}
}
func (p *SimpleConfigParser) ParseFromFile(content string) []error {
lines := strings.Split(content, "\n")
errors := make([]error, 0)
@ -142,7 +135,7 @@ func (p *SimpleConfigParser) Clear() {
}
// TODO: Use better approach: Store an extra array of lines in order; with references to the SimpleConfigLine
func (p SimpleConfigParser) FindByLineNumber(lineNumber int) (string, SimpleConfigLine, error) {
func (p *SimpleConfigParser) FindByLineNumber(lineNumber int) (string, SimpleConfigLine, error) {
for option, line := range p.Lines {
if line.Position.Line == lineNumber {
return option, line, nil

View File

@ -0,0 +1,56 @@
package handlers
import (
"config-lsp/common"
"fmt"
"unicode/utf8"
"github.com/tliron/glsp"
protocol "github.com/tliron/glsp/protocol_3_16"
)
func ClearDiagnostics(context *glsp.Context, uri protocol.DocumentUri) {
context.Notify(
"textDocument/publishDiagnostics",
protocol.PublishDiagnosticsParams{
URI: uri,
Diagnostics: []protocol.Diagnostic{},
},
)
}
func SendDiagnosticsFromParserErrors(context *glsp.Context, uri protocol.DocumentUri, parserErrors []error) {
diagnosticErrors := make([]protocol.Diagnostic, 0)
for _, parserError := range parserErrors {
switch parserError.(type) {
case common.OptionAlreadyExistsError: {
err := parserError.(common.OptionAlreadyExistsError)
existingOption, _ := Parser.GetOption(err.Option)
diagnosticErrors = append(diagnosticErrors, protocol.Diagnostic{
Range: protocol.Range{
Start: protocol.Position{
Line: err.FoundOnLine,
Character: 0,
},
End: protocol.Position{
Line: err.FoundOnLine,
Character: uint32(utf8.RuneCountInString(err.Option)),
},
},
Message: fmt.Sprintf("Option '%s' has already been declared on line %v", err.Option, existingOption.Position.Line + 1),
})
}
}
}
context.Notify(
"textDocument/publishDiagnostics",
protocol.PublishDiagnosticsParams{
URI: uri,
Diagnostics: diagnosticErrors,
},
)
}

View File

@ -10,7 +10,14 @@ func TextDocumentDidChange(context *glsp.Context, params *protocol.DidChangeText
content := params.ContentChanges[0].(protocol.TextDocumentContentChangeEventWhole).Text
Parser.Clear()
Parser.ParseFromFile(content)
errors := Parser.ParseFromFile(content)
if len(errors) > 0 {
SendDiagnosticsFromParserErrors(context, params.TextDocument.URI, errors)
} else {
ClearDiagnostics(context, params.TextDocument.URI)
}
return nil
}

View File

@ -17,7 +17,7 @@ func TextDocumentDidOpen(context *glsp.Context, params *protocol.DidOpenTextDocu
errors := Parser.ParseFromFile(string(readBytes))
if len(errors) > 0 {
return errors[0]
SendDiagnosticsFromParserErrors(context, params.TextDocument.URI, errors)
}
return nil