Skip to content

Commit 963325c

Browse files
committed
fixed signature providers
1 parent d3a0414 commit 963325c

2 files changed

Lines changed: 90 additions & 27 deletions

File tree

pythonFiles/completion.py

Lines changed: 80 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ def _get_top_level_module(cls, path):
5656
def _generate_signature(self, completion):
5757
"""Generate signature with function arguments.
5858
"""
59-
if not hasattr(completion, 'params'):
59+
if completion.type in ['module'] or not hasattr(completion, 'params'):
6060
return ''
6161
return '%s(%s)' % (
6262
completion.name,
63-
', '.join(param.description for param in completion.params))
63+
', '.join(p.description for p in completion.params if p))
6464

6565
def _get_call_signatures(self, script):
6666
"""Extract call signatures from jedi.api.Script object in failsafe way.
@@ -195,6 +195,38 @@ def _serialize_completions(self, script, identifier=None, prefix=''):
195195
_completions.append(_completion)
196196
return json.dumps({'id': identifier, 'results': _completions})
197197

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+
198230
def _serialize_arguments(self, script, identifier=None):
199231
"""Serialize response to be read from VSCode.
200232
@@ -207,6 +239,16 @@ def _serialize_arguments(self, script, identifier=None):
207239
"""
208240
return json.dumps({"id": identifier, "results": self._get_call_signatures_with_args(script)})
209241

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+
210252
def _serialize_definitions(self, definitions, identifier=None):
211253
"""Serialize response to be read from VSCode.
212254
@@ -217,24 +259,14 @@ def _serialize_definitions(self, definitions, identifier=None):
217259
Returns:
218260
Serialized string to send to VSCode.
219261
"""
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-
231262
_definitions = []
232263
for definition in definitions:
233264
try:
234265
if definition.module_path:
235266
if definition.type == 'import':
236-
definition = _top_definition(definition)
237-
267+
definition = self._top_definition(definition)
268+
if not definition.module_path:
269+
continue
238270
_definition = {
239271
'text': definition.name,
240272
'type': self._get_definition_type(definition),
@@ -248,6 +280,32 @@ def _top_definition(definition):
248280
pass
249281
return json.dumps({'id': identifier, 'results': _definitions})
250282

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+
251309
def _serialize_usages(self, usages, identifier=None):
252310
_usages = []
253311
for usage in usages:
@@ -318,12 +376,19 @@ def _process_request(self, request):
318376
if lookup == 'definitions':
319377
return self._write_response(self._serialize_definitions(
320378
script.goto_assignments(), request['id']))
379+
if lookup == 'tooltip':
380+
return self._write_response(self._serialize_tooltip(
381+
script.goto_assignments(), request['id']))
321382
elif lookup == 'arguments':
322383
return self._write_response(self._serialize_arguments(
323384
script, request['id']))
324385
elif lookup == 'usages':
325386
return self._write_response(self._serialize_usages(
326387
script.usages(), request['id']))
388+
elif lookup == 'methods':
389+
return self._write_response(
390+
self._serialize_methods(script, request['id'],
391+
request.get('prefix', '')))
327392
else:
328393
return self._write_response(
329394
self._serialize_completions(script, request['id'],

src/client/providers/signatureProvider.ts

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -80,18 +80,16 @@ export class PythonSignatureProvider implements vscode.SignatureHelpProvider {
8080
return new SignatureHelp();
8181
}
8282
provideSignatureHelp(document: TextDocument, position: Position, token: CancellationToken): Thenable<SignatureHelp> {
83-
return new Promise<SignatureHelp>((resolve, reject) => {
84-
let cmd: proxy.ICommand<proxy.IArgumentsResult> = {
85-
telemetryEvent: telemetryContracts.IDE.Symbol,
86-
command: proxy.CommandType.Arguments,
87-
fileName: document.fileName,
88-
columnIndex: position.character,
89-
lineIndex: position.line,
90-
source: document.getText()
91-
};
92-
return this.jediProxyHandler.sendCommand(cmd, token).then(data => {
93-
return PythonSignatureProvider.parseData(data);
94-
});
83+
let cmd: proxy.ICommand<proxy.IArgumentsResult> = {
84+
telemetryEvent: telemetryContracts.IDE.Symbol,
85+
command: proxy.CommandType.Arguments,
86+
fileName: document.fileName,
87+
columnIndex: position.character,
88+
lineIndex: position.line,
89+
source: document.getText()
90+
};
91+
return this.jediProxyHandler.sendCommand(cmd, token).then(data => {
92+
return PythonSignatureProvider.parseData(data);
9593
});
9694
}
9795
}

0 commit comments

Comments
 (0)