|
8 | 8 |
|
9 | 9 | @hookimpl
|
10 | 10 | def pyls_document_symbols(config, document):
|
11 |
| - all_scopes = config.plugin_settings('jedi_symbols').get('all_scopes', True) |
| 11 | + # pylint: disable=broad-except |
| 12 | + # pylint: disable=too-many-nested-blocks |
| 13 | + # pylint: disable=too-many-locals |
| 14 | + # pylint: disable=too-many-branches |
| 15 | + symbols_settings = config.plugin_settings('jedi_symbols') |
| 16 | + all_scopes = symbols_settings.get('all_scopes', True) |
| 17 | + add_import_symbols = symbols_settings.get('include_import_symbols', True) |
12 | 18 | definitions = document.jedi_names(all_scopes=all_scopes)
|
13 |
| - return [{ |
14 |
| - 'name': d.name, |
15 |
| - 'containerName': _container(d), |
16 |
| - 'location': { |
17 |
| - 'uri': document.uri, |
18 |
| - 'range': _range(d), |
19 |
| - }, |
20 |
| - 'kind': _kind(d), |
21 |
| - } for d in definitions if _include_def(d)] |
| 19 | + module_name = document.dot_path |
| 20 | + symbols = [] |
| 21 | + exclude = set({}) |
| 22 | + redefinitions = {} |
| 23 | + while definitions != []: |
| 24 | + d = definitions.pop(0) |
| 25 | + if not add_import_symbols: |
| 26 | + sym_full_name = d.full_name |
| 27 | + if sym_full_name is not None: |
| 28 | + if (not sym_full_name.startswith(module_name) and |
| 29 | + not sym_full_name.startswith('__main__')): |
| 30 | + continue |
| 31 | + |
| 32 | + if _include_def(d) and document.path == d.module_path: |
| 33 | + tuple_range = _tuple_range(d) |
| 34 | + if tuple_range in exclude: |
| 35 | + continue |
| 36 | + |
| 37 | + kind = redefinitions.get(tuple_range, None) |
| 38 | + if kind is not None: |
| 39 | + exclude |= {tuple_range} |
| 40 | + |
| 41 | + if d.type == 'statement': |
| 42 | + if d.description.startswith('self'): |
| 43 | + kind = 'field' |
| 44 | + |
| 45 | + symbol = { |
| 46 | + 'name': d.name, |
| 47 | + 'containerName': _container(d), |
| 48 | + 'location': { |
| 49 | + 'uri': document.uri, |
| 50 | + 'range': _range(d), |
| 51 | + }, |
| 52 | + 'kind': _kind(d) if kind is None else _SYMBOL_KIND_MAP[kind], |
| 53 | + } |
| 54 | + symbols.append(symbol) |
| 55 | + |
| 56 | + if d.type == 'class': |
| 57 | + try: |
| 58 | + defined_names = list(d.defined_names()) |
| 59 | + for method in defined_names: |
| 60 | + if method.type == 'function': |
| 61 | + redefinitions[_tuple_range(method)] = 'method' |
| 62 | + elif method.type == 'statement': |
| 63 | + redefinitions[_tuple_range(method)] = 'field' |
| 64 | + else: |
| 65 | + redefinitions[_tuple_range(method)] = method.type |
| 66 | + definitions = list(defined_names) + definitions |
| 67 | + except Exception: |
| 68 | + pass |
| 69 | + return symbols |
22 | 70 |
|
23 | 71 |
|
24 | 72 | def _include_def(definition):
|
@@ -56,6 +104,11 @@ def _range(definition):
|
56 | 104 | }
|
57 | 105 |
|
58 | 106 |
|
| 107 | +def _tuple_range(definition): |
| 108 | + definition = definition._name.tree_name.get_definition() |
| 109 | + return (definition.start_pos, definition.end_pos) |
| 110 | + |
| 111 | + |
59 | 112 | _SYMBOL_KIND_MAP = {
|
60 | 113 | 'none': SymbolKind.Variable,
|
61 | 114 | 'type': SymbolKind.Class,
|
@@ -95,6 +148,7 @@ def _range(definition):
|
95 | 148 | 'string': SymbolKind.String,
|
96 | 149 | 'unicode': SymbolKind.String,
|
97 | 150 | 'list': SymbolKind.Array,
|
| 151 | + 'field': SymbolKind.Field |
98 | 152 | }
|
99 | 153 |
|
100 | 154 |
|
|
0 commit comments