From 716beae455ab9b9d8008b382b66cee9ba077a666 Mon Sep 17 00:00:00 2001 From: Sam Roeca Date: Sat, 16 May 2020 15:08:36 -0400 Subject: [PATCH 1/2] Add BaseName.definition_[start,end]_position Provides two public (property) methods getting the (row, column) of the start / end of the definition range. Rows start with 1, columns start with 0. :rtype: Tuple[int, int] --- jedi/api/classes.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) 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. From d84804701256e7846f8cfc90c7b144cd992c0393 Mon Sep 17 00:00:00 2001 From: Sam Roeca Date: Sun, 17 May 2020 11:48:28 -0400 Subject: [PATCH 2/2] Add unit tests for definition_[start,end]_position --- test/test_api/test_classes.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) 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)