gopls/internal/lsp: add clear builtin

For golang/go#56351

Change-Id: I5948b776cf7fde275a329d02a4f5728579f13ee9
Reviewed-on: https://go-review.googlesource.com/c/tools/+/463055
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
diff --git a/gopls/internal/lsp/completion_test.go b/gopls/internal/lsp/completion_test.go
index cd3bcec..d9a3e0d 100644
--- a/gopls/internal/lsp/completion_test.go
+++ b/gopls/internal/lsp/completion_test.go
@@ -25,8 +25,8 @@
 		opts.LiteralCompletions = strings.Contains(string(src.URI()), "literal")
 		opts.ExperimentalPostfixCompletions = strings.Contains(string(src.URI()), "postfix")
 	})
-	got = tests.FilterBuiltins(src, got)
-	want := expected(t, test, items)
+	got = filterSkipCompletionItems(tests.FilterBuiltins(src, got))
+	want := filterSkipCompletionItems(expected(t, test, items))
 	if diff := tests.DiffCompletionItems(want, got); diff != "" {
 		t.Errorf("mismatching completion items (-want +got):\n%s", diff)
 	}
@@ -174,3 +174,16 @@
 	}
 	return list.Items
 }
+
+func filterSkipCompletionItems(items []protocol.CompletionItem) []protocol.CompletionItem {
+	n := 0
+	for _, item := range items {
+		// TODO(cuonglm): remove once https://go-review.googlesource.com/c/go/+/462935 land.
+		if item.Label == "clear" {
+			continue
+		}
+		items[n] = item
+		n++
+	}
+	return items[:n]
+}
diff --git a/gopls/internal/lsp/testdata/builtins/builtin_go118.go b/gopls/internal/lsp/testdata/builtins/builtin_go118.go
index 1fa0b14..dabffcc 100644
--- a/gopls/internal/lsp/testdata/builtins/builtin_go118.go
+++ b/gopls/internal/lsp/testdata/builtins/builtin_go118.go
@@ -1,5 +1,5 @@
-//go:build go1.18
-// +build go1.18
+//go:build go1.18 && !go1.21
+// +build go1.18,!go1.21
 
 package builtins
 
diff --git a/gopls/internal/lsp/testdata/builtins/builtin_go121.go b/gopls/internal/lsp/testdata/builtins/builtin_go121.go
new file mode 100644
index 0000000..cb8e8fa
--- /dev/null
+++ b/gopls/internal/lsp/testdata/builtins/builtin_go121.go
@@ -0,0 +1,8 @@
+//go:build go1.21
+// +build go1.21
+
+package builtins
+
+func _() {
+	//@complete("", any, append, bool, byte, cap, clear, close, comparable, complex, complex128, complex64, copy, delete, error, _false, float32, float64, imag, int, int16, int32, int64, int8, len, make, new, panic, print, println, real, recover, rune, string, _true, uint, uint16, uint32, uint64, uint8, uintptr, _nil)
+}
diff --git a/gopls/internal/lsp/testdata/builtins/builtins.go b/gopls/internal/lsp/testdata/builtins/builtins.go
index d30176c..75c6e41 100644
--- a/gopls/internal/lsp/testdata/builtins/builtins.go
+++ b/gopls/internal/lsp/testdata/builtins/builtins.go
@@ -8,6 +8,7 @@
 /* bool */ //@item(bool, "bool", "", "type")
 /* byte */ //@item(byte, "byte", "", "type")
 /* cap(v Type) int */ //@item(cap, "cap", "func(v Type) int", "func")
+/* clear[T interface{ ~[]Type | ~map[Type]Type1 }](t T) */ //@item(clear, "clear", "func(t T)", "func")
 /* close(c chan<- Type) */ //@item(close, "close", "func(c chan<- Type)", "func")
 /* comparable */ //@item(comparable, "comparable", "", "interface")
 /* complex(r float64, i float64) */ //@item(complex, "complex", "func(r float64, i float64) complex128", "func")
diff --git a/gopls/internal/lsp/tests/util_go121.go b/gopls/internal/lsp/tests/util_go121.go
new file mode 100644
index 0000000..9306586
--- /dev/null
+++ b/gopls/internal/lsp/tests/util_go121.go
@@ -0,0 +1,12 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.21
+// +build go1.21
+
+package tests
+
+func init() {
+	builtins["clear"] = true
+}