├── debian ├── compat ├── docs ├── source │ └── format ├── changelog ├── gocode.default ├── rules ├── control └── copyright ├── _testing ├── test.0001 │ ├── cursor.47 │ ├── test.go.in │ └── out.expected ├── test.0007 │ ├── cursor.58 │ ├── test.go.in │ └── out.expected ├── test.0011 │ ├── cursor.76 │ ├── test.go.in │ └── out.expected ├── test.0017 │ ├── cursor.70 │ ├── out.expected │ └── test.go.in ├── test.0019 │ ├── cursor.72 │ ├── test.go.in │ └── out.expected ├── test.0021 │ ├── cursor.82 │ ├── test.go.in │ └── out.expected ├── test.0022 │ ├── cursor.79 │ ├── out.expected │ └── test.go.in ├── test.0023 │ ├── cursor.88 │ ├── test.go.in │ └── out.expected ├── test.0024 │ ├── cursor.71 │ ├── out.expected │ └── test.go.in ├── test.0025 │ ├── cursor.53 │ ├── test.go.in │ └── out.expected ├── test.0027 │ ├── cursor.84 │ ├── out.expected │ └── test.go.in ├── test.0029 │ ├── cursor.62 │ ├── test.go.in │ └── out.expected ├── test.0030 │ ├── cursor.85 │ ├── out.expected │ └── test.go.in ├── test.0031 │ ├── cursor.80 │ ├── out.expected │ └── test.go.in ├── test.0034 │ ├── cursor.82 │ ├── test.go.in │ └── out.expected ├── test.0035 │ ├── cursor.91 │ ├── out.expected │ └── test.go.in ├── test.0036 │ ├── cursor.67 │ ├── test.go.in │ └── out.expected ├── test.0038 │ ├── cursor.87 │ ├── out.expected │ └── test.go.in ├── test.0039 │ ├── cursor.88 │ ├── out.expected │ └── test.go.in ├── test.0040 │ ├── cursor.96 │ ├── out.expected │ └── test.go.in ├── test.0045 │ ├── cursor.51 │ ├── test.go.in │ └── out.expected ├── test.0046 │ ├── cursor.53 │ ├── test.go.in │ └── out.expected ├── test.0048 │ ├── cursor.53 │ ├── test.go.in │ └── out.expected ├── test.0049 │ ├── cursor.44 │ ├── out.expected │ └── test.go.in ├── test.0050 │ ├── cursor.45 │ ├── out.expected │ └── test.go.in ├── test.0052 │ ├── cursor.96 │ ├── out.expected │ └── test.go.in ├── test.0057 │ ├── cursor.56 │ ├── test.go.in │ └── out.expected ├── test.0058 │ ├── cursor.65 │ ├── test.go.in │ └── out.expected ├── test.0059 │ ├── cursor.81 │ ├── out.expected │ └── test.go.in ├── test.0061 │ ├── cursor.61 │ ├── out.expected │ └── test.go.in ├── test.0002 │ ├── cursor.105 │ ├── out.expected │ └── test.go.in ├── test.0003 │ ├── cursor.552 │ ├── out.expected │ └── test.go.in ├── test.0004 │ ├── cursor.1348 │ ├── out.expected │ └── test.go.in ├── test.0005 │ ├── cursor.327 │ ├── out.expected │ ├── test.go.in │ └── b.go ├── test.0006 │ ├── cursor.286 │ ├── out.expected │ ├── test.go.in │ └── b.go ├── test.0008 │ ├── cursor.120 │ ├── out.expected │ └── test.go.in ├── test.0009 │ ├── cursor.126 │ ├── out.expected │ └── test.go.in ├── test.0010 │ ├── cursor.104 │ ├── test.go.in │ └── out.expected ├── test.0012 │ ├── cursor.114 │ ├── out.expected │ └── test.go.in ├── test.0013 │ ├── cursor.359 │ ├── out.expected │ └── test.go.in ├── test.0014 │ ├── cursor.191 │ ├── out.expected │ └── test.go.in ├── test.0015 │ ├── cursor.130 │ ├── test.go.in │ └── out.expected ├── test.0016 │ ├── cursor.122 │ ├── out.expected │ └── test.go.in ├── test.0018 │ ├── cursor.355 │ ├── out.expected │ └── test.go.in ├── test.0020 │ ├── cursor.174 │ ├── out.expected │ └── test.go.in ├── test.0026 │ ├── cursor.164 │ ├── out.expected │ └── test.go.in ├── test.0028 │ ├── cursor.129 │ ├── out.expected │ └── test.go.in ├── test.0032 │ ├── cursor.1835 │ ├── test.go.in │ └── out.expected ├── test.0033 │ ├── cursor.138 │ ├── out.expected │ └── test.go.in ├── test.0037 │ ├── cursor.139 │ ├── out.expected │ └── test.go.in ├── test.0041 │ ├── cursor.140 │ ├── out.expected │ └── test.go.in ├── test.0042 │ ├── cursor.126 │ ├── out.expected │ └── test.go.in ├── test.0043 │ ├── cursor.182 │ ├── out.expected │ └── test.go.in ├── test.0044 │ ├── cursor.105 │ ├── out.expected │ └── test.go.in ├── test.0047 │ ├── cursor.43 │ ├── out.expected │ └── test.go.in ├── test.0051 │ ├── cursor.247 │ ├── out.expected │ └── test.go.in ├── test.0053 │ ├── cursor.215 │ ├── out.expected │ └── test.go.in ├── test.0054 │ ├── cursor.168 │ ├── out.expected │ └── test.go.in ├── test.0055 │ ├── cursor.229 │ ├── out.expected │ └── test.go.in ├── test.0056 │ ├── cursor.211 │ ├── out.expected │ └── test.go.in ├── test.0060 │ ├── cursor.109 │ ├── out.expected │ └── test.go.in ├── test.0062 │ ├── cursor.141 │ ├── out.expected │ └── test.go.in ├── test.0063 │ ├── cursor.109 │ ├── out.expected │ └── test.go.in ├── all.bash ├── README ├── run.rb ├── run.tcl ├── run.py └── DESC ├── nvim ├── ftplugin │ └── go │ │ └── gocomplete.vim ├── update.sh ├── symlink.sh ├── pathogen_update.sh └── autoload │ └── gocomplete.vim ├── vim ├── ftplugin │ └── go │ │ └── gocomplete.vim ├── update.sh ├── symlink.sh ├── pathogen_update.sh └── autoload │ └── gocomplete.vim ├── go.mod ├── pre_go17.go ├── .gitignore ├── internal ├── gcimporter │ ├── testdata │ │ ├── issue20046.go │ │ ├── b.go │ │ ├── p.go │ │ ├── a.go │ │ ├── issue25301.go │ │ ├── issue15920.go │ │ ├── versions │ │ │ └── test.go │ │ └── exports.go │ ├── israce_test.go │ ├── newInterface11.go │ ├── newInterface10.go │ ├── typeparams_go118.go │ ├── typeparams_go117.go │ ├── exportdata.go │ └── gcimporter11_test.go └── gcexportdata │ ├── gcexportdata_test.go │ ├── importer.go │ ├── main.go │ ├── example_test.go │ └── gcexportdata.go ├── subl3 ├── syntax │ ├── GoSublime-HTML.tmLanguage.json │ ├── GoSublime-HTML.tmLanguage │ ├── LICENSE.md │ ├── GoSublime-Template.tmLanguage.json │ ├── GoSublime-Template.tmLanguage │ └── GoSublime-Go.tmLanguage.json ├── README.md └── gocode.py ├── unsafe_go116.go ├── type_alias_build_hack_18.go ├── type_alias_build_hack_19.go ├── unsafe_go117.go ├── .github └── workflows │ └── go.yml ├── unsafe_go120.go ├── os_posix.go ├── LICENSE ├── os_windows.go ├── scope.go ├── emacs-company └── README.md ├── package_types.go ├── gocode.go ├── docs ├── IDE_integration.md └── autocomplete_formats.md ├── go.sum ├── ripper.go ├── rpc.go ├── client.go ├── formatters.go ├── ast.go ├── _goremote └── goremote.go └── types_go117.go /debian/compat: -------------------------------------------------------------------------------- 1 | 7 2 | -------------------------------------------------------------------------------- /_testing/test.0001/cursor.47: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0007/cursor.58: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0011/cursor.76: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0017/cursor.70: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0019/cursor.72: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0021/cursor.82: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0022/cursor.79: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0023/cursor.88: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0024/cursor.71: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0025/cursor.53: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0027/cursor.84: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0029/cursor.62: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0030/cursor.85: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0031/cursor.80: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0034/cursor.82: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0035/cursor.91: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0036/cursor.67: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0038/cursor.87: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0039/cursor.88: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0040/cursor.96: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0045/cursor.51: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0046/cursor.53: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0048/cursor.53: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0049/cursor.44: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0050/cursor.45: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0052/cursor.96: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0057/cursor.56: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0058/cursor.65: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0059/cursor.81: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0061/cursor.61: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /debian/docs: -------------------------------------------------------------------------------- 1 | README.md 2 | -------------------------------------------------------------------------------- /_testing/test.0002/cursor.105: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0003/cursor.552: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0004/cursor.1348: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0005/cursor.327: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0006/cursor.286: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0008/cursor.120: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0009/cursor.126: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0010/cursor.104: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0012/cursor.114: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0013/cursor.359: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0014/cursor.191: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0015/cursor.130: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0016/cursor.122: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0018/cursor.355: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0020/cursor.174: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0026/cursor.164: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0028/cursor.129: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0032/cursor.1835: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0033/cursor.138: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0037/cursor.139: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0041/cursor.140: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0042/cursor.126: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0043/cursor.182: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0044/cursor.105: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0047/cursor.43: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /_testing/test.0051/cursor.247: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0053/cursor.215: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0054/cursor.168: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0055/cursor.229: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0056/cursor.211: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0060/cursor.109: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0062/cursor.141: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_testing/test.0063/cursor.109: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /_testing/test.0047/out.expected: -------------------------------------------------------------------------------- 1 | Nothing to complete. 2 | -------------------------------------------------------------------------------- /_testing/test.0049/out.expected: -------------------------------------------------------------------------------- 1 | Found 1 candidates: 2 | var i int 3 | -------------------------------------------------------------------------------- /_testing/test.0050/out.expected: -------------------------------------------------------------------------------- 1 | Found 1 candidates: 2 | var i int 3 | -------------------------------------------------------------------------------- /nvim/ftplugin/go/gocomplete.vim: -------------------------------------------------------------------------------- 1 | setlocal omnifunc=gocomplete#Complete 2 | -------------------------------------------------------------------------------- /vim/ftplugin/go/gocomplete.vim: -------------------------------------------------------------------------------- 1 | setlocal omnifunc=gocomplete#Complete 2 | -------------------------------------------------------------------------------- /_testing/test.0028/out.expected: -------------------------------------------------------------------------------- 1 | Found 1 candidates: 2 | func PowerOfTwo() int 3 | -------------------------------------------------------------------------------- /_testing/test.0038/out.expected: -------------------------------------------------------------------------------- 1 | Found 2 candidates: 2 | func main() 3 | var x 4 | -------------------------------------------------------------------------------- /_testing/test.0039/out.expected: -------------------------------------------------------------------------------- 1 | Found 2 candidates: 2 | func main() 3 | var z 4 | -------------------------------------------------------------------------------- /_testing/test.0018/out.expected: -------------------------------------------------------------------------------- 1 | Found 2 candidates: 2 | func Bark() 3 | var Legs int 4 | -------------------------------------------------------------------------------- /_testing/test.0031/out.expected: -------------------------------------------------------------------------------- 1 | Found 2 candidates: 2 | func main() 3 | var c int 4 | -------------------------------------------------------------------------------- /_testing/test.0042/out.expected: -------------------------------------------------------------------------------- 1 | Found 2 candidates: 2 | var Ya int 3 | var Yb int 4 | -------------------------------------------------------------------------------- /_testing/test.0044/out.expected: -------------------------------------------------------------------------------- 1 | Found 2 candidates: 2 | var Xa int 3 | var Xb int 4 | -------------------------------------------------------------------------------- /_testing/test.0047/test.go.in: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | type T struct{ X } 4 | 5 | var _ = T.x. 6 | -------------------------------------------------------------------------------- /_testing/test.0027/out.expected: -------------------------------------------------------------------------------- 1 | Found 2 candidates: 2 | func String() 3 | var name string 4 | -------------------------------------------------------------------------------- /_testing/test.0024/out.expected: -------------------------------------------------------------------------------- 1 | Found 3 candidates: 2 | var a int 3 | var b int 4 | var c int 5 | -------------------------------------------------------------------------------- /_testing/test.0059/out.expected: -------------------------------------------------------------------------------- 1 | Found 1 candidates: 2 | func NewReader(r myio.Reader) myio.Reader 3 | -------------------------------------------------------------------------------- /_testing/test.0060/out.expected: -------------------------------------------------------------------------------- 1 | Found 1 candidates: 2 | func Read(p []byte) (n int, err error) 3 | -------------------------------------------------------------------------------- /_testing/test.0063/out.expected: -------------------------------------------------------------------------------- 1 | Found 3 candidates: 2 | var A int 3 | var B int 4 | var C int 5 | -------------------------------------------------------------------------------- /_testing/test.0001/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt. 7 | } 8 | -------------------------------------------------------------------------------- /_testing/test.0030/out.expected: -------------------------------------------------------------------------------- 1 | Found 3 candidates: 2 | var F1 int 3 | var F2 int 4 | var F3 int 5 | -------------------------------------------------------------------------------- /_testing/test.0041/out.expected: -------------------------------------------------------------------------------- 1 | Found 3 candidates: 2 | var Xa int 3 | var Xb int 4 | var Xy Y 5 | -------------------------------------------------------------------------------- /_testing/test.0049/test.go.in: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | func t(a struct { 4 | i int 5 | }) { 6 | a. 7 | } 8 | -------------------------------------------------------------------------------- /_testing/test.0050/test.go.in: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | func t(a *struct { 4 | i int 5 | }) { 6 | a. 7 | } 8 | -------------------------------------------------------------------------------- /_testing/test.0052/out.expected: -------------------------------------------------------------------------------- 1 | Found 3 candidates: 2 | var A int 3 | var B int 4 | var C float64 5 | -------------------------------------------------------------------------------- /_testing/test.0025/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "unsafe" 4 | 5 | func main() { 6 | unsafe. 7 | } 8 | -------------------------------------------------------------------------------- /_testing/test.0045/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | if fmt. 7 | } 8 | -------------------------------------------------------------------------------- /_testing/test.0046/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | x := fmt. 7 | } 8 | -------------------------------------------------------------------------------- /_testing/test.0007/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "syscall" 4 | 5 | func main() { 6 | syscall.var 7 | } 8 | -------------------------------------------------------------------------------- /_testing/test.0048/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | x := fmt.Fpr 7 | } 8 | -------------------------------------------------------------------------------- /_testing/test.0057/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "io" 4 | 5 | func main() { 6 | io.ReadWriter. 7 | } 8 | -------------------------------------------------------------------------------- /_testing/test.0009/out.expected: -------------------------------------------------------------------------------- 1 | Found 3 candidates: 2 | func Lock() 3 | func TryLock() bool 4 | func Unlock() 5 | -------------------------------------------------------------------------------- /_testing/test.0040/out.expected: -------------------------------------------------------------------------------- 1 | Found 3 candidates: 2 | func create_foo() Foo 3 | type Foo struct 4 | var t Foo 5 | -------------------------------------------------------------------------------- /_testing/test.0043/out.expected: -------------------------------------------------------------------------------- 1 | Found 4 candidates: 2 | func foo() 3 | var Xa int 4 | var Xb int 5 | var Xy Y 6 | -------------------------------------------------------------------------------- /_testing/test.0055/out.expected: -------------------------------------------------------------------------------- 1 | Found 3 candidates: 2 | var Jim string 3 | var John string 4 | var Kim string 5 | -------------------------------------------------------------------------------- /_testing/test.0016/out.expected: -------------------------------------------------------------------------------- 1 | Found 4 candidates: 2 | func main() 3 | var a int 4 | var b string 5 | var d bool 6 | -------------------------------------------------------------------------------- /_testing/test.0029/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import . "fmt" 4 | 5 | func main() { 6 | var a Formatter 7 | 8 | } 9 | -------------------------------------------------------------------------------- /_testing/test.0036/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "debug/elf" 4 | 5 | func main() { 6 | var f elf.File 7 | f. 8 | } -------------------------------------------------------------------------------- /_testing/test.0058/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import myast "go/ast" 4 | 5 | func main() { 6 | myast.NewPack 7 | } 8 | -------------------------------------------------------------------------------- /_testing/test.0061/out.expected: -------------------------------------------------------------------------------- 1 | Found 3 candidates: 2 | func Foo() *http.Request 3 | func main() 4 | package http 5 | -------------------------------------------------------------------------------- /_testing/test.0019/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "compress/zlib" 4 | 5 | func main() { 6 | var b map[int]zlib. 7 | } 8 | -------------------------------------------------------------------------------- /_testing/test.0051/out.expected: -------------------------------------------------------------------------------- 1 | Found 3 candidates: 2 | var NumApples int 3 | var NumBananas int 4 | var NumOranges int 5 | -------------------------------------------------------------------------------- /_testing/test.0053/out.expected: -------------------------------------------------------------------------------- 1 | Found 4 candidates: 2 | func Fooer() string 3 | var A int 4 | var B int 5 | var C float64 6 | -------------------------------------------------------------------------------- /_testing/test.0062/out.expected: -------------------------------------------------------------------------------- 1 | Found 4 candidates: 2 | var A int 3 | var ABCAlias ABCAlias 4 | var B int 5 | var C int 6 | -------------------------------------------------------------------------------- /_testing/test.0054/out.expected: -------------------------------------------------------------------------------- 1 | Found 4 candidates: 2 | func Foobarer() string 3 | var A int 4 | var B int 5 | var C float64 6 | -------------------------------------------------------------------------------- /_testing/test.0011/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "reflect" 4 | 5 | func main() { 6 | var test reflect.Value 7 | test. 8 | } 9 | -------------------------------------------------------------------------------- /_testing/test.0017/out.expected: -------------------------------------------------------------------------------- 1 | Found 3 candidates: 2 | func a(a, b, c int) int 3 | func b(a, b, c string) string 4 | func main() 5 | -------------------------------------------------------------------------------- /_testing/test.0021/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "go/ast" 4 | 5 | func main() { 6 | var test *ast.ImportSpec 7 | test.Name. 8 | } 9 | -------------------------------------------------------------------------------- /_testing/test.0034/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "image/png" 4 | 5 | func test() { 6 | img, err := png.Decode(nil) 7 | img. 8 | } 9 | -------------------------------------------------------------------------------- /_testing/test.0057/out.expected: -------------------------------------------------------------------------------- 1 | Found 2 candidates: 2 | func Read(p []byte) (n int, err error) 3 | func Write(p []byte) (n int, err error) 4 | -------------------------------------------------------------------------------- /_testing/test.0059/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import myio "io" 4 | import "compress/bzip2" 5 | 6 | func main() { 7 | bzip2.NewR 8 | } 9 | -------------------------------------------------------------------------------- /_testing/test.0035/out.expected: -------------------------------------------------------------------------------- 1 | Found 5 candidates: 2 | func main() 3 | var err error 4 | var offset int 5 | var r rune 6 | var s string 7 | -------------------------------------------------------------------------------- /_testing/test.0038/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | if y := 20; y == 0 { 5 | } 6 | if x := 10; x == 0 { 7 | } else if 8 | } 9 | -------------------------------------------------------------------------------- /_testing/test.0024/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type X struct { 4 | a,b,c int 5 | } 6 | 7 | func main() { 8 | var X *X 9 | X. 10 | } 11 | -------------------------------------------------------------------------------- /_testing/test.0056/out.expected: -------------------------------------------------------------------------------- 1 | Found 5 candidates: 2 | func MethodMe() bool 3 | func MethodYou() bool 4 | var A int 5 | var B int 6 | var C int 7 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/visualfc/gocode 2 | 3 | go 1.13 4 | 5 | require ( 6 | github.com/visualfc/gotools v1.5.3 7 | golang.org/x/tools v0.5.0 8 | ) 9 | -------------------------------------------------------------------------------- /pre_go17.go: -------------------------------------------------------------------------------- 1 | // +build !go1.7,!go1.8 2 | 3 | package main 4 | 5 | func init() { 6 | knownPackageIdents["context"] = "golang.org/x/net/context" 7 | } 8 | -------------------------------------------------------------------------------- /_testing/test.0061/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "net/http" 4 | 5 | func Foo() *http.Request { 6 | 7 | } 8 | 9 | func main() { 10 | } 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.8 2 | *.a 3 | *.out 4 | gocode 5 | gocode.exe 6 | goremote 7 | gocodetest 8 | *.swp 9 | listidents 10 | showcursor 11 | showsmap 12 | rename 13 | -------------------------------------------------------------------------------- /_testing/test.0020/out.expected: -------------------------------------------------------------------------------- 1 | Found 5 candidates: 2 | func Lock() 3 | func TryLock() bool 4 | func Unlock() 5 | var Dummy Dummy 6 | var Mutex sync.Mutex 7 | -------------------------------------------------------------------------------- /_testing/test.0023/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // Simple check for unicode awareness 4 | 5 | import ъ "fmt" 6 | 7 | func main() { 8 | ъ. 9 | } 10 | -------------------------------------------------------------------------------- /_testing/test.0034/out.expected: -------------------------------------------------------------------------------- 1 | Found 3 candidates: 2 | func At(x int, y int) color.Color 3 | func Bounds() image.Rectangle 4 | func ColorModel() color.Model 5 | -------------------------------------------------------------------------------- /_testing/test.0002/out.expected: -------------------------------------------------------------------------------- 1 | Found 5 candidates: 2 | func main() 3 | package os 4 | var key string 5 | var test map[string]os.Error 6 | var value os.Error 7 | -------------------------------------------------------------------------------- /_testing/test.0035/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | var err error 5 | s := err.Error() 6 | for offset, r := range s { 7 | 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /_testing/test.0039/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | z := 5 5 | if y := 20; y == 0 { 6 | } 7 | if x := 10; x == 0 { 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /_testing/test.0022/out.expected: -------------------------------------------------------------------------------- 1 | Found 5 candidates: 2 | func getMap() map[string]os.Error 3 | func main() 4 | package os 5 | var key string 6 | var value os.Error 7 | -------------------------------------------------------------------------------- /_testing/test.0026/out.expected: -------------------------------------------------------------------------------- 1 | Found 7 candidates: 2 | func main() 3 | var A struct 4 | var B struct 5 | var C struct 6 | var a int 7 | var d int 8 | var g int 9 | -------------------------------------------------------------------------------- /_testing/test.0030/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type A struct { 4 | F1, F2, F3 int 5 | } 6 | 7 | type B A 8 | 9 | func main() { 10 | var b B 11 | b. 12 | } 13 | -------------------------------------------------------------------------------- /_testing/test.0040/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type Foo struct {} 4 | 5 | func (f *Foo) Bar() {} 6 | 7 | func create_foo() Foo { 8 | t := Foo{} 9 | 10 | } 11 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | gocode (0.0.1~20110805-1) oneiric; urgency=low 2 | 3 | * Initial release 4 | 5 | -- Juan L. Negron Fri, 05 Aug 2011 22:58:48 -0700 6 | -------------------------------------------------------------------------------- /_testing/test.0007/out.expected: -------------------------------------------------------------------------------- 1 | Found 5 candidates: 2 | var ForkLock sync.RWMutex 3 | var SocketDisableIPv6 bool 4 | var Stderr int 5 | var Stdin int 6 | var Stdout int 7 | -------------------------------------------------------------------------------- /_testing/test.0010/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "go/ast" 4 | 5 | func main() { 6 | var gd *ast.GenDecl 7 | v := gd.Specs[0].(*ast.ValueSpec) 8 | v. 9 | } 10 | -------------------------------------------------------------------------------- /_testing/test.0012/out.expected: -------------------------------------------------------------------------------- 1 | Found 6 candidates: 2 | func main() 3 | type MyMap map[string]int 4 | var key string 5 | var m MyMap 6 | var value int 7 | var z int 8 | -------------------------------------------------------------------------------- /_testing/test.0031/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | var c chan int 5 | select { 6 | case c := <-c: 7 | _ = c 8 | 9 | default: 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /_testing/test.0005/out.expected: -------------------------------------------------------------------------------- 1 | Found 5 candidates: 2 | func A() localos.Error 3 | func B() superos.Error 4 | package localos 5 | type Tester struct 6 | var test superos.Error 7 | -------------------------------------------------------------------------------- /_testing/test.0037/out.expected: -------------------------------------------------------------------------------- 1 | Found 7 candidates: 2 | func main() 3 | type Array [5]int 4 | var a Array 5 | var s []string 6 | var s1 []string 7 | var s2 []int 8 | var s3 9 | -------------------------------------------------------------------------------- /_testing/test.0060/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "io" 4 | 5 | func f() (a, b io.Reader, c error) { return a } 6 | 7 | func main() { 8 | a, b, c := f() 9 | b. 10 | } 11 | -------------------------------------------------------------------------------- /_testing/test.0002/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "os" 4 | 5 | var test map[string]os.Error 6 | 7 | func main() { 8 | for key, value := range test { 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /_testing/test.0006/out.expected: -------------------------------------------------------------------------------- 1 | Found 8 candidates: 2 | func SetA() 3 | func SetB() 4 | func SetC() 5 | func SetD() 6 | var a int 7 | var b int 8 | var c int 9 | var d int 10 | -------------------------------------------------------------------------------- /_testing/test.0052/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type FooBar struct { 4 | A int 5 | B int 6 | C float64 7 | } 8 | 9 | func main() { 10 | x := []FooBar{ 11 | {}, 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /_testing/test.0058/out.expected: -------------------------------------------------------------------------------- 1 | Found 1 candidates: 2 | func NewPackage(fset *token.FileSet, files map[string]*myast.File, importer myast.Importer, universe *myast.Scope) (*myast.Package, error) 3 | -------------------------------------------------------------------------------- /_testing/test.0012/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type MyMap map[string]int 4 | 5 | func main() { 6 | var m MyMap 7 | for key, value := range m { 8 | z := m["15"] 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /_testing/test.0033/out.expected: -------------------------------------------------------------------------------- 1 | Found 6 candidates: 2 | func testEllipsis(dummies ...*Dummy) 3 | type Dummy struct 4 | var d *Dummy 5 | var dummies ...*Dummy 6 | var i int 7 | var x *Dummy 8 | -------------------------------------------------------------------------------- /_testing/test.0044/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type X struct { 4 | Xa int 5 | Xb int 6 | } 7 | 8 | func (x X) foo() { 9 | return 10 | } 11 | 12 | func main() { 13 | x := X{ 14 | 15 | } 16 | -------------------------------------------------------------------------------- /_testing/test.0004/out.expected: -------------------------------------------------------------------------------- 1 | Found 6 candidates: 2 | func PrettyPrintTypeExpr(out io.Writer, e ast.Expr) 3 | package ast 4 | package io 5 | var e ast.Expr 6 | var out io.Writer 7 | var t ast.Expr 8 | -------------------------------------------------------------------------------- /_testing/test.0017/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func a(a, b, c int) int { 4 | return 123 5 | } 6 | 7 | func main() { 8 | 9 | } 10 | 11 | func b(a, b, c string) string { 12 | return "abc" 13 | } 14 | 15 | -------------------------------------------------------------------------------- /_testing/test.0063/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type ABC struct { 4 | A int 5 | B int 6 | C int 7 | } 8 | 9 | type ABCAlias = ABC 10 | 11 | func main() { 12 | x := ABCAlias{ 13 | 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /_testing/test.0008/out.expected: -------------------------------------------------------------------------------- 1 | Found 7 candidates: 2 | func Lock() 3 | func TryLock() bool 4 | func Unlock() 5 | var Mutex sync.Mutex 6 | var data map[string][]string 7 | var path string 8 | var time int64 9 | -------------------------------------------------------------------------------- /_testing/test.0015/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | var a int 5 | var b bool 6 | var c chan bool 7 | uadd := +a 8 | usub := -a 9 | unot := !b 10 | uxor := ^b 11 | arro := <-c 12 | 13 | } 14 | -------------------------------------------------------------------------------- /_testing/test.0027/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type file struct { 4 | name string 5 | } 6 | 7 | func (file *file) String() { 8 | file. 9 | return file.name 10 | } 11 | 12 | func main() { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /_testing/test.0016/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | var a int 5 | for { 6 | var b string 7 | if a == len(b) { 8 | var c bool 9 | } else { 10 | var d bool 11 | 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /_testing/test.0028/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type X int 4 | 5 | func (x X) PowerOfTwo() int { 6 | return int(x * x) 7 | } 8 | 9 | func main() { 10 | a := X(56) 11 | i := a + 67 12 | j := ^i 13 | j. 14 | } 15 | -------------------------------------------------------------------------------- /_testing/test.0037/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type Array [5]int 4 | 5 | func main() { 6 | var s []string 7 | var a Array 8 | s1 := append(s[:], "123") 9 | s2 := a[0:100500] 10 | s3 := append() 11 | 12 | } 13 | -------------------------------------------------------------------------------- /vim/update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | mkdir -p "$HOME/.vim/autoload" 3 | mkdir -p "$HOME/.vim/ftplugin/go" 4 | cp "${0%/*}/autoload/gocomplete.vim" "$HOME/.vim/autoload" 5 | cp "${0%/*}/ftplugin/go/gocomplete.vim" "$HOME/.vim/ftplugin/go" 6 | -------------------------------------------------------------------------------- /_testing/test.0015/out.expected: -------------------------------------------------------------------------------- 1 | Found 9 candidates: 2 | func main() 3 | var a int 4 | var arro bool 5 | var b bool 6 | var c chan bool 7 | var uadd int 8 | var unot bool 9 | var usub int 10 | var uxor bool 11 | -------------------------------------------------------------------------------- /_testing/test.0033/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type Dummy struct { 4 | a, b, c int 5 | } 6 | 7 | func testEllipsis(dummies ...*Dummy) { 8 | for i, d := range dummies { 9 | x := dummies[0] 10 | 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /_testing/test.0003/out.expected: -------------------------------------------------------------------------------- 1 | Found 7 candidates: 2 | func End() token.Pos 3 | func IsExported() bool 4 | func Pos() token.Pos 5 | func String() string 6 | var Name string 7 | var NamePos token.Pos 8 | var Obj *ast.Object 9 | -------------------------------------------------------------------------------- /_testing/test.0008/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "sync" 4 | 5 | var hosts struct { 6 | sync.Mutex 7 | data map[string][]string 8 | time int64 9 | path string 10 | } 11 | 12 | hosts. 13 | 14 | func main() { 15 | } 16 | -------------------------------------------------------------------------------- /_testing/test.0021/out.expected: -------------------------------------------------------------------------------- 1 | Found 7 candidates: 2 | func End() token.Pos 3 | func IsExported() bool 4 | func Pos() token.Pos 5 | func String() string 6 | var Name string 7 | var NamePos token.Pos 8 | var Obj *ast.Object 9 | -------------------------------------------------------------------------------- /_testing/test.0042/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type X struct { 4 | Xa int 5 | Xb int 6 | Xy Y 7 | } 8 | 9 | type Y struct { 10 | Ya int 11 | Yb int 12 | } 13 | 14 | func main() { 15 | x := X{ 16 | Xy: Y{ 17 | 18 | } 19 | -------------------------------------------------------------------------------- /_testing/test.0009/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "sync" 4 | 5 | var hosts struct { 6 | sync.Mutex 7 | data map[string][]string 8 | time int64 9 | path string 10 | } 11 | 12 | hosts.Mutex. 13 | 14 | func main() { 15 | } 16 | -------------------------------------------------------------------------------- /_testing/test.0010/out.expected: -------------------------------------------------------------------------------- 1 | Found 7 candidates: 2 | func End() token.Pos 3 | func Pos() token.Pos 4 | var Comment *ast.CommentGroup 5 | var Doc *ast.CommentGroup 6 | var Names []*ast.Ident 7 | var Type ast.Expr 8 | var Values []ast.Expr 9 | -------------------------------------------------------------------------------- /_testing/test.0026/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | var A = struct { a, b, c int }{1,2,3} 4 | var B struct { d, e, f int } 5 | 6 | func main() { 7 | C := struct { g, h, i int }{1,2,3} 8 | 9 | a := A.a 10 | d := B.d 11 | g := C.g 12 | 13 | } 14 | -------------------------------------------------------------------------------- /_testing/test.0062/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type ABC struct { 4 | A int 5 | B int 6 | C int 7 | } 8 | 9 | type ABCAlias = ABC 10 | 11 | type Foo struct { 12 | ABCAlias 13 | } 14 | 15 | func main() { 16 | foo := Foo{} 17 | foo. 18 | } 19 | -------------------------------------------------------------------------------- /nvim/update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | mkdir -p "$HOME/.config/nvim/autoload" 3 | mkdir -p "$HOME/.config/nvim/ftplugin/go" 4 | cp "${0%/*}/autoload/gocomplete.vim" "$HOME/.config/nvim/autoload" 5 | cp "${0%/*}/ftplugin/go/gocomplete.vim" "$HOME/.config/nvim/ftplugin/go" 6 | -------------------------------------------------------------------------------- /_testing/test.0022/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "os" 4 | 5 | func main() { 6 | for key, value := range getMap() { 7 | 8 | } 9 | } 10 | 11 | func getMap() map[string]os.Error { 12 | // simply to trick type inference 13 | return nil 14 | } 15 | -------------------------------------------------------------------------------- /_testing/test.0041/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type X struct { 4 | Xa int 5 | Xb int 6 | Xy Y 7 | } 8 | 9 | type Y struct { 10 | Ya int 11 | Yb int 12 | } 13 | 14 | func main() { 15 | x := X{ 16 | Xy: Y{ 17 | Ya: 1, 18 | }, 19 | 20 | } 21 | -------------------------------------------------------------------------------- /_testing/test.0054/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type FooBar struct { 4 | A int 5 | B int 6 | C float64 7 | } 8 | 9 | func (b *FooBar) Foobarer() string { return "foobarer" } 10 | 11 | type Bar = FooBar 12 | 13 | func main() { 14 | var b Bar 15 | b. 16 | } 17 | -------------------------------------------------------------------------------- /vim/symlink.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd "${0%/*}" 3 | ROOTDIR=`pwd` 4 | mkdir -p "$HOME/.vim/autoload" 5 | mkdir -p "$HOME/.vim/ftplugin/go" 6 | ln -fs "$ROOTDIR/autoload/gocomplete.vim" "$HOME/.vim/autoload/" 7 | ln -fs "$ROOTDIR/ftplugin/go/gocomplete.vim" "$HOME/.vim/ftplugin/go/" 8 | -------------------------------------------------------------------------------- /internal/gcimporter/testdata/issue20046.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 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 | package p 6 | 7 | var V interface { 8 | M() 9 | } 10 | -------------------------------------------------------------------------------- /_testing/test.0014/out.expected: -------------------------------------------------------------------------------- 1 | Found 11 candidates: 2 | func main() 3 | type MyPtrInt *int 4 | var a *int 5 | var aa int 6 | var b int 7 | var bb *MyPtrInt 8 | var c *int 9 | var d **int 10 | var megaptr **int 11 | var superint int 12 | var typeptr MyPtrInt 13 | -------------------------------------------------------------------------------- /vim/pathogen_update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | mkdir -p "$HOME/.vim/bundle/gocode/autoload" 3 | mkdir -p "$HOME/.vim/bundle/gocode/ftplugin/go" 4 | cp "${0%/*}/autoload/gocomplete.vim" "$HOME/.vim/bundle/gocode/autoload" 5 | cp "${0%/*}/ftplugin/go/gocomplete.vim" "$HOME/.vim/bundle/gocode/ftplugin/go" 6 | -------------------------------------------------------------------------------- /debian/gocode.default: -------------------------------------------------------------------------------- 1 | # Defaults for gocode initscript 2 | # sourced by /etc/init.d/gocode 3 | # installed at /etc/default/gocode by the maintainer scripts 4 | 5 | # 6 | # This is a POSIX shell fragment 7 | # 8 | 9 | # Additional options that are passed to the Daemon. 10 | DAEMON_OPTS="" 11 | -------------------------------------------------------------------------------- /nvim/symlink.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd "${0%/*}" 3 | ROOTDIR=`pwd` 4 | mkdir -p "$HOME/.config/nvim/autoload" 5 | mkdir -p "$HOME/.config/nvim/ftplugin/go" 6 | ln -fs "$ROOTDIR/autoload/gocomplete.vim" "$HOME/.config/nvim/autoload/" 7 | ln -fs "$ROOTDIR/ftplugin/go/gocomplete.vim" "$HOME/.config/nvim/ftplugin/go/" 8 | -------------------------------------------------------------------------------- /_testing/test.0014/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type MyPtrInt *int 4 | 5 | func main() { 6 | var megaptr **int 7 | a := *megaptr 8 | b := *a 9 | 10 | var superint int 11 | c := &superint 12 | d := &c 13 | 14 | var typeptr MyPtrInt 15 | aa := *typeptr 16 | bb := &typeptr 17 | 18 | } 19 | -------------------------------------------------------------------------------- /_testing/test.0020/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "sync" 4 | 5 | type Dummy struct { 6 | sync.Mutex 7 | } 8 | 9 | type Bar struct { 10 | Dummy 11 | } 12 | 13 | func (b *Bar) Lock() { 14 | } 15 | 16 | func (b *Bar) Unlock() { 17 | } 18 | 19 | func main() { 20 | var b Bar 21 | b. 22 | } 23 | -------------------------------------------------------------------------------- /internal/gcimporter/testdata/b.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 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 | // Input for TestIssue13566 6 | 7 | package b 8 | 9 | import "./a" 10 | 11 | type A a.A 12 | -------------------------------------------------------------------------------- /internal/gcimporter/israce_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 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 | // +build race 6 | 7 | package gcimporter_test 8 | 9 | func init() { 10 | isRace = true 11 | } 12 | -------------------------------------------------------------------------------- /_testing/test.0053/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type FooBar struct { 4 | A int 5 | B int 6 | C float64 7 | } 8 | 9 | func (b *FooBar) Foobarer() string { return "foobarer" } 10 | 11 | type Bar FooBar 12 | 13 | func (b *Bar) Fooer() string { return "fooer" } 14 | 15 | func main() { 16 | var b Bar 17 | b. 18 | } 19 | -------------------------------------------------------------------------------- /internal/gcimporter/testdata/p.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 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 | // Input for TestIssue15517 6 | 7 | package p 8 | 9 | const C = 0 10 | 11 | var V int 12 | 13 | func F() {} 14 | -------------------------------------------------------------------------------- /_testing/test.0043/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type X struct { 4 | Xa int 5 | Xb int 6 | Xy Y 7 | } 8 | 9 | type Y struct { 10 | Ya int 11 | Yb int 12 | } 13 | 14 | func (x X) foo() { 15 | return 16 | } 17 | 18 | func main() { 19 | x := X{ 20 | Xa: 1, 21 | Xb: 2, 22 | } 23 | y := Y{ 24 | Ya: x. 25 | } 26 | -------------------------------------------------------------------------------- /_testing/test.0056/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func (x *Baz) MethodMe() bool { return true } 4 | 5 | func (x *Bar) MethodYou() bool { return false } 6 | 7 | type Foo struct { 8 | A int 9 | B int 10 | C int 11 | } 12 | 13 | type Bar = Foo 14 | type Baz = Bar 15 | 16 | func main() { 17 | var f Foo 18 | f. 19 | } 20 | -------------------------------------------------------------------------------- /_testing/test.0025/out.expected: -------------------------------------------------------------------------------- 1 | Found 6 candidates: 2 | func Add(ptr Pointer, len IntegerType) Pointer 3 | func Alignof(x ArbitraryType) uintptr 4 | func Offsetof(x ArbitraryType) uintptr 5 | func Sizeof(x ArbitraryType) uintptr 6 | func Slice(ptr *ArbitraryType, len IntegerType) []ArbitraryType 7 | type Pointer *ArbitraryType 8 | -------------------------------------------------------------------------------- /_testing/test.0055/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type Baz struct { 4 | Jim string 5 | John string 6 | Kim string 7 | } 8 | 9 | type FooBar struct { 10 | A int 11 | B int 12 | C float64 13 | } 14 | 15 | func (b *FooBar) Foobarer() Baz { return Baz{} } 16 | 17 | func main() { 18 | type Bar = FooBar 19 | var b Bar 20 | b.Foobarer(). 21 | } 22 | -------------------------------------------------------------------------------- /subl3/syntax/GoSublime-HTML.tmLanguage.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GoSublime: HTML", 3 | "uuid": "78c486ec-0101-11e2-a85a-00262d996a67", 4 | "scopeName": "text.html.gohtml", 5 | "fileTypes": ["gohtml"], 6 | 7 | "patterns": [ 8 | { 9 | "include": "text.html.basic", 10 | }, 11 | { 12 | "include": "source.gotemplate", 13 | }, 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /internal/gcimporter/testdata/a.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 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 | // Input for TestIssue13566 6 | 7 | package a 8 | 9 | import "encoding/json" 10 | 11 | type A struct { 12 | a *A 13 | json json.RawMessage 14 | } 15 | -------------------------------------------------------------------------------- /unsafe_go116.go: -------------------------------------------------------------------------------- 1 | //go:build !go1.17 2 | // +build !go1.17 3 | 4 | package main 5 | 6 | var g_builtin_unsafe_package = []byte(` 7 | import 8 | $$ 9 | package unsafe 10 | func @"".Alignof(x ArbitraryType) uintptr 11 | func @"".Offsetof(x ArbitraryType) uintptr 12 | func @"".Sizeof(x ArbitraryType) uintptr 13 | type @"".Pointer *ArbitraryType 14 | $$ 15 | `) 16 | -------------------------------------------------------------------------------- /type_alias_build_hack_18.go: -------------------------------------------------------------------------------- 1 | // +build !go1.9,!go1.8.typealias 2 | 3 | package main 4 | 5 | import ( 6 | "go/ast" 7 | ) 8 | 9 | func typeAliasSpec(name string, typ ast.Expr) *ast.TypeSpec { 10 | return &ast.TypeSpec{ 11 | Name: ast.NewIdent(name), 12 | Type: typ, 13 | } 14 | } 15 | 16 | func isAliasTypeSpec(t *ast.TypeSpec) bool { 17 | return false 18 | } 19 | -------------------------------------------------------------------------------- /_testing/all.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | go build ../. 3 | ./gocode close 4 | sleep 0.5 5 | echo "--------------------------------------------------------------------" 6 | echo "Autocompletion tests..." 7 | echo "--------------------------------------------------------------------" 8 | export XDG_CONFIG_HOME="$(mktemp -d)" 9 | ./run.rb 10 | sleep 0.5 11 | ./gocode close 12 | rm ./gocode 13 | -------------------------------------------------------------------------------- /internal/gcimporter/testdata/issue25301.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 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 | package issue25301 6 | 7 | type ( 8 | A = interface { 9 | M() 10 | } 11 | T interface { 12 | A 13 | } 14 | S struct{} 15 | ) 16 | 17 | func (S) M() { println("m") } 18 | -------------------------------------------------------------------------------- /type_alias_build_hack_19.go: -------------------------------------------------------------------------------- 1 | // +build go1.9 go1.8.typealias 2 | 3 | package main 4 | 5 | import ( 6 | "go/ast" 7 | ) 8 | 9 | func typeAliasSpec(name string, typ ast.Expr) *ast.TypeSpec { 10 | return &ast.TypeSpec{ 11 | Name: ast.NewIdent(name), 12 | Assign: 1, 13 | Type: typ, 14 | } 15 | } 16 | 17 | func isAliasTypeSpec(t *ast.TypeSpec) bool { 18 | return t.Assign != 0 19 | } 20 | -------------------------------------------------------------------------------- /nvim/pathogen_update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ -z $XDG_CONFIG_HOME ]; then 3 | XDG_CONFIG_HOME="$HOME/.config" 4 | fi 5 | mkdir -p "$XDG_CONFIG_HOME/nvim/bundle/gocode/autoload" 6 | mkdir -p "$XDG_CONFIG_HOME/nvim/bundle/gocode/ftplugin/go" 7 | cp "${0%/*}/autoload/gocomplete.vim" "$XDG_CONFIG_HOME/nvim/bundle/gocode/autoload" 8 | cp "${0%/*}/ftplugin/go/gocomplete.vim" "$XDG_CONFIG_HOME/nvim/bundle/gocode/ftplugin/go" 9 | -------------------------------------------------------------------------------- /internal/gcimporter/testdata/issue15920.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 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 | package p 6 | 7 | // The underlying type of Error is the underlying type of error. 8 | // Make sure we can import this again without problems. 9 | type Error error 10 | 11 | func F() Error { return nil } 12 | -------------------------------------------------------------------------------- /internal/gcimporter/newInterface11.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 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 | // +build go1.11 6 | 7 | package gcimporter 8 | 9 | import "go/types" 10 | 11 | func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface { 12 | return types.NewInterfaceType(methods, embeddeds) 13 | } 14 | -------------------------------------------------------------------------------- /_testing/README: -------------------------------------------------------------------------------- 1 | --== Desc ==-- 2 | 3 | This is a bunch of automated tests for gocode. 4 | 5 | Tests can be slow, because after each request gocode server runs GC. 6 | And current Go GC is slow. You won't notice that other than in tests 7 | because usually you spend some time in editor between requests and 8 | that time is wasted on a GC run, but testing app throws requests one 9 | after another and it causes GC to eat a lot of CPU. So.. don't worry 10 | about that. 11 | -------------------------------------------------------------------------------- /_testing/test.0005/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // this is a file 'a.go' 4 | 5 | import ( 6 | localos "os" 7 | ) 8 | 9 | func A() localos.Error { 10 | return nil 11 | } 12 | 13 | // B() is defined in file 'b.go' 14 | var test = B() 15 | 16 | type Tester struct { 17 | a, b, c, d int 18 | } 19 | 20 | func (t *Tester) SetA() { 21 | t.a = 31337 22 | } 23 | 24 | func (t *Tester) SetB() { 25 | t.b = 31337 26 | } 27 | 28 | // methods SetC and SetD are defined in 'b.go' 29 | 30 | -------------------------------------------------------------------------------- /_testing/test.0006/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // this is a file 'a.go' 4 | 5 | import ( 6 | localos "os" 7 | ) 8 | 9 | func A() localos.Error { 10 | return nil 11 | } 12 | 13 | // B() is defined in file 'b.go' 14 | var test = B() 15 | 16 | type Tester struct { 17 | a, b, c, d int 18 | } 19 | 20 | func (t *Tester) SetA() { 21 | t.a = 31337 22 | } 23 | 24 | func (t *Tester) SetB() { 25 | t.b = 31337 26 | } 27 | 28 | Tester. 29 | 30 | // methods SetC and SetD are defined in 'b.go' 31 | -------------------------------------------------------------------------------- /_testing/test.0013/out.expected: -------------------------------------------------------------------------------- 1 | Found 24 candidates: 2 | func main() 3 | var a int 4 | var add int 5 | var and int 6 | var andnot int 7 | var b int 8 | var c bool 9 | var d bool 10 | var div int 11 | var eq bool 12 | var geq bool 13 | var greater bool 14 | var leq bool 15 | var less bool 16 | var logand bool 17 | var logor bool 18 | var mul int 19 | var neq bool 20 | var or int 21 | var rem int 22 | var shl int 23 | var shr int 24 | var sub int 25 | var xor int 26 | -------------------------------------------------------------------------------- /_testing/test.0048/out.expected: -------------------------------------------------------------------------------- 1 | Found 7 candidates: 2 | func Fprint(w io.Writer, a ...interface{}) (n int, err error) 3 | func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) 4 | func Fprintln(w io.Writer, a ...interface{}) (n int, err error) 5 | func Fscan(r io.Reader, a ...interface{}) (n int, err error) 6 | func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error) 7 | func Fscanln(r io.Reader, a ...interface{}) (n int, err error) 8 | type Formatter interface 9 | -------------------------------------------------------------------------------- /unsafe_go117.go: -------------------------------------------------------------------------------- 1 | //go:build go1.17 && !go1.20 2 | // +build go1.17,!go1.20 3 | 4 | package main 5 | 6 | var g_builtin_unsafe_package = []byte(` 7 | import 8 | $$ 9 | package unsafe 10 | func @"".Alignof(x ArbitraryType) uintptr 11 | func @"".Offsetof(x ArbitraryType) uintptr 12 | func @"".Sizeof(x ArbitraryType) uintptr 13 | type @"".Pointer *ArbitraryType 14 | func @"".Slice(ptr *ArbitraryType, len IntegerType) []ArbitraryType 15 | func @"".Add(ptr Pointer, len IntegerType) Pointer 16 | $$ 17 | `) 18 | -------------------------------------------------------------------------------- /_testing/test.0005/b.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // this is a file 'a.go' 4 | 5 | import ( 6 | superos "os" 7 | ) 8 | 9 | func B() superos.Error { 10 | return nil 11 | } 12 | 13 | // notice how changing type of a return function in one file, 14 | // the inferred type of a variable in another file changes also 15 | 16 | func (t *Tester) SetC() { 17 | t.c = 31337 18 | } 19 | 20 | func (t *Tester) SetD() { 21 | t.d = 31337 22 | } 23 | 24 | // support for multifile packages, including correct namespace handling 25 | -------------------------------------------------------------------------------- /_testing/test.0006/b.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // this is a file 'a.go' 4 | 5 | import ( 6 | superos "os" 7 | ) 8 | 9 | func B() superos.Error { 10 | return nil 11 | } 12 | 13 | // notice how changing type of a return function in one file, 14 | // the inferred type of a variable in another file changes also 15 | 16 | func (t *Tester) SetC() { 17 | t.c = 31337 18 | } 19 | 20 | func (t *Tester) SetD() { 21 | t.d = 31337 22 | } 23 | 24 | // support for multifile packages, including correct namespace handling 25 | -------------------------------------------------------------------------------- /_testing/test.0013/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | var a, b int 5 | add := a + b 6 | sub := a - b 7 | mul := a * b 8 | div := a / b 9 | or := a | b 10 | xor := a ^ b 11 | rem := a % b 12 | shr := a >> uint(b) 13 | shl := a << uint(b) 14 | and := a & b 15 | andnot := a &^ b 16 | 17 | eq := a == b 18 | neq := a != b 19 | less := a < b 20 | leq := a <= b 21 | greater := a > b 22 | geq := a >= b 23 | 24 | var c, d bool 25 | logor := c || d 26 | logand := c && d 27 | 28 | } 29 | -------------------------------------------------------------------------------- /_testing/test.0018/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | // just a dummy example 8 | type Dog struct { 9 | Legs int 10 | } 11 | 12 | func (d *Dog) Bark() { 13 | fmt.Printf("Bark!\n") 14 | } 15 | 16 | // another one 17 | type Test struct { 18 | // map of slices of pointer to a *Dog 19 | MoreTests map[string][]**Dog 20 | } 21 | 22 | func (t *Test) GetMe() *Test { 23 | return t 24 | } 25 | 26 | func main() { 27 | t := new(Test) 28 | (*t.GetMe().MoreTests["blabla"][10]). 29 | } 30 | -------------------------------------------------------------------------------- /_testing/test.0051/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type Item struct { 4 | Quantity int 5 | Name string 6 | } 7 | 8 | type Config struct { 9 | NumApples int 10 | NumOranges int 11 | NumBananas int 12 | } 13 | 14 | func main() { 15 | var cfg Config 16 | items := []Item{ 17 | {cfg.NumApples, "apple"}, 18 | {cfg.NumOranges, "orange"}, 19 | {cfg.NumApples, "banana"}, 20 | } 21 | 22 | var a int 23 | var b int 24 | var c int 25 | var d int 26 | var e int 27 | var f int 28 | var g int 29 | var h int 30 | var i int 31 | var j int 32 | } 33 | -------------------------------------------------------------------------------- /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | name: gocode 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | Test: 11 | strategy: 12 | matrix: 13 | go-version: [1.16.x, 1.17.x, 1.18.x, 1.19.x] 14 | os: [ubuntu-latest, windows-latest, macos-11] 15 | runs-on: ${{ matrix.os }} 16 | steps: 17 | - uses: actions/checkout@v2 18 | 19 | - name: Set up Go 20 | uses: actions/setup-go@v2 21 | with: 22 | go-version: ${{ matrix.go-version }} 23 | 24 | - name: Build 25 | run: go build -v 26 | 27 | -------------------------------------------------------------------------------- /unsafe_go120.go: -------------------------------------------------------------------------------- 1 | //go:build go1.20 2 | // +build go1.20 3 | 4 | package main 5 | 6 | var g_builtin_unsafe_package = []byte(` 7 | import 8 | $$ 9 | package unsafe 10 | func @"".Alignof(x ArbitraryType) uintptr 11 | func @"".Offsetof(x ArbitraryType) uintptr 12 | func @"".Sizeof(x ArbitraryType) uintptr 13 | type @"".Pointer *ArbitraryType 14 | func @"".Slice(ptr *ArbitraryType, len IntegerType) []ArbitraryType 15 | func @"".SliceData(slice []ArbitraryType) *ArbitraryType 16 | func @"".Add(ptr Pointer, len IntegerType) Pointer 17 | func @"".String(ptr *byte, len IntegerType) string 18 | func @"".StringData(str string) *byte 19 | $$ 20 | `) 21 | -------------------------------------------------------------------------------- /_testing/test.0019/out.expected: -------------------------------------------------------------------------------- 1 | Found 15 candidates: 2 | const BestCompression 3 | const BestSpeed 4 | const DefaultCompression 5 | const HuffmanOnly 6 | const NoCompression 7 | func NewReader(r io.Reader) (io.ReadCloser, error) 8 | func NewReaderDict(r io.Reader, dict []byte) (io.ReadCloser, error) 9 | func NewWriter(w io.Writer) *zlib.Writer 10 | func NewWriterLevel(w io.Writer, level int) (*zlib.Writer, error) 11 | func NewWriterLevelDict(w io.Writer, level int, dict []byte) (*zlib.Writer, error) 12 | type Resetter interface 13 | type Writer struct 14 | var ErrChecksum error 15 | var ErrDictionary error 16 | var ErrHeader error 17 | -------------------------------------------------------------------------------- /internal/gcimporter/newInterface10.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 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 | // +build !go1.11 6 | 7 | package gcimporter 8 | 9 | import "go/types" 10 | 11 | func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface { 12 | named := make([]*types.Named, len(embeddeds)) 13 | for i, e := range embeddeds { 14 | var ok bool 15 | named[i], ok = e.(*types.Named) 16 | if !ok { 17 | panic("embedding of non-defined interfaces in interfaces is not supported before Go 1.11") 18 | } 19 | } 20 | return types.NewInterface(methods, named) 21 | } 22 | -------------------------------------------------------------------------------- /subl3/syntax/GoSublime-HTML.tmLanguage: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | fileTypes 6 | 7 | gohtml 8 | 9 | name 10 | GoSublime: HTML 11 | patterns 12 | 13 | 14 | include 15 | text.html.basic 16 | 17 | 18 | include 19 | source.gotemplate 20 | 21 | 22 | scopeName 23 | text.html.gohtml 24 | uuid 25 | 78c486ec-0101-11e2-a85a-00262d996a67 26 | 27 | 28 | -------------------------------------------------------------------------------- /_testing/test.0036/out.expected: -------------------------------------------------------------------------------- 1 | Found 21 candidates: 2 | func Close() error 3 | func DWARF() (*dwarf.Data, error) 4 | func DynString(tag elf.DynTag) ([]string, error) 5 | func DynamicSymbols() ([]elf.Symbol, error) 6 | func ImportedLibraries() ([]string, error) 7 | func ImportedSymbols() ([]elf.ImportedSymbol, error) 8 | func Section(name string) *elf.Section 9 | func SectionByType(typ elf.SectionType) *elf.Section 10 | func Symbols() ([]elf.Symbol, error) 11 | var ABIVersion uint8 12 | var ByteOrder binary.ByteOrder 13 | var Class elf.Class 14 | var Data elf.Data 15 | var Entry uint64 16 | var FileHeader elf.FileHeader 17 | var Machine elf.Machine 18 | var OSABI elf.OSABI 19 | var Progs []*elf.Prog 20 | var Sections []*elf.Section 21 | var Type elf.Type 22 | var Version elf.Version 23 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | # Sample debian/rules that uses debhelper. 4 | # This file was originally written by Joey Hess and Craig Small. 5 | # As a special exception, when this file is copied by dh-make into a 6 | # dh-make output file, you may use that output file without restriction. 7 | # This special exception was added by Craig Small in version 0.37 of dh-make. 8 | 9 | # Uncomment this to turn on verbose mode. 10 | #export DH_VERBOSE=1 11 | export GOROOT=/usr/lib/go 12 | 13 | %: 14 | dh $@ 15 | 16 | override_dh_auto_install: install 17 | 18 | install: 19 | mkdir -p debian/gocode/usr/bin 20 | cp gocode debian/gocode/usr/bin 21 | mkdir -p debian/gocode/usr/share/gocode 22 | cp -av emacs debian/gocode/usr/share/gocode 23 | cp -av vim debian/gocode/usr/share/gocode 24 | mkdir -p debian/gocode/usr/share/doc/gocode 25 | cp LICENSE debian/gocode/usr/share/doc/gocode 26 | cp README.md debian/gocode/usr/share/doc/gocode 27 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: gocode 2 | Section: devel 3 | Priority: extra 4 | Maintainer: Juan L. Negron 5 | Build-Depends: debhelper (>= 7.0.50~), golang 6 | Standards-Version: 3.9.1 7 | Homepage: https://github.com/nsf/gocode 8 | #Vcs-Git: git://git.debian.org/collab-maint/gocode.git 9 | #Vcs-Browser: http://git.debian.org/?p=collab-maint/gocode.git;a=summary 10 | 11 | Package: gocode 12 | Architecture: any 13 | Depends: ${shlibs:Depends}, ${misc:Depends}, golang 14 | Description: An autocompletion daemon for the Go programming language 15 | Gocode is a helper tool which is intended to be integraded with your source 16 | code editor, like vim and emacs. It provides several advanced capabilities, 17 | which currently includes: 18 | - Context-sensitive autocompletion 19 | It is called daemon, because it uses client/server architecture for caching 20 | purposes. In particular, it makes autocompletions very fast. Typical 21 | autocompletion time with warm cache is 30ms, which is barely noticeable. 22 | -------------------------------------------------------------------------------- /internal/gcexportdata/gcexportdata_test.go: -------------------------------------------------------------------------------- 1 | package gcexportdata_test 2 | 3 | import ( 4 | "go/token" 5 | "go/types" 6 | "log" 7 | "os" 8 | "testing" 9 | 10 | "golang.org/x/tools/go/gcexportdata" 11 | ) 12 | 13 | // Test to ensure that gcexportdata can read files produced by App 14 | // Engine Go runtime v1.6. 15 | func TestAppEngine16(t *testing.T) { 16 | // Open and read the file. 17 | f, err := os.Open("testdata/errors-ae16.a") 18 | if err != nil { 19 | t.Fatal(err) 20 | } 21 | defer f.Close() 22 | r, err := gcexportdata.NewReader(f) 23 | if err != nil { 24 | log.Fatalf("reading export data: %v", err) 25 | } 26 | 27 | // Decode the export data. 28 | fset := token.NewFileSet() 29 | imports := make(map[string]*types.Package) 30 | pkg, err := gcexportdata.Read(r, fset, imports, "errors") 31 | if err != nil { 32 | log.Fatal(err) 33 | } 34 | 35 | // Print package information. 36 | got := pkg.Scope().Lookup("New").Type().String() 37 | want := "func(text string) error" 38 | if got != want { 39 | t.Errorf("New.Type = %s, want %s", got, want) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /os_posix.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package main 4 | 5 | import ( 6 | "flag" 7 | "os" 8 | "os/exec" 9 | "path/filepath" 10 | ) 11 | 12 | func create_sock_flag(name, desc string) *string { 13 | return flag.String(name, "unix", desc) 14 | } 15 | 16 | // Full path of the current executable 17 | func get_executable_filename() string { 18 | // try readlink first 19 | path, err := os.Readlink("/proc/self/exe") 20 | if err == nil { 21 | return path 22 | } 23 | // use argv[0] 24 | path = os.Args[0] 25 | if !filepath.IsAbs(path) { 26 | cwd, _ := os.Getwd() 27 | path = filepath.Join(cwd, path) 28 | } 29 | if file_exists(path) { 30 | return path 31 | } 32 | // Fallback : use "gocode" and assume we are in the PATH... 33 | path, err = exec.LookPath("gocode") 34 | if err == nil { 35 | return path 36 | } 37 | return "" 38 | } 39 | 40 | // config location 41 | 42 | func config_dir() string { 43 | return filepath.Join(xdg_home_dir(), "gocode") 44 | } 45 | 46 | func config_file() string { 47 | return filepath.Join(xdg_home_dir(), "gocode", "config.json") 48 | } 49 | -------------------------------------------------------------------------------- /subl3/syntax/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 The GoSublime Authors 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2010 nsf 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /internal/gcimporter/testdata/versions/test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 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 | // This file is a copy of $GOROOT/src/go/internal/gcimporter/testdata/versions.test.go. 6 | 7 | // To create a test case for a new export format version, 8 | // build this package with the latest compiler and store 9 | // the resulting .a file appropriately named in the versions 10 | // directory. The VersionHandling test will pick it up. 11 | // 12 | // In the testdata/versions: 13 | // 14 | // go build -o test_go1.$X_$Y.a test.go 15 | // 16 | // with $X = Go version and $Y = export format version 17 | // (add 'b' or 'i' to distinguish between binary and 18 | // indexed format starting with 1.11 as long as both 19 | // formats are supported). 20 | // 21 | // Make sure this source is extended such that it exercises 22 | // whatever export format change has taken place. 23 | 24 | package test 25 | 26 | // Any release before and including Go 1.7 didn't encode 27 | // the package for a blank struct field. 28 | type BlankField struct { 29 | _ int 30 | } 31 | -------------------------------------------------------------------------------- /internal/gcimporter/typeparams_go118.go: -------------------------------------------------------------------------------- 1 | //go:build go1.18 2 | // +build go1.18 3 | 4 | package gcimporter 5 | 6 | import ( 7 | "go/types" 8 | ) 9 | 10 | type TypeParam = types.TypeParam 11 | type TypeParamList = types.TypeParamList 12 | 13 | func typeParamsForNamed(named *types.Named) *types.TypeParamList { 14 | return named.TypeParams() 15 | } 16 | 17 | func typeParamsForRecv(sig *types.Signature) *types.TypeParamList { 18 | return sig.RecvTypeParams() 19 | } 20 | 21 | func typeParamsForSig(sig *types.Signature) *types.TypeParamList { 22 | return sig.TypeParams() 23 | } 24 | 25 | func typeParamsToTuple(tparams *types.TypeParamList) *types.Tuple { 26 | if tparams == nil { 27 | return types.NewTuple() 28 | } 29 | n := tparams.Len() 30 | ar := make([]*types.Var, n) 31 | for i := 0; i < n; i++ { 32 | tp := tparams.At(i) 33 | obj := tp.Obj() 34 | ar[i] = types.NewVar(obj.Pos(), obj.Pkg(), obj.Name(), tp.Constraint()) 35 | } 36 | return types.NewTuple(ar...) 37 | } 38 | 39 | func originType(t types.Type) types.Type { 40 | if named, ok := t.(*types.Named); ok { 41 | t = named.Origin() 42 | } 43 | return t 44 | } 45 | 46 | type Union = types.Union 47 | type Term = types.Term 48 | 49 | // comparable 50 | var comparableType = types.Universe.Lookup("comparable").Type() 51 | -------------------------------------------------------------------------------- /_testing/run.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # encoding: utf-8 3 | 4 | RED = "\033[0;31m" 5 | GRN = "\033[0;32m" 6 | NC = "\033[0m" 7 | 8 | PASS = "#{GRN}PASS!#{NC}" 9 | FAIL = "#{RED}FAIL!#{NC}" 10 | 11 | Stats = Struct.new :total, :ok, :fail 12 | $stats = Stats.new 0, 0, 0 13 | 14 | def print_fail_report(t, out, outexpected) 15 | puts "#{t}: #{FAIL}" 16 | puts "-"*65 17 | puts "Got:\n#{out}" 18 | puts "-"*65 19 | puts "Expected:\n#{outexpected}" 20 | puts "-"*65 21 | end 22 | 23 | def print_pass_report(t) 24 | puts "#{t}: #{PASS}" 25 | end 26 | 27 | def print_stats 28 | puts "\nSummary (total: #{$stats.total})" 29 | puts "#{GRN} PASS#{NC}: #{$stats.ok}" 30 | puts "#{RED} FAIL#{NC}: #{$stats.fail}" 31 | puts "#{$stats.fail == 0 ? GRN : RED}#{"█"*72}#{NC}" 32 | end 33 | 34 | def run_test(t) 35 | $stats.total += 1 36 | 37 | cursorpos = Dir["#{t}/cursor.*"].map{|d| File.extname(d)[1..-1]}.first 38 | outexpected = IO.read("#{t}/out.expected") rescue "To be determined" 39 | filename = "#{t}/test.go.in" 40 | 41 | out = %x[gocode -in #{filename} autocomplete #{filename} #{cursorpos}] 42 | 43 | if out != outexpected then 44 | print_fail_report(t, out, outexpected) 45 | $stats.fail += 1 46 | else 47 | print_pass_report(t) 48 | $stats.ok += 1 49 | end 50 | end 51 | 52 | if ARGV.one? 53 | run_test ARGV[0] 54 | else 55 | Dir["test.*"].sort.each do |t| 56 | run_test t 57 | end 58 | end 59 | 60 | print_stats 61 | -------------------------------------------------------------------------------- /subl3/README.md: -------------------------------------------------------------------------------- 1 | # Sublime Text 3 plugin 2 | 3 | If you want full Go experience in sublime, use [GoSublime](https://github.com/DisposaBoy/GoSublime). 4 | 5 | This plugin is written by me (nsf) as a result of frustration with GoSublime. I wanted something simpler and plugin has to use system version of the gocode. As you may know, GoSublime uses a fork of gocode, which is integrated into its own daemon called MarGo (as far as I know). 6 | 7 | The plugin does: 8 | 9 | 1. Basic gocode autocompletion. I did my best presenting the results to the user. Maybe it's possible to improve that part a bit, not quite sure yet. For functions I use "{**class**} {**name**}\t{**returns**}", for everything else "{**class**} {**name**}\t{**type**}". In addition to that functions are properly augmented with argument snippets. 10 | 11 | 2. Gofmt on save. Here I use difflib to calculate differences, which results in line by line changes. GoSublime uses [google-diff-match-patch](https://code.google.com/archive/p/google-diff-match-patch/) library, which calculates changes on finer granularity, maybe I should switch to that lib as well. 12 | 13 | I don't have any big plans on this plugin. The reason why I moved to sublime in the first place is, again, frustration, but with Atom (too slow). We'll see how it goes. 14 | 15 | Oh yes, this plugin uses GoSublime syntax files for Go. Well, they use a fork of gocode, I'll use the fork of their syntax files, fair deal. 16 | -------------------------------------------------------------------------------- /_testing/test.0001/out.expected: -------------------------------------------------------------------------------- 1 | Found 25 candidates: 2 | func Errorf(format string, a ...interface{}) error 3 | func Fprint(w io.Writer, a ...interface{}) (n int, err error) 4 | func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) 5 | func Fprintln(w io.Writer, a ...interface{}) (n int, err error) 6 | func Fscan(r io.Reader, a ...interface{}) (n int, err error) 7 | func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error) 8 | func Fscanln(r io.Reader, a ...interface{}) (n int, err error) 9 | func Print(a ...interface{}) (n int, err error) 10 | func Printf(format string, a ...interface{}) (n int, err error) 11 | func Println(a ...interface{}) (n int, err error) 12 | func Scan(a ...interface{}) (n int, err error) 13 | func Scanf(format string, a ...interface{}) (n int, err error) 14 | func Scanln(a ...interface{}) (n int, err error) 15 | func Sprint(a ...interface{}) string 16 | func Sprintf(format string, a ...interface{}) string 17 | func Sprintln(a ...interface{}) string 18 | func Sscan(str string, a ...interface{}) (n int, err error) 19 | func Sscanf(str string, format string, a ...interface{}) (n int, err error) 20 | func Sscanln(str string, a ...interface{}) (n int, err error) 21 | type Formatter interface 22 | type GoStringer interface 23 | type ScanState interface 24 | type Scanner interface 25 | type State interface 26 | type Stringer interface 27 | -------------------------------------------------------------------------------- /_testing/test.0023/out.expected: -------------------------------------------------------------------------------- 1 | Found 25 candidates: 2 | func Errorf(format string, a ...interface{}) error 3 | func Fprint(w io.Writer, a ...interface{}) (n int, err error) 4 | func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) 5 | func Fprintln(w io.Writer, a ...interface{}) (n int, err error) 6 | func Fscan(r io.Reader, a ...interface{}) (n int, err error) 7 | func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error) 8 | func Fscanln(r io.Reader, a ...interface{}) (n int, err error) 9 | func Print(a ...interface{}) (n int, err error) 10 | func Printf(format string, a ...interface{}) (n int, err error) 11 | func Println(a ...interface{}) (n int, err error) 12 | func Scan(a ...interface{}) (n int, err error) 13 | func Scanf(format string, a ...interface{}) (n int, err error) 14 | func Scanln(a ...interface{}) (n int, err error) 15 | func Sprint(a ...interface{}) string 16 | func Sprintf(format string, a ...interface{}) string 17 | func Sprintln(a ...interface{}) string 18 | func Sscan(str string, a ...interface{}) (n int, err error) 19 | func Sscanf(str string, format string, a ...interface{}) (n int, err error) 20 | func Sscanln(str string, a ...interface{}) (n int, err error) 21 | type Formatter interface 22 | type GoStringer interface 23 | type ScanState interface 24 | type Scanner interface 25 | type State interface 26 | type Stringer interface 27 | -------------------------------------------------------------------------------- /_testing/test.0045/out.expected: -------------------------------------------------------------------------------- 1 | Found 25 candidates: 2 | func Errorf(format string, a ...interface{}) error 3 | func Fprint(w io.Writer, a ...interface{}) (n int, err error) 4 | func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) 5 | func Fprintln(w io.Writer, a ...interface{}) (n int, err error) 6 | func Fscan(r io.Reader, a ...interface{}) (n int, err error) 7 | func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error) 8 | func Fscanln(r io.Reader, a ...interface{}) (n int, err error) 9 | func Print(a ...interface{}) (n int, err error) 10 | func Printf(format string, a ...interface{}) (n int, err error) 11 | func Println(a ...interface{}) (n int, err error) 12 | func Scan(a ...interface{}) (n int, err error) 13 | func Scanf(format string, a ...interface{}) (n int, err error) 14 | func Scanln(a ...interface{}) (n int, err error) 15 | func Sprint(a ...interface{}) string 16 | func Sprintf(format string, a ...interface{}) string 17 | func Sprintln(a ...interface{}) string 18 | func Sscan(str string, a ...interface{}) (n int, err error) 19 | func Sscanf(str string, format string, a ...interface{}) (n int, err error) 20 | func Sscanln(str string, a ...interface{}) (n int, err error) 21 | type Formatter interface 22 | type GoStringer interface 23 | type ScanState interface 24 | type Scanner interface 25 | type State interface 26 | type Stringer interface 27 | -------------------------------------------------------------------------------- /_testing/test.0046/out.expected: -------------------------------------------------------------------------------- 1 | Found 25 candidates: 2 | func Errorf(format string, a ...interface{}) error 3 | func Fprint(w io.Writer, a ...interface{}) (n int, err error) 4 | func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) 5 | func Fprintln(w io.Writer, a ...interface{}) (n int, err error) 6 | func Fscan(r io.Reader, a ...interface{}) (n int, err error) 7 | func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error) 8 | func Fscanln(r io.Reader, a ...interface{}) (n int, err error) 9 | func Print(a ...interface{}) (n int, err error) 10 | func Printf(format string, a ...interface{}) (n int, err error) 11 | func Println(a ...interface{}) (n int, err error) 12 | func Scan(a ...interface{}) (n int, err error) 13 | func Scanf(format string, a ...interface{}) (n int, err error) 14 | func Scanln(a ...interface{}) (n int, err error) 15 | func Sprint(a ...interface{}) string 16 | func Sprintf(format string, a ...interface{}) string 17 | func Sprintln(a ...interface{}) string 18 | func Sscan(str string, a ...interface{}) (n int, err error) 19 | func Sscanf(str string, format string, a ...interface{}) (n int, err error) 20 | func Sscanln(str string, a ...interface{}) (n int, err error) 21 | type Formatter interface 22 | type GoStringer interface 23 | type ScanState interface 24 | type Scanner interface 25 | type State interface 26 | type Stringer interface 27 | -------------------------------------------------------------------------------- /_testing/test.0029/out.expected: -------------------------------------------------------------------------------- 1 | Found 27 candidates: 2 | func Errorf(format string, a ...interface{}) error 3 | func Fprint(w io.Writer, a ...interface{}) (n int, err error) 4 | func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) 5 | func Fprintln(w io.Writer, a ...interface{}) (n int, err error) 6 | func Fscan(r io.Reader, a ...interface{}) (n int, err error) 7 | func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error) 8 | func Fscanln(r io.Reader, a ...interface{}) (n int, err error) 9 | func Print(a ...interface{}) (n int, err error) 10 | func Printf(format string, a ...interface{}) (n int, err error) 11 | func Println(a ...interface{}) (n int, err error) 12 | func Scan(a ...interface{}) (n int, err error) 13 | func Scanf(format string, a ...interface{}) (n int, err error) 14 | func Scanln(a ...interface{}) (n int, err error) 15 | func Sprint(a ...interface{}) string 16 | func Sprintf(format string, a ...interface{}) string 17 | func Sprintln(a ...interface{}) string 18 | func Sscan(str string, a ...interface{}) (n int, err error) 19 | func Sscanf(str string, format string, a ...interface{}) (n int, err error) 20 | func Sscanln(str string, a ...interface{}) (n int, err error) 21 | func main() 22 | type Formatter interface 23 | type GoStringer interface 24 | type ScanState interface 25 | type Scanner interface 26 | type State interface 27 | type Stringer interface 28 | var a Formatter 29 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | This work was packaged for Ubuntu by: 2 | 3 | Juan L. Negron on Fri, 05 Aug 2011 22:58:48 -0700 4 | 5 | It was downloaded from: 6 | 7 | https://github.com/nsf/gocode 8 | 9 | Upstream Author(s) and copyright: 10 | 11 | Copyright (C) 2010 nsf 12 | 13 | License: 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy 16 | of this software and associated documentation files (the "Software"), to deal 17 | in the Software without restriction, including without limitation the rights 18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | copies of the Software, and to permit persons to whom the Software is 20 | furnished to do so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in 23 | all copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | THE SOFTWARE. 32 | 33 | The Debian packaging is: 34 | 35 | Copyright (C) 2011 Canonical Ltd. 36 | -------------------------------------------------------------------------------- /os_windows.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "path/filepath" 7 | "syscall" 8 | "unsafe" 9 | ) 10 | 11 | var ( 12 | shell32 = syscall.NewLazyDLL("shell32.dll") 13 | kernel32 = syscall.NewLazyDLL("kernel32.dll") 14 | ) 15 | 16 | var ( 17 | proc_sh_get_folder_path = shell32.NewProc("SHGetFolderPathW") 18 | proc_get_module_file_name = kernel32.NewProc("GetModuleFileNameW") 19 | ) 20 | 21 | func create_sock_flag(name, desc string) *string { 22 | return flag.String(name, "tcp", desc) 23 | } 24 | 25 | // Full path of the current executable 26 | func get_executable_filename() string { 27 | b := make([]uint16, syscall.MAX_PATH) 28 | ret, _, err := syscall.Syscall(proc_get_module_file_name.Addr(), 3, 29 | 0, uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))) 30 | if int(ret) == 0 { 31 | panic(fmt.Sprintf("GetModuleFileNameW : err %d", int(err))) 32 | } 33 | return syscall.UTF16ToString(b) 34 | } 35 | 36 | const ( 37 | csidl_appdata = 0x1a 38 | ) 39 | 40 | func get_appdata_folder_path() string { 41 | b := make([]uint16, syscall.MAX_PATH) 42 | ret, _, err := syscall.Syscall6(proc_sh_get_folder_path.Addr(), 5, 43 | 0, csidl_appdata, 0, 0, uintptr(unsafe.Pointer(&b[0])), 0) 44 | if int(ret) != 0 { 45 | panic(fmt.Sprintf("SHGetFolderPathW : err %d", int(err))) 46 | } 47 | return syscall.UTF16ToString(b) 48 | } 49 | 50 | func config_dir() string { 51 | return filepath.Join(get_appdata_folder_path(), "gocode") 52 | } 53 | 54 | func config_file() string { 55 | return filepath.Join(get_appdata_folder_path(), "gocode", "config.json") 56 | } 57 | -------------------------------------------------------------------------------- /_testing/test.0003/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "go/ast" 5 | "io" 6 | ) 7 | 8 | func PrettyPrintTypeExpr(out io.Writer, e ast.Expr) { 9 | switch t := e.(type) { 10 | case *ast.StarExpr: 11 | fmt.Fprintf(out, "*") 12 | PrettyPrintTypeExpr(out, t.X) 13 | case *ast.Ident: 14 | // ast.Ident type decl as a reminder (note embedded type): 15 | // 16 | // type Ident struct { 17 | // token.Position // identifier position 18 | // Obj *Object // denoted object 19 | // } 20 | // 21 | // Correct type inference in complex type switch statements + 22 | // support for type embedding 23 | fmt.Fprintf(out, t.Name()) 24 | t. 25 | case *ast.ArrayType: 26 | fmt.Fprintf(out, "[]") 27 | PrettyPrintTypeExpr(out, t.Elt) 28 | case *ast.SelectorExpr: 29 | PrettyPrintTypeExpr(out, t.X) 30 | fmt.Fprintf(out, ".%s", t.Sel.Name()) 31 | case *ast.FuncType: 32 | // SKIP THIS FOR DEMO 33 | case *ast.MapType: 34 | fmt.Fprintf(out, "map[") 35 | PrettyPrintTypeExpr(out, t.Key) 36 | fmt.Fprintf(out, "]") 37 | PrettyPrintTypeExpr(out, t.Value) 38 | case *ast.InterfaceType: 39 | fmt.Fprintf(out, "interface{}") 40 | case *ast.Ellipsis: 41 | fmt.Fprintf(out, "...") 42 | PrettyPrintTypeExpr(out, t.Elt) 43 | case *ast.StructType: 44 | fmt.Fprintf(out, "struct") 45 | case *ast.ChanType: 46 | switch t.Dir { 47 | case ast.RECV: 48 | fmt.Fprintf(out, "<-chan ") 49 | case ast.SEND: 50 | fmt.Fprintf(out, "chan<- ") 51 | case ast.SEND | ast.RECV: 52 | fmt.Fprintf(out, "chan ") 53 | } 54 | PrettyPrintTypeExpr(out, t.Value) 55 | default: 56 | panic("OMGWTFBBQ!") 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /_testing/test.0004/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "go/ast" 5 | "io" 6 | ) 7 | 8 | func PrettyPrintTypeExpr(out io.Writer, e ast.Expr) { 9 | switch t := e.(type) { 10 | case *ast.StarExpr: 11 | fmt.Fprintf(out, "*") 12 | PrettyPrintTypeExpr(out, t.X) 13 | case *ast.Ident: 14 | // ast.Ident type decl as a reminder (note embedded type): 15 | // 16 | // type Ident struct { 17 | // token.Position // identifier position 18 | // Obj *Object // denoted object 19 | // } 20 | // 21 | // Correct type inference in complex type switch statements + 22 | // support for type embedding 23 | fmt.Fprintf(out, t.Name()) 24 | case *ast.ArrayType: 25 | fmt.Fprintf(out, "[]") 26 | PrettyPrintTypeExpr(out, t.Elt) 27 | case *ast.SelectorExpr: 28 | PrettyPrintTypeExpr(out, t.X) 29 | fmt.Fprintf(out, ".%s", t.Sel.Name()) 30 | case *ast.FuncType: 31 | // SKIP THIS FOR DEMO 32 | case *ast.MapType: 33 | fmt.Fprintf(out, "map[") 34 | PrettyPrintTypeExpr(out, t.Key) 35 | fmt.Fprintf(out, "]") 36 | PrettyPrintTypeExpr(out, t.Value) 37 | case *ast.InterfaceType: 38 | fmt.Fprintf(out, "interface{}") 39 | case *ast.Ellipsis: 40 | fmt.Fprintf(out, "...") 41 | PrettyPrintTypeExpr(out, t.Elt) 42 | case *ast.StructType: 43 | fmt.Fprintf(out, "struct") 44 | case *ast.ChanType: 45 | switch t.Dir { 46 | case ast.RECV: 47 | fmt.Fprintf(out, "<-chan ") 48 | case ast.SEND: 49 | fmt.Fprintf(out, "chan<- ") 50 | case ast.SEND | ast.RECV: 51 | fmt.Fprintf(out, "chan ") 52 | } 53 | PrettyPrintTypeExpr(out, t.Value) 54 | default: 55 | 56 | panic("OMGWTFBBQ!") 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /_testing/run.tcl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env tclsh 2 | 3 | set red "\033\[0;31m" 4 | set grn "\033\[0;32m" 5 | set nc "\033\[0m" 6 | 7 | set pass "${grn}PASS!${nc}" 8 | set fail "${red}FAIL!${nc}" 9 | 10 | set stats.total 0 11 | set stats.ok 0 12 | set stats.fail 0 13 | 14 | proc print_fail_report {t out expected} { 15 | global fail 16 | 17 | set hr [join [lrepeat 65 "-"] ""] 18 | puts "${t}: ${fail}" 19 | puts $hr 20 | puts "Got:\n${out}" 21 | puts $hr 22 | puts "Expected:\n${expected}" 23 | puts $hr 24 | } 25 | 26 | proc print_pass_report {t} { 27 | global pass 28 | 29 | puts "${t}: ${pass}" 30 | } 31 | 32 | proc print_stats {} { 33 | global red grn nc stats.total stats.ok stats.fail 34 | 35 | set hr [join [lrepeat 72 "█"] ""] 36 | set hrcol [expr {${stats.fail} ? $red : $grn}] 37 | puts "\nSummary (total: ${stats.total})" 38 | puts "${grn} PASS${nc}: ${stats.ok}" 39 | puts "${red} FAIL${nc}: ${stats.fail}" 40 | puts "${hrcol}${hr}${nc}" 41 | } 42 | 43 | proc read_file {filename} { 44 | set f [open $filename r] 45 | set data [read $f] 46 | close $f 47 | return $data 48 | } 49 | 50 | proc run_test {t} { 51 | global stats.total stats.ok stats.fail 52 | 53 | incr stats.total 54 | set cursorpos [string range [file extension [glob "${t}/cursor.*"]] 1 end] 55 | set expected [read_file "${t}/out.expected"] 56 | set filename "${t}/test.go.in" 57 | 58 | set out [read_file "| gocode -in ${filename} autocomplete ${filename} ${cursorpos}"] 59 | if {$out eq $expected} { 60 | print_pass_report $t 61 | incr stats.ok 62 | } else { 63 | print_fail_report $t $out $expected 64 | incr stats.fail 65 | } 66 | } 67 | 68 | if {$argc == 1} { 69 | run_test $argv 70 | } else { 71 | foreach t [lsort [glob test.*]] { 72 | run_test $t 73 | } 74 | } 75 | 76 | print_stats 77 | 78 | 79 | -------------------------------------------------------------------------------- /scope.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | //------------------------------------------------------------------------- 4 | // scope 5 | //------------------------------------------------------------------------- 6 | 7 | type scope struct { 8 | // the package name that this scope resides in 9 | pkgname string 10 | parent *scope // nil for universe scope 11 | entities map[string]*decl 12 | } 13 | 14 | func new_named_scope(outer *scope, name string) *scope { 15 | s := new_scope(outer) 16 | s.pkgname = name 17 | return s 18 | } 19 | 20 | func new_scope(outer *scope) *scope { 21 | s := new(scope) 22 | if outer != nil { 23 | s.pkgname = outer.pkgname 24 | } 25 | s.parent = outer 26 | s.entities = make(map[string]*decl) 27 | return s 28 | } 29 | 30 | // returns: new, prev 31 | func advance_scope(s *scope) (*scope, *scope) { 32 | if len(s.entities) == 0 { 33 | return s, s.parent 34 | } 35 | return new_scope(s), s 36 | } 37 | 38 | // adds declaration or returns an existing one 39 | func (s *scope) add_named_decl(d *decl) *decl { 40 | return s.add_decl(d.name, d) 41 | } 42 | 43 | func (s *scope) add_decl(name string, d *decl) *decl { 44 | decl, ok := s.entities[name] 45 | if !ok { 46 | s.entities[name] = d 47 | return d 48 | } 49 | return decl 50 | } 51 | 52 | func (s *scope) replace_decl(name string, d *decl) { 53 | s.entities[name] = d 54 | } 55 | 56 | func (s *scope) merge_decl(d *decl) { 57 | decl, ok := s.entities[d.name] 58 | if !ok { 59 | s.entities[d.name] = d 60 | } else { 61 | decl := decl.deep_copy() 62 | decl.expand_or_replace(d) 63 | s.entities[d.name] = decl 64 | } 65 | } 66 | 67 | func (s *scope) lookup(name string) *decl { 68 | decl, ok := s.entities[name] 69 | if !ok { 70 | if s.parent != nil { 71 | return s.parent.lookup(name) 72 | } else { 73 | return nil 74 | } 75 | } 76 | return decl 77 | } 78 | -------------------------------------------------------------------------------- /internal/gcimporter/testdata/exports.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 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 | // This file is used to generate an object file which 6 | // serves as test file for gcimporter_test.go. 7 | 8 | package exports 9 | 10 | import ( 11 | "go/ast" 12 | ) 13 | 14 | // Issue 3682: Correctly read dotted identifiers from export data. 15 | const init1 = 0 16 | 17 | func init() {} 18 | 19 | const ( 20 | C0 int = 0 21 | C1 = 3.14159265 22 | C2 = 2.718281828i 23 | C3 = -123.456e-789 24 | C4 = +123.456E+789 25 | C5 = 1234i 26 | C6 = "foo\n" 27 | C7 = `bar\n` 28 | ) 29 | 30 | type ( 31 | T1 int 32 | T2 [10]int 33 | T3 []int 34 | T4 *int 35 | T5 chan int 36 | T6a chan<- int 37 | T6b chan (<-chan int) 38 | T6c chan<- (chan int) 39 | T7 <-chan *ast.File 40 | T8 struct{} 41 | T9 struct { 42 | a int 43 | b, c float32 44 | d []string `go:"tag"` 45 | } 46 | T10 struct { 47 | T8 48 | T9 49 | _ *T10 50 | } 51 | T11 map[int]string 52 | T12 interface{} 53 | T13 interface { 54 | m1() 55 | m2(int) float32 56 | } 57 | T14 interface { 58 | T12 59 | T13 60 | m3(x ...struct{}) []T9 61 | } 62 | T15 func() 63 | T16 func(int) 64 | T17 func(x int) 65 | T18 func() float32 66 | T19 func() (x float32) 67 | T20 func(...interface{}) 68 | T21 struct{ next *T21 } 69 | T22 struct{ link *T23 } 70 | T23 struct{ link *T22 } 71 | T24 *T24 72 | T25 *T26 73 | T26 *T27 74 | T27 *T25 75 | T28 func(T28) T28 76 | ) 77 | 78 | var ( 79 | V0 int 80 | V1 = -991.0 81 | ) 82 | 83 | func F1() {} 84 | func F2(x int) {} 85 | func F3() int { return 0 } 86 | func F4() float32 { return 0 } 87 | func F5(a, b, c int, u, v, w struct{ x, y T1 }, more ...interface{}) (p, q, r chan<- T10) 88 | 89 | func (p *T1) M1() 90 | -------------------------------------------------------------------------------- /_testing/run.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | import os, glob, subprocess, sys 5 | 6 | total = 0 7 | ok = 0 8 | fail = 0 9 | expected_fail = 0 10 | 11 | RED = "\033[0;31m" 12 | GREEN = "\033[0;32m" 13 | YELLOW = "\033[0;33m" 14 | NC = "\033[0m" 15 | 16 | OK = GREEN + "PASS!" + NC 17 | FAIL = RED + "FAIL!" + NC 18 | EXPECTED = YELLOW + "EXPECTED: " + NC 19 | 20 | # name of the test + commentary (why it is expected to fail) 21 | expected_to_fail = { 22 | } 23 | 24 | def run_test(t): 25 | global total, ok, fail, expected_fail 26 | total += 1 27 | c = glob.glob(t + "/cursor.*")[0] 28 | cursorpos = os.path.splitext(c)[1][1:] 29 | try: 30 | with open(t + "/out.expected", "r") as f: 31 | outexpected = f.read() 32 | except: 33 | outexpected = "To be determined" 34 | filename = t + "/test.go.in" 35 | gocode = subprocess.Popen(["gocode", "-in", filename, "autocomplete", filename, cursorpos], 36 | shell=False, stdout=subprocess.PIPE) 37 | out = gocode.communicate()[0] 38 | if out != outexpected: 39 | if t in expected_to_fail: 40 | print t + ": " + FAIL + " " + EXPECTED + expected_to_fail[t] 41 | expected_fail += 1 42 | else: 43 | print t + ": " + FAIL 44 | print "--------------------------------------------------------" 45 | print "Got:\n" + out 46 | print "--------------------------------------------------------" 47 | print "Expected:\n" + outexpected 48 | print "--------------------------------------------------------" 49 | fail += 1 50 | else: 51 | print t + ": " + OK 52 | ok += 1 53 | 54 | if len(sys.argv) == 2: 55 | run_test(sys.argv[1]) 56 | else: 57 | for t in sorted(glob.glob("test.*")): 58 | run_test(t) 59 | 60 | print "\nSummary (total: %d):" % total 61 | print GREEN + " PASS" + NC + ": %d" % ok 62 | print RED +" FAIL" + NC + ": %d (unexpected failures)" % fail 63 | 64 | if fail == 0: 65 | print GREEN + "████████████████████████████████████████████████████████████████████" + NC 66 | else: 67 | print RED + "████████████████████████████████████████████████████████████████████" + NC 68 | -------------------------------------------------------------------------------- /emacs-company/README.md: -------------------------------------------------------------------------------- 1 | # Company-go 2 | Company-go is an alternative emacs plugin for autocompletion. It uses [company-mode](http://company-mode.github.io). 3 | Completion will start automatically whenever the current symbol is preceded by a `.`, or after you type `company-minimum-prefix-length` letters. 4 | 5 | ## Setup 6 | Install `company` and `company-go`. 7 | 8 | Add the following to your emacs-config: 9 | 10 | ```lisp 11 | (require 'company) ; load company mode 12 | (require 'company-go) ; load company mode go backend 13 | ``` 14 | 15 | ## Possible improvements 16 | 17 | ```lisp 18 | (setq company-tooltip-limit 20) ; bigger popup window 19 | (setq company-idle-delay .3) ; decrease delay before autocompletion popup shows 20 | (setq company-echo-delay 0) ; remove annoying blinking 21 | (setq company-begin-commands '(self-insert-command)) ; start autocompletion only after typing 22 | ``` 23 | 24 | ### Only use company-mode with company-go in go-mode 25 | By default company-mode loads every backend it has. If you want to only have company-mode enabled in go-mode add the following to your emacs-config: 26 | 27 | ```lisp 28 | (add-hook 'go-mode-hook (lambda () 29 | (set (make-local-variable 'company-backends) '(company-go)) 30 | (company-mode))) 31 | ``` 32 | 33 | ### Color customization 34 | 35 | ```lisp 36 | (custom-set-faces 37 | '(company-preview 38 | ((t (:foreground "darkgray" :underline t)))) 39 | '(company-preview-common 40 | ((t (:inherit company-preview)))) 41 | '(company-tooltip 42 | ((t (:background "lightgray" :foreground "black")))) 43 | '(company-tooltip-selection 44 | ((t (:background "steelblue" :foreground "white")))) 45 | '(company-tooltip-common 46 | ((((type x)) (:inherit company-tooltip :weight bold)) 47 | (t (:inherit company-tooltip)))) 48 | '(company-tooltip-common-selection 49 | ((((type x)) (:inherit company-tooltip-selection :weight bold)) 50 | (t (:inherit company-tooltip-selection))))) 51 | ``` 52 | -------------------------------------------------------------------------------- /internal/gcexportdata/importer.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 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 | package gcexportdata 6 | 7 | import ( 8 | "fmt" 9 | "go/token" 10 | "go/types" 11 | "os" 12 | ) 13 | 14 | // NewImporter returns a new instance of the types.Importer interface 15 | // that reads type information from export data files written by gc. 16 | // The Importer also satisfies types.ImporterFrom. 17 | // 18 | // Export data files are located using "go build" workspace conventions 19 | // and the build.Default context. 20 | // 21 | // Use this importer instead of go/importer.For("gc", ...) to avoid the 22 | // version-skew problems described in the documentation of this package, 23 | // or to control the FileSet or access the imports map populated during 24 | // package loading. 25 | // 26 | func NewImporter(fset *token.FileSet, imports map[string]*types.Package) types.ImporterFrom { 27 | return importer{fset, imports} 28 | } 29 | 30 | type importer struct { 31 | fset *token.FileSet 32 | imports map[string]*types.Package 33 | } 34 | 35 | func (imp importer) Import(importPath string) (*types.Package, error) { 36 | return imp.ImportFrom(importPath, "", 0) 37 | } 38 | 39 | func (imp importer) ImportFrom(importPath, srcDir string, mode types.ImportMode) (_ *types.Package, err error) { 40 | filename, path := Find(importPath, srcDir) 41 | if filename == "" { 42 | if importPath == "unsafe" { 43 | // Even for unsafe, call Find first in case 44 | // the package was vendored. 45 | return types.Unsafe, nil 46 | } 47 | return nil, fmt.Errorf("can't find import: %s", importPath) 48 | } 49 | 50 | if pkg, ok := imp.imports[path]; ok && pkg.Complete() { 51 | return pkg, nil // cache hit 52 | } 53 | 54 | // open file 55 | f, err := os.Open(filename) 56 | if err != nil { 57 | return nil, err 58 | } 59 | defer func() { 60 | f.Close() 61 | if err != nil { 62 | // add file name to error 63 | err = fmt.Errorf("reading export data: %s: %v", filename, err) 64 | } 65 | }() 66 | 67 | r, err := NewReader(f) 68 | if err != nil { 69 | return nil, err 70 | } 71 | 72 | return Read(r, imp.fset, imp.imports, path) 73 | } 74 | -------------------------------------------------------------------------------- /internal/gcimporter/typeparams_go117.go: -------------------------------------------------------------------------------- 1 | //go:build !go1.18 2 | // +build !go1.18 3 | 4 | package gcimporter 5 | 6 | import ( 7 | "go/types" 8 | ) 9 | 10 | func unsupported() { 11 | panic("type parameters are unsupported at this go version") 12 | } 13 | 14 | // TypeParam is a placeholder type, as type parameters are not supported at 15 | // this Go version. Its methods panic on use. 16 | type TypeParam struct{ types.Type } 17 | 18 | func (*TypeParam) Index() int { unsupported(); return 0 } 19 | func (*TypeParam) Constraint() types.Type { unsupported(); return nil } 20 | func (*TypeParam) Obj() *types.TypeName { unsupported(); return nil } 21 | 22 | type TypeParamList struct{} 23 | 24 | func (*TypeParamList) Len() int { return 0 } 25 | func (*TypeParamList) At(int) *TypeParam { unsupported(); return nil } 26 | 27 | func typeParamsForNamed(named *types.Named) *TypeParamList { 28 | return nil 29 | } 30 | 31 | func typeParamsForRecv(sig *types.Signature) *TypeParamList { 32 | return nil 33 | } 34 | 35 | func typeParamsForSig(sig *types.Signature) *TypeParamList { 36 | return nil 37 | } 38 | 39 | func typeParamsToTuple(tparams *TypeParamList) *types.Tuple { 40 | return types.NewTuple() 41 | } 42 | 43 | func originType(t types.Type) types.Type { 44 | return t 45 | } 46 | 47 | // Term holds information about a structural type restriction. 48 | type Term struct { 49 | tilde bool 50 | typ types.Type 51 | } 52 | 53 | func (m *Term) Tilde() bool { return m.tilde } 54 | func (m *Term) Type() types.Type { return m.typ } 55 | func (m *Term) String() string { 56 | pre := "" 57 | if m.tilde { 58 | pre = "~" 59 | } 60 | return pre + m.typ.String() 61 | } 62 | 63 | // NewTerm creates a new placeholder term type. 64 | func NewTerm(tilde bool, typ types.Type) *Term { 65 | return &Term{tilde, typ} 66 | } 67 | 68 | // Union is a placeholder type, as type parameters are not supported at this Go 69 | // version. Its methods panic on use. 70 | type Union struct{ types.Type } 71 | 72 | func (*Union) String() string { unsupported(); return "" } 73 | func (*Union) Underlying() types.Type { unsupported(); return nil } 74 | func (*Union) Len() int { return 0 } 75 | func (*Union) Term(i int) *Term { unsupported(); return nil } 76 | 77 | var comparableType = comparable{} 78 | 79 | type comparable struct{} 80 | 81 | func (t comparable) Underlying() types.Type { return t } 82 | func (t comparable) String() string { return "comparable" } 83 | -------------------------------------------------------------------------------- /_testing/test.0011/out.expected: -------------------------------------------------------------------------------- 1 | Found 70 candidates: 2 | func Addr() reflect.Value 3 | func Bool() bool 4 | func Bytes() []byte 5 | func Call(in []reflect.Value) []reflect.Value 6 | func CallSlice(in []reflect.Value) []reflect.Value 7 | func CanAddr() bool 8 | func CanComplex() bool 9 | func CanConvert(t reflect.Type) bool 10 | func CanFloat() bool 11 | func CanInt() bool 12 | func CanInterface() bool 13 | func CanSet() bool 14 | func CanUint() bool 15 | func Cap() int 16 | func Close() 17 | func Complex() complex128 18 | func Convert(t reflect.Type) reflect.Value 19 | func Elem() reflect.Value 20 | func Field(i int) reflect.Value 21 | func FieldByIndex(index []int) reflect.Value 22 | func FieldByIndexErr(index []int) (reflect.Value, error) 23 | func FieldByName(name string) reflect.Value 24 | func FieldByNameFunc(match func(string) bool) reflect.Value 25 | func Float() float64 26 | func Index(i int) reflect.Value 27 | func Int() int64 28 | func Interface() (i interface{}) 29 | func InterfaceData() [2]uintptr 30 | func IsNil() bool 31 | func IsValid() bool 32 | func IsZero() bool 33 | func Kind() reflect.Kind 34 | func Len() int 35 | func MapIndex(key reflect.Value) reflect.Value 36 | func MapKeys() []reflect.Value 37 | func MapRange() *reflect.MapIter 38 | func Method(i int) reflect.Value 39 | func MethodByName(name string) reflect.Value 40 | func NumField() int 41 | func NumMethod() int 42 | func OverflowComplex(x complex128) bool 43 | func OverflowFloat(x float64) bool 44 | func OverflowInt(x int64) bool 45 | func OverflowUint(x uint64) bool 46 | func Pointer() uintptr 47 | func Recv() (x reflect.Value, ok bool) 48 | func Send(x reflect.Value) 49 | func Set(x reflect.Value) 50 | func SetBool(x bool) 51 | func SetBytes(x []byte) 52 | func SetCap(n int) 53 | func SetComplex(x complex128) 54 | func SetFloat(x float64) 55 | func SetInt(x int64) 56 | func SetIterKey(iter *reflect.MapIter) 57 | func SetIterValue(iter *reflect.MapIter) 58 | func SetLen(n int) 59 | func SetMapIndex(key reflect.Value, elem reflect.Value) 60 | func SetPointer(x unsafe.Pointer) 61 | func SetString(x string) 62 | func SetUint(x uint64) 63 | func Slice(i int, j int) reflect.Value 64 | func Slice3(i int, j int, k int) reflect.Value 65 | func String() string 66 | func TryRecv() (x reflect.Value, ok bool) 67 | func TrySend(x reflect.Value) bool 68 | func Type() reflect.Type 69 | func Uint() uint64 70 | func UnsafeAddr() uintptr 71 | func UnsafePointer() unsafe.Pointer 72 | -------------------------------------------------------------------------------- /_testing/test.0032/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "archive/tar" 5 | "archive/zip" 6 | "bufio" 7 | "bytes" 8 | "compress/bzip2" 9 | "compress/flate" 10 | "compress/gzip" 11 | "compress/lzw" 12 | "compress/zlib" 13 | "container/heap" 14 | "container/list" 15 | "container/ring" 16 | "crypto" 17 | "crypto/aes" 18 | "crypto/cipher" 19 | "crypto/des" 20 | "crypto/dsa" 21 | "crypto/ecdsa" 22 | "crypto/elliptic" 23 | "crypto/hmac" 24 | "crypto/md5" 25 | "crypto/rand" 26 | "crypto/rc4" 27 | "crypto/rsa" 28 | "crypto/sha1" 29 | "crypto/sha256" 30 | "crypto/sha512" 31 | "crypto/subtle" 32 | "crypto/tls" 33 | "crypto/x509" 34 | "crypto/x509/pkix" 35 | "database/sql" 36 | "database/sql/driver" 37 | "debug/dwarf" 38 | "debug/elf" 39 | "debug/gosym" 40 | "debug/macho" 41 | "debug/pe" 42 | "encoding/ascii85" 43 | "encoding/asn1" 44 | "encoding/base32" 45 | "encoding/base64" 46 | "encoding/binary" 47 | "encoding/csv" 48 | "encoding/gob" 49 | "encoding/hex" 50 | "encoding/json" 51 | "encoding/pem" 52 | "encoding/xml" 53 | "errors" 54 | "expvar" 55 | "flag" 56 | "fmt" 57 | "go/ast" 58 | "go/build" 59 | "go/doc" 60 | "go/parser" 61 | "go/printer" 62 | "go/scanner" 63 | "go/token" 64 | "hash" 65 | "hash/adler32" 66 | "hash/crc32" 67 | "hash/crc64" 68 | "hash/fnv" 69 | "html" 70 | "html/template" 71 | "image" 72 | "image/color" 73 | "image/draw" 74 | "image/gif" 75 | "image/jpeg" 76 | "image/png" 77 | "index/suffixarray" 78 | "io" 79 | "io/ioutil" 80 | "log" 81 | "log/syslog" 82 | "math" 83 | "math/big" 84 | "math/cmplx" 85 | "math/rand" 86 | "mime" 87 | "mime/multipart" 88 | "net" 89 | "net/http" 90 | "net/http/cgi" 91 | "net/http/fcgi" 92 | "net/http/httptest" 93 | "net/http/httputil" 94 | "net/http/pprof" 95 | "net/mail" 96 | "net/rpc" 97 | "net/rpc/jsonrpc" 98 | "net/smtp" 99 | "net/textproto" 100 | "net/url" 101 | "os" 102 | "os/exec" 103 | "os/signal" 104 | "os/user" 105 | "path" 106 | "path/filepath" 107 | "reflect" 108 | "regexp" 109 | "regexp/syntax" 110 | "runtime" 111 | "runtime/cgo" 112 | "runtime/debug" 113 | "runtime/pprof" 114 | "sort" 115 | "strconv" 116 | "strings" 117 | "sync" 118 | "sync/atomic" 119 | "syscall" 120 | "testing" 121 | "testing/iotest" 122 | "testing/quick" 123 | "text/scanner" 124 | "text/tabwriter" 125 | "text/template" 126 | "text/template/parse" 127 | "time" 128 | "unicode" 129 | "unicode/utf16" 130 | "unicode/utf8" 131 | ) 132 | 133 | func main() { 134 | 135 | } 136 | -------------------------------------------------------------------------------- /vim/autoload/gocomplete.vim: -------------------------------------------------------------------------------- 1 | if exists('g:loaded_gocode') 2 | finish 3 | endif 4 | let g:loaded_gocode = 1 5 | 6 | fu! s:gocodeCurrentBuffer() 7 | let buf = getline(1, '$') 8 | if &encoding != 'utf-8' 9 | let buf = map(buf, 'iconv(v:val, &encoding, "utf-8")') 10 | endif 11 | if &l:fileformat == 'dos' 12 | " XXX: line2byte() depend on 'fileformat' option. 13 | " so if fileformat is 'dos', 'buf' must include '\r'. 14 | let buf = map(buf, 'v:val."\r"') 15 | endif 16 | let file = tempname() 17 | call writefile(buf, file) 18 | return file 19 | endf 20 | 21 | let s:vim_system = get(g:, 'gocomplete#system_function', 'system') 22 | 23 | fu! s:system(str, ...) 24 | return call(s:vim_system, [a:str] + a:000) 25 | endf 26 | 27 | fu! s:gocodeShellescape(arg) 28 | try 29 | let ssl_save = &shellslash 30 | set noshellslash 31 | return shellescape(a:arg) 32 | finally 33 | let &shellslash = ssl_save 34 | endtry 35 | endf 36 | 37 | fu! s:gocodeCommand(cmd, preargs, args) 38 | for i in range(0, len(a:args) - 1) 39 | let a:args[i] = s:gocodeShellescape(a:args[i]) 40 | endfor 41 | for i in range(0, len(a:preargs) - 1) 42 | let a:preargs[i] = s:gocodeShellescape(a:preargs[i]) 43 | endfor 44 | let result = s:system(printf('gocode %s %s %s', join(a:preargs), a:cmd, join(a:args))) 45 | if v:shell_error != 0 46 | return "[\"0\", []]" 47 | else 48 | if &encoding != 'utf-8' 49 | let result = iconv(result, 'utf-8', &encoding) 50 | endif 51 | return result 52 | endif 53 | endf 54 | 55 | fu! s:gocodeCurrentBufferOpt(filename) 56 | return '-in=' . a:filename 57 | endf 58 | 59 | fu! s:gocodeCursor() 60 | if &encoding != 'utf-8' 61 | let c = col('.') 62 | let buf = line('.') == 1 ? "" : (join(getline(1, line('.')-1), "\n") . "\n") 63 | let buf .= c == 1 ? "" : getline('.')[:c-2] 64 | return printf('%d', len(iconv(buf, &encoding, "utf-8"))) 65 | endif 66 | return printf('%d', line2byte(line('.')) + (col('.')-2)) 67 | endf 68 | 69 | fu! s:gocodeAutocomplete() 70 | let filename = s:gocodeCurrentBuffer() 71 | let result = s:gocodeCommand('autocomplete', 72 | \ [s:gocodeCurrentBufferOpt(filename), '-f=vim'], 73 | \ [expand('%:p'), s:gocodeCursor()]) 74 | call delete(filename) 75 | return result 76 | endf 77 | 78 | fu! gocomplete#Complete(findstart, base) 79 | "findstart = 1 when we need to get the text length 80 | if a:findstart == 1 81 | execute "silent let g:gocomplete_completions = " . s:gocodeAutocomplete() 82 | return col('.') - g:gocomplete_completions[0] - 1 83 | "findstart = 0 when we need to return the list of completions 84 | else 85 | return g:gocomplete_completions[1] 86 | endif 87 | endf 88 | -------------------------------------------------------------------------------- /nvim/autoload/gocomplete.vim: -------------------------------------------------------------------------------- 1 | if exists('g:loaded_gocode') 2 | finish 3 | endif 4 | let g:loaded_gocode = 1 5 | 6 | fu! s:gocodeCurrentBuffer() 7 | let buf = getline(1, '$') 8 | if &encoding != 'utf-8' 9 | let buf = map(buf, 'iconv(v:val, &encoding, "utf-8")') 10 | endif 11 | if &l:fileformat == 'dos' 12 | " XXX: line2byte() depend on 'fileformat' option. 13 | " so if fileformat is 'dos', 'buf' must include '\r'. 14 | let buf = map(buf, 'v:val."\r"') 15 | endif 16 | let file = tempname() 17 | call writefile(buf, file) 18 | return file 19 | endf 20 | 21 | let s:vim_system = get(g:, 'gocomplete#system_function', 'system') 22 | 23 | fu! s:system(str, ...) 24 | return call(s:vim_system, [a:str] + a:000) 25 | endf 26 | 27 | fu! s:gocodeShellescape(arg) 28 | try 29 | let ssl_save = &shellslash 30 | set noshellslash 31 | return shellescape(a:arg) 32 | finally 33 | let &shellslash = ssl_save 34 | endtry 35 | endf 36 | 37 | fu! s:gocodeCommand(cmd, preargs, args) 38 | for i in range(0, len(a:args) - 1) 39 | let a:args[i] = s:gocodeShellescape(a:args[i]) 40 | endfor 41 | for i in range(0, len(a:preargs) - 1) 42 | let a:preargs[i] = s:gocodeShellescape(a:preargs[i]) 43 | endfor 44 | let result = s:system(printf('gocode %s %s %s', join(a:preargs), a:cmd, join(a:args))) 45 | if v:shell_error != 0 46 | return "[\"0\", []]" 47 | else 48 | if &encoding != 'utf-8' 49 | let result = iconv(result, 'utf-8', &encoding) 50 | endif 51 | return result 52 | endif 53 | endf 54 | 55 | fu! s:gocodeCurrentBufferOpt(filename) 56 | return '-in=' . a:filename 57 | endf 58 | 59 | fu! s:gocodeCursor() 60 | if &encoding != 'utf-8' 61 | let c = col('.') 62 | let buf = line('.') == 1 ? "" : (join(getline(1, line('.')-1), "\n") . "\n") 63 | let buf .= c == 1 ? "" : getline('.')[:c-2] 64 | return printf('%d', len(iconv(buf, &encoding, "utf-8"))) 65 | endif 66 | return printf('%d', line2byte(line('.')) + (col('.')-2)) 67 | endf 68 | 69 | fu! s:gocodeAutocomplete() 70 | let filename = s:gocodeCurrentBuffer() 71 | let result = s:gocodeCommand('autocomplete', 72 | \ [s:gocodeCurrentBufferOpt(filename), '-f=vim'], 73 | \ [expand('%:p'), s:gocodeCursor()]) 74 | call delete(filename) 75 | return result 76 | endf 77 | 78 | fu! gocomplete#Complete(findstart, base) 79 | "findstart = 1 when we need to get the text length 80 | if a:findstart == 1 81 | execute "silent let g:gocomplete_completions = " . s:gocodeAutocomplete() 82 | return col('.') - g:gocomplete_completions[0] - 1 83 | "findstart = 0 when we need to return the list of completions 84 | else 85 | return g:gocomplete_completions[1] 86 | endif 87 | endf 88 | -------------------------------------------------------------------------------- /package_types.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "go/importer" 6 | "go/token" 7 | "go/types" 8 | "io" 9 | "log" 10 | 11 | "github.com/visualfc/gocode/internal/gcexportdata" 12 | pkgwalk "github.com/visualfc/gotools/types" 13 | ) 14 | 15 | type types_parser struct { 16 | pfc *package_file_cache 17 | pkg *types.Package 18 | } 19 | 20 | // func DefaultPkgConfig() *pkgwalk.PkgConfig { 21 | // conf := &pkgwalk.PkgConfig{IgnoreFuncBodies: true, AllowBinary: true, WithTestFiles: false} 22 | // conf.Info = &types.Info{ 23 | // Uses: make(map[*ast.Ident]types.Object), 24 | // Defs: make(map[*ast.Ident]types.Object), 25 | // Selections: make(map[*ast.SelectorExpr]*types.Selection), 26 | // //Types: make(map[ast.Expr]types.TypeAndValue), 27 | // //Scopes : make(map[ast.Node]*types.Scope) 28 | // //Implicits : make(map[ast.Node]types.Object) 29 | // } 30 | // conf.XInfo = &types.Info{ 31 | // Uses: make(map[*ast.Ident]types.Object), 32 | // Defs: make(map[*ast.Ident]types.Object), 33 | // Selections: make(map[*ast.SelectorExpr]*types.Selection), 34 | // } 35 | // return conf 36 | // } 37 | 38 | func (p *types_parser) initSource(import_path string, path string, dir string, pfc *package_file_cache, c *auto_complete_context) { 39 | //conf := &pkgwalk.PkgConfig{IgnoreFuncBodies: true, AllowBinary: false, WithTestFiles: true} 40 | // conf.Info = &types.Info{} 41 | // conf.XInfo = &types.Info{} 42 | c.mutex.Lock() 43 | defer c.mutex.Unlock() 44 | conf := pkgwalk.DefaultPkgConfig() 45 | pkg, _, err := c.typesWalker.ImportHelper(".", path, import_path, conf, nil) 46 | if err != nil { 47 | log.Println(err) 48 | } 49 | p.pkg = pkg 50 | // im := srcimporter.New(&build.Default, c.fset, c.packages) 51 | // if dir != "" { 52 | // p.pkg, _ = im.ImportFrom(path, dir, 0) 53 | // } else { 54 | // p.pkg, _ = im.Import(path) 55 | // } 56 | p.pfc = pfc 57 | } 58 | 59 | func (p *types_parser) initData(path string, data []byte, pfc *package_file_cache, c *auto_complete_context) { 60 | p.pkg, _ = importer.For("gc", func(path string) (io.ReadCloser, error) { 61 | return NewMemReadClose(data), nil 62 | }).Import(path) 63 | p.pfc = pfc 64 | if p.pkg != nil { 65 | c.typesWalker.Imported[p.pkg.Path()] = p.pkg 66 | } 67 | } 68 | 69 | type MemReadClose struct { 70 | *bytes.Buffer 71 | } 72 | 73 | func (m *MemReadClose) Close() error { 74 | return nil 75 | } 76 | 77 | func NewMemReadClose(data []byte) *MemReadClose { 78 | return &MemReadClose{bytes.NewBuffer(data)} 79 | } 80 | 81 | func (p *types_parser) exportData() []byte { 82 | if p.pkg == nil { 83 | return nil 84 | } 85 | fset := token.NewFileSet() 86 | var buf bytes.Buffer 87 | gcexportdata.Write(&buf, fset, p.pkg) 88 | return buf.Bytes() 89 | } 90 | -------------------------------------------------------------------------------- /gocode.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "log" 7 | "net/http" 8 | _ "net/http/pprof" 9 | "os" 10 | "path/filepath" 11 | ) 12 | 13 | var ( 14 | g_is_server = flag.Bool("s", false, "run a server instead of a client") 15 | g_format = flag.String("f", "nice", "output format (vim | emacs | nice | csv | csv-with-package | json)") 16 | g_input = flag.String("in", "", "use this file instead of stdin input") 17 | g_sock = create_sock_flag("sock", "socket type (unix | tcp)") 18 | g_addr = flag.String("addr", "127.0.0.1:37372", "address for tcp socket") 19 | g_debug = flag.Bool("debug", false, "enable server-side debug mode") 20 | g_profile = flag.Int("profile", 0, "port on which to expose profiling information for pprof; 0 to disable profiling") 21 | g_daemon_name = flag.String("daemon", "gocode-daemon-liteide", "unix socket daemon prefix name") 22 | ) 23 | 24 | func get_socket_filename() string { 25 | user := os.Getenv("USER") 26 | if user == "" { 27 | user = "all" 28 | } 29 | return filepath.Join(os.TempDir(), fmt.Sprintf("%s.%s", *g_daemon_name, user)) 30 | } 31 | 32 | func show_usage() { 33 | fmt.Fprintf(os.Stderr, 34 | "Usage: %s [-s] [-f=] [-in=] [-sock=] [-addr=]\n"+ 35 | " []\n\n", 36 | os.Args[0]) 37 | fmt.Fprintf(os.Stderr, 38 | "Flags:\n") 39 | flag.PrintDefaults() 40 | fmt.Fprintf(os.Stderr, 41 | "\nCommands:\n"+ 42 | " autocomplete [] main autocompletion command\n"+ 43 | " close close the gocode daemon\n"+ 44 | " drop-cache drop gocode daemon's cache\n"+ 45 | " options list config options (extended)\n"+ 46 | " set [ []] list or set config options\n"+ 47 | " status gocode daemon status report\n"+ 48 | "") 49 | } 50 | 51 | func main() { 52 | flag.Usage = show_usage 53 | flag.Parse() 54 | 55 | var retval int 56 | if *g_is_server { 57 | go func() { 58 | if *g_profile <= 0 { 59 | return 60 | } 61 | addr := fmt.Sprintf("localhost:%d", *g_profile) 62 | // Use the following commands to profile the binary: 63 | // go tool pprof http://localhost:6060/debug/pprof/profile # 30-second CPU profile 64 | // go tool pprof http://localhost:6060/debug/pprof/heap # heap profile 65 | // go tool pprof http://localhost:6060/debug/pprof/block # goroutine blocking profile 66 | // See http://blog.golang.org/profiling-go-programs for more info. 67 | log.Printf("enabling profiler on %s", addr) 68 | log.Print(http.ListenAndServe(addr, nil)) 69 | }() 70 | retval = do_server() 71 | } else { 72 | retval = do_client() 73 | } 74 | os.Exit(retval) 75 | } 76 | -------------------------------------------------------------------------------- /_testing/test.0032/out.expected: -------------------------------------------------------------------------------- 1 | Found 124 candidates: 2 | func main() 3 | package adler32 4 | package aes 5 | package ascii85 6 | package asn1 7 | package ast 8 | package atomic 9 | package base32 10 | package base64 11 | package big 12 | package binary 13 | package bufio 14 | package build 15 | package bytes 16 | package bzip2 17 | package cgi 18 | package cgo 19 | package cipher 20 | package cmplx 21 | package color 22 | package crc32 23 | package crc64 24 | package crypto 25 | package csv 26 | package debug 27 | package des 28 | package doc 29 | package draw 30 | package driver 31 | package dsa 32 | package dwarf 33 | package ecdsa 34 | package elf 35 | package elliptic 36 | package errors 37 | package exec 38 | package expvar 39 | package fcgi 40 | package filepath 41 | package flag 42 | package flate 43 | package fmt 44 | package fnv 45 | package gif 46 | package gob 47 | package gosym 48 | package gzip 49 | package hash 50 | package heap 51 | package hex 52 | package hmac 53 | package html 54 | package http 55 | package httptest 56 | package httputil 57 | package image 58 | package io 59 | package iotest 60 | package ioutil 61 | package jpeg 62 | package json 63 | package jsonrpc 64 | package list 65 | package log 66 | package lzw 67 | package macho 68 | package mail 69 | package math 70 | package md5 71 | package mime 72 | package multipart 73 | package net 74 | package os 75 | package parse 76 | package parser 77 | package path 78 | package pe 79 | package pem 80 | package pkix 81 | package png 82 | package pprof 83 | package printer 84 | package quick 85 | package rand 86 | package rc4 87 | package reflect 88 | package regexp 89 | package ring 90 | package rpc 91 | package rsa 92 | package runtime 93 | package scanner 94 | package sha1 95 | package sha256 96 | package sha512 97 | package signal 98 | package smtp 99 | package sort 100 | package sql 101 | package strconv 102 | package strings 103 | package subtle 104 | package suffixarray 105 | package sync 106 | package syntax 107 | package syscall 108 | package syslog 109 | package tabwriter 110 | package tar 111 | package template 112 | package testing 113 | package textproto 114 | package time 115 | package tls 116 | package token 117 | package unicode 118 | package url 119 | package user 120 | package utf16 121 | package utf8 122 | package x509 123 | package xml 124 | package zip 125 | package zlib 126 | -------------------------------------------------------------------------------- /internal/gcexportdata/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 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 | // +build ignore 6 | 7 | // The gcexportdata command is a diagnostic tool that displays the 8 | // contents of gc export data files. 9 | package main 10 | 11 | import ( 12 | "flag" 13 | "fmt" 14 | "go/token" 15 | "go/types" 16 | "log" 17 | "os" 18 | 19 | "golang.org/x/tools/go/gcexportdata" 20 | "golang.org/x/tools/go/types/typeutil" 21 | ) 22 | 23 | var packageFlag = flag.String("package", "", "alternative package to print") 24 | 25 | func main() { 26 | log.SetPrefix("gcexportdata: ") 27 | log.SetFlags(0) 28 | flag.Usage = func() { 29 | fmt.Fprintln(os.Stderr, "usage: gcexportdata [-package path] file.a") 30 | } 31 | flag.Parse() 32 | if flag.NArg() != 1 { 33 | flag.Usage() 34 | os.Exit(2) 35 | } 36 | filename := flag.Args()[0] 37 | 38 | f, err := os.Open(filename) 39 | if err != nil { 40 | log.Fatal(err) 41 | } 42 | 43 | r, err := gcexportdata.NewReader(f) 44 | if err != nil { 45 | log.Fatalf("%s: %s", filename, err) 46 | } 47 | 48 | // Decode the package. 49 | const primary = "" 50 | imports := make(map[string]*types.Package) 51 | fset := token.NewFileSet() 52 | pkg, err := gcexportdata.Read(r, fset, imports, primary) 53 | if err != nil { 54 | log.Fatalf("%s: %s", filename, err) 55 | } 56 | 57 | // Optionally select an indirectly mentioned package. 58 | if *packageFlag != "" { 59 | pkg = imports[*packageFlag] 60 | if pkg == nil { 61 | fmt.Fprintf(os.Stderr, "export data file %s does not mention %s; has:\n", 62 | filename, *packageFlag) 63 | for p := range imports { 64 | if p != primary { 65 | fmt.Fprintf(os.Stderr, "\t%s\n", p) 66 | } 67 | } 68 | os.Exit(1) 69 | } 70 | } 71 | 72 | // Print all package-level declarations, including non-exported ones. 73 | fmt.Printf("package %s\n", pkg.Name()) 74 | for _, imp := range pkg.Imports() { 75 | fmt.Printf("import %q\n", imp.Path()) 76 | } 77 | qual := func(p *types.Package) string { 78 | if pkg == p { 79 | return "" 80 | } 81 | return p.Name() 82 | } 83 | scope := pkg.Scope() 84 | for _, name := range scope.Names() { 85 | obj := scope.Lookup(name) 86 | fmt.Printf("%s: %s\n", 87 | fset.Position(obj.Pos()), 88 | types.ObjectString(obj, qual)) 89 | 90 | // For types, print each method. 91 | if _, ok := obj.(*types.TypeName); ok { 92 | for _, method := range typeutil.IntuitiveMethodSet(obj.Type(), nil) { 93 | fmt.Printf("%s: %s\n", 94 | fset.Position(method.Obj().Pos()), 95 | types.SelectionString(method, qual)) 96 | } 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /internal/gcimporter/exportdata.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 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 | // This file is a copy of $GOROOT/src/go/internal/gcimporter/exportdata.go. 6 | 7 | // This file implements FindExportData. 8 | 9 | package gcimporter 10 | 11 | import ( 12 | "bufio" 13 | "fmt" 14 | "io" 15 | "strconv" 16 | "strings" 17 | ) 18 | 19 | func readGopackHeader(r *bufio.Reader) (name string, size int, err error) { 20 | // See $GOROOT/include/ar.h. 21 | hdr := make([]byte, 16+12+6+6+8+10+2) 22 | _, err = io.ReadFull(r, hdr) 23 | if err != nil { 24 | return 25 | } 26 | // leave for debugging 27 | if false { 28 | fmt.Printf("header: %s", hdr) 29 | } 30 | s := strings.TrimSpace(string(hdr[16+12+6+6+8:][:10])) 31 | size, err = strconv.Atoi(s) 32 | if err != nil || hdr[len(hdr)-2] != '`' || hdr[len(hdr)-1] != '\n' { 33 | err = fmt.Errorf("invalid archive header") 34 | return 35 | } 36 | name = strings.TrimSpace(string(hdr[:16])) 37 | return 38 | } 39 | 40 | // FindExportData positions the reader r at the beginning of the 41 | // export data section of an underlying GC-created object/archive 42 | // file by reading from it. The reader must be positioned at the 43 | // start of the file before calling this function. The hdr result 44 | // is the string before the export data, either "$$" or "$$B". 45 | // 46 | func FindExportData(r *bufio.Reader) (hdr string, err error) { 47 | // Read first line to make sure this is an object file. 48 | line, err := r.ReadSlice('\n') 49 | if err != nil { 50 | err = fmt.Errorf("can't find export data (%v)", err) 51 | return 52 | } 53 | 54 | if string(line) == "!\n" { 55 | // Archive file. Scan to __.PKGDEF. 56 | var name string 57 | if name, _, err = readGopackHeader(r); err != nil { 58 | return 59 | } 60 | 61 | // First entry should be __.PKGDEF. 62 | if name != "__.PKGDEF" { 63 | err = fmt.Errorf("go archive is missing __.PKGDEF") 64 | return 65 | } 66 | 67 | // Read first line of __.PKGDEF data, so that line 68 | // is once again the first line of the input. 69 | if line, err = r.ReadSlice('\n'); err != nil { 70 | err = fmt.Errorf("can't find export data (%v)", err) 71 | return 72 | } 73 | } 74 | 75 | // Now at __.PKGDEF in archive or still at beginning of file. 76 | // Either way, line should begin with "go object ". 77 | if !strings.HasPrefix(string(line), "go object ") { 78 | err = fmt.Errorf("not a Go object file") 79 | return 80 | } 81 | 82 | // Skip over object header to export data. 83 | // Begins after first line starting with $$. 84 | for line[0] != '$' { 85 | if line, err = r.ReadSlice('\n'); err != nil { 86 | err = fmt.Errorf("can't find export data (%v)", err) 87 | return 88 | } 89 | } 90 | hdr = string(line) 91 | 92 | return 93 | } 94 | -------------------------------------------------------------------------------- /_testing/DESC: -------------------------------------------------------------------------------- 1 | test.0001 - basic package import (fmt) 2 | test.0002 - range statement over map variable 3 | test.0003 - type switch statement valid type case 4 | test.0004 - type switch statement default type case 5 | test.0005 - multifile package test, type inference 6 | test.0006 - multifile package test, methods 7 | test.0007 - class selector on packages (var) 8 | test.0008 - variable with anonymous type + type embedding 9 | test.0009 - same as test.0008, but more deeply 10 | test.0010 - type assertion (to *ast.ValueSpec) 11 | test.0011 - *reflect.StructValue, unexported type embedding 12 | test.0012 - type advancing, file with no import statements 13 | test.0013 - binary operators 14 | test.0014 - address of and pointer dereferences 15 | test.0015 - unary operators 16 | test.0016 - for and if else statements 17 | test.0017 - simple functions before and after cursor 18 | test.0018 - complex type inference case 19 | test.0019 - map[string]something.# case 20 | test.0020 - embedded types, method overloading (sort of) 21 | test.0021 - SelectorExpr case, uses package local scope 22 | test.0022 - range loop, but iteratable is returned by a function 23 | test.0023 - simple check for unicode awareness 24 | test.0024 - variable and the type with the same name 25 | test.0025 - built-in package "unsafe" 26 | test.0026 - more anonymous structs 27 | test.0027 - function specific variables scope issues (recv, args, results) 28 | test.0028 - the reason why I need to implement binary ops 29 | test.0029 - import to the current package scope (import . "whatever") 30 | test.0030 - typedef struct type and try to use its fields 31 | test.0031 - simple test for select clause 32 | test.0032 - import all packages (tests package parser) 33 | test.0033 - varargs type as a slice type in different contexts 34 | test.0034 - interface with methods imported from another package 35 | test.0035 - built-in "error" interface 36 | test.0036 - embedded struct in a package as an ordinary field 37 | test.0037 - slice expressions 38 | test.0038 - if init declaration inside else stmt 39 | test.0039 - addition to test 38, make sure decl doesn't leak 40 | test.0040 - anonymous return values shouldn't introduce new vars 41 | test.0041 - nested struct initialization expressions (outer) 42 | test.0042 - nested struct initialization expressions (inner) 43 | test.0043 - sequential struct initialization expressions 44 | test.0044 - struct initialization expression only suggests var names (no functions) 45 | test.0045 - if statement 46 | test.0046 - ":=" statement 47 | test.0047 - completion on struct with undefined embedded type 48 | test.0048 - completion with cursor in the middle of existing token 49 | test.0049 - anonymous struct type as a function argument 50 | test.0050 - anonymous struct pointer type as a function argument 51 | test.0051 - go parser stops parsing after 10 errors without AllErrors flag 52 | test.0052 - implicit type of a struct within slice/array literal 53 | test.0053 - type redefinition should not inherit method sets 54 | test.0054 - type alias dealiasing 55 | test.0055 - type alias inference 56 | test.0056 - type alias method propagation 57 | test.0057 - embedded interfaces 58 | test.0058 - canonical import aliases 59 | test.0059 - canonical import aliases, more complicated case (doesn't work as you might expect) 60 | test.0060 - shortcut syntax for return value types in functions 61 | test.0061 - function body vs struct literal cursor context detection 62 | test.0062 - struct type alias embedding 63 | test.0063 - fields autocompletion for a struct literal which is defined by a type alias 64 | -------------------------------------------------------------------------------- /docs/IDE_integration.md: -------------------------------------------------------------------------------- 1 | 2 | # IDE Integration Guide # 3 | 4 | This guide should help programmers to develop Go lang plugins for IDEs and editors. It documents command arguments and output formats, and also mentions common pitfails. Note that gocode is not intended to be used from command-line by human. 5 | 6 | ## Code Completion Assistance ## 7 | 8 | Gocode proposes completion depending on current scope and context. Currently some obvious features are missed: 9 | * No keywords completion (no context-sensitive neither absolute) 10 | * No package names completion 11 | * No completion proposal priority 12 | * Information about context not passed to output, i.e. gocode does not report if you've typed `st.` or `fn(` 13 | 14 | Also keep in mind following things: 15 | * Editor keeps unsaved file copy in memory, so you should pass file content via stdin, or mirror it to temporary file and use `-in=*` parameter. Gocode does not support more than one unsaved file. 16 | * You should also pass full path (relative or absolute) to target file as parameter, otherwise completion will be incomplete because other files from the same package will not be resolved. 17 | * If coder started to type identifier like `Pr`, gocode will produce completions `Printf`, `Produce`, etc. In other words, completion contains identifier prefix and is already filtered. Filtering uses case-sensitive comparison if possible, and fallbacks to case-insensitive comparison. 18 | * If you want to see built-in identifiers like `uint32`, `error`, etc, you can call `gocode set propose-builtins yes` once. 19 | 20 | Use autocomplete command to produce completion assistance for particular position at file: 21 | ```bash 22 | # Read source from file and show completions for character at offset 449 from beginning 23 | gocode -f=json --in=server.go autocomplete 449 24 | # Read source from stdin (more suitable for editor since it keeps unsaved file copy in memory) 25 | gocode -f=json autocomplete 449 26 | # You can also pass target file path along with position, it's used to find other files from the same package 27 | gocode -f=json autocomplete server.go 889 28 | # By default gocode interprets offset as bytes offset, but 'c' or 'C' prefix means that offset is unicode code points offset 29 | gocode -f=json autocomplete server.go c619 30 | ``` 31 | 32 | ## Server-side Debug Mode ## 33 | 34 | There is a special server-side debug mode available in order to help developers with gocode integration. Invoke the gocode's server manually passing the following arguments: 35 | ```bash 36 | # make sure gocode server isn't running 37 | gocode close 38 | # -s for "server" 39 | # -debug for special server-side debug mode 40 | gocode -s -debug 41 | ``` 42 | 43 | After that when your editor sends autocompletion requests, the server will print some information about them to the stdout, for example: 44 | ``` 45 | Got autocompletion request for '/home/nsf/tmp/gobug/main.go' 46 | Cursor at: 52 47 | ------------------------------------------------------- 48 | package main 49 | 50 | import "bytes" 51 | 52 | func main() { 53 | bytes.F# 54 | } 55 | ------------------------------------------------------- 56 | Offset: 1 57 | Number of candidates found: 2 58 | Candidates are: 59 | func Fields(s []byte) [][]byte 60 | func FieldsFunc(s []byte, f func(rune) bool) [][]byte 61 | ======================================================= 62 | ``` 63 | 64 | Note that '#' symbol is inserted at the cursor location as gocode sees it. This debug mode is useful when you need to make sure your editor sends the right position in all cases. Keep in mind that Go source files are UTF-8 files, try inserting non-english comments before the completion location to check if everything works properly. 65 | 66 | [Output formats reference.](autocomplete_formats.md) 67 | -------------------------------------------------------------------------------- /subl3/syntax/GoSublime-Template.tmLanguage.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GoSublime: Template", 3 | "uuid": "43606de8-c638-11e2-b661-6711676f99ca", 4 | "scopeName": "source.gotemplate", 5 | 6 | "foldingStartMarker": "\\{\\{\\s*(?:if|with|range)\\b", 7 | "foldingStopMarker": "\\{\\{\\s*(?:else|end)\\b", 8 | 9 | "patterns": [ 10 | { 11 | "begin": "\\{\\{", 12 | "beginCaptures": { 13 | "0": { 14 | "name": "punctuation.section.embedded.begin.gotemplate" 15 | } 16 | }, 17 | 18 | "end": "\\}\\}", 19 | "endCaptures": { 20 | "0": { 21 | "name": "punctuation.section.embedded.end.gotemplate" 22 | } 23 | }, 24 | 25 | "patterns": [ 26 | { 27 | "match": ":=", 28 | "name": "keyword.operator.initialize.gotemplate" 29 | }, 30 | { 31 | "match": "\\|", 32 | "name": "keyword.operator.pipe.gotemplate" 33 | }, 34 | { 35 | "match": "[.$][\\w]*", 36 | "name": "variable.other.gotemplate" 37 | }, 38 | { 39 | "match": "\\b(if|else|range|template|with|end|nil|with|define)\\b", 40 | "name": "keyword.control.gotemplate" 41 | }, 42 | { 43 | "match": "\\b(and|call|html|index|js|len|not|or|print|printf|println|urlquery|eq|ne|lt|le|gt|ge)\\b", 44 | "name": "support.function.builtin.gotemplate" 45 | }, 46 | { 47 | "begin": "/\\*", 48 | "end": "\\*/", 49 | "name": "comment.block.gotemplate" 50 | }, 51 | { 52 | "begin": "\"", 53 | "beginCaptures": { 54 | "0": { 55 | "name": "punctuation.definition.string.begin.gotemplate" 56 | } 57 | }, 58 | "end": "\"", 59 | "endCaptures": { 60 | "0": { 61 | "name": "punctuation.definition.string.end.gotemplate" 62 | } 63 | }, 64 | "name": "string.quoted.double.gotemplate", 65 | "patterns": [ 66 | { 67 | "include": "#string_placeholder" 68 | }, 69 | { 70 | "include": "#string_escaped_char" 71 | } 72 | ] 73 | }, 74 | { 75 | "begin": "`", 76 | "beginCaptures": { 77 | "0": { 78 | "name": "punctuation.definition.string.begin.gotemplate" 79 | } 80 | }, 81 | "end": "`", 82 | "endCaptures": { 83 | "0": { 84 | "name": "punctuation.definition.string.end.gotemplate" 85 | } 86 | }, 87 | "name": "string.quoted.raw.gotemplate", 88 | "patterns": [ 89 | { 90 | "include": "#string_placeholder" 91 | } 92 | ] 93 | } 94 | ], 95 | } 96 | ], 97 | "repository": { 98 | "string_escaped_char": { 99 | "patterns": [ 100 | { 101 | // note: keep this in sync with constant.other.rune.go 102 | "match": "\\\\(\\\\|[abfnrtv'\"]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}|[0-7]{3})", 103 | "name": "constant.character.escape.gotemplate" 104 | }, 105 | { 106 | "match": "\\\\.", 107 | "name": "invalid.illegal.unknown-escape.gotemplate" 108 | } 109 | ] 110 | }, 111 | "string_placeholder": { 112 | "patterns": [ 113 | { 114 | "match": "(?x)%\n (\\d+\\$)? # field (argument #)\n [#0\\- +']* # flags\n [,;:_]? # separator character (AltiVec)\n ((-?\\d+)|\\*(-?\\d+\\$)?)? # minimum field width\n (\\.((-?\\d+)|\\*(-?\\d+\\$)?)?)? # precision\n [diouxXDOUeEfFgGaAcCsSqpnvtTbyYhHmMzZ%] # conversion type\n ", 115 | "name": "constant.other.placeholder.gotemplate" 116 | }, 117 | { 118 | "match": "%", 119 | "name": "invalid.illegal.placeholder.gotemplate" 120 | } 121 | ] 122 | } 123 | }, 124 | } 125 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 2 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 3 | github.com/visualfc/gomod v0.1.2 h1:7qfPmifcA8r/0ZTpTPZQqsm5aJUiQ/EeyHEENPyywDg= 4 | github.com/visualfc/gomod v0.1.2/go.mod h1:rV5goiA/Ul6yT8X2eDnc/dl0dVy0cDHJLZVOuJ8PdmM= 5 | github.com/visualfc/gotools v1.5.3 h1:22TyNM6i+/psP07vjveWy6PhhMGNtwWEbDL8PrW4jms= 6 | github.com/visualfc/gotools v1.5.3/go.mod h1:VlP59ccCsSmRbFZTbuHgQDrTOi40EGKvyFK2Cq2Far8= 7 | github.com/visualfc/goversion v1.1.0/go.mod h1:Gr3s6bW8NTomhheImwAttqno97Mw6pAnFn2dU8/EMa8= 8 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= 9 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 10 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 11 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= 12 | golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= 13 | golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 14 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 15 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 16 | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 17 | golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= 18 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 19 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 20 | golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= 21 | golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 22 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 23 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 24 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 25 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 26 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 27 | golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= 28 | golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 29 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 30 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 31 | golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= 32 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 33 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 34 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 35 | golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 36 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 37 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 38 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= 39 | golang.org/x/tools v0.5.0 h1:+bSpV5HIeWkuvgaMfI3UmKRThoTA5ODJTUd8T17NO+4= 40 | golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= 41 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 42 | -------------------------------------------------------------------------------- /internal/gcexportdata/example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 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 | // +build go1.7 6 | // +build gc 7 | 8 | package gcexportdata_test 9 | 10 | import ( 11 | "fmt" 12 | "go/ast" 13 | "go/parser" 14 | "go/token" 15 | "go/types" 16 | "log" 17 | "os" 18 | "path/filepath" 19 | 20 | "golang.org/x/tools/go/gcexportdata" 21 | ) 22 | 23 | // ExampleRead uses gcexportdata.Read to load type information for the 24 | // "fmt" package from the fmt.a file produced by the gc compiler. 25 | func ExampleRead() { 26 | // Find the export data file. 27 | filename, path := gcexportdata.Find("fmt", "") 28 | if filename == "" { 29 | log.Fatalf("can't find export data for fmt") 30 | } 31 | fmt.Printf("Package path: %s\n", path) 32 | fmt.Printf("Export data: %s\n", filepath.Base(filename)) 33 | 34 | // Open and read the file. 35 | f, err := os.Open(filename) 36 | if err != nil { 37 | log.Fatal(err) 38 | } 39 | defer f.Close() 40 | r, err := gcexportdata.NewReader(f) 41 | if err != nil { 42 | log.Fatalf("reading export data %s: %v", filename, err) 43 | } 44 | 45 | // Decode the export data. 46 | fset := token.NewFileSet() 47 | imports := make(map[string]*types.Package) 48 | pkg, err := gcexportdata.Read(r, fset, imports, path) 49 | if err != nil { 50 | log.Fatal(err) 51 | } 52 | 53 | // Print package information. 54 | members := pkg.Scope().Names() 55 | if members[0] == ".inittask" { 56 | // An improvement to init handling in 1.13 added ".inittask". Remove so go >= 1.13 and go < 1.13 both pass. 57 | members = members[1:] 58 | } 59 | fmt.Printf("Package members: %s...\n", members[:5]) 60 | println := pkg.Scope().Lookup("Println") 61 | posn := fset.Position(println.Pos()) 62 | posn.Line = 123 // make example deterministic 63 | fmt.Printf("Println type: %s\n", println.Type()) 64 | fmt.Printf("Println location: %s\n", slashify(posn)) 65 | 66 | // Output: 67 | // 68 | // Package path: fmt 69 | // Export data: fmt.a 70 | // Package members: [Errorf Formatter Fprint Fprintf Fprintln]... 71 | // Println type: func(a ...interface{}) (n int, err error) 72 | // Println location: $GOROOT/src/fmt/print.go:123:1 73 | } 74 | 75 | // ExampleNewImporter demonstrates usage of NewImporter to provide type 76 | // information for dependencies when type-checking Go source code. 77 | func ExampleNewImporter() { 78 | const src = `package myrpc 79 | 80 | // choosing a package that doesn't change across releases 81 | import "net/rpc" 82 | 83 | const serverError rpc.ServerError = "" 84 | ` 85 | fset := token.NewFileSet() 86 | f, err := parser.ParseFile(fset, "myrpc.go", src, 0) 87 | if err != nil { 88 | log.Fatal(err) 89 | } 90 | 91 | packages := make(map[string]*types.Package) 92 | imp := gcexportdata.NewImporter(fset, packages) 93 | conf := types.Config{Importer: imp} 94 | pkg, err := conf.Check("myrpc", fset, []*ast.File{f}, nil) 95 | if err != nil { 96 | log.Fatal(err) 97 | } 98 | 99 | // object from imported package 100 | pi := packages["net/rpc"].Scope().Lookup("ServerError") 101 | fmt.Printf("type %s.%s %s // %s\n", 102 | pi.Pkg().Path(), 103 | pi.Name(), 104 | pi.Type().Underlying(), 105 | slashify(fset.Position(pi.Pos())), 106 | ) 107 | 108 | // object in source package 109 | twopi := pkg.Scope().Lookup("serverError") 110 | fmt.Printf("const %s %s = %s // %s\n", 111 | twopi.Name(), 112 | twopi.Type(), 113 | twopi.(*types.Const).Val(), 114 | slashify(fset.Position(twopi.Pos())), 115 | ) 116 | 117 | // Output: 118 | // 119 | // type net/rpc.ServerError string // $GOROOT/src/net/rpc/client.go:20:1 120 | // const serverError net/rpc.ServerError = "" // myrpc.go:6:7 121 | } 122 | 123 | func slashify(posn token.Position) token.Position { 124 | posn.Filename = filepath.ToSlash(posn.Filename) // for MS Windows portability 125 | return posn 126 | } 127 | -------------------------------------------------------------------------------- /ripper.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "go/scanner" 5 | "go/token" 6 | ) 7 | 8 | // All the code in this file serves single purpose: 9 | // It separates a function with the cursor inside and the rest of the code. I'm 10 | // doing that, because sometimes parser is not able to recover itself from an 11 | // error and the autocompletion results become less complete. 12 | 13 | type tok_pos_pair struct { 14 | tok token.Token 15 | pos token.Pos 16 | } 17 | 18 | type tok_collection struct { 19 | tokens []tok_pos_pair 20 | fset *token.FileSet 21 | toplevel token.Token 22 | } 23 | 24 | func (this *tok_collection) next(s *scanner.Scanner) bool { 25 | pos, tok, _ := s.Scan() 26 | if tok == token.EOF { 27 | return false 28 | } 29 | 30 | this.tokens = append(this.tokens, tok_pos_pair{tok, pos}) 31 | return true 32 | } 33 | 34 | func (this *tok_collection) find_decl_beg(pos int) int { 35 | lowest := 0 36 | lowpos := -1 37 | lowi := -1 38 | cur := 0 39 | for i := pos; i >= 0; i-- { 40 | t := this.tokens[i] 41 | switch t.tok { 42 | case token.RBRACE: 43 | cur++ 44 | case token.LBRACE: 45 | cur-- 46 | } 47 | 48 | if cur < lowest { 49 | lowest = cur 50 | lowpos = this.fset.Position(t.pos).Offset 51 | lowi = i 52 | } 53 | } 54 | cur = lowest 55 | var findvar bool 56 | for i := lowi - 1; i >= 0; i-- { 57 | t := this.tokens[i] 58 | switch t.tok { 59 | case token.RBRACE: 60 | cur++ 61 | case token.LBRACE: 62 | cur-- 63 | case token.VAR: 64 | findvar = true 65 | } 66 | if t.tok == token.SEMICOLON && cur == lowest { 67 | lowpos = this.fset.Position(t.pos).Offset 68 | //var (\n jsData = `{ }`\n file2 *File = func() *File { 69 | if this.toplevel == token.VAR && !findvar { 70 | next := lowest 71 | for j := i - 1; j >= 0; j-- { 72 | jt := this.tokens[j] 73 | switch jt.tok { 74 | case token.RBRACE: 75 | next++ 76 | case token.LBRACE: 77 | next-- 78 | case token.VAR: 79 | findvar = true 80 | } 81 | if jt.tok == token.SEMICOLON && next == lowest && findvar { 82 | lowpos = this.fset.Position(jt.pos).Offset 83 | break 84 | } 85 | } 86 | } 87 | break 88 | } 89 | } 90 | return lowpos 91 | } 92 | 93 | func (this *tok_collection) find_decl_end(pos int) int { 94 | highest := 0 95 | highpos := -1 96 | cur := 0 97 | 98 | if this.tokens[pos].tok == token.LBRACE { 99 | pos++ 100 | } 101 | 102 | for i := pos; i < len(this.tokens); i++ { 103 | t := this.tokens[i] 104 | switch t.tok { 105 | case token.RBRACE: 106 | cur++ 107 | case token.LBRACE: 108 | cur-- 109 | } 110 | 111 | if cur > highest { 112 | highest = cur 113 | highpos = this.fset.Position(t.pos).Offset 114 | } 115 | } 116 | 117 | return highpos 118 | } 119 | 120 | func (this *tok_collection) find_outermost_scope(cursor int) (int, int) { 121 | pos := 0 122 | 123 | for i, t := range this.tokens { 124 | if cursor <= this.fset.Position(t.pos).Offset { 125 | break 126 | } 127 | pos = i 128 | } 129 | 130 | return this.find_decl_beg(pos), this.find_decl_end(pos) 131 | } 132 | 133 | // return new cursor position, file without ripped part and the ripped part itself 134 | // variants: 135 | // new-cursor, file-without-ripped-part, ripped-part 136 | // old-cursor, file, nil 137 | func (this *tok_collection) rip_off_decl(file []byte, cursor int) (int, []byte, []byte) { 138 | this.fset = token.NewFileSet() 139 | var s scanner.Scanner 140 | s.Init(this.fset.AddFile("", this.fset.Base(), len(file)), file, nil, scanner.ScanComments) 141 | for this.next(&s) { 142 | } 143 | beg, end := this.find_outermost_scope(cursor) 144 | if beg == -1 || end == -1 { 145 | return cursor, file, nil 146 | } 147 | 148 | ripped := make([]byte, end+1-beg) 149 | copy(ripped, file[beg:end+1]) 150 | 151 | newfile := make([]byte, len(file)-len(ripped)) 152 | copy(newfile, file[:beg]) 153 | copy(newfile[beg:], file[end+1:]) 154 | 155 | return cursor - beg, newfile, ripped 156 | } 157 | 158 | func rip_off_decl(file []byte, cursor int, topLevelTok token.Token) (int, []byte, []byte) { 159 | var tc tok_collection 160 | tc.toplevel = topLevelTok 161 | return tc.rip_off_decl(file, cursor) 162 | } 163 | -------------------------------------------------------------------------------- /subl3/gocode.py: -------------------------------------------------------------------------------- 1 | import sublime, sublime_plugin, subprocess, difflib 2 | 3 | # go to balanced pair, e.g.: 4 | # ((abc(def))) 5 | # ^ 6 | # \--------->^ 7 | # 8 | # returns -1 on failure 9 | def skip_to_balanced_pair(str, i, open, close): 10 | count = 1 11 | i += 1 12 | while i < len(str): 13 | if str[i] == open: 14 | count += 1 15 | elif str[i] == close: 16 | count -= 1 17 | 18 | if count == 0: 19 | break 20 | i += 1 21 | if i >= len(str): 22 | return -1 23 | return i 24 | 25 | # split balanced parens string using comma as separator 26 | # e.g.: "ab, (1, 2), cd" -> ["ab", "(1, 2)", "cd"] 27 | # filters out empty strings 28 | def split_balanced(s): 29 | out = [] 30 | i = 0 31 | beg = 0 32 | while i < len(s): 33 | if s[i] == ',': 34 | out.append(s[beg:i].strip()) 35 | beg = i+1 36 | i += 1 37 | elif s[i] == '(': 38 | i = skip_to_balanced_pair(s, i, "(", ")") 39 | if i == -1: 40 | i = len(s) 41 | else: 42 | i += 1 43 | 44 | out.append(s[beg:i].strip()) 45 | return list(filter(bool, out)) 46 | 47 | 48 | def extract_arguments_and_returns(sig): 49 | sig = sig.strip() 50 | if not sig.startswith("func"): 51 | return [], [] 52 | 53 | # find first pair of parens, these are arguments 54 | beg = sig.find("(") 55 | if beg == -1: 56 | return [], [] 57 | end = skip_to_balanced_pair(sig, beg, "(", ")") 58 | if end == -1: 59 | return [], [] 60 | args = split_balanced(sig[beg+1:end]) 61 | 62 | # find the rest of the string, these are returns 63 | sig = sig[end+1:].strip() 64 | sig = sig[1:-1] if sig.startswith("(") and sig.endswith(")") else sig 65 | returns = split_balanced(sig) 66 | 67 | return args, returns 68 | 69 | # takes gocode's candidate and returns sublime's hint and subj 70 | def hint_and_subj(cls, name, type): 71 | subj = name 72 | if cls == "func": 73 | hint = cls + " " + name 74 | args, returns = extract_arguments_and_returns(type) 75 | if returns: 76 | hint += "\t" + ", ".join(returns) 77 | if args: 78 | sargs = [] 79 | for i, a in enumerate(args): 80 | ea = a.replace("{", "\\{").replace("}", "\\}") 81 | sargs.append("${{{0}:{1}}}".format(i+1, ea)) 82 | subj += "(" + ", ".join(sargs) + ")" 83 | else: 84 | subj += "()" 85 | else: 86 | hint = cls + " " + name + "\t" + type 87 | return hint, subj 88 | 89 | def diff_sanity_check(a, b): 90 | if a != b: 91 | raise Exception("diff sanity check mismatch\n-%s\n+%s" % (a, b)) 92 | 93 | class GocodeGofmtCommand(sublime_plugin.TextCommand): 94 | def run(self, edit): 95 | view = self.view 96 | src = view.substr(sublime.Region(0, view.size())) 97 | gofmt = subprocess.Popen(["gofmt"], 98 | stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 99 | sout, serr = gofmt.communicate(src.encode()) 100 | if gofmt.returncode != 0: 101 | print(serr.decode(), end="") 102 | return 103 | 104 | newsrc = sout.decode() 105 | diff = difflib.ndiff(src.splitlines(), newsrc.splitlines()) 106 | i = 0 107 | for line in diff: 108 | if line.startswith("?"): # skip hint lines 109 | continue 110 | 111 | l = (len(line)-2)+1 112 | if line.startswith("-"): 113 | diff_sanity_check(view.substr(sublime.Region(i, i+l-1)), line[2:]) 114 | view.erase(edit, sublime.Region(i, i+l)) 115 | elif line.startswith("+"): 116 | view.insert(edit, i, line[2:]+"\n") 117 | i += l 118 | else: 119 | diff_sanity_check(view.substr(sublime.Region(i, i+l-1)), line[2:]) 120 | i += l 121 | 122 | class Gocode(sublime_plugin.EventListener): 123 | def on_query_completions(self, view, prefix, locations): 124 | loc = locations[0] 125 | if not view.match_selector(loc, "source.go"): 126 | return None 127 | 128 | src = view.substr(sublime.Region(0, view.size())) 129 | filename = view.file_name() 130 | cloc = "c{0}".format(loc) 131 | gocode = subprocess.Popen(["gocode", "-f=csv", "autocomplete", filename, cloc], 132 | stdin=subprocess.PIPE, stdout=subprocess.PIPE) 133 | out = gocode.communicate(src.encode())[0].decode() 134 | 135 | result = [] 136 | for line in filter(bool, out.split("\n")): 137 | arg = line.split(",,") 138 | hint, subj = hint_and_subj(*arg) 139 | result.append([hint, subj]) 140 | 141 | return (result, sublime.INHIBIT_WORD_COMPLETIONS) 142 | 143 | def on_pre_save(self, view): 144 | if not view.match_selector(0, "source.go"): 145 | return 146 | view.run_command('gocode_gofmt') 147 | -------------------------------------------------------------------------------- /internal/gcimporter/gcimporter11_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 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 | // +build go1.11 6 | 7 | package gcimporter 8 | 9 | import ( 10 | "go/types" 11 | "runtime" 12 | "strings" 13 | "testing" 14 | ) 15 | 16 | var importedObjectTests = []struct { 17 | name string 18 | want string 19 | }{ 20 | // non-interfaces 21 | {"crypto.Hash", "type Hash uint"}, 22 | {"go/ast.ObjKind", "type ObjKind int"}, 23 | {"go/types.Qualifier", "type Qualifier func(*Package) string"}, 24 | {"go/types.Comparable", "func Comparable(T Type) bool"}, 25 | {"math.Pi", "const Pi untyped float"}, 26 | {"math.Sin", "func Sin(x float64) float64"}, 27 | {"go/ast.NotNilFilter", "func NotNilFilter(_ string, v reflect.Value) bool"}, 28 | {"go/internal/gcimporter.BImportData", "func BImportData(fset *go/token.FileSet, imports map[string]*go/types.Package, data []byte, path string) (_ int, pkg *go/types.Package, err error)"}, 29 | 30 | // interfaces 31 | {"context.Context", "type Context interface{Deadline() (deadline time.Time, ok bool); Done() <-chan struct{}; Err() error; Value(key interface{}) interface{}}"}, 32 | {"crypto.Decrypter", "type Decrypter interface{Decrypt(rand io.Reader, msg []byte, opts DecrypterOpts) (plaintext []byte, err error); Public() PublicKey}"}, 33 | {"encoding.BinaryMarshaler", "type BinaryMarshaler interface{MarshalBinary() (data []byte, err error)}"}, 34 | {"io.Reader", "type Reader interface{Read(p []byte) (n int, err error)}"}, 35 | {"io.ReadWriter", "type ReadWriter interface{Reader; Writer}"}, 36 | {"go/ast.Node", "type Node interface{End() go/token.Pos; Pos() go/token.Pos}"}, 37 | {"go/types.Type", "type Type interface{String() string; Underlying() Type}"}, 38 | } 39 | 40 | func TestImportedTypes(t *testing.T) { 41 | skipSpecialPlatforms(t) 42 | 43 | // This package only handles gc export data. 44 | if runtime.Compiler != "gc" { 45 | t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler) 46 | } 47 | 48 | for _, test := range importedObjectTests { 49 | s := strings.Split(test.name, ".") 50 | if len(s) != 2 { 51 | t.Fatal("inconsistent test data") 52 | } 53 | importPath := s[0] 54 | objName := s[1] 55 | 56 | pkg, err := Import(make(map[string]*types.Package), importPath, ".", nil) 57 | if err != nil { 58 | t.Error(err) 59 | continue 60 | } 61 | 62 | obj := pkg.Scope().Lookup(objName) 63 | if obj == nil { 64 | t.Errorf("%s: object not found", test.name) 65 | continue 66 | } 67 | 68 | got := types.ObjectString(obj, types.RelativeTo(pkg)) 69 | if got != test.want { 70 | t.Errorf("%s: got %q; want %q", test.name, got, test.want) 71 | } 72 | 73 | if named, _ := obj.Type().(*types.Named); named != nil { 74 | verifyInterfaceMethodRecvs(t, named, 0) 75 | } 76 | } 77 | } 78 | 79 | // verifyInterfaceMethodRecvs verifies that method receiver types 80 | // are named if the methods belong to a named interface type. 81 | func verifyInterfaceMethodRecvs(t *testing.T, named *types.Named, level int) { 82 | // avoid endless recursion in case of an embedding bug that lead to a cycle 83 | if level > 10 { 84 | t.Errorf("%s: embeds itself", named) 85 | return 86 | } 87 | 88 | iface, _ := named.Underlying().(*types.Interface) 89 | if iface == nil { 90 | return // not an interface 91 | } 92 | 93 | // check explicitly declared methods 94 | for i := 0; i < iface.NumExplicitMethods(); i++ { 95 | m := iface.ExplicitMethod(i) 96 | recv := m.Type().(*types.Signature).Recv() 97 | if recv == nil { 98 | t.Errorf("%s: missing receiver type", m) 99 | continue 100 | } 101 | if recv.Type() != named { 102 | t.Errorf("%s: got recv type %s; want %s", m, recv.Type(), named) 103 | } 104 | } 105 | 106 | // check embedded interfaces (if they are named, too) 107 | for i := 0; i < iface.NumEmbeddeds(); i++ { 108 | // embedding of interfaces cannot have cycles; recursion will terminate 109 | if etype, _ := iface.EmbeddedType(i).(*types.Named); etype != nil { 110 | verifyInterfaceMethodRecvs(t, etype, level+1) 111 | } 112 | } 113 | } 114 | func TestIssue25301(t *testing.T) { 115 | skipSpecialPlatforms(t) 116 | 117 | // This package only handles gc export data. 118 | if runtime.Compiler != "gc" { 119 | t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler) 120 | } 121 | 122 | // On windows, we have to set the -D option for the compiler to avoid having a drive 123 | // letter and an illegal ':' in the import path - just skip it (see also issue #3483). 124 | if runtime.GOOS == "windows" { 125 | t.Skip("avoid dealing with relative paths/drive letters on windows") 126 | } 127 | 128 | compileAndImportPkg(t, "issue25301") 129 | } 130 | -------------------------------------------------------------------------------- /internal/gcexportdata/gcexportdata.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 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 | // Package gcexportdata provides functions for locating, reading, and 6 | // writing export data files containing type information produced by the 7 | // gc compiler. This package supports go1.7 export data format and all 8 | // later versions. 9 | // 10 | // Although it might seem convenient for this package to live alongside 11 | // go/types in the standard library, this would cause version skew 12 | // problems for developer tools that use it, since they must be able to 13 | // consume the outputs of the gc compiler both before and after a Go 14 | // update such as from Go 1.7 to Go 1.8. Because this package lives in 15 | // golang.org/x/tools, sites can update their version of this repo some 16 | // time before the Go 1.8 release and rebuild and redeploy their 17 | // developer tools, which will then be able to consume both Go 1.7 and 18 | // Go 1.8 export data files, so they will work before and after the 19 | // Go update. (See discussion at https://golang.org/issue/15651.) 20 | // 21 | package gcexportdata 22 | 23 | import ( 24 | "bufio" 25 | "bytes" 26 | "fmt" 27 | "go/token" 28 | "go/types" 29 | "io" 30 | "io/ioutil" 31 | 32 | "github.com/visualfc/gocode/internal/gcimporter" 33 | ) 34 | 35 | // Find returns the name of an object (.o) or archive (.a) file 36 | // containing type information for the specified import path, 37 | // using the workspace layout conventions of go/build. 38 | // If no file was found, an empty filename is returned. 39 | // 40 | // A relative srcDir is interpreted relative to the current working directory. 41 | // 42 | // Find also returns the package's resolved (canonical) import path, 43 | // reflecting the effects of srcDir and vendoring on importPath. 44 | func Find(importPath, srcDir string) (filename, path string) { 45 | return gcimporter.FindPkg(importPath, srcDir) 46 | } 47 | 48 | // NewReader returns a reader for the export data section of an object 49 | // (.o) or archive (.a) file read from r. The new reader may provide 50 | // additional trailing data beyond the end of the export data. 51 | func NewReader(r io.Reader) (io.Reader, error) { 52 | buf := bufio.NewReader(r) 53 | _, err := gcimporter.FindExportData(buf) 54 | // If we ever switch to a zip-like archive format with the ToC 55 | // at the end, we can return the correct portion of export data, 56 | // but for now we must return the entire rest of the file. 57 | return buf, err 58 | } 59 | 60 | // Read reads export data from in, decodes it, and returns type 61 | // information for the package. 62 | // The package name is specified by path. 63 | // File position information is added to fset. 64 | // 65 | // Read may inspect and add to the imports map to ensure that references 66 | // within the export data to other packages are consistent. The caller 67 | // must ensure that imports[path] does not exist, or exists but is 68 | // incomplete (see types.Package.Complete), and Read inserts the 69 | // resulting package into this map entry. 70 | // 71 | // On return, the state of the reader is undefined. 72 | func Read(in io.Reader, fset *token.FileSet, imports map[string]*types.Package, path string) (*types.Package, error) { 73 | data, err := ioutil.ReadAll(in) 74 | if err != nil { 75 | return nil, fmt.Errorf("reading export data for %q: %v", path, err) 76 | } 77 | 78 | if bytes.HasPrefix(data, []byte("!")) { 79 | return nil, fmt.Errorf("can't read export data for %q directly from an archive file (call gcexportdata.NewReader first to extract export data)", path) 80 | } 81 | 82 | // The App Engine Go runtime v1.6 uses the old export data format. 83 | // TODO(adonovan): delete once v1.7 has been around for a while. 84 | if bytes.HasPrefix(data, []byte("package ")) { 85 | return gcimporter.ImportData(imports, path, path, bytes.NewReader(data)) 86 | } 87 | 88 | // The indexed export format starts with an 'i'; the older 89 | // binary export format starts with a 'c', 'd', or 'v' 90 | // (from "version"). Select appropriate importer. 91 | if len(data) > 0 && data[0] == 'i' { 92 | _, pkg, err := gcimporter.IImportData(fset, imports, data[1:], path) 93 | return pkg, err 94 | } 95 | 96 | _, pkg, err := gcimporter.BImportData(fset, imports, data, path) 97 | return pkg, err 98 | } 99 | 100 | // Write writes encoded type information for the specified package to out. 101 | // The FileSet provides file position information for named objects. 102 | func Write(out io.Writer, fset *token.FileSet, pkg *types.Package) error { 103 | b, err := gcimporter.BExportData(fset, pkg) 104 | if err != nil { 105 | return err 106 | } 107 | _, err = out.Write(b) 108 | return err 109 | } 110 | -------------------------------------------------------------------------------- /rpc.go: -------------------------------------------------------------------------------- 1 | // WARNING! Autogenerated by goremote, don't touch. 2 | 3 | package main 4 | 5 | import ( 6 | "net/rpc" 7 | ) 8 | 9 | type RPC struct { 10 | } 11 | 12 | // wrapper for: server_auto_complete 13 | 14 | type Args_auto_complete struct { 15 | Arg0 []byte 16 | Arg1 string 17 | Arg2 int 18 | Arg3 go_build_context 19 | } 20 | type Reply_auto_complete struct { 21 | Arg0 []candidate 22 | Arg1 int 23 | } 24 | 25 | func (r *RPC) RPC_auto_complete(args *Args_auto_complete, reply *Reply_auto_complete) error { 26 | reply.Arg0, reply.Arg1 = server_auto_complete(args.Arg0, args.Arg1, args.Arg2, args.Arg3) 27 | return nil 28 | } 29 | 30 | func client_auto_complete(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int, Arg3 go_build_context) (c []candidate, d int) { 31 | var args Args_auto_complete 32 | var reply Reply_auto_complete 33 | args.Arg0 = Arg0 34 | args.Arg1 = Arg1 35 | args.Arg2 = Arg2 36 | args.Arg3 = Arg3 37 | err := cli.Call("RPC.RPC_auto_complete", &args, &reply) 38 | if err != nil { 39 | panic(err) 40 | } 41 | return reply.Arg0, reply.Arg1 42 | } 43 | 44 | type Args_types_info struct { 45 | Arg0 []byte 46 | Arg1 string 47 | Arg2 int 48 | Arg3 string 49 | Arg4 go_build_context 50 | } 51 | type Reply_types_info struct { 52 | Arg0 []string 53 | Arg1 int 54 | } 55 | 56 | func (r *RPC) RPC_types_info(args *Args_types_info, reply *Reply_types_info) error { 57 | reply.Arg0, reply.Arg1 = server_types_info(args.Arg0, args.Arg1, args.Arg2, args.Arg3, args.Arg4) 58 | return nil 59 | } 60 | 61 | func client_types_info(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int, Arg3 string, Arg4 go_build_context) (c []string, d int) { 62 | var args Args_types_info 63 | var reply Reply_types_info 64 | args.Arg0 = Arg0 65 | args.Arg1 = Arg1 66 | args.Arg2 = Arg2 67 | args.Arg3 = Arg3 68 | args.Arg4 = Arg4 69 | err := cli.Call("RPC.RPC_types_info", &args, &reply) 70 | if err != nil { 71 | panic(err) 72 | } 73 | return reply.Arg0, reply.Arg1 74 | } 75 | 76 | // wrapper for: server_close 77 | 78 | type Args_close struct { 79 | Arg0 int 80 | } 81 | type Reply_close struct { 82 | Arg0 int 83 | } 84 | 85 | func (r *RPC) RPC_close(args *Args_close, reply *Reply_close) error { 86 | reply.Arg0 = server_close(args.Arg0) 87 | return nil 88 | } 89 | func client_close(cli *rpc.Client, Arg0 int) int { 90 | var args Args_close 91 | var reply Reply_close 92 | args.Arg0 = Arg0 93 | err := cli.Call("RPC.RPC_close", &args, &reply) 94 | if err != nil { 95 | panic(err) 96 | } 97 | return reply.Arg0 98 | } 99 | 100 | // wrapper for: server_status 101 | 102 | type Args_status struct { 103 | Arg0 int 104 | } 105 | type Reply_status struct { 106 | Arg0 string 107 | } 108 | 109 | func (r *RPC) RPC_status(args *Args_status, reply *Reply_status) error { 110 | reply.Arg0 = server_status(args.Arg0) 111 | return nil 112 | } 113 | func client_status(cli *rpc.Client, Arg0 int) string { 114 | var args Args_status 115 | var reply Reply_status 116 | args.Arg0 = Arg0 117 | err := cli.Call("RPC.RPC_status", &args, &reply) 118 | if err != nil { 119 | panic(err) 120 | } 121 | return reply.Arg0 122 | } 123 | 124 | // wrapper for: server_drop_cache 125 | 126 | type Args_drop_cache struct { 127 | Arg0 int 128 | } 129 | type Reply_drop_cache struct { 130 | Arg0 int 131 | } 132 | 133 | func (r *RPC) RPC_drop_cache(args *Args_drop_cache, reply *Reply_drop_cache) error { 134 | reply.Arg0 = server_drop_cache(args.Arg0) 135 | return nil 136 | } 137 | func client_drop_cache(cli *rpc.Client, Arg0 int) int { 138 | var args Args_drop_cache 139 | var reply Reply_drop_cache 140 | args.Arg0 = Arg0 141 | err := cli.Call("RPC.RPC_drop_cache", &args, &reply) 142 | if err != nil { 143 | panic(err) 144 | } 145 | return reply.Arg0 146 | } 147 | 148 | // wrapper for: server_set 149 | 150 | type Args_set struct { 151 | Arg0, Arg1 string 152 | } 153 | type Reply_set struct { 154 | Arg0 string 155 | } 156 | 157 | func (r *RPC) RPC_set(args *Args_set, reply *Reply_set) error { 158 | reply.Arg0 = server_set(args.Arg0, args.Arg1) 159 | return nil 160 | } 161 | func client_set(cli *rpc.Client, Arg0, Arg1 string) string { 162 | var args Args_set 163 | var reply Reply_set 164 | args.Arg0 = Arg0 165 | args.Arg1 = Arg1 166 | err := cli.Call("RPC.RPC_set", &args, &reply) 167 | if err != nil { 168 | panic(err) 169 | } 170 | return reply.Arg0 171 | } 172 | 173 | // wrapper for: server_options 174 | 175 | type Args_options struct { 176 | Arg0 int 177 | } 178 | type Reply_options struct { 179 | Arg0 string 180 | } 181 | 182 | func (r *RPC) RPC_options(args *Args_options, reply *Reply_options) error { 183 | reply.Arg0 = server_options(args.Arg0) 184 | return nil 185 | } 186 | func client_options(cli *rpc.Client, Arg0 int) string { 187 | var args Args_options 188 | var reply Reply_options 189 | args.Arg0 = Arg0 190 | err := cli.Call("RPC.RPC_options", &args, &reply) 191 | if err != nil { 192 | panic(err) 193 | } 194 | return reply.Arg0 195 | } 196 | -------------------------------------------------------------------------------- /client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "go/build" 7 | "io/ioutil" 8 | "net/rpc" 9 | "os" 10 | "path/filepath" 11 | "strconv" 12 | "time" 13 | ) 14 | 15 | func do_client() int { 16 | addr := *g_addr 17 | if *g_sock == "unix" { 18 | addr = get_socket_filename() 19 | } 20 | 21 | // client 22 | client, err := rpc.Dial(*g_sock, addr) 23 | if err != nil { 24 | if *g_sock == "unix" && file_exists(addr) { 25 | os.Remove(addr) 26 | } 27 | 28 | err = try_run_server() 29 | if err != nil { 30 | fmt.Printf("%s\n", err.Error()) 31 | return 1 32 | } 33 | client, err = try_to_connect(*g_sock, addr) 34 | if err != nil { 35 | fmt.Printf("%s\n", err.Error()) 36 | return 1 37 | } 38 | } 39 | defer client.Close() 40 | 41 | if flag.NArg() > 0 { 42 | switch flag.Arg(0) { 43 | case "autocomplete": 44 | cmd_auto_complete(client) 45 | case "liteide_typesinfo": 46 | cmd_types_info(client) 47 | case "close": 48 | cmd_close(client) 49 | case "status": 50 | cmd_status(client) 51 | case "drop-cache": 52 | cmd_drop_cache(client) 53 | case "set": 54 | cmd_set(client) 55 | case "options": 56 | cmd_options(client) 57 | default: 58 | fmt.Printf("unknown argument: %q, try running \"gocode -h\"\n", flag.Arg(0)) 59 | return 1 60 | } 61 | } 62 | return 0 63 | } 64 | 65 | func try_run_server() error { 66 | path := get_executable_filename() 67 | args := []string{os.Args[0], "-s", "-sock", *g_sock, "-addr", *g_addr} 68 | cwd, _ := os.Getwd() 69 | 70 | var err error 71 | stdin, err := os.Open(os.DevNull) 72 | if err != nil { 73 | return err 74 | } 75 | stdout, err := os.OpenFile(os.DevNull, os.O_WRONLY, 0) 76 | if err != nil { 77 | return err 78 | } 79 | stderr, err := os.OpenFile(os.DevNull, os.O_WRONLY, 0) 80 | if err != nil { 81 | return err 82 | } 83 | 84 | procattr := os.ProcAttr{Dir: cwd, Env: os.Environ(), Files: []*os.File{stdin, stdout, stderr}} 85 | p, err := os.StartProcess(path, args, &procattr) 86 | if err != nil { 87 | return err 88 | } 89 | 90 | return p.Release() 91 | } 92 | 93 | func try_to_connect(network, address string) (client *rpc.Client, err error) { 94 | t := 0 95 | for { 96 | client, err = rpc.Dial(network, address) 97 | if err != nil && t < 1000 { 98 | time.Sleep(10 * time.Millisecond) 99 | t += 10 100 | continue 101 | } 102 | break 103 | } 104 | 105 | return 106 | } 107 | 108 | func prepare_file_filename_cursor(filter bool) ([]byte, string, int, string) { 109 | var file []byte 110 | var err error 111 | 112 | if *g_input != "" { 113 | file, err = ioutil.ReadFile(*g_input) 114 | } else { 115 | file, err = ioutil.ReadAll(os.Stdin) 116 | } 117 | 118 | if err != nil { 119 | panic(err.Error()) 120 | } 121 | 122 | filename := *g_input 123 | cursor := -1 124 | 125 | offset := "" 126 | addin := "" 127 | switch flag.NArg() { 128 | case 2: 129 | offset = flag.Arg(1) 130 | case 3: 131 | filename = flag.Arg(1) // Override default filename 132 | offset = flag.Arg(2) 133 | case 4: 134 | filename = flag.Arg(1) // Override default filename 135 | offset = flag.Arg(2) 136 | addin = flag.Arg(3) 137 | } 138 | 139 | var skipped int 140 | if filter { 141 | file, skipped = filter_out_shebang(file) 142 | } 143 | 144 | if offset != "" { 145 | if offset[0] == 'c' || offset[0] == 'C' { 146 | cursor, _ = strconv.Atoi(offset[1:]) 147 | cursor = char_to_byte_offset(file, cursor) 148 | } else { 149 | cursor, _ = strconv.Atoi(offset) 150 | } 151 | } 152 | 153 | cursor -= skipped 154 | 155 | if filename != "" && !filepath.IsAbs(filename) { 156 | cwd, _ := os.Getwd() 157 | filename = filepath.Join(cwd, filename) 158 | } 159 | return file, filename, cursor, addin 160 | } 161 | 162 | //------------------------------------------------------------------------- 163 | // commands 164 | //------------------------------------------------------------------------- 165 | 166 | func cmd_status(c *rpc.Client) { 167 | fmt.Printf("%s\n", client_status(c, 0)) 168 | } 169 | 170 | func cmd_auto_complete(c *rpc.Client) { 171 | context := pack_build_context(&build.Default) 172 | file, filename, cursor, _ := prepare_file_filename_cursor(true) 173 | f := get_formatter(*g_format) 174 | f.write_candidates(client_auto_complete(c, file, filename, cursor, context)) 175 | } 176 | 177 | func write_tyepsinfo(infos []string, num int) { 178 | if infos == nil { 179 | return 180 | } 181 | for _, c := range infos { 182 | fmt.Printf("%s\n", c) 183 | } 184 | } 185 | 186 | func cmd_types_info(c *rpc.Client) { 187 | context := pack_build_context(&build.Default) 188 | file, filename, cursor, addin := prepare_file_filename_cursor(true) 189 | write_tyepsinfo(client_types_info(c, file, filename, cursor, addin, context)) 190 | } 191 | 192 | func cmd_close(c *rpc.Client) { 193 | client_close(c, 0) 194 | } 195 | 196 | func cmd_drop_cache(c *rpc.Client) { 197 | client_drop_cache(c, 0) 198 | } 199 | 200 | func cmd_set(c *rpc.Client) { 201 | switch flag.NArg() { 202 | case 1: 203 | fmt.Print(client_set(c, "\x00", "\x00")) 204 | case 2: 205 | fmt.Print(client_set(c, flag.Arg(1), "\x00")) 206 | case 3: 207 | fmt.Print(client_set(c, flag.Arg(1), flag.Arg(2))) 208 | } 209 | } 210 | 211 | func cmd_options(c *rpc.Client) { 212 | fmt.Print(client_options(c, 0)) 213 | } 214 | -------------------------------------------------------------------------------- /formatters.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | //------------------------------------------------------------------------- 9 | // formatter interfaces 10 | //------------------------------------------------------------------------- 11 | 12 | type formatter interface { 13 | write_candidates(candidates []candidate, num int) 14 | } 15 | 16 | type formatter_ex interface { 17 | formatter 18 | } 19 | 20 | //------------------------------------------------------------------------- 21 | // nice_formatter (just for testing, simple textual output) 22 | //------------------------------------------------------------------------- 23 | 24 | type nice_formatter struct{} 25 | 26 | func (*nice_formatter) write_candidates(candidates []candidate, num int) { 27 | if candidates == nil { 28 | fmt.Printf("Nothing to complete.\n") 29 | return 30 | } 31 | 32 | fmt.Printf("Found %d candidates:\n", len(candidates)) 33 | for _, c := range candidates { 34 | abbr := fmt.Sprintf("%s %s %s", c.Class, c.Name, c.Type) 35 | if c.Class == decl_func { 36 | abbr = fmt.Sprintf("%s %s%s", c.Class, c.Name, c.Type[len("func"):]) 37 | } 38 | fmt.Printf(" %s\n", abbr) 39 | } 40 | } 41 | 42 | //------------------------------------------------------------------------- 43 | // vim_formatter 44 | //------------------------------------------------------------------------- 45 | 46 | type vim_formatter struct{} 47 | 48 | func (*vim_formatter) write_candidates(candidates []candidate, num int) { 49 | if candidates == nil { 50 | fmt.Print("[0, []]") 51 | return 52 | } 53 | 54 | fmt.Printf("[%d, [", num) 55 | for i, c := range candidates { 56 | if i != 0 { 57 | fmt.Printf(", ") 58 | } 59 | 60 | word := c.Name 61 | if c.Class == decl_func { 62 | word += "(" 63 | if strings.HasPrefix(c.Type, "func()") { 64 | word += ")" 65 | } 66 | } 67 | 68 | abbr := fmt.Sprintf("%s %s %s", c.Class, c.Name, c.Type) 69 | if c.Class == decl_func { 70 | abbr = fmt.Sprintf("%s %s%s", c.Class, c.Name, c.Type[len("func"):]) 71 | } 72 | fmt.Printf("{'word': '%s', 'abbr': '%s', 'info': '%s'}", word, abbr, abbr) 73 | } 74 | fmt.Printf("]]") 75 | } 76 | 77 | //------------------------------------------------------------------------- 78 | // godit_formatter 79 | //------------------------------------------------------------------------- 80 | 81 | type godit_formatter struct{} 82 | 83 | func (*godit_formatter) write_candidates(candidates []candidate, num int) { 84 | fmt.Printf("%d,,%d\n", num, len(candidates)) 85 | for _, c := range candidates { 86 | contents := c.Name 87 | if c.Class == decl_func { 88 | contents += "(" 89 | if strings.HasPrefix(c.Type, "func()") { 90 | contents += ")" 91 | } 92 | } 93 | 94 | display := fmt.Sprintf("%s %s %s", c.Class, c.Name, c.Type) 95 | if c.Class == decl_func { 96 | display = fmt.Sprintf("%s %s%s", c.Class, c.Name, c.Type[len("func"):]) 97 | } 98 | fmt.Printf("%s,,%s\n", display, contents) 99 | } 100 | } 101 | 102 | //------------------------------------------------------------------------- 103 | // emacs_formatter 104 | //------------------------------------------------------------------------- 105 | 106 | type emacs_formatter struct{} 107 | 108 | func (*emacs_formatter) write_candidates(candidates []candidate, num int) { 109 | for _, c := range candidates { 110 | var hint string 111 | switch { 112 | case c.Class == decl_func: 113 | hint = c.Type 114 | case c.Type == "": 115 | hint = c.Class.String() 116 | default: 117 | hint = c.Class.String() + " " + c.Type 118 | } 119 | fmt.Printf("%s,,%s\n", c.Name, hint) 120 | } 121 | } 122 | 123 | //------------------------------------------------------------------------- 124 | // csv_formatter 125 | //------------------------------------------------------------------------- 126 | 127 | type csv_formatter struct{} 128 | 129 | func (*csv_formatter) write_candidates(candidates []candidate, num int) { 130 | for _, c := range candidates { 131 | fmt.Printf("%s,,%s,,%s\n", c.Class, c.Name, c.Type) 132 | } 133 | } 134 | 135 | //------------------------------------------------------------------------- 136 | // csv_with_package_formatter 137 | //------------------------------------------------------------------------- 138 | 139 | type csv_with_package_formatter struct{} 140 | 141 | func (*csv_with_package_formatter) write_candidates(candidates []candidate, num int) { 142 | for _, c := range candidates { 143 | fmt.Printf("%s,,%s,,%s,,%s\n", c.Class, c.Name, c.Type, c.Package) 144 | } 145 | } 146 | 147 | //------------------------------------------------------------------------- 148 | // json_formatter 149 | //------------------------------------------------------------------------- 150 | 151 | type json_formatter struct{} 152 | 153 | func (*json_formatter) write_candidates(candidates []candidate, num int) { 154 | if candidates == nil { 155 | fmt.Print("[]") 156 | return 157 | } 158 | 159 | fmt.Printf(`[%d, [`, num) 160 | for i, c := range candidates { 161 | if i != 0 { 162 | fmt.Printf(", ") 163 | } 164 | fmt.Printf(`{"class": "%s", "name": "%s", "type": "%s", "package": "%s"}`, 165 | c.Class, c.Name, c.Type, c.Package) 166 | } 167 | fmt.Print("]]") 168 | } 169 | 170 | //------------------------------------------------------------------------- 171 | 172 | func get_formatter(name string) formatter { 173 | switch name { 174 | case "vim": 175 | return new(vim_formatter) 176 | case "emacs": 177 | return new(emacs_formatter) 178 | case "nice": 179 | return new(nice_formatter) 180 | case "csv": 181 | return new(csv_formatter) 182 | case "csv-with-package": 183 | return new(csv_with_package_formatter) 184 | case "json": 185 | return new(json_formatter) 186 | case "godit": 187 | return new(godit_formatter) 188 | } 189 | return new(nice_formatter) 190 | } 191 | -------------------------------------------------------------------------------- /subl3/syntax/GoSublime-Template.tmLanguage: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | foldingStartMarker 6 | \{\{\s*(?:if|with|range)\b 7 | foldingStopMarker 8 | \{\{\s*(?:else|end)\b 9 | name 10 | GoSublime: Template 11 | patterns 12 | 13 | 14 | begin 15 | \{\{ 16 | beginCaptures 17 | 18 | 0 19 | 20 | name 21 | punctuation.section.embedded.begin.gotemplate 22 | 23 | 24 | end 25 | \}\} 26 | endCaptures 27 | 28 | 0 29 | 30 | name 31 | punctuation.section.embedded.end.gotemplate 32 | 33 | 34 | patterns 35 | 36 | 37 | match 38 | := 39 | name 40 | keyword.operator.initialize.gotemplate 41 | 42 | 43 | match 44 | \| 45 | name 46 | keyword.operator.pipe.gotemplate 47 | 48 | 49 | match 50 | [.$][\w]* 51 | name 52 | variable.other.gotemplate 53 | 54 | 55 | match 56 | \b(if|else|range|template|with|end|nil|with|define)\b 57 | name 58 | keyword.control.gotemplate 59 | 60 | 61 | match 62 | \b(and|call|html|index|js|len|not|or|print|printf|println|urlquery|eq|ne|lt|le|gt|ge)\b 63 | name 64 | support.function.builtin.gotemplate 65 | 66 | 67 | begin 68 | /\* 69 | end 70 | \*/ 71 | name 72 | comment.block.gotemplate 73 | 74 | 75 | begin 76 | " 77 | beginCaptures 78 | 79 | 0 80 | 81 | name 82 | punctuation.definition.string.begin.gotemplate 83 | 84 | 85 | end 86 | " 87 | endCaptures 88 | 89 | 0 90 | 91 | name 92 | punctuation.definition.string.end.gotemplate 93 | 94 | 95 | name 96 | string.quoted.double.gotemplate 97 | patterns 98 | 99 | 100 | include 101 | #string_placeholder 102 | 103 | 104 | include 105 | #string_escaped_char 106 | 107 | 108 | 109 | 110 | begin 111 | ` 112 | beginCaptures 113 | 114 | 0 115 | 116 | name 117 | punctuation.definition.string.begin.gotemplate 118 | 119 | 120 | end 121 | ` 122 | endCaptures 123 | 124 | 0 125 | 126 | name 127 | punctuation.definition.string.end.gotemplate 128 | 129 | 130 | name 131 | string.quoted.raw.gotemplate 132 | patterns 133 | 134 | 135 | include 136 | #string_placeholder 137 | 138 | 139 | 140 | 141 | 142 | 143 | repository 144 | 145 | string_escaped_char 146 | 147 | patterns 148 | 149 | 150 | match 151 | \\(\\|[abfnrtv'"]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}|[0-7]{3}) 152 | name 153 | constant.character.escape.gotemplate 154 | 155 | 156 | match 157 | \\. 158 | name 159 | invalid.illegal.unknown-escape.gotemplate 160 | 161 | 162 | 163 | string_placeholder 164 | 165 | patterns 166 | 167 | 168 | match 169 | (?x)% 170 | (\d+\$)? # field (argument #) 171 | [#0\- +']* # flags 172 | [,;:_]? # separator character (AltiVec) 173 | ((-?\d+)|\*(-?\d+\$)?)? # minimum field width 174 | (\.((-?\d+)|\*(-?\d+\$)?)?)? # precision 175 | [diouxXDOUeEfFgGaAcCsSqpnvtTbyYhHmMzZ%] # conversion type 176 | 177 | name 178 | constant.other.placeholder.gotemplate 179 | 180 | 181 | match 182 | % 183 | name 184 | invalid.illegal.placeholder.gotemplate 185 | 186 | 187 | 188 | 189 | scopeName 190 | source.gotemplate 191 | uuid 192 | 43606de8-c638-11e2-b661-6711676f99ca 193 | 194 | 195 | -------------------------------------------------------------------------------- /docs/autocomplete_formats.md: -------------------------------------------------------------------------------- 1 | 2 | # Description of Completion Assistance Formats # 3 | 4 | Use `-f` parameter for `autocomplete` command to set format. "nice" format is the default and fallback. 5 | 6 | Following formats supported: 7 | * json 8 | * nice 9 | * vim 10 | * godit 11 | * emacs 12 | * csv 13 | 14 | ## json ### 15 | Generic JSON format. Example (manually formatted): 16 | ```json 17 | [6, [{ 18 | "class": "func", 19 | "name": "client_auto_complete", 20 | "type": "func(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int, Arg3 gocode_env) (c []candidate, d int)" 21 | }, { 22 | "class": "func", 23 | "name": "client_close", 24 | "type": "func(cli *rpc.Client, Arg0 int) int" 25 | }, { 26 | "class": "func", 27 | "name": "client_cursor_type_pkg", 28 | "type": "func(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int) (typ, pkg string)" 29 | }, { 30 | "class": "func", 31 | "name": "client_drop_cache", 32 | "type": "func(cli *rpc.Client, Arg0 int) int" 33 | }, { 34 | "class": "func", 35 | "name": "client_highlight", 36 | "type": "func(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 gocode_env) (c []highlight_range, d int)" 37 | }, { 38 | "class": "func", 39 | "name": "client_set", 40 | "type": "func(cli *rpc.Client, Arg0, Arg1 string) string" 41 | }, { 42 | "class": "func", 43 | "name": "client_status", 44 | "type": "func(cli *rpc.Client, Arg0 int) string" 45 | } 46 | ]] 47 | ``` 48 | Limitations: 49 | * `class` can be one of: `func`, `package`, `var`, `type`, `const`, `PANIC` 50 | * `PANIC` means suspicious error inside gocode 51 | * `name` is text which can be inserted 52 | * `type` can be used to create code assistance hint 53 | * You can re-format type by using following approach: if `class` is prefix of `type`, delete this prefix and add another prefix `class` + " " + `name`. 54 | 55 | ## nice ## 56 | You can use it to test from command-line. 57 | ``` 58 | Found 7 candidates: 59 | func client_auto_complete(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int, Arg3 gocode_env) (c []candidate, d int) 60 | func client_close(cli *rpc.Client, Arg0 int) int 61 | func client_cursor_type_pkg(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int) (typ, pkg string) 62 | func client_drop_cache(cli *rpc.Client, Arg0 int) int 63 | func client_highlight(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 gocode_env) (c []highlight_range, d int) 64 | func client_set(cli *rpc.Client, Arg0, Arg1 string) string 65 | func client_status(cli *rpc.Client, Arg0 int) string 66 | ``` 67 | 68 | ## vim ## 69 | Format designed to be used in VIM scripts. Example: 70 | ``` 71 | [6, [{'word': 'client_auto_complete(', 'abbr': 'func client_auto_complete(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int, Arg3 gocode_env) (c []candidate, d int)', 'info': 'func client_auto_complete(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int, Arg3 gocode_env) (c []candidate, d int)'}, {'word': 'client_close(', 'abbr': 'func client_close(cli *rpc.Client, Arg0 int) int', 'info': 'func client_close(cli *rpc.Client, Arg0 int) int'}, {'word': 'client_cursor_type_pkg(', 'abbr': 'func client_cursor_type_pkg(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int) (typ, pkg string)', 'info': 'func client_cursor_type_pkg(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int) (typ, pkg string)'}, {'word': 'client_drop_cache(', 'abbr': 'func client_drop_cache(cli *rpc.Client, Arg0 int) int', 'info': 'func client_drop_cache(cli *rpc.Client, Arg0 int) int'}, {'word': 'client_highlight(', 'abbr': 'func client_highlight(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 gocode_env) (c []highlight_range, d int)', 'info': 'func client_highlight(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 gocode_env) (c []highlight_range, d int)'}, {'word': 'client_set(', 'abbr': 'func client_set(cli *rpc.Client, Arg0, Arg1 string) string', 'info': 'func client_set(cli *rpc.Client, Arg0, Arg1 string) string'}, {'word': 'client_status(', 'abbr': 'func client_status(cli *rpc.Client, Arg0 int) string', 'info': 'func client_status(cli *rpc.Client, Arg0 int) string'}]] 72 | ``` 73 | 74 | ## godit ## 75 | Example: 76 | ``` 77 | 6,,7 78 | func client_auto_complete(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int, Arg3 gocode_env) (c []candidate, d int),,client_auto_complete( 79 | func client_close(cli *rpc.Client, Arg0 int) int,,client_close( 80 | func client_cursor_type_pkg(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int) (typ, pkg string),,client_cursor_type_pkg( 81 | func client_drop_cache(cli *rpc.Client, Arg0 int) int,,client_drop_cache( 82 | func client_highlight(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 gocode_env) (c []highlight_range, d int),,client_highlight( 83 | func client_set(cli *rpc.Client, Arg0, Arg1 string) string,,client_set( 84 | func client_status(cli *rpc.Client, Arg0 int) string,,client_status( 85 | ``` 86 | 87 | ## emacs ## 88 | Format designed to be used in Emacs scripts. Example: 89 | ``` 90 | client_auto_complete,,func(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int, Arg3 gocode_env) (c []candidate, d int) 91 | client_close,,func(cli *rpc.Client, Arg0 int) int 92 | client_cursor_type_pkg,,func(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int) (typ, pkg string) 93 | client_drop_cache,,func(cli *rpc.Client, Arg0 int) int 94 | client_highlight,,func(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 gocode_env) (c []highlight_range, d int) 95 | client_set,,func(cli *rpc.Client, Arg0, Arg1 string) string 96 | client_status,,func(cli *rpc.Client, Arg0 int) string 97 | ``` 98 | 99 | ## csv ## 100 | Comma-separated values format which has small size. Example: 101 | ```csv 102 | func,,client_auto_complete,,func(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int, Arg3 gocode_env) (c []candidate, d int) 103 | func,,client_close,,func(cli *rpc.Client, Arg0 int) int 104 | func,,client_cursor_type_pkg,,func(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int) (typ, pkg string) 105 | func,,client_drop_cache,,func(cli *rpc.Client, Arg0 int) int 106 | func,,client_highlight,,func(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 gocode_env) (c []highlight_range, d int) 107 | func,,client_set,,func(cli *rpc.Client, Arg0, Arg1 string) string 108 | func,,client_status,,func(cli *rpc.Client, Arg0 int) string 109 | ``` 110 | -------------------------------------------------------------------------------- /subl3/syntax/GoSublime-Go.tmLanguage.json: -------------------------------------------------------------------------------- 1 | { 2 | "comment": "Based on work from github.com/frou/GoFeather and github.com/DisposaBoy/GoSublime", 3 | "fileTypes": [ 4 | "go" 5 | ], 6 | "firstLineMatch": "-[*]-( Mode:)? Go -[*]-", 7 | "keyEquivalent": "^~G", 8 | "name": "GoSublime: Go", 9 | "patterns": [ 10 | { 11 | "begin": "/\\*", 12 | "end": "\\*/", 13 | "name": "comment.block.go" 14 | }, 15 | { 16 | "begin": "//", 17 | "end": "\\z", 18 | "name": "comment.line.double-slash.go" 19 | }, 20 | { 21 | "begin": "\"", 22 | "beginCaptures": { 23 | "0": { 24 | "name": "punctuation.definition.string.begin.go" 25 | } 26 | }, 27 | "end": "\"", 28 | "endCaptures": { 29 | "0": { 30 | "name": "punctuation.definition.string.end.go" 31 | } 32 | }, 33 | "name": "string.quoted.double.go", 34 | "patterns": [ 35 | { 36 | "include": "#string_placeholder" 37 | }, 38 | { 39 | "include": "#string_escaped_char" 40 | } 41 | ] 42 | }, 43 | { 44 | "begin": "`", 45 | "beginCaptures": { 46 | "0": { 47 | "name": "punctuation.definition.string.begin.go" 48 | } 49 | }, 50 | "end": "`", 51 | "endCaptures": { 52 | "0": { 53 | "name": "punctuation.definition.string.end.go" 54 | } 55 | }, 56 | "name": "string.quoted.raw.go", 57 | "patterns": [ 58 | { 59 | "include": "#string_placeholder" 60 | }, 61 | { 62 | "include": "source.gotemplate" 63 | } 64 | ] 65 | }, 66 | { 67 | "match": "\\b(true|false|nil|iota)\\b", 68 | "name": "constant.language.go" 69 | }, 70 | { 71 | "match": "\\b((\\d+\\.(\\d+)?([eE][+-]?\\d+)?|\\d+[eE][+-]?\\d+|\\.\\d+([eE][+-]?\\d+)?)i?)\\b", 72 | "name": "constant.numeric.floating-point.go" 73 | }, 74 | { 75 | "match": "\\b(\\d+i|0[xX][0-9A-Fa-f]+|0[0-7]*|[1-9][0-9]*)\\b", 76 | "name": "constant.numeric.integer.go" 77 | }, 78 | { 79 | "name": "constant.other.rune.go", 80 | "match": "'(?:[^'\\\\]|\\\\(?:\\\\|[abfnrtv']|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}|[0-7]{3}))'" 81 | }, 82 | { 83 | "match": "\\b(bool|byte|complex(64|128)|error|float(32|64)|rune|string|u?int(8|16|32|64)?|uintptr)\\b", 84 | "name": "storage.type.go" 85 | }, 86 | { 87 | "comment": "A subset of keyword.other.go for flow control keywords.", 88 | "match": "\\b(break|case|continue|default|defer|else|for|go|goto|if|range|return|select|switch)\\b", 89 | "name": "keyword.control.go" 90 | }, 91 | { 92 | "match": "\\b(break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go|goto|if|import|interface|map|package|range|return|select|struct|switch|type|var)\\b", 93 | "name": "keyword.other.go" 94 | }, 95 | { 96 | "captures": { 97 | "0": { 98 | "name": "variable.other.go" 99 | }, 100 | "1": { 101 | "name": "keyword.operator.initialize.go" 102 | } 103 | }, 104 | "comment": "This matches the 'x := 0' style of variable declaration.", 105 | "match": "(?:[[:alpha:]_][[:alnum:]_]*)(?:,\\s+[[:alpha:]_][[:alnum:]_]*)*\\s*(:=)", 106 | "name": "meta.initialization.short.go" 107 | }, 108 | { 109 | "match": "(?<=(\\Afunc|...\\))\\s)\\b(\\w+)\\b(?=\\()", 110 | "name": "entity.name.function.go" 111 | }, 112 | { 113 | "match": "(?<=(\\sfunc|....\\))\\s)\\b(\\w+)\\b(?=\\()", 114 | "name": "entity.name.function.go" 115 | }, 116 | { 117 | "match": "(?<=\\Atype\\s)\\b(\\w+)\\b", 118 | "name": "entity.name.type.go" 119 | }, 120 | { 121 | "match": "(?<=\\stype\\s)\\b(\\w+)\\b", 122 | "name": "entity.name.type.go" 123 | }, 124 | { 125 | "match": "\\b(append|cap|close|complex|copy|delete|imag|len|make|new|panic|print|println|real|recover)\\b", 126 | "name": "support.function.builtin.go" 127 | }, 128 | { 129 | "match": "\\b(\\w+)\\b(?=\\()", 130 | "name": "support.function.go" 131 | }, 132 | { 133 | "match": "(<-)", 134 | "name": "keyword.operator.channel.go" 135 | }, 136 | { 137 | "match": "(==|!=|<|<=|>|>=)", 138 | "name": "keyword.operator.comparison.go" 139 | }, 140 | { 141 | "match": "(&&|[|]{2}|!)", 142 | "name": "keyword.operator.logical.go" 143 | }, 144 | { 145 | "match": "([+]{2})", 146 | "name": "keyword.operator.increment.go" 147 | }, 148 | { 149 | "match": "(--)", 150 | "name": "keyword.decrement.go" 151 | }, 152 | { 153 | "match": "(=|(?:[+]|-|[|]|^|[*]|/|%|<<|>>|&|&^)=)", 154 | "name": "keyword.operator.assignment.go" 155 | }, 156 | { 157 | "match": "([+]|-|[*]|/|%|&|[|]|^|&^|<<|>>)", 158 | "name": "keyword.operator.arithmetic.go" 159 | }, 160 | { 161 | "match": "(;)", 162 | "name": "keyword.operator.semi-colon.go" 163 | }, 164 | { 165 | "match": "(,)", 166 | "name": "punctuation.definition.comma.go" 167 | }, 168 | { 169 | "match": "([.])", 170 | "name": "punctuation.definition.dot.go" 171 | }, 172 | { 173 | "match": "(:)", 174 | "name": "punctuation.definition.colon.go" 175 | }, 176 | { 177 | "match": "(\\[|\\]|{|}|\\(|\\))", 178 | "name": "punctuation.definition.bracket.go" 179 | } 180 | ], 181 | // note: keep this in sync with GoTemplate 182 | "repository": { 183 | "string_escaped_char": { 184 | "patterns": [ 185 | { 186 | // note: keep this in sync with constant.other.rune.go 187 | "match": "\\\\(\\\\|[abfnrtv'\"]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}|[0-7]{3})", 188 | "name": "constant.character.escape.go" 189 | }, 190 | { 191 | "match": "\\\\.", 192 | "name": "invalid.illegal.unknown-escape.go" 193 | } 194 | ] 195 | }, 196 | "string_placeholder": { 197 | "patterns": [ 198 | { 199 | "match": "(?x)%\n (\\d+\\$)? # field (argument #)\n [#0\\- +']* # flags\n [,;:_]? # separator character (AltiVec)\n ((-?\\d+)|\\*(-?\\d+\\$)?)? # minimum field width\n (\\.((-?\\d+)|\\*(-?\\d+\\$)?)?)? # precision\n [diouxXDOUeEfFgGaAcCsSqpnvtTbyYhHmMzZ%] # conversion type\n ", 200 | "name": "constant.other.placeholder.go" 201 | } 202 | ] 203 | } 204 | }, 205 | "scopeName": "source.go", 206 | "uuid": "1caaa75c-b61d-11e2-ba93-138feb5db969" 207 | } 208 | -------------------------------------------------------------------------------- /ast.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 The GoPlus Authors (goplus.org) 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | http://www.apache.org/licenses/LICENSE-2.0 7 | Unless required by applicable law or agreed to in writing, software 8 | distributed under the License is distributed on an "AS IS" BASIS, 9 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | See the License for the specific language governing permissions and 11 | limitations under the License. 12 | */ 13 | 14 | package main 15 | 16 | import ( 17 | "go/ast" 18 | "go/token" 19 | "go/types" 20 | "log" 21 | "reflect" 22 | "strconv" 23 | ) 24 | 25 | var ( 26 | underscore = &ast.Ident{Name: "_"} 27 | ) 28 | 29 | var ( 30 | identTrue = ident("true") 31 | identFalse = ident("false") 32 | identNil = ident("nil") 33 | identAppend = ident("append") 34 | identLen = ident("len") 35 | identCap = ident("cap") 36 | identNew = ident("new") 37 | identMake = ident("make") 38 | identIota = ident("iota") 39 | ) 40 | 41 | func ident(name string) *ast.Ident { 42 | return &ast.Ident{Name: name} 43 | } 44 | 45 | func boolean(v bool) *ast.Ident { 46 | if v { 47 | return identTrue 48 | } 49 | return identFalse 50 | } 51 | 52 | func toRecv(pkg *types.Package, recv *types.Var) *ast.FieldList { 53 | if recv == nil { 54 | return nil 55 | } 56 | var names []*ast.Ident 57 | if name := recv.Name(); name != "" { 58 | names = []*ast.Ident{ident(name)} 59 | } 60 | fld := &ast.Field{Names: names, Type: toType(pkg, recv.Type())} 61 | return &ast.FieldList{List: []*ast.Field{fld}} 62 | } 63 | 64 | // ----------------------------------------------------------------------------- 65 | // function type 66 | 67 | func toFieldList(pkg *types.Package, t *types.Tuple) []*ast.Field { 68 | if t == nil { 69 | return nil 70 | } 71 | n := t.Len() 72 | flds := make([]*ast.Field, n) 73 | for i := 0; i < n; i++ { 74 | item := t.At(i) 75 | var names []*ast.Ident 76 | if name := item.Name(); name != "" { 77 | names = []*ast.Ident{ident(name)} 78 | } 79 | typ := toType(pkg, item.Type()) 80 | flds[i] = &ast.Field{Names: names, Type: typ} 81 | } 82 | return flds 83 | } 84 | 85 | func toFields(pkg *types.Package, t *types.Struct) []*ast.Field { 86 | n := t.NumFields() 87 | flds := make([]*ast.Field, n) 88 | for i := 0; i < n; i++ { 89 | item := t.Field(i) 90 | var names []*ast.Ident 91 | if !item.Embedded() { 92 | names = []*ast.Ident{{Name: item.Name()}} 93 | } 94 | typ := toType(pkg, item.Type()) 95 | fld := &ast.Field{Names: names, Type: typ} 96 | if tag := t.Tag(i); tag != "" { 97 | fld.Tag = &ast.BasicLit{Kind: token.STRING, Value: strconv.Quote(tag)} 98 | } 99 | flds[i] = fld 100 | } 101 | return flds 102 | } 103 | 104 | func toVariadic(fld *ast.Field) { 105 | t, ok := fld.Type.(*ast.ArrayType) 106 | if !ok || t.Len != nil { 107 | panic("TODO: not a slice type") 108 | } 109 | fld.Type = &ast.Ellipsis{Elt: t.Elt} 110 | } 111 | 112 | // ----------------------------------------------------------------------------- 113 | 114 | func toType(pkg *types.Package, typ types.Type) ast.Expr { 115 | switch t := typ.(type) { 116 | case *types.Basic: // bool, int, etc 117 | return toBasicType(pkg, t) 118 | case *types.Pointer: 119 | return &ast.StarExpr{X: toType(pkg, t.Elem())} 120 | case *types.Named: 121 | return toNamedType(pkg, t) 122 | case *types.Interface: 123 | return toInterface(pkg, t) 124 | case *types.Slice: 125 | return toSliceType(pkg, t) 126 | case *types.Array: 127 | return toArrayType(pkg, t) 128 | case *types.Map: 129 | return toMapType(pkg, t) 130 | case *types.Struct: 131 | return toStructType(pkg, t) 132 | case *types.Chan: 133 | return toChanType(pkg, t) 134 | case *types.Signature: 135 | return toFuncType(pkg, t) 136 | case *TypeParam: 137 | return toTypeParam(pkg, t) 138 | } 139 | log.Panicln("TODO: toType -", reflect.TypeOf(typ)) 140 | return nil 141 | } 142 | 143 | func toObjectExpr(pkg *types.Package, v types.Object) ast.Expr { 144 | vpkg, name := v.Pkg(), v.Name() 145 | if vpkg == nil || vpkg == g_daemon.autocomplete.typesPkg { // at universe or at this package 146 | return ident(name) 147 | } 148 | return &ast.SelectorExpr{ 149 | X: ident(vpkg.Name()), 150 | Sel: ident(name), 151 | } 152 | } 153 | 154 | func toBasicType(pkg *types.Package, t *types.Basic) ast.Expr { 155 | if t.Kind() == types.UnsafePointer { 156 | return &ast.SelectorExpr{X: ast.NewIdent("unsafe"), Sel: ast.NewIdent("Pointer")} 157 | } 158 | if (t.Info() & types.IsUntyped) != 0 { 159 | //panic("unexpected: untyped type") 160 | } 161 | return &ast.Ident{Name: t.Name()} 162 | } 163 | 164 | func isUntyped(pkg *types.Package, typ types.Type) bool { 165 | switch t := typ.(type) { 166 | case *types.Basic: 167 | return (t.Info() & types.IsUntyped) != 0 168 | } 169 | return false 170 | } 171 | 172 | func toChanType(pkg *types.Package, t *types.Chan) ast.Expr { 173 | return &ast.ChanType{Value: toType(pkg, t.Elem()), Dir: chanDirs[t.Dir()]} 174 | } 175 | 176 | var ( 177 | chanDirs = [...]ast.ChanDir{ 178 | types.SendRecv: ast.SEND | ast.RECV, 179 | types.SendOnly: ast.SEND, 180 | types.RecvOnly: ast.RECV, 181 | } 182 | ) 183 | 184 | func toStructType(pkg *types.Package, t *types.Struct) ast.Expr { 185 | list := toFields(pkg, t) 186 | return &ast.StructType{Fields: &ast.FieldList{List: list}} 187 | } 188 | 189 | func toArrayType(pkg *types.Package, t *types.Array) ast.Expr { 190 | var len ast.Expr 191 | if n := t.Len(); n < 0 { 192 | len = &ast.Ellipsis{} 193 | } else { 194 | len = &ast.BasicLit{Kind: token.INT, Value: strconv.FormatInt(t.Len(), 10)} 195 | } 196 | return &ast.ArrayType{Len: len, Elt: toType(pkg, t.Elem())} 197 | } 198 | 199 | func toSliceType(pkg *types.Package, t *types.Slice) ast.Expr { 200 | return &ast.ArrayType{Elt: toType(pkg, t.Elem())} 201 | } 202 | 203 | func toMapType(pkg *types.Package, t *types.Map) ast.Expr { 204 | return &ast.MapType{Key: toType(pkg, t.Key()), Value: toType(pkg, t.Elem())} 205 | } 206 | 207 | func toInterface(pkg *types.Package, t *types.Interface) ast.Expr { 208 | var flds []*ast.Field 209 | for i, n := 0, t.NumEmbeddeds(); i < n; i++ { 210 | typ := toType(pkg, t.EmbeddedType(i)) 211 | fld := &ast.Field{Type: typ} 212 | flds = append(flds, fld) 213 | } 214 | for i, n := 0, t.NumExplicitMethods(); i < n; i++ { 215 | fn := t.ExplicitMethod(i) 216 | name := ident(fn.Name()) 217 | typ := toFuncType(pkg, fn.Type().(*types.Signature)) 218 | fld := &ast.Field{Names: []*ast.Ident{name}, Type: typ} 219 | flds = append(flds, fld) 220 | } 221 | return &ast.InterfaceType{Methods: &ast.FieldList{List: flds}} 222 | } 223 | -------------------------------------------------------------------------------- /_goremote/goremote.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "flag" 6 | "fmt" 7 | "go/ast" 8 | "go/parser" 9 | "go/token" 10 | "io" 11 | "os" 12 | "reflect" 13 | "strings" 14 | ) 15 | 16 | const prefix = "server_" 17 | 18 | func pretty_print_type_expr(out io.Writer, e ast.Expr) { 19 | ty := reflect.TypeOf(e) 20 | switch t := e.(type) { 21 | case *ast.StarExpr: 22 | fmt.Fprintf(out, "*") 23 | pretty_print_type_expr(out, t.X) 24 | case *ast.Ident: 25 | fmt.Fprintf(out, t.Name) 26 | case *ast.ArrayType: 27 | fmt.Fprintf(out, "[]") 28 | pretty_print_type_expr(out, t.Elt) 29 | case *ast.SelectorExpr: 30 | pretty_print_type_expr(out, t.X) 31 | fmt.Fprintf(out, ".%s", t.Sel.Name) 32 | case *ast.FuncType: 33 | fmt.Fprintf(out, "func(") 34 | pretty_print_func_field_list(out, t.Params) 35 | fmt.Fprintf(out, ")") 36 | 37 | buf := bytes.NewBuffer(make([]byte, 0, 256)) 38 | nresults := pretty_print_func_field_list(buf, t.Results) 39 | if nresults > 0 { 40 | results := buf.String() 41 | if strings.Index(results, " ") != -1 { 42 | results = "(" + results + ")" 43 | } 44 | fmt.Fprintf(out, " %s", results) 45 | } 46 | case *ast.MapType: 47 | fmt.Fprintf(out, "map[") 48 | pretty_print_type_expr(out, t.Key) 49 | fmt.Fprintf(out, "]") 50 | pretty_print_type_expr(out, t.Value) 51 | case *ast.InterfaceType: 52 | fmt.Fprintf(out, "interface{}") 53 | case *ast.Ellipsis: 54 | fmt.Fprintf(out, "...") 55 | pretty_print_type_expr(out, t.Elt) 56 | default: 57 | fmt.Fprintf(out, "\n[!!] unknown type: %s\n", ty.String()) 58 | } 59 | } 60 | 61 | func pretty_print_func_field_list(out io.Writer, f *ast.FieldList) int { 62 | count := 0 63 | if f == nil { 64 | return count 65 | } 66 | for i, field := range f.List { 67 | // names 68 | if field.Names != nil { 69 | for j, name := range field.Names { 70 | fmt.Fprintf(out, "%s", name.Name) 71 | if j != len(field.Names)-1 { 72 | fmt.Fprintf(out, ", ") 73 | } 74 | count++ 75 | } 76 | fmt.Fprintf(out, " ") 77 | } else { 78 | count++ 79 | } 80 | 81 | // type 82 | pretty_print_type_expr(out, field.Type) 83 | 84 | // , 85 | if i != len(f.List)-1 { 86 | fmt.Fprintf(out, ", ") 87 | } 88 | } 89 | return count 90 | } 91 | 92 | func pretty_print_func_field_list_using_args(out io.Writer, f *ast.FieldList) int { 93 | count := 0 94 | if f == nil { 95 | return count 96 | } 97 | for i, field := range f.List { 98 | // names 99 | if field.Names != nil { 100 | for j := range field.Names { 101 | fmt.Fprintf(out, "Arg%d", count) 102 | if j != len(field.Names)-1 { 103 | fmt.Fprintf(out, ", ") 104 | } 105 | count++ 106 | } 107 | fmt.Fprintf(out, " ") 108 | } else { 109 | count++ 110 | } 111 | 112 | // type 113 | pretty_print_type_expr(out, field.Type) 114 | 115 | // , 116 | if i != len(f.List)-1 { 117 | fmt.Fprintf(out, ", ") 118 | } 119 | } 120 | return count 121 | } 122 | 123 | func generate_struct_wrapper(out io.Writer, fun *ast.FieldList, structname, name string) int { 124 | fmt.Fprintf(out, "type %s_%s struct {\n", structname, name) 125 | argn := 0 126 | for _, field := range fun.List { 127 | fmt.Fprintf(out, "\t") 128 | // names 129 | if field.Names != nil { 130 | for j := range field.Names { 131 | fmt.Fprintf(out, "Arg%d", argn) 132 | if j != len(field.Names)-1 { 133 | fmt.Fprintf(out, ", ") 134 | } 135 | argn++ 136 | } 137 | fmt.Fprintf(out, " ") 138 | } else { 139 | fmt.Fprintf(out, "Arg%d ", argn) 140 | argn++ 141 | } 142 | 143 | // type 144 | pretty_print_type_expr(out, field.Type) 145 | 146 | // \n 147 | fmt.Fprintf(out, "\n") 148 | } 149 | fmt.Fprintf(out, "}\n") 150 | return argn 151 | } 152 | 153 | // function that is being exposed to an RPC API, but calls simple "Server_" one 154 | func generate_server_rpc_wrapper(out io.Writer, fun *ast.FuncDecl, name string, argcnt, replycnt int) { 155 | fmt.Fprintf(out, "func (r *RPC) RPC_%s(args *Args_%s, reply *Reply_%s) error {\n", 156 | name, name, name) 157 | 158 | fmt.Fprintf(out, "\t") 159 | for i := 0; i < replycnt; i++ { 160 | fmt.Fprintf(out, "reply.Arg%d", i) 161 | if i != replycnt-1 { 162 | fmt.Fprintf(out, ", ") 163 | } 164 | } 165 | fmt.Fprintf(out, " = %s(", fun.Name.Name) 166 | for i := 0; i < argcnt; i++ { 167 | fmt.Fprintf(out, "args.Arg%d", i) 168 | if i != argcnt-1 { 169 | fmt.Fprintf(out, ", ") 170 | } 171 | } 172 | fmt.Fprintf(out, ")\n") 173 | fmt.Fprintf(out, "\treturn nil\n}\n") 174 | } 175 | 176 | func generate_client_rpc_wrapper(out io.Writer, fun *ast.FuncDecl, name string, argcnt, replycnt int) { 177 | fmt.Fprintf(out, "func client_%s(cli *rpc.Client, ", name) 178 | pretty_print_func_field_list_using_args(out, fun.Type.Params) 179 | fmt.Fprintf(out, ")") 180 | 181 | buf := bytes.NewBuffer(make([]byte, 0, 256)) 182 | nresults := pretty_print_func_field_list(buf, fun.Type.Results) 183 | if nresults > 0 { 184 | results := buf.String() 185 | if strings.Index(results, " ") != -1 { 186 | results = "(" + results + ")" 187 | } 188 | fmt.Fprintf(out, " %s", results) 189 | } 190 | fmt.Fprintf(out, " {\n") 191 | fmt.Fprintf(out, "\tvar args Args_%s\n", name) 192 | fmt.Fprintf(out, "\tvar reply Reply_%s\n", name) 193 | for i := 0; i < argcnt; i++ { 194 | fmt.Fprintf(out, "\targs.Arg%d = Arg%d\n", i, i) 195 | } 196 | fmt.Fprintf(out, "\terr := cli.Call(\"RPC.RPC_%s\", &args, &reply)\n", name) 197 | fmt.Fprintf(out, "\tif err != nil {\n") 198 | fmt.Fprintf(out, "\t\tpanic(err)\n\t}\n") 199 | 200 | fmt.Fprintf(out, "\treturn ") 201 | for i := 0; i < replycnt; i++ { 202 | fmt.Fprintf(out, "reply.Arg%d", i) 203 | if i != replycnt-1 { 204 | fmt.Fprintf(out, ", ") 205 | } 206 | } 207 | fmt.Fprintf(out, "\n}\n") 208 | } 209 | 210 | func wrap_function(out io.Writer, fun *ast.FuncDecl) { 211 | name := fun.Name.Name[len(prefix):] 212 | fmt.Fprintf(out, "// wrapper for: %s\n\n", fun.Name.Name) 213 | argcnt := generate_struct_wrapper(out, fun.Type.Params, "Args", name) 214 | replycnt := generate_struct_wrapper(out, fun.Type.Results, "Reply", name) 215 | generate_server_rpc_wrapper(out, fun, name, argcnt, replycnt) 216 | generate_client_rpc_wrapper(out, fun, name, argcnt, replycnt) 217 | fmt.Fprintf(out, "\n") 218 | } 219 | 220 | func process_file(out io.Writer, filename string) { 221 | fset := token.NewFileSet() 222 | file, err := parser.ParseFile(fset, filename, nil, 0) 223 | if err != nil { 224 | panic(err) 225 | } 226 | 227 | for _, decl := range file.Decls { 228 | if fdecl, ok := decl.(*ast.FuncDecl); ok { 229 | namelen := len(fdecl.Name.Name) 230 | if namelen >= len(prefix) && fdecl.Name.Name[0:len(prefix)] == prefix { 231 | wrap_function(out, fdecl) 232 | } 233 | } 234 | } 235 | } 236 | 237 | const head = `// WARNING! Autogenerated by goremote, don't touch. 238 | 239 | package main 240 | 241 | import ( 242 | "net/rpc" 243 | ) 244 | 245 | type RPC struct { 246 | } 247 | 248 | ` 249 | 250 | func main() { 251 | flag.Parse() 252 | fmt.Fprintf(os.Stdout, head) 253 | for _, file := range flag.Args() { 254 | process_file(os.Stdout, file) 255 | } 256 | } 257 | -------------------------------------------------------------------------------- /types_go117.go: -------------------------------------------------------------------------------- 1 | //go:build !go1.18 2 | // +build !go1.18 3 | 4 | package main 5 | 6 | import ( 7 | "bytes" 8 | "fmt" 9 | "go/ast" 10 | "go/token" 11 | "go/types" 12 | "io" 13 | "strings" 14 | 15 | pkgwalk "github.com/visualfc/gotools/types" 16 | ) 17 | 18 | func unsupported() { 19 | panic("type parameters are unsupported at this go version") 20 | } 21 | 22 | var TILDE = token.VAR + 3 23 | 24 | type TypeParam struct{ types.Type } 25 | 26 | func (*TypeParam) String() string { unsupported(); return "" } 27 | func (*TypeParam) Underlying() types.Type { unsupported(); return nil } 28 | func (*TypeParam) Index() int { unsupported(); return 0 } 29 | func (*TypeParam) Constraint() types.Type { unsupported(); return nil } 30 | func (*TypeParam) SetConstraint(types.Type) { unsupported() } 31 | func (*TypeParam) Obj() *types.TypeName { unsupported(); return nil } 32 | 33 | // TypeParamList is a placeholder for an empty type parameter list. 34 | type TypeParamList struct{} 35 | 36 | func (*TypeParamList) Len() int { return 0 } 37 | func (*TypeParamList) At(int) *TypeParam { unsupported(); return nil } 38 | 39 | func newFuncType(tparams, params, results *ast.FieldList) *ast.FuncType { 40 | return &ast.FuncType{Params: params, Results: results} 41 | } 42 | 43 | func newTypeSpec(name string, tparams *ast.FieldList) *ast.TypeSpec { 44 | return &ast.TypeSpec{ 45 | Name: ast.NewIdent(name), 46 | } 47 | } 48 | 49 | func toTypeParam(pkg *types.Package, t *TypeParam) ast.Expr { 50 | unsupported() 51 | return nil 52 | } 53 | 54 | func toTypeSpec(pkg *types.Package, t *types.TypeName) *ast.TypeSpec { 55 | var assign token.Pos 56 | if t.IsAlias() { 57 | assign = 1 58 | } 59 | typ := t.Type() 60 | return &ast.TypeSpec{ 61 | Name: ast.NewIdent(t.Name()), 62 | Assign: assign, 63 | Type: toType(pkg, typ.Underlying()), 64 | } 65 | } 66 | 67 | func toFuncType(pkg *types.Package, sig *types.Signature) *ast.FuncType { 68 | params := toFieldList(pkg, sig.Params()) 69 | results := toFieldList(pkg, sig.Results()) 70 | if sig.Variadic() { 71 | n := len(params) 72 | if n == 0 { 73 | panic("TODO: toFuncType error") 74 | } 75 | toVariadic(params[n-1]) 76 | } 77 | return &ast.FuncType{ 78 | Params: &ast.FieldList{List: params}, 79 | Results: &ast.FieldList{List: results}, 80 | } 81 | } 82 | 83 | func ForFuncType(typ *ast.FuncType) *ast.FieldList { 84 | return nil 85 | } 86 | 87 | // converts type expressions like: 88 | // ast.Expr 89 | // *ast.Expr 90 | // $ast$go/ast.Expr 91 | // to a path that can be used to lookup a type related Decl 92 | func get_type_path(e ast.Expr) (r type_path) { 93 | if e == nil { 94 | return type_path{"", "", nil} 95 | } 96 | 97 | switch t := e.(type) { 98 | case *ast.Ident: 99 | r.name = t.Name 100 | case *ast.StarExpr: 101 | r = get_type_path(t.X) 102 | case *ast.SelectorExpr: 103 | if ident, ok := t.X.(*ast.Ident); ok { 104 | r.pkg = ident.Name 105 | } 106 | r.name = t.Sel.Name 107 | } 108 | return 109 | } 110 | 111 | func ast_decl_typeparams(decl ast.Decl) *ast.FieldList { 112 | return nil 113 | } 114 | 115 | func hasTypeParams(typ types.Type) bool { 116 | return false 117 | } 118 | 119 | func funcHasTypeParams(typ *ast.FuncType) bool { 120 | return false 121 | } 122 | 123 | func toNamedType(pkg *types.Package, t *types.Named) ast.Expr { 124 | return toObjectExpr(pkg, t.Obj()) 125 | } 126 | 127 | func lookup_types_near_instance(ident *ast.Ident, pos token.Pos, info *types.Info) types.Type { 128 | return nil 129 | } 130 | 131 | func DefaultPkgConfig() *pkgwalk.PkgConfig { 132 | conf := &pkgwalk.PkgConfig{IgnoreFuncBodies: false, AllowBinary: true, WithTestFiles: true} 133 | conf.Info = &types.Info{ 134 | Uses: make(map[*ast.Ident]types.Object), 135 | Defs: make(map[*ast.Ident]types.Object), 136 | Selections: make(map[*ast.SelectorExpr]*types.Selection), 137 | Types: make(map[ast.Expr]types.TypeAndValue), 138 | Scopes: make(map[ast.Node]*types.Scope), 139 | Implicits: make(map[ast.Node]types.Object), 140 | } 141 | conf.XInfo = &types.Info{ 142 | Uses: make(map[*ast.Ident]types.Object), 143 | Defs: make(map[*ast.Ident]types.Object), 144 | Selections: make(map[*ast.SelectorExpr]*types.Selection), 145 | Types: make(map[ast.Expr]types.TypeAndValue), 146 | Scopes: make(map[ast.Node]*types.Scope), 147 | Implicits: make(map[ast.Node]types.Object), 148 | } 149 | return conf 150 | } 151 | 152 | func pretty_print_type_expr(out io.Writer, e ast.Expr, canonical_aliases map[string]string) { 153 | switch t := e.(type) { 154 | case *ast.StarExpr: 155 | fmt.Fprintf(out, "*") 156 | pretty_print_type_expr(out, t.X, canonical_aliases) 157 | case *ast.Ident: 158 | if strings.HasPrefix(t.Name, "$") { 159 | // beautify anonymous types 160 | switch t.Name[1] { 161 | case 's': 162 | fmt.Fprintf(out, "struct") 163 | case 'i': 164 | // ok, in most cases anonymous interface is an 165 | // empty interface, I'll just pretend that 166 | // it's always true 167 | fmt.Fprintf(out, "interface{}") 168 | } 169 | } else if !*g_debug && strings.HasPrefix(t.Name, "!") { 170 | // these are full package names for disambiguating and pretty 171 | // printing packages within packages, e.g. 172 | // !go/ast!ast vs. !github.com/nsf/my/ast!ast 173 | // another ugly hack, if people are punished in hell for ugly hacks 174 | // I'm screwed... 175 | emarkIdx := strings.LastIndex(t.Name, "!") 176 | path := t.Name[1:emarkIdx] 177 | alias := canonical_aliases[path] 178 | if alias == "" { 179 | alias = t.Name[emarkIdx+1:] 180 | } 181 | fmt.Fprintf(out, alias) 182 | } else { 183 | fmt.Fprintf(out, t.Name) 184 | } 185 | case *ast.ArrayType: 186 | al := "" 187 | if t.Len != nil { 188 | al = get_array_len(t.Len) 189 | } 190 | if al != "" { 191 | fmt.Fprintf(out, "[%s]", al) 192 | } else { 193 | fmt.Fprintf(out, "[]") 194 | } 195 | pretty_print_type_expr(out, t.Elt, canonical_aliases) 196 | case *ast.SelectorExpr: 197 | pretty_print_type_expr(out, t.X, canonical_aliases) 198 | fmt.Fprintf(out, ".%s", t.Sel.Name) 199 | case *ast.FuncType: 200 | fmt.Fprintf(out, "func(") 201 | pretty_print_func_field_list(out, t.Params, canonical_aliases) 202 | fmt.Fprintf(out, ")") 203 | 204 | buf := bytes.NewBuffer(make([]byte, 0, 256)) 205 | nresults := pretty_print_func_field_list(buf, t.Results, canonical_aliases) 206 | if nresults > 0 { 207 | results := buf.String() 208 | if strings.IndexAny(results, ", ") != -1 { 209 | results = "(" + results + ")" 210 | } 211 | fmt.Fprintf(out, " %s", results) 212 | } 213 | case *ast.MapType: 214 | fmt.Fprintf(out, "map[") 215 | pretty_print_type_expr(out, t.Key, canonical_aliases) 216 | fmt.Fprintf(out, "]") 217 | pretty_print_type_expr(out, t.Value, canonical_aliases) 218 | case *ast.InterfaceType: 219 | fmt.Fprintf(out, "interface{}") 220 | case *ast.Ellipsis: 221 | fmt.Fprintf(out, "...") 222 | pretty_print_type_expr(out, t.Elt, canonical_aliases) 223 | case *ast.StructType: 224 | fmt.Fprintf(out, "struct") 225 | case *ast.ChanType: 226 | switch t.Dir { 227 | case ast.RECV: 228 | fmt.Fprintf(out, "<-chan ") 229 | case ast.SEND: 230 | fmt.Fprintf(out, "chan<- ") 231 | case ast.SEND | ast.RECV: 232 | fmt.Fprintf(out, "chan ") 233 | } 234 | pretty_print_type_expr(out, t.Value, canonical_aliases) 235 | case *ast.ParenExpr: 236 | fmt.Fprintf(out, "(") 237 | pretty_print_type_expr(out, t.X, canonical_aliases) 238 | fmt.Fprintf(out, ")") 239 | case *ast.BadExpr: 240 | // TODO: probably I should check that in a separate function 241 | // and simply discard declarations with BadExpr as a part of their 242 | // type 243 | default: 244 | // the element has some weird type, just ignore it 245 | } 246 | } 247 | 248 | func funHasTypeArgs(fun ast.Expr) bool { 249 | return false 250 | } 251 | --------------------------------------------------------------------------------