mirror of
https://github.com/Myzel394/config-lsp.git
synced 2025-06-18 23:15:26 +02:00
fix(server): Improve ssh_config
This commit is contained in:
parent
e569516aae
commit
dbf543db66
@ -54,7 +54,6 @@ func Analyze(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
analyzeValuesAreValid(ctx)
|
|
||||||
analyzeTokens(ctx)
|
analyzeTokens(ctx)
|
||||||
analyzeIgnoreUnknownHasNoUnnecessary(ctx)
|
analyzeIgnoreUnknownHasNoUnnecessary(ctx)
|
||||||
analyzeDependents(ctx)
|
analyzeDependents(ctx)
|
||||||
|
@ -4,6 +4,7 @@ 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"
|
||||||
@ -41,11 +42,33 @@ func checkOption(
|
|||||||
checkIsUsingDoubleQuotes(ctx, option.Key.Value, option.Key.LocationRange)
|
checkIsUsingDoubleQuotes(ctx, option.Key.Value, option.Key.LocationRange)
|
||||||
checkQuotesAreClosed(ctx, option.Key.Value, option.Key.LocationRange)
|
checkQuotesAreClosed(ctx, option.Key.Value, option.Key.LocationRange)
|
||||||
|
|
||||||
docOption, found := fields.Options[option.Key.Key]
|
docOption, optionFound := fields.Options[option.Key.Key]
|
||||||
|
|
||||||
if !found {
|
if !optionFound {
|
||||||
// Diagnostics will be handled by `values.go`
|
// Diagnostics will be handled by `values.go`
|
||||||
return
|
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,
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if block != nil && block.GetBlockType() == ast.SSHBlockTypeHost && utils.KeyExists(fields.HostDisallowedOptions, option.Key.Key) {
|
||||||
|
ctx.diagnostics = append(ctx.diagnostics, protocol.Diagnostic{
|
||||||
|
Range: option.Key.LocationRange.ToLSPRange(),
|
||||||
|
Message: fmt.Sprintf("Option '%s' is not allowed in Host blocks", option.Key.Key),
|
||||||
|
Severity: &common.SeverityError,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for values that are not allowed in Host blocks
|
// Check for values that are not allowed in Host blocks
|
||||||
@ -59,7 +82,7 @@ func checkOption(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if option.OptionValue != nil {
|
if option.OptionValue != nil && optionFound {
|
||||||
checkIsUsingDoubleQuotes(ctx, option.OptionValue.Value, option.OptionValue.LocationRange)
|
checkIsUsingDoubleQuotes(ctx, option.OptionValue.Value, option.OptionValue.LocationRange)
|
||||||
checkQuotesAreClosed(ctx, option.OptionValue.Value, option.OptionValue.LocationRange)
|
checkQuotesAreClosed(ctx, option.OptionValue.Value, option.OptionValue.LocationRange)
|
||||||
|
|
||||||
|
@ -112,3 +112,79 @@ 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,84 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user