diff options
Diffstat (limited to 'bindings')
-rw-r--r-- | bindings/python/clang/cindex.py | 103 | ||||
-rw-r--r-- | bindings/python/tests/cindex/test_cdb.py | 17 | ||||
-rw-r--r-- | bindings/python/tests/cindex/test_cursor.py | 82 | ||||
-rw-r--r-- | bindings/python/tests/cindex/test_diagnostics.py | 12 |
4 files changed, 208 insertions, 6 deletions
diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py index e4b38769b77d4..aeb34f8cb2320 100644 --- a/bindings/python/clang/cindex.py +++ b/bindings/python/clang/cindex.py @@ -360,6 +360,23 @@ class Diagnostic(object): return FixItIterator(self) @property + def children(self): + class ChildDiagnosticsIterator: + def __init__(self, diag): + self.diag_set = conf.lib.clang_getChildDiagnostics(diag) + + def __len__(self): + return int(conf.lib.clang_getNumDiagnosticsInSet(self.diag_set)) + + def __getitem__(self, key): + diag = conf.lib.clang_getDiagnosticInSet(self.diag_set, key) + if not diag: + raise IndexError + return Diagnostic(diag) + + return ChildDiagnosticsIterator(self) + + @property def category_number(self): """The category number for this diagnostic or 0 if unavailable.""" return conf.lib.clang_getDiagnosticCategory(self) @@ -1120,6 +1137,9 @@ CursorKind.MODULE_IMPORT_DECL = CursorKind(600) # A type alias template declaration CursorKind.TYPE_ALIAS_TEMPLATE_DECL = CursorKind(601) +# A code completion overload candidate. +CursorKind.OVERLOAD_CANDIDATE = CursorKind(700) + ### Template Argument Kinds ### class TemplateArgumentKind(BaseEnumeration): """ @@ -1174,6 +1194,32 @@ class Cursor(Structure): """ return conf.lib.clang_CXXMethod_isConst(self) + def is_converting_constructor(self): + """Returns True if the cursor refers to a C++ converting constructor. + """ + return conf.lib.clang_CXXConstructor_isConvertingConstructor(self) + + def is_copy_constructor(self): + """Returns True if the cursor refers to a C++ copy constructor. + """ + return conf.lib.clang_CXXConstructor_isCopyConstructor(self) + + def is_default_constructor(self): + """Returns True if the cursor refers to a C++ default constructor. + """ + return conf.lib.clang_CXXConstructor_isDefaultConstructor(self) + + def is_move_constructor(self): + """Returns True if the cursor refers to a C++ move constructor. + """ + return conf.lib.clang_CXXConstructor_isMoveConstructor(self) + + def is_default_method(self): + """Returns True if the cursor refers to a C++ member function or member + function template that is declared '= default'. + """ + return conf.lib.clang_CXXMethod_isDefaulted(self) + def is_mutable_field(self): """Returns True if the cursor refers to a C++ field that is declared 'mutable'. @@ -1685,6 +1731,7 @@ TypeKind.DEPENDENT = TypeKind(26) TypeKind.OBJCID = TypeKind(27) TypeKind.OBJCCLASS = TypeKind(28) TypeKind.OBJCSEL = TypeKind(29) +TypeKind.FLOAT128 = TypeKind(30) TypeKind.COMPLEX = TypeKind(100) TypeKind.POINTER = TypeKind(101) TypeKind.BLOCKPOINTER = TypeKind(102) @@ -1704,6 +1751,7 @@ TypeKind.VARIABLEARRAY = TypeKind(115) TypeKind.DEPENDENTSIZEDARRAY = TypeKind(116) TypeKind.MEMBERPOINTER = TypeKind(117) TypeKind.AUTO = TypeKind(118) +TypeKind.ELABORATED = TypeKind(119) class RefQualifierKind(BaseEnumeration): """Describes a specific ref-qualifier of a type.""" @@ -1902,6 +1950,12 @@ class Type(Structure): """ return conf.lib.clang_Type_getClassType(self) + def get_named_type(self): + """ + Retrieve the type named by the qualified-id. + """ + return conf.lib.clang_Type_getNamedType(self) + def get_align(self): """ Retrieve the alignment of the record. @@ -2383,7 +2437,7 @@ class TranslationUnit(ClangObject): functions above. __init__ is only called internally. """ assert isinstance(index, Index) - + self.index = index ClangObject.__init__(self, ptr) def __del__(self): @@ -2703,6 +2757,11 @@ class CompileCommand(object): return conf.lib.clang_CompileCommand_getDirectory(self.cmd) @property + def filename(self): + """Get the working filename for this CompileCommand""" + return conf.lib.clang_CompileCommand_getFilename(self.cmd) + + @property def arguments(self): """ Get an iterable object providing each argument in the @@ -2884,6 +2943,11 @@ functionList = [ _CXString, _CXString.from_result), + ("clang_CompileCommand_getFilename", + [c_object_p], + _CXString, + _CXString.from_result), + ("clang_CompileCommand_getNumArgs", [c_object_p], c_uint), @@ -2908,6 +2972,22 @@ functionList = [ [Index, c_char_p], c_object_p), + ("clang_CXXConstructor_isConvertingConstructor", + [Cursor], + bool), + + ("clang_CXXConstructor_isCopyConstructor", + [Cursor], + bool), + + ("clang_CXXConstructor_isDefaultConstructor", + [Cursor], + bool), + + ("clang_CXXConstructor_isMoveConstructor", + [Cursor], + bool), + ("clang_CXXField_isMutable", [Cursor], bool), @@ -2916,6 +2996,10 @@ functionList = [ [Cursor], bool), + ("clang_CXXMethod_isDefaulted", + [Cursor], + bool), + ("clang_CXXMethod_isPureVirtual", [Cursor], bool), @@ -2997,6 +3081,10 @@ functionList = [ Type, Type.from_result), + ("clang_getChildDiagnostics", + [Diagnostic], + c_object_p), + ("clang_getCompletionAvailability", [c_void_p], c_int), @@ -3117,6 +3205,10 @@ functionList = [ _CXString, _CXString.from_result), + ("clang_getDiagnosticInSet", + [c_object_p, c_uint], + c_object_p), + ("clang_getDiagnosticLocation", [Diagnostic], SourceLocation), @@ -3218,6 +3310,10 @@ functionList = [ [c_object_p], c_uint), + ("clang_getNumDiagnosticsInSet", + [c_object_p], + c_uint), + ("clang_getNumElements", [Type], c_longlong), @@ -3477,6 +3573,11 @@ functionList = [ [Type], c_uint), + ("clang_Type_getNamedType", + [Type], + Type, + Type.from_result), + ("clang_Type_visitFields", [Type, callbacks['fields_visit'], py_object], c_uint), diff --git a/bindings/python/tests/cindex/test_cdb.py b/bindings/python/tests/cindex/test_cdb.py index e1f824f797f22..35fe3e108a12e 100644 --- a/bindings/python/tests/cindex/test_cdb.py +++ b/bindings/python/tests/cindex/test_cdb.py @@ -38,27 +38,34 @@ def test_all_compilecommand(): cmds = cdb.getAllCompileCommands() assert len(cmds) == 3 expected = [ + { 'wd': '/home/john.doe/MyProject', + 'file': '/home/john.doe/MyProject/project.cpp', + 'line': ['clang++', '-o', 'project.o', '-c', + '/home/john.doe/MyProject/project.cpp']}, { 'wd': '/home/john.doe/MyProjectA', + 'file': '/home/john.doe/MyProject/project2.cpp', 'line': ['clang++', '-o', 'project2.o', '-c', '/home/john.doe/MyProject/project2.cpp']}, { 'wd': '/home/john.doe/MyProjectB', + 'file': '/home/john.doe/MyProject/project2.cpp', 'line': ['clang++', '-DFEATURE=1', '-o', 'project2-feature.o', '-c', '/home/john.doe/MyProject/project2.cpp']}, - { 'wd': '/home/john.doe/MyProject', - 'line': ['clang++', '-o', 'project.o', '-c', - '/home/john.doe/MyProject/project.cpp']} + ] for i in range(len(cmds)): assert cmds[i].directory == expected[i]['wd'] + assert cmds[i].filename == expected[i]['file'] for arg, exp in zip(cmds[i].arguments, expected[i]['line']): assert arg == exp def test_1_compilecommand(): """Check file with single compile command""" cdb = CompilationDatabase.fromDirectory(kInputsDir) - cmds = cdb.getCompileCommands('/home/john.doe/MyProject/project.cpp') + file = '/home/john.doe/MyProject/project.cpp' + cmds = cdb.getCompileCommands(file) assert len(cmds) == 1 - assert cmds[0].directory == '/home/john.doe/MyProject' + assert cmds[0].directory == os.path.dirname(file) + assert cmds[0].filename == file expected = [ 'clang++', '-o', 'project.o', '-c', '/home/john.doe/MyProject/project.cpp'] for arg, exp in zip(cmds[0].arguments, expected): diff --git a/bindings/python/tests/cindex/test_cursor.py b/bindings/python/tests/cindex/test_cursor.py index c5ea50516ad21..6c8230d4283c4 100644 --- a/bindings/python/tests/cindex/test_cursor.py +++ b/bindings/python/tests/cindex/test_cursor.py @@ -112,6 +112,88 @@ def test_is_const_method(): assert foo.is_const_method() assert not bar.is_const_method() +def test_is_converting_constructor(): + """Ensure Cursor.is_converting_constructor works.""" + source = 'class X { explicit X(int); X(double); X(); };' + tu = get_tu(source, lang='cpp') + + xs = get_cursors(tu, 'X') + + assert len(xs) == 4 + assert xs[0].kind == CursorKind.CLASS_DECL + cs = xs[1:] + assert cs[0].kind == CursorKind.CONSTRUCTOR + assert cs[1].kind == CursorKind.CONSTRUCTOR + assert cs[2].kind == CursorKind.CONSTRUCTOR + + assert not cs[0].is_converting_constructor() + assert cs[1].is_converting_constructor() + assert not cs[2].is_converting_constructor() + + +def test_is_copy_constructor(): + """Ensure Cursor.is_copy_constructor works.""" + source = 'class X { X(); X(const X&); X(X&&); };' + tu = get_tu(source, lang='cpp') + + xs = get_cursors(tu, 'X') + assert xs[0].kind == CursorKind.CLASS_DECL + cs = xs[1:] + assert cs[0].kind == CursorKind.CONSTRUCTOR + assert cs[1].kind == CursorKind.CONSTRUCTOR + assert cs[2].kind == CursorKind.CONSTRUCTOR + + assert not cs[0].is_copy_constructor() + assert cs[1].is_copy_constructor() + assert not cs[2].is_copy_constructor() + +def test_is_default_constructor(): + """Ensure Cursor.is_default_constructor works.""" + source = 'class X { X(); X(int); };' + tu = get_tu(source, lang='cpp') + + xs = get_cursors(tu, 'X') + assert xs[0].kind == CursorKind.CLASS_DECL + cs = xs[1:] + assert cs[0].kind == CursorKind.CONSTRUCTOR + assert cs[1].kind == CursorKind.CONSTRUCTOR + + assert cs[0].is_default_constructor() + assert not cs[1].is_default_constructor() + +def test_is_move_constructor(): + """Ensure Cursor.is_move_constructor works.""" + source = 'class X { X(); X(const X&); X(X&&); };' + tu = get_tu(source, lang='cpp') + + xs = get_cursors(tu, 'X') + assert xs[0].kind == CursorKind.CLASS_DECL + cs = xs[1:] + assert cs[0].kind == CursorKind.CONSTRUCTOR + assert cs[1].kind == CursorKind.CONSTRUCTOR + assert cs[2].kind == CursorKind.CONSTRUCTOR + + assert not cs[0].is_move_constructor() + assert not cs[1].is_move_constructor() + assert cs[2].is_move_constructor() + +def test_is_default_method(): + """Ensure Cursor.is_default_method works.""" + source = 'class X { X() = default; }; class Y { Y(); };' + tu = get_tu(source, lang='cpp') + + xs = get_cursors(tu, 'X') + ys = get_cursors(tu, 'Y') + + assert len(xs) == 2 + assert len(ys) == 2 + + xc = xs[1] + yc = ys[1] + + assert xc.is_default_method() + assert not yc.is_default_method() + def test_is_mutable_field(): """Ensure Cursor.is_mutable_field works.""" source = 'class X { int x_; mutable int y_; };' diff --git a/bindings/python/tests/cindex/test_diagnostics.py b/bindings/python/tests/cindex/test_diagnostics.py index 48ab6176fd1df..ba6e545e8b1ab 100644 --- a/bindings/python/tests/cindex/test_diagnostics.py +++ b/bindings/python/tests/cindex/test_diagnostics.py @@ -80,3 +80,15 @@ def test_diagnostic_option(): assert d.option == '-Wunused-parameter' assert d.disable_option == '-Wno-unused-parameter' + +def test_diagnostic_children(): + tu = get_tu('void f(int x) {} void g() { f(); }') + assert len(tu.diagnostics) == 1 + d = tu.diagnostics[0] + + children = d.children + assert len(children) == 1 + assert children[0].severity == Diagnostic.Note + assert children[0].spelling.endswith('declared here') + assert children[0].location.line == 1 + assert children[0].location.column == 1 |