diff --git a/jedi/api/classes.py b/jedi/api/classes.py index b521cc90..68f2efb2 100644 --- a/jedi/api/classes.py +++ b/jedi/api/classes.py @@ -231,6 +231,37 @@ class BaseName(object): return None return start_pos[1] + @property + def definition_start_position(self): + """ + The (row, column) of the start of the definition range. Rows start with + 1, columns start with 0. + + :rtype: Tuple[int, int] + """ + definition = self._name.tree_name.get_definition() + if definition is None: + return self._name.start_pos + return definition.start_pos + + @property + def definition_end_position(self): + """ + The (row, column) of the end of the definition range. Rows start with + 1, columns start with 0. + + :rtype: Tuple[int, int] + """ + definition = self._name.tree_name.get_definition() + if definition is None: + return self._name.end_pos + if self.type in ("function", "class"): + last_leaf = definition.get_last_leaf() + if last_leaf.type == "newline": + return last_leaf.get_previous_leaf().end_pos + return last_leaf.end_pos + return definition.end_pos + def docstring(self, raw=False, fast=True): r""" Return a document string for this completion object. diff --git a/test/test_api/test_classes.py b/test/test_api/test_classes.py index 8e4d935e..38d7b503 100644 --- a/test/test_api/test_classes.py +++ b/test/test_api/test_classes.py @@ -603,3 +603,38 @@ def test_get_type_hint(Script, code, expected, skip_pre_python36): def test_pseudotreenameclass_type(Script): assert Script('from typing import Any\n').get_names()[0].type == 'class' + +def test_definition_start_end_position(Script): + '''Tests for definition_start_position and definition_end_position''' + code = '\n'.join([ + 'def a_func():', + ' return "bar"', + '', + 'var1 = 12', + '', + 'class AClass:', + ' """my class"""', + ' @staticmethod', + ' def hello():', + ' func_var = 1', + ' return func_var', + ]) + script = Script(code=code) + names = script.get_names(all_scopes=True) + assert len(names) == 5 + a_func, var1, AClass, hello, func_var = names + + assert a_func.definition_start_position == (1, 0) + assert a_func.definition_end_position == (2, 16) + + assert var1.definition_start_position == (4, 0) + assert var1.definition_end_position == (4, 9) + + assert AClass.definition_start_position == (6, 0) + assert AClass.definition_end_position == (11, 23) + + assert hello.definition_start_position == (9, 4) + assert hello.definition_end_position == (11, 23) + + assert func_var.definition_start_position == (10, 8) + assert func_var.definition_end_position == (10, 20)