Skip to content
Newer
Older
100644 221 lines (198 sloc) 5.18 KB
a920047 @nsf Progress..
authored
1 package main
2
3 import (
8e75aff @nsf Add a config option to enable the debug mode and redirect logging.
authored
4 "bytes"
ed57256 @nsf Format everything with gofmt.
authored
5 "fmt"
014025c @nsf Experimental Go 1.5 vendoring support. It's always enabled.
authored
6 "go/build"
15511c3 @tiziano88 Log using the "log" package when in debug mode.
tiziano88 authored
7 "log"
a920047 @nsf Progress..
authored
8 "net"
fff16d1 @nsf Big refactoring, CamelCase -> words_with_underscores.
authored
9 "net/rpc"
4e9d7cf @nsf Separate code from gocode.go to client.go and server.go.
authored
10 "os"
014025c @nsf Experimental Go 1.5 vendoring support. It's always enabled.
authored
11 "path/filepath"
cd29ae0 @tiziano88 Use build.Context instead of gocode_env.
tiziano88 authored
12 "reflect"
ed57256 @nsf Format everything with gofmt.
authored
13 "runtime"
6379b17 @nsf Implement basics of a client and a server using jsonrpc.
authored
14 )
15
4e9d7cf @nsf Separate code from gocode.go to client.go and server.go.
authored
16 func do_server() int {
17 g_config.read()
8e75aff @nsf Add a config option to enable the debug mode and redirect logging.
authored
18 if g_config.ForceDebugOutput != "" {
19 // forcefully enable debugging and redirect logging into the
20 // specified file
21 *g_debug = true
22 f, err := os.Create(g_config.ForceDebugOutput)
23 if err != nil {
24 panic(err)
25 }
26 log.SetOutput(f)
27 }
4e9d7cf @nsf Separate code from gocode.go to client.go and server.go.
authored
28
29 addr := *g_addr
30 if *g_sock == "unix" {
31 addr = get_socket_filename()
32 if file_exists(addr) {
15511c3 @tiziano88 Log using the "log" package when in debug mode.
tiziano88 authored
33 log.Printf("unix socket: '%s' already exists\n", addr)
4e9d7cf @nsf Separate code from gocode.go to client.go and server.go.
authored
34 return 1
35 }
36 }
37 g_daemon = new_daemon(*g_sock, addr)
38 if *g_sock == "unix" {
39 // cleanup unix socket file
40 defer os.Remove(addr)
41 }
42
43 rpc.Register(new(RPC))
44
45 g_daemon.loop()
46 return 0
47 }
48
6379b17 @nsf Implement basics of a client and a server using jsonrpc.
authored
49 //-------------------------------------------------------------------------
fff16d1 @nsf Big refactoring, CamelCase -> words_with_underscores.
authored
50 // daemon
e30aeaa @nsf Misc comment updates and renames.
authored
51 //-------------------------------------------------------------------------
6379b17 @nsf Implement basics of a client and a server using jsonrpc.
authored
52
fff16d1 @nsf Big refactoring, CamelCase -> words_with_underscores.
authored
53 type daemon struct {
54 listener net.Listener
55 cmd_in chan int
56 autocomplete *auto_complete_context
57 pkgcache package_cache
58 declcache *decl_cache
61468c3 @nsf Add new config options: "package-lookup-mode".
authored
59 context package_lookup_context
6379b17 @nsf Implement basics of a client and a server using jsonrpc.
authored
60 }
61
fff16d1 @nsf Big refactoring, CamelCase -> words_with_underscores.
authored
62 func new_daemon(network, address string) *daemon {
63 var err error
64
65 d := new(daemon)
66 d.listener, err = net.Listen(network, address)
67 if err != nil {
68 panic(err)
69 }
70
71 d.cmd_in = make(chan int, 1)
72 d.pkgcache = new_package_cache()
61468c3 @nsf Add new config options: "package-lookup-mode".
authored
73 d.declcache = new_decl_cache(&d.context)
fff16d1 @nsf Big refactoring, CamelCase -> words_with_underscores.
authored
74 d.autocomplete = new_auto_complete_context(d.pkgcache, d.declcache)
668b580 @nsf Get rid of 'self' name in method variables.
authored
75 return d
6379b17 @nsf Implement basics of a client and a server using jsonrpc.
authored
76 }
77
fff16d1 @nsf Big refactoring, CamelCase -> words_with_underscores.
authored
78 func (this *daemon) drop_cache() {
79 this.pkgcache = new_package_cache()
61468c3 @nsf Add new config options: "package-lookup-mode".
authored
80 this.declcache = new_decl_cache(&this.context)
fff16d1 @nsf Big refactoring, CamelCase -> words_with_underscores.
authored
81 this.autocomplete = new_auto_complete_context(this.pkgcache, this.declcache)
82 }
83
84 const (
85 daemon_close = iota
86 )
87
88 func (this *daemon) loop() {
89 conn_in := make(chan net.Conn)
90 go func() {
91 for {
92 c, err := this.listener.Accept()
93 if err != nil {
94 panic(err)
95 }
96 conn_in <- c
97 }
98 }()
99 for {
100 // handle connections or server CMDs (currently one CMD)
101 select {
102 case c := <-conn_in:
103 rpc.ServeConn(c)
104 runtime.GC()
105 case cmd := <-this.cmd_in:
106 switch cmd {
107 case daemon_close:
108 return
109 }
110 }
111 }
112 }
113
114 func (this *daemon) close() {
115 this.cmd_in <- daemon_close
a5ad476 @nsf Add semanticcontext.go, a first step towards refactoring functionality.
authored
116 }
117
fff16d1 @nsf Big refactoring, CamelCase -> words_with_underscores.
authored
118 var g_daemon *daemon
94b7b01 @nsf More mess, change jsonrpc to simple rpc (uses gob).
authored
119
120 //-------------------------------------------------------------------------
fff16d1 @nsf Big refactoring, CamelCase -> words_with_underscores.
authored
121 // server_* functions
e30aeaa @nsf Misc comment updates and renames.
authored
122 //
fff16d1 @nsf Big refactoring, CamelCase -> words_with_underscores.
authored
123 // Corresponding client_* functions are autogenerated by goremote.
e30aeaa @nsf Misc comment updates and renames.
authored
124 //-------------------------------------------------------------------------
125
bd50cc0 @nsf Workaround for previous "encoding/gob" versions.
authored
126 func server_auto_complete(file []byte, filename string, cursor int, context_packed go_build_context) (c []candidate, d int) {
127 context := unpack_build_context(&context_packed)
e88dab2 @nsf Implement failsafe service.
authored
128 defer func() {
129 if err := recover(); err != nil {
fff16d1 @nsf Big refactoring, CamelCase -> words_with_underscores.
authored
130 print_backtrace(err)
4a058ff @nsf Structify the communication between daemon and client.
authored
131 c = []candidate{
8ce3695 @nsf Make the class into an integer type.
authored
132 {"PANIC", "PANIC", decl_invalid},
4a058ff @nsf Structify the communication between daemon and client.
authored
133 }
3bd2d40 @nsf Add drop-cache command and support for local packages.
authored
134
135 // drop cache
fff16d1 @nsf Big refactoring, CamelCase -> words_with_underscores.
authored
136 g_daemon.drop_cache()
e88dab2 @nsf Implement failsafe service.
authored
137 }
138 }()
cd29ae0 @tiziano88 Use build.Context instead of gocode_env.
tiziano88 authored
139 // TODO: Probably we don't care about comparing all the fields, checking GOROOT and GOPATH
140 // should be enough.
16e3f34 @chzyer fix cache missing
chzyer authored
141 if !reflect.DeepEqual(g_daemon.context.Context, context.Context) {
cd29ae0 @tiziano88 Use build.Context instead of gocode_env.
tiziano88 authored
142 g_daemon.context = context
4d2620a @nsf Pass some of the environment variables from client to server. Closes #79
authored
143 g_daemon.drop_cache()
144 }
014025c @nsf Experimental Go 1.5 vendoring support. It's always enabled.
authored
145 switch g_config.PackageLookupMode {
146 case "gb":
61468c3 @nsf Add new config options: "package-lookup-mode".
authored
147 // when package lookup mode is gb, we set GOPATH to "" explicitly and
148 // GBProjectRoot becomes valid (or empty)
149 var err error
150 g_daemon.context.GOPATH = ""
151 g_daemon.context.GBProjectRoot, err = find_gb_project_root(filename)
db85a48 @nsf Minor logging fixes.
authored
152 if *g_debug && err != nil {
61468c3 @nsf Add new config options: "package-lookup-mode".
authored
153 log.Printf("Gb project root not found: %s", err)
154 }
014025c @nsf Experimental Go 1.5 vendoring support. It's always enabled.
authored
155 case "go":
156 // get current package path for GO15VENDOREXPERIMENT hack
157 g_daemon.context.CurrentPackagePath = ""
158 pkg, err := g_daemon.context.ImportDir(filepath.Dir(filename), build.FindOnly)
159 if err == nil {
db85a48 @nsf Minor logging fixes.
authored
160 if *g_debug {
161 log.Printf("Go project path: %s", pkg.ImportPath)
162 }
014025c @nsf Experimental Go 1.5 vendoring support. It's always enabled.
authored
163 g_daemon.context.CurrentPackagePath = pkg.ImportPath
164 } else if *g_debug {
165 log.Printf("Go project path not found: %s", err)
166 }
61468c3 @nsf Add new config options: "package-lookup-mode".
authored
167 }
723821c @nsf Add -debug mode for developers.
authored
168 if *g_debug {
dedd9e7 @nsf Misc improvements for -debug logging.
authored
169 var buf bytes.Buffer
15511c3 @tiziano88 Log using the "log" package when in debug mode.
tiziano88 authored
170 log.Printf("Got autocompletion request for '%s'\n", filename)
171 log.Printf("Cursor at: %d\n", cursor)
dedd9e7 @nsf Misc improvements for -debug logging.
authored
172 buf.WriteString("-------------------------------------------------------\n")
173 buf.Write(file[:cursor])
174 buf.WriteString("#")
175 buf.Write(file[cursor:])
176 log.Print(buf.String())
15511c3 @tiziano88 Log using the "log" package when in debug mode.
tiziano88 authored
177 log.Println("-------------------------------------------------------")
723821c @nsf Add -debug mode for developers.
authored
178 }
b90a229 @nsf Extend -debug mode by including completion candidates, add docs.
authored
179 candidates, d := g_daemon.autocomplete.apropos(file, filename, cursor)
180 if *g_debug {
15511c3 @tiziano88 Log using the "log" package when in debug mode.
tiziano88 authored
181 log.Printf("Offset: %d\n", d)
182 log.Printf("Number of candidates found: %d\n", len(candidates))
183 log.Printf("Candidates are:\n")
b90a229 @nsf Extend -debug mode by including completion candidates, add docs.
authored
184 for _, c := range candidates {
185 abbr := fmt.Sprintf("%s %s %s", c.Class, c.Name, c.Type)
186 if c.Class == decl_func {
187 abbr = fmt.Sprintf("%s %s%s", c.Class, c.Name, c.Type[len("func"):])
188 }
15511c3 @tiziano88 Log using the "log" package when in debug mode.
tiziano88 authored
189 log.Printf(" %s\n", abbr)
b90a229 @nsf Extend -debug mode by including completion candidates, add docs.
authored
190 }
15511c3 @tiziano88 Log using the "log" package when in debug mode.
tiziano88 authored
191 log.Println("=======================================================")
b90a229 @nsf Extend -debug mode by including completion candidates, add docs.
authored
192 }
193 return candidates, d
6379b17 @nsf Implement basics of a client and a server using jsonrpc.
authored
194 }
195
fff16d1 @nsf Big refactoring, CamelCase -> words_with_underscores.
authored
196 func server_close(notused int) int {
197 g_daemon.close()
94b7b01 @nsf More mess, change jsonrpc to simple rpc (uses gob).
authored
198 return 0
6379b17 @nsf Implement basics of a client and a server using jsonrpc.
authored
199 }
200
fff16d1 @nsf Big refactoring, CamelCase -> words_with_underscores.
authored
201 func server_status(notused int) string {
202 return g_daemon.autocomplete.status()
a5fa988 @nsf Add new "status" command. Server now handles one request at a time.
authored
203 }
204
fff16d1 @nsf Big refactoring, CamelCase -> words_with_underscores.
authored
205 func server_drop_cache(notused int) int {
3bd2d40 @nsf Add drop-cache command and support for local packages.
authored
206 // drop cache
fff16d1 @nsf Big refactoring, CamelCase -> words_with_underscores.
authored
207 g_daemon.drop_cache()
3bd2d40 @nsf Add drop-cache command and support for local packages.
authored
208 return 0
209 }
210
fff16d1 @nsf Big refactoring, CamelCase -> words_with_underscores.
authored
211 func server_set(key, value string) string {
a889242 @nsf Radical change. Move towards goinstall compatibility.
authored
212 if key == "\x00" {
fff16d1 @nsf Big refactoring, CamelCase -> words_with_underscores.
authored
213 return g_config.list()
a889242 @nsf Radical change. Move towards goinstall compatibility.
authored
214 } else if value == "\x00" {
fff16d1 @nsf Big refactoring, CamelCase -> words_with_underscores.
authored
215 return g_config.list_option(key)
6379b17 @nsf Implement basics of a client and a server using jsonrpc.
authored
216 }
61468c3 @nsf Add new config options: "package-lookup-mode".
authored
217 // drop cache on settings changes
218 g_daemon.drop_cache()
fff16d1 @nsf Big refactoring, CamelCase -> words_with_underscores.
authored
219 return g_config.set_option(key, value)
a920047 @nsf Progress..
authored
220 }
Something went wrong with that request. Please try again.