From 0405282233d90196c5d2d7895d258f38488e8ef4 Mon Sep 17 00:00:00 2001 From: qvalentin Date: Sat, 23 Sep 2023 19:29:32 +0200 Subject: [PATCH] [FEAT] ignore "Map keys must be unique" in else branches --- internal/adapter/yamlls/diagnostics.go | 17 +++++++++-- internal/lsp/ast_diagnostics.go | 40 +++++++++++++++++++++++++ internal/lsp/ast_diagnostics_test.go | 41 ++++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 internal/lsp/ast_diagnostics.go create mode 100644 internal/lsp/ast_diagnostics_test.go diff --git a/internal/adapter/yamlls/diagnostics.go b/internal/adapter/yamlls/diagnostics.go index 8835a7ba..39318875 100644 --- a/internal/adapter/yamlls/diagnostics.go +++ b/internal/adapter/yamlls/diagnostics.go @@ -31,12 +31,25 @@ func filterDiagnostics(diagnostics []lsp.Diagnostic, ast *sitter.Tree, content s for _, diagnostic := range diagnostics { node := lsplocal.NodeAtPosition(ast, diagnostic.Range.Start) childNode := lsplocal.FindRelevantChildNode(ast.RootNode(), lsplocal.GetSitterPointForLspPos(diagnostic.Range.Start)) - diagnostic.Message = "Yamlls: " + diagnostic.Message if node.Type() == "text" && childNode.Type() == "text" { logger.Debug("Diagnostic", diagnostic) logger.Debug("Node", node.Content([]byte(content))) - filtered = append(filtered, diagnostic) + if diagnisticIsRelevant(diagnostic, childNode) { + diagnostic.Message = "Yamlls: " + diagnostic.Message + filtered = append(filtered, diagnostic) + } } } return filtered } + +func diagnisticIsRelevant(diagnostic lsp.Diagnostic, node *sitter.Node) bool { + logger.Println("Diagnostic", diagnostic.Message) + switch diagnostic.Message { + case "Map keys must be unique": + return !lsplocal.IsInElseBranch(node) + default: + return true + } + +} diff --git a/internal/lsp/ast_diagnostics.go b/internal/lsp/ast_diagnostics.go new file mode 100644 index 00000000..11cfcc2b --- /dev/null +++ b/internal/lsp/ast_diagnostics.go @@ -0,0 +1,40 @@ +package lsp + +import sitter "github.com/smacker/go-tree-sitter" + +func IsInElseBranch(node *sitter.Node) bool { + + parent := node.Parent() + + if parent == nil { + return false + } + + if parent.Type() == "if_action" { + + childIndex, err := getIndexOfChild(parent, node) + if err != nil { + return IsInElseBranch(parent) + } + + logger.Println("ChildIndex is", childIndex) + + if childIndex > 4 { + return true + } + + } + + return IsInElseBranch(parent) +} + +func getIndexOfChild(parent *sitter.Node, child *sitter.Node) (int, error) { + + count := parent.ChildCount() + for i := 0; i < int(count); i++ { + if parent.Child(i) == child { + return i, nil + } + } + return -1, nil +} diff --git a/internal/lsp/ast_diagnostics_test.go b/internal/lsp/ast_diagnostics_test.go new file mode 100644 index 00000000..0981fe1a --- /dev/null +++ b/internal/lsp/ast_diagnostics_test.go @@ -0,0 +1,41 @@ +package lsp + +import ( + "testing" + + sitter "github.com/smacker/go-tree-sitter" +) + +func TestIsInElseBranch(t *testing.T) { + template := `{{if pipeline}} t1 {{ else if pipeline }} t2 {{ else }} t3 {{ end }}` + var ast = ParseAst(template) + // (template + // (if_action + // (function_call (identifier)) + // (text) + // (function_call (identifier)) + // (text) + // (text))) + + t1_start := sitter.Point{Row: 0, Column: 16} + t1 := ast.RootNode().NamedDescendantForPointRange(t1_start, t1_start) + t2_start := sitter.Point{Row: 0, Column: 42} + t2 := ast.RootNode().NamedDescendantForPointRange(t2_start, t2_start) + t3_start := sitter.Point{Row: 0, Column: 56} + t3 := ast.RootNode().NamedDescendantForPointRange(t3_start, t3_start) + + if (t1.Content([]byte(template))) != " t1 " || (t2.Content([]byte(template))) != " t2 " || (t3.Content([]byte(template))) != " t3 " { + t.Errorf("Nodes were not correclty selected") + } + + if IsInElseBranch(t1) { + t.Errorf("t1 was incorrectly identified as in else branch") + } + if !IsInElseBranch(t2) { + t.Errorf("t2 was incorrectly identified as not in else branch") + } + if !IsInElseBranch(t3) { + t.Errorf("t3 was incorrectly identified as not in else branch") + } + +}