- Adding lexical_parent and semantic_parent properties to clang.cindex.Cursor

- Two new tests (one for each property), require libclang built from r155858 or later to pass
- New test utility function (get_cursors) that gets all the nodes with a specific spelling.

Patch by Evan Pipho.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156286 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Manuel Klimek 2012-05-07 05:56:03 +00:00
Родитель 0a84e7a4d6
Коммит 667fd80de4
3 изменённых файлов: 80 добавлений и 0 удалений

Просмотреть файл

@ -1047,6 +1047,22 @@ class Cursor(Structure):
return self._hash return self._hash
@property
def semantic_parent(self):
"""Return the semantic parent for this cursor."""
if not hasattr(self, '_semantic_parent'):
self._semantic_parent = Cursor_semantic_parent(self)
return self._semantic_parent
@property
def lexical_parent(self):
"""Return the lexical parent for this cursor."""
if not hasattr(self, '_lexical_parent'):
self._lexical_parent = Cursor_lexical_parent(self)
return self._lexical_parent
def get_children(self): def get_children(self):
"""Return an iterator for accessing the children of this cursor.""" """Return an iterator for accessing the children of this cursor."""
@ -1974,6 +1990,16 @@ Cursor_objc_type_encoding.argtypes = [Cursor]
Cursor_objc_type_encoding.restype = _CXString Cursor_objc_type_encoding.restype = _CXString
Cursor_objc_type_encoding.errcheck = _CXString.from_result Cursor_objc_type_encoding.errcheck = _CXString.from_result
Cursor_semantic_parent = lib.clang_getCursorSemanticParent
Cursor_semantic_parent.argtypes = [Cursor]
Cursor_semantic_parent.restype = Cursor
Cursor_semantic_parent.errcheck = Cursor.from_result
Cursor_lexical_parent = lib.clang_getCursorLexicalParent
Cursor_lexical_parent.argtypes = [Cursor]
Cursor_lexical_parent.restype = Cursor
Cursor_lexical_parent.errcheck = Cursor.from_result
Cursor_visit_callback = CFUNCTYPE(c_int, Cursor, Cursor, py_object) Cursor_visit_callback = CFUNCTYPE(c_int, Cursor, Cursor, py_object)
Cursor_visit = lib.clang_visitChildren Cursor_visit = lib.clang_visitChildren
Cursor_visit.argtypes = [Cursor, Cursor_visit_callback, py_object] Cursor_visit.argtypes = [Cursor, Cursor_visit_callback, py_object]

Просмотреть файл

@ -1,6 +1,7 @@
from clang.cindex import CursorKind from clang.cindex import CursorKind
from clang.cindex import TypeKind from clang.cindex import TypeKind
from .util import get_cursor from .util import get_cursor
from .util import get_cursors
from .util import get_tu from .util import get_tu
kInput = """\ kInput = """\
@ -75,6 +76,30 @@ def test_underlying_type():
underlying = typedef.underlying_typedef_type underlying = typedef.underlying_typedef_type
assert underlying.kind == TypeKind.INT assert underlying.kind == TypeKind.INT
kParentTest = """\
class C {
void f();
}
void C::f() { }
"""
def test_semantic_parent():
tu = get_tu(kParentTest, 'cpp')
curs = get_cursors(tu, 'f')
decl = get_cursor(tu, 'C')
assert(len(curs) == 2)
assert(curs[0].semantic_parent == curs[1].semantic_parent)
assert(curs[0].semantic_parent == decl)
def test_lexical_parent():
tu = get_tu(kParentTest, 'cpp')
curs = get_cursors(tu, 'f')
decl = get_cursor(tu, 'C')
assert(len(curs) == 2)
assert(curs[0].lexical_parent != curs[1].lexical_parent)
assert(curs[0].lexical_parent == decl)
assert(curs[1].lexical_parent == tu.cursor)
def test_enum_type(): def test_enum_type():
tu = get_tu('enum TEST { FOO=1, BAR=2 };') tu = get_tu('enum TEST { FOO=1, BAR=2 };')
enum = get_cursor(tu, 'TEST') enum = get_cursor(tu, 'TEST')

Просмотреть файл

@ -58,9 +58,38 @@ def get_cursor(source, spelling):
return result return result
return None return None
def get_cursors(source, spelling):
"""Obtain all cursors from a source object with a specific spelling.
This provides a convenient search mechanism to find all cursors with specific
spelling within a source. The first argument can be either a
TranslationUnit or Cursor instance.
If no cursors are found, an empty list is returned.
"""
cursors = []
children = []
if isinstance(source, Cursor):
children = source.get_children()
else:
# Assume TU
children = source.cursor.get_children()
for cursor in children:
if cursor.spelling == spelling:
cursors.append(cursor)
# Recurse into children.
cursors.extend(get_cursors(cursor, spelling))
return cursors
__all__ = [ __all__ = [
'get_cursor', 'get_cursor',
'get_cursors',
'get_tu', 'get_tu',
] ]