@@ -56,11 +56,11 @@ def _get_top_level_module(cls, path): |
56 | 56 | def _generate_signature(self, completion): |
57 | 57 | """Generate signature with function arguments. |
58 | 58 | """ |
59 | | - if not hasattr(completion, 'params'): |
| 59 | + if completion.type in ['module'] or not hasattr(completion, 'params'): |
60 | 60 | return '' |
61 | 61 | return '%s(%s)' % ( |
62 | 62 | completion.name, |
63 | | - ', '.join(param.description for param in completion.params)) |
| 63 | + ', '.join(p.description for p in completion.params if p)) |
64 | 64 |
|
65 | 65 | def _get_call_signatures(self, script): |
66 | 66 | """Extract call signatures from jedi.api.Script object in failsafe way. |
@@ -195,6 +195,38 @@ def _serialize_completions(self, script, identifier=None, prefix=''): |
195 | 195 | _completions.append(_completion) |
196 | 196 | return json.dumps({'id': identifier, 'results': _completions}) |
197 | 197 |
|
| 198 | + def _serialize_methods(self, script, identifier=None, prefix=''): |
| 199 | + _methods = [] |
| 200 | + try: |
| 201 | + completions = script.completions() |
| 202 | + except KeyError: |
| 203 | + return [] |
| 204 | + |
| 205 | + for completion in completions: |
| 206 | + if completion.name == '__autocomplete_python': |
| 207 | + instance = completion.parent().name |
| 208 | + break |
| 209 | + else: |
| 210 | + instance = 'self.__class__' |
| 211 | + |
| 212 | + for completion in completions: |
| 213 | + params = [] |
| 214 | + if hasattr(completion, 'params'): |
| 215 | + params = [p.description for p in completion.params |
| 216 | + if ARGUMENT_RE.match(p.description)] |
| 217 | + if completion.parent().type == 'class': |
| 218 | + _methods.append({ |
| 219 | + 'parent': completion.parent().name, |
| 220 | + 'instance': instance, |
| 221 | + 'name': completion.name, |
| 222 | + 'params': params, |
| 223 | + 'moduleName': completion.module_name, |
| 224 | + 'fileName': completion.module_path, |
| 225 | + 'line': completion.line, |
| 226 | + 'column': completion.column, |
| 227 | + }) |
| 228 | + return json.dumps({'id': identifier, 'results': _methods}) |
| 229 | + |
198 | 230 | def _serialize_arguments(self, script, identifier=None): |
199 | 231 | """Serialize response to be read from VSCode. |
200 | 232 |
|
@@ -207,6 +239,16 @@ def _serialize_arguments(self, script, identifier=None): |
207 | 239 | """ |
208 | 240 | return json.dumps({"id": identifier, "results": self._get_call_signatures_with_args(script)}) |
209 | 241 |
|
| 242 | + def _top_definition(self, definition): |
| 243 | + for d in definition.goto_assignments(): |
| 244 | + if d == definition: |
| 245 | + continue |
| 246 | + if d.type == 'import': |
| 247 | + return self._top_definition(d) |
| 248 | + else: |
| 249 | + return d |
| 250 | + return definition |
| 251 | + |
210 | 252 | def _serialize_definitions(self, definitions, identifier=None): |
211 | 253 | """Serialize response to be read from VSCode. |
212 | 254 |
|
@@ -217,24 +259,14 @@ def _serialize_definitions(self, definitions, identifier=None): |
217 | 259 | Returns: |
218 | 260 | Serialized string to send to VSCode. |
219 | 261 | """ |
220 | | - |
221 | | - def _top_definition(definition): |
222 | | - for d in definition.goto_assignments(): |
223 | | - if d == definition: |
224 | | - continue |
225 | | - if d.type == 'import': |
226 | | - return _top_definition(d) |
227 | | - else: |
228 | | - return d |
229 | | - return definition |
230 | | - |
231 | 262 | _definitions = [] |
232 | 263 | for definition in definitions: |
233 | 264 | try: |
234 | 265 | if definition.module_path: |
235 | 266 | if definition.type == 'import': |
236 | | - definition = _top_definition(definition) |
237 | | - |
| 267 | + definition = self._top_definition(definition) |
| 268 | + if not definition.module_path: |
| 269 | + continue |
238 | 270 | _definition = { |
239 | 271 | 'text': definition.name, |
240 | 272 | 'type': self._get_definition_type(definition), |
@@ -248,6 +280,32 @@ def _top_definition(definition): |
248 | 280 | pass |
249 | 281 | return json.dumps({'id': identifier, 'results': _definitions}) |
250 | 282 |
|
| 283 | + def _serialize_tooltip(self, definitions, identifier=None): |
| 284 | + _definitions = [] |
| 285 | + for definition in definitions: |
| 286 | + if definition.module_path: |
| 287 | + if definition.type == 'import': |
| 288 | + definition = self._top_definition(definition) |
| 289 | + if not definition.module_path: |
| 290 | + continue |
| 291 | + |
| 292 | + description = definition.docstring() |
| 293 | + if description is not None: |
| 294 | + description = description.strip() |
| 295 | + if not description: |
| 296 | + description = self._additional_info(definition) |
| 297 | + _definition = { |
| 298 | + 'text': definition.name, |
| 299 | + 'type': self._get_definition_type(definition), |
| 300 | + 'fileName': definition.module_path, |
| 301 | + 'description': description, |
| 302 | + 'line': definition.line - 1, |
| 303 | + 'column': definition.column |
| 304 | + } |
| 305 | + _definitions.append(_definition) |
| 306 | + break |
| 307 | + return json.dumps({'id': identifier, 'results': _definitions}) |
| 308 | + |
251 | 309 | def _serialize_usages(self, usages, identifier=None): |
252 | 310 | _usages = [] |
253 | 311 | for usage in usages: |
@@ -318,12 +376,19 @@ def _process_request(self, request): |
318 | 376 | if lookup == 'definitions': |
319 | 377 | return self._write_response(self._serialize_definitions( |
320 | 378 | script.goto_assignments(), request['id'])) |
| 379 | + if lookup == 'tooltip': |
| 380 | + return self._write_response(self._serialize_tooltip( |
| 381 | + script.goto_assignments(), request['id'])) |
321 | 382 | elif lookup == 'arguments': |
322 | 383 | return self._write_response(self._serialize_arguments( |
323 | 384 | script, request['id'])) |
324 | 385 | elif lookup == 'usages': |
325 | 386 | return self._write_response(self._serialize_usages( |
326 | 387 | script.usages(), request['id'])) |
| 388 | + elif lookup == 'methods': |
| 389 | + return self._write_response( |
| 390 | + self._serialize_methods(script, request['id'], |
| 391 | + request.get('prefix', ''))) |
327 | 392 | else: |
328 | 393 | return self._write_response( |
329 | 394 | self._serialize_completions(script, request['id'], |
|