-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathcontroller.py
More file actions
161 lines (142 loc) · 6.1 KB
/
controller.py
File metadata and controls
161 lines (142 loc) · 6.1 KB
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#!/usr/bin/env python2
from __future__ import absolute_import
import codeintel2.common
from codeintel2.common import EvalController
import logging
from six.moves import cStringIO as StringIO
import pprint
from six.moves import map
log = logging.getLogger("codeintel.oop.controller")
class OOPEvalController(EvalController):
"""Eval controller for out-of-process codeintel
"""
have_errors = have_warnings = False
silent = False
def __init__(self, driver=None, request=None, trg=None, *args, **kwargs):
"""Create an eval controller
@param driver {Driver} The OOP driver instance to communicate via
@param request {Request} The request causing the evaluation
"""
log.debug("__init__")
EvalController.__init__(self, *args, **kwargs)
self.driver = driver
self.request = request
self.trg = trg
self.silent = request.get("silent", False)
self.keep_existing = request.get("keep_existing", self.keep_existing)
# Set up a *new* logger to record any errors
# Note that the output will be discarded if there is no error
self.log_stream = StringIO()
self.log_hndlr = logging.StreamHandler(self.log_stream)
loggerClass = logging.Logger.manager.loggerClass
if not loggerClass:
loggerClass = logging.getLoggerClass()
self.log = loggerClass("codeintel.evaluator")
self.log.manager = logging.Logger.manager
self.log.propagate = False
self.log.addHandler(self.log_hndlr)
self.best_msg = (0, "")
self.has_sent_response = False
def close(self):
log.debug("close")
EvalController.close(self)
if not self.has_sent_response:
self.driver.fail(request=self.request, message="aborted")
self.has_sent_response = True
def set_desc(self, desc):
log.debug("set_desc: %s", desc)
EvalController.set_desc(self, desc)
if not self.silent:
# Reset the formatter to be minimal
fmt = logging.Formatter(fmt=" %(levelname)s: %(message)s")
self.log_hndlr.setFormatter(fmt)
def setStatusMessage(self, msg, highlight):
log.debug("setStatusMessage: %s, %s", msg, highlight)
self.driver.send(request=self.request, success=None,
message=msg, highlight=highlight)
def abort(self):
log.debug("abort: %r", self.request)
if self.is_aborted:
# Controllers don't abort immediately; this is in the process of
# aborting but hasn't finished yet
log.debug("Suppressing repeat abort message: %r", self.request)
return
EvalController.abort(self)
self.driver.fail(request=self.request, message="aborted")
def done(self, reason):
if log.isEnabledFor(logging.DEBUG):
log.debug("done: %s %s\n%s", reason, "(aborted)" if self.is_aborted() else "", self.log_stream.getvalue())
self.has_sent_response = True
retrigger = self.trg.retriggerOnCompletion if self.trg else False
if self.cplns:
# Report completions
self.driver.send(cplns=self.cplns, request=self.request,
retrigger=retrigger)
elif self.calltips:
self.driver.send(calltip=self.calltips[0], request=self.request,
retrigger=retrigger)
elif self.defns:
# We can't exactly serialize blobs directly...
def defn_serializer(defn):
return defn.__dict__
self.driver.send(defns=list(map(defn_serializer, self.defns or [])),
request=self.request, retrigger=retrigger)
elif self.is_aborted():
pass # already reported the abort
elif self.best_msg[0]:
try:
msg = "No %s found" % (self.desc,)
if self.have_errors:
msg = self.best_msg[1] + " (error determining %s)" % (self.desc,)
self.driver.report_error(self.log_stream.getvalue())
elif self.have_warnings:
msg += "(warning: %s)" % (self.best_msg[1],)
except TypeError as ex:
# Guard against this common problem in log formatting above:
# TypeError: not enough arguments for format string
log.exception("problem logging eval failure: self.log=%r", self.log_entries)
msg = "error evaluating '%s'" % self.desc
self.driver.fail(request=self.request, message=msg)
else:
# ERROR
self.driver.fail(request=self.request, message=reason)
self.log = log # If we have any more problems, put it in the main log
self.log_stream.close()
EvalController.done(self, reason)
def setup_log(self):
if not self.desc:
desc = {codeintel2.common.TRG_FORM_CPLN: "completions",
codeintel2.common.TRG_FORM_CALLTIP: "calltip",
codeintel2.common.TRG_FORM_DEFN: "definition",
}.get(self.trg.form, "???")
self.set_desc(desc)
def debug(self, msg, *args):
if self.silent:
return
self.setup_log()
self.log.debug(msg, *args)
if self.best_msg[0] < logging.DEBUG:
self.best_msg = (logging.DEBUG, msg % args)
def info(self, msg, *args):
if self.silent:
return
self.setup_log()
self.log.info(msg, *args)
if self.best_msg[0] < logging.INFO:
self.best_msg = (logging.INFO, msg % args)
def warn(self, msg, *args):
if self.silent:
return
self.setup_log()
self.log.warn(msg, *args)
if self.best_msg[0] < logging.WARN:
self.best_msg = (logging.WARN, msg % args)
self.have_warnings = True
def error(self, msg, *args):
if self.silent:
return
self.setup_log()
self.log.error(msg, *args)
if self.best_msg[0] < logging.ERROR:
self.best_msg = (logging.ERROR, msg % args)
self.have_errors = True