mirror of
https://github.com/Myzel394/config-lsp.git
synced 2025-06-18 15:05:28 +02:00
refactor(server): ssh_config improvements
Signed-off-by: Myzel394 <github.7a2op@simplelogin.co>
This commit is contained in:
parent
0b2690910f
commit
1cfb9bbfba
@ -54,6 +54,7 @@ func Analyze(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
analyzeValuesAreValid(ctx)
|
||||||
analyzeTokens(ctx)
|
analyzeTokens(ctx)
|
||||||
analyzeIgnoreUnknownHasNoUnnecessary(ctx)
|
analyzeIgnoreUnknownHasNoUnnecessary(ctx)
|
||||||
analyzeDependents(ctx)
|
analyzeDependents(ctx)
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"config-lsp/common"
|
"config-lsp/common"
|
||||||
docvalues "config-lsp/doc-values"
|
docvalues "config-lsp/doc-values"
|
||||||
"config-lsp/handlers/ssh_config/ast"
|
"config-lsp/handlers/ssh_config/ast"
|
||||||
"config-lsp/handlers/ssh_config/diagnostics"
|
|
||||||
"config-lsp/handlers/ssh_config/fields"
|
"config-lsp/handlers/ssh_config/fields"
|
||||||
"config-lsp/utils"
|
"config-lsp/utils"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -63,31 +62,16 @@ func checkOption(
|
|||||||
|
|
||||||
if !optionFound {
|
if !optionFound {
|
||||||
// Diagnostics will be handled by `values.go`
|
// Diagnostics will be handled by `values.go`
|
||||||
if !ctx.document.Indexes.CanOptionBeIgnored(option, block) {
|
|
||||||
ctx.diagnostics = append(
|
|
||||||
ctx.diagnostics,
|
|
||||||
diagnostics.GenerateUnknownOption(
|
|
||||||
option.Key.ToLSPRange(),
|
|
||||||
option.Key.Value.Value,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
ctx.document.Indexes.UnknownOptions[option.Start.Line] = ast.AllOptionInfo{
|
|
||||||
Option: option,
|
|
||||||
Block: block,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Since we don't know the option, we can't verify the value
|
|
||||||
return
|
return
|
||||||
} else {
|
}
|
||||||
// Check for values that are not allowed in Host blocks
|
|
||||||
if block != nil && block.GetBlockType() == ast.SSHBlockTypeHost && utils.KeyExists(fields.HostDisallowedOptions, option.Key.Key) {
|
// Check for values that are not allowed in Host blocks
|
||||||
ctx.diagnostics = append(ctx.diagnostics, protocol.Diagnostic{
|
if block != nil && block.GetBlockType() == ast.SSHBlockTypeHost && utils.KeyExists(fields.HostDisallowedOptions, option.Key.Key) {
|
||||||
Range: option.Key.LocationRange.ToLSPRange(),
|
ctx.diagnostics = append(ctx.diagnostics, protocol.Diagnostic{
|
||||||
Message: fmt.Sprintf("Option '%s' is not allowed in Host blocks", option.Key.Key),
|
Range: option.Key.LocationRange.ToLSPRange(),
|
||||||
Severity: &common.SeverityError,
|
Message: fmt.Sprintf("Option '%s' is not allowed in Host blocks", option.Key.Key),
|
||||||
})
|
Severity: &common.SeverityError,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
///// Check if the value is valid
|
///// Check if the value is valid
|
||||||
|
@ -112,79 +112,3 @@ Match
|
|||||||
t.Fatalf("Expected 1 error, got %v", ctx.diagnostics)
|
t.Fatalf("Expected 1 error, got %v", ctx.diagnostics)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUnknownOptionExample(
|
|
||||||
t *testing.T,
|
|
||||||
) {
|
|
||||||
d := testutils_test.DocumentFromInput(t, `
|
|
||||||
ThisOptionDoesNotExist okay
|
|
||||||
`)
|
|
||||||
ctx := &analyzerContext{
|
|
||||||
document: d,
|
|
||||||
diagnostics: make([]protocol.Diagnostic, 0),
|
|
||||||
}
|
|
||||||
|
|
||||||
analyzeStructureIsValid(ctx)
|
|
||||||
|
|
||||||
if !(len(ctx.diagnostics) == 1) {
|
|
||||||
t.Errorf("Expected 1 error, got %v", len(ctx.diagnostics))
|
|
||||||
}
|
|
||||||
|
|
||||||
if !(len(ctx.document.Indexes.UnknownOptions) == 1) {
|
|
||||||
t.Errorf("Expected 1 unknown option, got %v", len(ctx.document.Indexes.UnknownOptions))
|
|
||||||
}
|
|
||||||
|
|
||||||
if !(ctx.document.Indexes.UnknownOptions[0].Option.Key.Value.Value == "ThisOptionDoesNotExist") {
|
|
||||||
t.Errorf("Expected 'ThisOptionDoesNotExist', got %v", ctx.document.Indexes.UnknownOptions[0].Option.Key.Value.Value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUnknownOptionButIgnoredExample(
|
|
||||||
t *testing.T,
|
|
||||||
) {
|
|
||||||
d := testutils_test.DocumentFromInput(t, `
|
|
||||||
IgnoreUnknown ThisOptionDoesNotExist
|
|
||||||
ThisOptionDoesNotExist okay
|
|
||||||
`)
|
|
||||||
ctx := &analyzerContext{
|
|
||||||
document: d,
|
|
||||||
diagnostics: make([]protocol.Diagnostic, 0),
|
|
||||||
}
|
|
||||||
|
|
||||||
analyzeStructureIsValid(ctx)
|
|
||||||
|
|
||||||
if len(ctx.diagnostics) > 0 {
|
|
||||||
t.Fatalf("Expected no errors, but got %v", len(ctx.diagnostics))
|
|
||||||
}
|
|
||||||
|
|
||||||
if !(len(ctx.document.Indexes.UnknownOptions) == 0) {
|
|
||||||
t.Errorf("Expected 0 unknown options, got %v", len(ctx.document.Indexes.UnknownOptions))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUnknownOptionIgnoredIsAfterDefinitionExample(
|
|
||||||
t *testing.T,
|
|
||||||
) {
|
|
||||||
d := testutils_test.DocumentFromInput(t, `
|
|
||||||
ThisOptionDoesNotExist okay
|
|
||||||
IgnoreUnknown ThisOptionDoesNotExist
|
|
||||||
`)
|
|
||||||
ctx := &analyzerContext{
|
|
||||||
document: d,
|
|
||||||
diagnostics: make([]protocol.Diagnostic, 0),
|
|
||||||
}
|
|
||||||
|
|
||||||
analyzeStructureIsValid(ctx)
|
|
||||||
|
|
||||||
if !(len(ctx.diagnostics) == 1) {
|
|
||||||
t.Errorf("Expected 1 error, got %v", len(ctx.diagnostics))
|
|
||||||
}
|
|
||||||
|
|
||||||
if !(len(ctx.document.Indexes.UnknownOptions) == 1) {
|
|
||||||
t.Errorf("Expected 1 unknown option, got %v", len(ctx.document.Indexes.UnknownOptions))
|
|
||||||
}
|
|
||||||
|
|
||||||
if !(ctx.document.Indexes.UnknownOptions[0].Option.Key.Value.Value == "ThisOptionDoesNotExist") {
|
|
||||||
t.Errorf("Expected 'ThisOptionDoesNotExist', got %v", ctx.document.Indexes.UnknownOptions[0].Option.Key.Value.Value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
36
server/handlers/ssh_config/analyzer/values.go
Normal file
36
server/handlers/ssh_config/analyzer/values.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package analyzer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"config-lsp/handlers/ssh_config/diagnostics"
|
||||||
|
"config-lsp/handlers/ssh_config/fields"
|
||||||
|
)
|
||||||
|
|
||||||
|
func analyzeValuesAreValid(
|
||||||
|
ctx *analyzerContext,
|
||||||
|
) {
|
||||||
|
// Check if there are unknown options
|
||||||
|
for _, info := range ctx.document.Config.GetAllOptions() {
|
||||||
|
option := info.Option
|
||||||
|
block := info.Block
|
||||||
|
|
||||||
|
_, found := fields.Options[option.Key.Key]
|
||||||
|
|
||||||
|
if !found {
|
||||||
|
if ctx.document.Indexes.CanOptionBeIgnored(option, block) {
|
||||||
|
// Skip
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.diagnostics = append(
|
||||||
|
ctx.diagnostics,
|
||||||
|
diagnostics.GenerateUnknownOption(
|
||||||
|
option.Key.ToLSPRange(),
|
||||||
|
option.Key.Value.Value,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
ctx.document.Indexes.UnknownOptions[info.Option.Start.Line] = info
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
84
server/handlers/ssh_config/analyzer/values_test.go
Normal file
84
server/handlers/ssh_config/analyzer/values_test.go
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
package analyzer
|
||||||
|
|
||||||
|
import (
|
||||||
|
testutils_test "config-lsp/handlers/ssh_config/test_utils"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestUnknownOptionExample(
|
||||||
|
t *testing.T,
|
||||||
|
) {
|
||||||
|
d := testutils_test.DocumentFromInput(t, `
|
||||||
|
ThisOptionDoesNotExist okay
|
||||||
|
`)
|
||||||
|
ctx := &analyzerContext{
|
||||||
|
document: d,
|
||||||
|
diagnostics: make([]protocol.Diagnostic, 0),
|
||||||
|
}
|
||||||
|
|
||||||
|
analyzeValuesAreValid(ctx)
|
||||||
|
|
||||||
|
if !(len(ctx.diagnostics) == 1) {
|
||||||
|
t.Errorf("Expected 1 error, got %v", len(ctx.diagnostics))
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(len(ctx.document.Indexes.UnknownOptions) == 1) {
|
||||||
|
t.Errorf("Expected 1 unknown option, got %v", len(ctx.document.Indexes.UnknownOptions))
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(ctx.document.Indexes.UnknownOptions[0].Option.Key.Value.Value == "ThisOptionDoesNotExist") {
|
||||||
|
t.Errorf("Expected 'ThisOptionDoesNotExist', got %v", ctx.document.Indexes.UnknownOptions[0].Option.Key.Value.Value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnknownOptionButIgnoredExample(
|
||||||
|
t *testing.T,
|
||||||
|
) {
|
||||||
|
d := testutils_test.DocumentFromInput(t, `
|
||||||
|
IgnoreUnknown ThisOptionDoesNotExist
|
||||||
|
ThisOptionDoesNotExist okay
|
||||||
|
`)
|
||||||
|
ctx := &analyzerContext{
|
||||||
|
document: d,
|
||||||
|
diagnostics: make([]protocol.Diagnostic, 0),
|
||||||
|
}
|
||||||
|
|
||||||
|
analyzeValuesAreValid(ctx)
|
||||||
|
|
||||||
|
if len(ctx.diagnostics) > 0 {
|
||||||
|
t.Fatalf("Expected no errors, but got %v", len(ctx.diagnostics))
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(len(ctx.document.Indexes.UnknownOptions) == 0) {
|
||||||
|
t.Errorf("Expected 0 unknown options, got %v", len(ctx.document.Indexes.UnknownOptions))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnknownOptionIgnoredIsAfterDefinitionExample(
|
||||||
|
t *testing.T,
|
||||||
|
) {
|
||||||
|
d := testutils_test.DocumentFromInput(t, `
|
||||||
|
ThisOptionDoesNotExist okay
|
||||||
|
IgnoreUnknown ThisOptionDoesNotExist
|
||||||
|
`)
|
||||||
|
ctx := &analyzerContext{
|
||||||
|
document: d,
|
||||||
|
diagnostics: make([]protocol.Diagnostic, 0),
|
||||||
|
}
|
||||||
|
|
||||||
|
analyzeValuesAreValid(ctx)
|
||||||
|
|
||||||
|
if !(len(ctx.diagnostics) == 1) {
|
||||||
|
t.Errorf("Expected 1 error, got %v", len(ctx.diagnostics))
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(len(ctx.document.Indexes.UnknownOptions) == 1) {
|
||||||
|
t.Errorf("Expected 1 unknown option, got %v", len(ctx.document.Indexes.UnknownOptions))
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(ctx.document.Indexes.UnknownOptions[0].Option.Key.Value.Value == "ThisOptionDoesNotExist") {
|
||||||
|
t.Errorf("Expected 'ThisOptionDoesNotExist', got %v", ctx.document.Indexes.UnknownOptions[0].Option.Key.Value.Value)
|
||||||
|
}
|
||||||
|
}
|
@ -33,7 +33,7 @@ func FormatDocument(
|
|||||||
// it := d.Config.Options.Iterator()
|
// it := d.Config.Options.Iterator()
|
||||||
// for it.Next() {
|
// for it.Next() {
|
||||||
// line := it.Key().(uint32)
|
// line := it.Key().(uint32)
|
||||||
// entry := it.Value().(ast.SSHEntry)
|
// entry := it.Name().(ast.SSHEntry)
|
||||||
//
|
//
|
||||||
// if !(line >= textRange.Start.Line && line <= textRange.End.Line) {
|
// if !(line >= textRange.Start.Line && line <= textRange.End.Line) {
|
||||||
// continue
|
// continue
|
||||||
|
@ -20,6 +20,7 @@ func TextDocumentDidChange(
|
|||||||
document := sshconfig.DocumentParserMap[params.TextDocument.URI]
|
document := sshconfig.DocumentParserMap[params.TextDocument.URI]
|
||||||
document.Config.Clear()
|
document.Config.Clear()
|
||||||
|
|
||||||
|
println("reparsing everything")
|
||||||
diagnostics := make([]protocol.Diagnostic, 0)
|
diagnostics := make([]protocol.Diagnostic, 0)
|
||||||
errors := document.Config.Parse(content)
|
errors := document.Config.Parse(content)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user