From 1bc1480f4d076b00932dc518e1c10f94586e1f2d Mon Sep 17 00:00:00 2001 From: Jonathan B Coe Date: Thu, 18 Oct 2018 22:13:30 +0100 Subject: [PATCH] Add test for compile errors in parsed source file. (#454) More work is needed to fail for compile errors in transitively included headers. --- ffig/cppmodel.py | 24 ++++++++++++++++++++++-- tests/cppmodel/test_classes.py | 6 +++--- tests/cppmodel/test_model.py | 10 ++++++++++ 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/ffig/cppmodel.py b/ffig/cppmodel.py index 195a0fc2..0845a42f 100644 --- a/ffig/cppmodel.py +++ b/ffig/cppmodel.py @@ -2,6 +2,7 @@ import sys from ffig.clang.cindex import AccessSpecifier from ffig.clang.cindex import CursorKind +from ffig.clang.cindex import Diagnostic from ffig.clang.cindex import ExceptionSpecificationKind from ffig.clang.cindex import TypeKind @@ -56,7 +57,8 @@ def __init__(self, cursor): self.name = cursor.spelling arguments = [x.spelling or None for x in cursor.get_arguments()] argument_types = [Type(x) for x in cursor.type.argument_types()] - self.is_noexcept = (cursor.exception_specification_kind == ExceptionSpecificationKind.BASIC_NOEXCEPT) + self.is_noexcept = (cursor.exception_specification_kind == + ExceptionSpecificationKind.BASIC_NOEXCEPT) self.return_type = Type(cursor.type.get_result()) self.arguments = [] self.annotations = _get_annotations(cursor) @@ -162,11 +164,29 @@ def __init__(self, translation_unit): self.filename = translation_unit.spelling self.functions = [] self.classes = [] + + def is_error_in_current_file(diagnostic): + if str(diagnostic.location.file) != str(translation_unit.spelling): + return False + if diagnostic.severity == Diagnostic.Error: + return True + if diagnostic.severity == Diagnostic.Fatal: + return True + return False + + errors = [ + d for d in translation_unit.diagnostics if is_error_in_current_file(d)] + if errors: + raise ValueError('Errors in source file:\{}'.format( + '\n'.join(str(e) for e in errors))) + self.add_child_nodes(translation_unit.cursor, []) def __repr__(self): return "".format( - self.filename, [c.name for c in self.classes], [f.name for f in self.functions]) + self.filename, + [c.name for c in self.classes], + [f.name for f in self.functions]) def extend(self, translation_unit): m = Model(translation_unit) diff --git a/tests/cppmodel/test_classes.py b/tests/cppmodel/test_classes.py index a3395f83..94c449d2 100644 --- a/tests/cppmodel/test_classes.py +++ b/tests/cppmodel/test_classes.py @@ -142,7 +142,7 @@ def test_class_member_data(): class A {}; class B { int x_; - B b_; + A a_; }; """ @@ -156,8 +156,8 @@ class B { assert c.members[0].name == "x_" assert c.members[1].type.kind == TypeKind.RECORD - assert c.members[1].type.name == "B" - assert c.members[1].name == "b_" + assert c.members[1].type.name == "A" + assert c.members[1].name == "a_" def test_string_representation(): diff --git a/tests/cppmodel/test_model.py b/tests/cppmodel/test_model.py index 0de67762..ff6d81d8 100644 --- a/tests/cppmodel/test_model.py +++ b/tests/cppmodel/test_model.py @@ -1,6 +1,7 @@ from util import get_tu import ffig.cppmodel from nose.tools import assert_equals +from nose.tools import assert_raises def test_repr(): @@ -12,3 +13,12 @@ def test_repr(): assert_equals( str(model), "") + + +def test_exception_for_missing_include(): + source = '#include "major_tom.h"' + tu = get_tu(source, 'cpp') + + def f(): + ffig.cppmodel.Model(tu) + assert_raises(ValueError, f)