forked from mdempsky/gocode
/
server.go
114 lines (100 loc) · 2.36 KB
/
server.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package main
import (
"bytes"
"fmt"
"go/types"
"log"
"net"
"net/rpc"
"os"
"os/signal"
"runtime/debug"
"time"
"github.com/mdempsky/gocode/gbimporter"
"github.com/mdempsky/gocode/suggest"
)
func doServer() {
addr := *g_addr
if *g_sock == "unix" {
addr = getSocketPath()
}
lis, err := net.Listen(*g_sock, addr)
if err != nil {
log.Fatal(err)
}
sigs := make(chan os.Signal)
signal.Notify(sigs, os.Interrupt)
go func() {
<-sigs
exitServer()
}()
if err = rpc.Register(&Server{}); err != nil {
log.Fatal(err)
}
rpc.Accept(lis)
}
func exitServer() {
if *g_sock == "unix" {
_ = os.Remove(getSocketPath())
}
os.Exit(0)
}
type Server struct {
}
type AutoCompleteRequest struct {
Filename string
Data []byte
Cursor int
Context gbimporter.PackedContext
}
type AutoCompleteReply struct {
Candidates []suggest.Candidate
Len int
}
func (s *Server) AutoComplete(req *AutoCompleteRequest, res *AutoCompleteReply) error {
defer func() {
if err := recover(); err != nil {
fmt.Printf("panic: %s\n\n", err)
debug.PrintStack()
res.Candidates = []suggest.Candidate{
{Class: "PANIC", Name: "PANIC", Type: "PANIC"},
}
}
}()
if *g_debug {
var buf bytes.Buffer
log.Printf("Got autocompletion request for '%s'\n", req.Filename)
log.Printf("Cursor at: %d\n", req.Cursor)
buf.WriteString("-------------------------------------------------------\n")
buf.Write(req.Data[:req.Cursor])
buf.WriteString("#")
buf.Write(req.Data[req.Cursor:])
log.Print(buf.String())
log.Println("-------------------------------------------------------")
}
now := time.Now()
var imp types.Importer = gbimporter.New(&req.Context, req.Filename)
candidates, d := suggest.New(*g_debug).Suggest(imp, req.Filename, req.Data, req.Cursor)
elapsed := time.Since(now)
if *g_debug {
log.Printf("Elapsed duration: %v\n", elapsed)
log.Printf("Offset: %d\n", res.Len)
log.Printf("Number of candidates found: %d\n", len(candidates))
log.Printf("Candidates are:\n")
for _, c := range candidates {
log.Printf(" %s\n", c.String())
}
log.Println("=======================================================")
}
res.Candidates, res.Len = candidates, d
return nil
}
type ExitRequest struct{}
type ExitReply struct{}
func (s *Server) Exit(req *ExitRequest, res *ExitReply) error {
go func() {
time.Sleep(time.Second)
exitServer()
}()
return nil
}