arthurp created this revision. arthurp added a reviewer: ilya-biryukov. Herald added subscribers: cfe-commits, arphaman. Herald added a project: clang. arthurp added a comment.
This is my first new revision here, and I guessed on the review based solely on resent reviews of related code. Please correct me as needed. Thanks. Add a python method to Cursor to access clang_getCursorReferenceNameRange which was already included in the C function list of the python binding. Also add required constants and a test. This revision only changes the python binding and does not touch the underlying C code at all. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D70358 Files: clang/bindings/python/clang/cindex.py clang/bindings/python/tests/cindex/test_cursor.py clang/bindings/python/tests/cindex/util.py
Index: clang/bindings/python/tests/cindex/util.py =================================================================== --- clang/bindings/python/tests/cindex/util.py +++ clang/bindings/python/tests/cindex/util.py @@ -58,6 +58,18 @@ return None + +def get_subcursor_by_path(cursor, *path): + """Obtain a cursor by following the path provided from cursor. + + path is a series of ints specifying which child to select. + """ + + if path: + return get_subcursor_by_path(list(cursor.get_children())[path[0]], *path[1:]) + else: + return cursor + def get_cursors(source, spelling): """Obtain all cursors from a source object with a specific spelling. @@ -84,6 +96,7 @@ __all__ = [ 'get_cursor', 'get_cursors', + 'get_subcursor_by_path', 'get_tu', 'skip_if_no_fspath', 'str_to_path', Index: clang/bindings/python/tests/cindex/test_cursor.py =================================================================== --- clang/bindings/python/tests/cindex/test_cursor.py +++ clang/bindings/python/tests/cindex/test_cursor.py @@ -9,10 +9,14 @@ from clang.cindex import AvailabilityKind from clang.cindex import CursorKind +from clang.cindex import Cursor from clang.cindex import TemplateArgumentKind from clang.cindex import TranslationUnit from clang.cindex import TypeKind +from clang.cindex import SourceRange +from clang.cindex import SourceLocation from .util import get_cursor +from .util import get_subcursor_by_path from .util import get_cursors from .util import get_tu @@ -53,6 +57,37 @@ void foo<-7, float, true>(); """ +kCPPReferenceNameRangeTest = """\ +void baz(); + +class C { +public: + void foo(); + template <typename T> + void bar(T v) { } + int operator[](int i) { return i; } +}; + +void ref1() { + baz(); +} + +void ref2() { + C x; + x.C::foo(); +} + +void ref3() { + C x; + x.bar<const char*>("str"); +} + +void ref4() { + C x; + x[1]; +} + """ + class TestCursor(unittest.TestCase): def test_get_children(self): tu = get_tu(kInput) @@ -554,6 +589,30 @@ self.assertEqual(c.referenced.spelling, foo.spelling) break + def test_get_reference_name_range(self): + tu = get_tu(kCPPReferenceNameRangeTest, lang='cpp') + + c = get_subcursor_by_path(get_cursor(tu, 'ref1'), 0, 0) + self.assertEqual(c.get_reference_name_range(0, 0), + tu.get_extent("t.cpp", ((12, 5), (12, 10)))) + + c = get_subcursor_by_path(get_cursor(tu, 'ref2'), 0, 1) + self.assertEqual(c.get_reference_name_range(Cursor.NAME_RANGE_WANT_QUALIFIER, 0), + tu.get_extent("t.cpp", ((17, 5), (17, 15)))) + + c = get_subcursor_by_path(get_cursor(tu, 'ref3'), 0, 1) + self.assertEqual(c.get_reference_name_range(Cursor.NAME_RANGE_WANT_TEMPLATE_ARGS, 0), + tu.get_extent("t.cpp", ((22, 5), (22, 30)))) + + c = get_subcursor_by_path(get_cursor(tu, 'ref4'), 0, 1) + self.assertEqual(c.get_reference_name_range(0, 0), + tu.get_extent("t.cpp", ((27, 6), (27, 7)))) + self.assertEqual(c.get_reference_name_range(0, 1), + tu.get_extent("t.cpp", ((27, 8), (27, 9)))) + self.assertEqual(c.get_reference_name_range(Cursor.NAME_RANGE_WANT_SINGLE_PIECE, 0), + tu.get_extent("t.cpp", ((27, 6), (27, 9)))) + + def test_mangled_name(self): kInputForMangling = """\ int foo(int, int); Index: clang/bindings/python/clang/cindex.py =================================================================== --- clang/bindings/python/clang/cindex.py +++ clang/bindings/python/clang/cindex.py @@ -1419,6 +1419,20 @@ """ _fields_ = [("_kind_id", c_int), ("xdata", c_int), ("data", c_void_p * 3)] + # Include the nested-name-specifier, e.g. Foo:: in x.Foo::y, in the range. + NAME_RANGE_WANT_QUALIFIER = 0x1 + + # Include the explicit template arguments, e.g. <int> in x.f<int>, in the range. + NAME_RANGE_WANT_TEMPLATE_ARGS = 0x2 + + # If the name is non-contiguous, return the full spanning range. + # Non-contiguous names occur in Objective-C when a selector with two or + # more parameters is used, or in C++ when using an operator: + # + # [object doSomething:here withValue:there]; // Objective-C + # return some_vector[1]; // C++ + NAME_RANGE_WANT_SINGLE_PIECE = 0x4 + @staticmethod def from_location(tu, location): # We store a reference to the TU in the instance so the TU won't get @@ -1824,6 +1838,20 @@ """Returns the value of the indicated arg as an unsigned 64b integer.""" return conf.lib.clang_Cursor_getTemplateArgumentUnsignedValue(self, num) + def get_reference_name_range(self, name_flags, piece_index): + """Return the source range covering the reference at this cursor, if applicable. + + name_flags is a bitset of the three independent flags: NAME_RANGE_WANT_QUALIFIER, + NAME_RANGE_WANT_TEMPLATE_ARGS, NAME_RANGE_WANT_SINGLE_PIECE. + + piece_index identifies a piece of the overall reference. For contiguous names + or when passing the flag NAME_RANGE_WANT_SINGLE_PIECE, only one piece with index + 0 is available. When the NAME_RANGE_WANT_SINGLE_PIECE flag is not passed for a + non-contiguous names, this index can be used to retrieve the individual pieces + of the name. + """ + return conf.lib.clang_getCursorReferenceNameRange(self, name_flags, piece_index) + def get_children(self): """Return an iterator for accessing the children of this cursor."""
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits