GoPLS Viewer

Home|gopls/internal/typeparams/copytermlist.go
1// Copyright 2021 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5//go:build ignore
6// +build ignore
7
8// copytermlist.go copies the term list algorithm from GOROOT/src/go/types.
9
10package main
11
12import (
13    "bytes"
14    "fmt"
15    "go/ast"
16    "go/format"
17    "go/parser"
18    "go/token"
19    "os"
20    "path/filepath"
21    "reflect"
22    "runtime"
23    "strings"
24
25    "golang.org/x/tools/go/ast/astutil"
26)
27
28func main() {
29    if err := doCopy(); err != nil {
30        fmt.Fprintf(os.Stderr"error copying from go/types: %v"err)
31        os.Exit(1)
32    }
33}
34
35func doCopy() error {
36    dir := filepath.Join(runtime.GOROOT(), "src""go""types")
37    for _name := range []string{"typeterm.go""termlist.go"} {
38        path := filepath.Join(dirname)
39        fset := token.NewFileSet()
40        fileerr := parser.ParseFile(fsetpathnilparser.ParseComments)
41        if err != nil {
42            return err
43        }
44        file.Name.Name = "typeparams"
45        file.Doc = &ast.CommentGroup{List: []*ast.Comment{{Text"DO NOT MODIFY"}}}
46        var needImport bool
47        selectorType := reflect.TypeOf((*ast.SelectorExpr)(nil))
48        astutil.Apply(file, func(c *astutil.Cursorbool {
49            if id_ := c.Node().(*ast.Ident); id != nil {
50                // Check if this ident should be qualified with types. For simplicity,
51                // assume the copied files do not themselves contain any exported
52                // symbols.
53
54                // As a simple heuristic, just verify that the ident may be replaced by
55                // a selector.
56                if !token.IsExported(id.Name) {
57                    return false
58                }
59                v := reflect.TypeOf(c.Parent()).Elem() // ast nodes are all pointers
60                fieldok := v.FieldByName(c.Name())
61                if !ok {
62                    panic("missing field")
63                }
64                t := field.Type
65                if c.Index() > 0 { // => t is a slice
66                    t = t.Elem()
67                }
68                if !selectorType.AssignableTo(t) {
69                    return false
70                }
71                needImport = true
72                c.Replace(&ast.SelectorExpr{
73                    X:   &ast.Ident{NamePosid.NamePosName"types"},
74                    Sel: &ast.Ident{NamePosid.NamePosNameid.NameObjid.Obj},
75                })
76            }
77            return true
78        }, nil)
79        if needImport {
80            astutil.AddImport(fsetfile"go/types")
81        }
82
83        var b bytes.Buffer
84        if err := format.Node(&bfsetfile); err != nil {
85            return err
86        }
87
88        // Hack in the 'generated' byline.
89        content := b.String()
90        header := "// Code generated by copytermlist.go DO NOT EDIT.\n\npackage typeparams"
91        content = strings.Replace(content"package typeparams"header1)
92
93        if err := os.WriteFile(name, []byte(content), 0644); err != nil {
94            return err
95        }
96    }
97    return nil
98}
99
MembersX
doCopy.RangeStmt_675.BlockStmt.BlockStmt.BlockStmt.field
format
doCopy
doCopy.dir
doCopy.RangeStmt_675.BlockStmt.selectorType
main
doCopy.RangeStmt_675.BlockStmt.err
doCopy.RangeStmt_675.BlockStmt.BlockStmt.BlockStmt.t
doCopy.RangeStmt_675.BlockStmt.content
doCopy.RangeStmt_675.BlockStmt.header
os
filepath
astutil
doCopy.RangeStmt_675.BlockStmt.path
doCopy.RangeStmt_675.BlockStmt.BlockStmt.BlockStmt.ok
fmt
doCopy.RangeStmt_675.BlockStmt.needImport
reflect
strings
doCopy.RangeStmt_675.BlockStmt.BlockStmt.BlockStmt.v
doCopy.RangeStmt_675.BlockStmt.b
runtime
main.err
doCopy.RangeStmt_675.name
doCopy.RangeStmt_675.BlockStmt.file
bytes
doCopy.RangeStmt_675.BlockStmt.fset
Members
X