1
0
mirror of https://github.com/golang/go synced 2024-11-19 03:24:40 -07:00
go/internal/lsp/testdata/unimported/mkunimported.go
Suzy Mueller caa95bb40b internal/lsp: add completions of unimported std lib pkgs
Unimported packages may be suggested as completion items. Since these
are not yet imported, they should be ranked lower than other candidates.

They also require an additional import statement to be valid, which is
provided as an AdditionalTextEdit.

Adding this import does not use astutil.AddNamedImport, to avoid
editing the current ast and work even if there are errors. Additionally,
it can be hard to determine what changes need to be made to the source
document from the ast, as astutil.AddNamedImport includes a merging
pass. Instead, the completion item simply adds another import
declaration.

Change-Id: Icbde226d843bd49ee3713cafcbd5299d51530695
Reviewed-on: https://go-review.googlesource.com/c/tools/+/190338
Run-TryBot: Suzy Mueller <suzmue@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
2019-08-16 18:32:40 +00:00

116 lines
2.6 KiB
Go

// +build ignore
// mkunimported generates the unimported.go file, containing the Go standard
// library packages.
// The completion items from the std library are computed in the same way as in the
// golang.org/x/tools/internal/imports.
package main
import (
"bufio"
"bytes"
"fmt"
"go/format"
"io"
"io/ioutil"
"log"
"os"
pkgpath "path"
"path/filepath"
"regexp"
"runtime"
"sort"
"strings"
)
func mustOpen(name string) io.Reader {
f, err := os.Open(name)
if err != nil {
log.Fatal(err)
}
return f
}
func api(base string) string {
return filepath.Join(runtime.GOROOT(), "api", base)
}
var sym = regexp.MustCompile(`^pkg (\S+).*?, (?:var|func|type|const) ([A-Z]\w*)`)
var unsafeSyms = map[string]bool{"Alignof": true, "ArbitraryType": true, "Offsetof": true, "Pointer": true, "Sizeof": true}
func main() {
var buf bytes.Buffer
outf := func(format string, args ...interface{}) {
fmt.Fprintf(&buf, format, args...)
}
outf("// Code generated by mkstdlib.go. DO NOT EDIT.\n\n")
outf("package unimported\n")
outf("func _() {\n")
f := io.MultiReader(
mustOpen(api("go1.txt")),
mustOpen(api("go1.1.txt")),
mustOpen(api("go1.2.txt")),
mustOpen(api("go1.3.txt")),
mustOpen(api("go1.4.txt")),
mustOpen(api("go1.5.txt")),
mustOpen(api("go1.6.txt")),
mustOpen(api("go1.7.txt")),
mustOpen(api("go1.8.txt")),
mustOpen(api("go1.9.txt")),
mustOpen(api("go1.10.txt")),
mustOpen(api("go1.11.txt")),
mustOpen(api("go1.12.txt")),
)
sc := bufio.NewScanner(f)
pkgs := map[string]bool{
"unsafe": true,
"syscall/js": true,
}
paths := []string{"unsafe", "syscall/js"}
for sc.Scan() {
l := sc.Text()
has := func(v string) bool { return strings.Contains(l, v) }
if has("struct, ") || has("interface, ") || has(", method (") {
continue
}
if m := sym.FindStringSubmatch(l); m != nil {
path, _ := m[1], m[2]
if _, ok := pkgs[path]; !ok {
pkgs[path] = true
paths = append(paths, path)
}
}
}
if err := sc.Err(); err != nil {
log.Fatal(err)
}
sort.Strings(paths)
var markers []string
for _, path := range paths {
marker := strings.ReplaceAll(path, "/", "slash")
markers = append(markers, marker)
}
outf(" //@complete(\"\", %s)\n", strings.Join(markers, ", "))
outf("}\n")
outf("// Create markers for unimported std lib packages. Only for use by this test.\n")
for i, path := range paths {
name := pkgpath.Base(path)
marker := markers[i]
outf("/* %s *///@item(%s, \"%s\", \"\\\"%s\\\"\", \"package\")\n", name, marker, name, path)
}
fmtbuf, err := format.Source(buf.Bytes())
if err != nil {
log.Fatal(err)
}
err = ioutil.WriteFile("unimported.go", fmtbuf, 0666)
if err != nil {
log.Fatal(err)
}
}