зеркало из https://github.com/microsoft/clang-1.git
- 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:
Родитель
0a84e7a4d6
Коммит
667fd80de4
|
@ -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',
|
||||||
]
|
]
|
||||||
|
|
Загрузка…
Ссылка в новой задаче