brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.0 KiB · 0d3453e Raw
104 lines · python
1import unittest2from pathlib import Path3 4from clang.cindex import (5    AccessSpecifier,6    AvailabilityKind,7    BinaryOperator,8    CursorKind,9    ExceptionSpecificationKind,10    LanguageKind,11    LinkageKind,12    RefQualifierKind,13    StorageClass,14    TemplateArgumentKind,15    TLSKind,16    TokenKind,17    TranslationUnit,18    TypeKind,19    PrintingPolicyProperty,20    BaseEnumeration,21)22 23 24class TestEnums(unittest.TestCase):25    enums = BaseEnumeration.__subclasses__()26 27    def test_from_id(self):28        """Check that kinds can be constructed from valid IDs"""29        for enum in self.enums:30            self.assertEqual(enum.from_id(2), enum(2))31            max_value = max([variant.value for variant in enum])32            with self.assertRaises(ValueError):33                enum.from_id(max_value + 1)34            with self.assertRaises(ValueError):35                enum.from_id(-1)36 37    def test_all_variants(self):38        """Check that all libclang enum values are also defined in cindex.py"""39        cenum_to_pythonenum = {40            "CX_CXXAccessSpecifier": AccessSpecifier,41            "CX_StorageClass": StorageClass,42            "CXAvailabilityKind": AvailabilityKind,43            "CXBinaryOperatorKind": BinaryOperator,44            "CXCursorKind": CursorKind,45            "CXCursor_ExceptionSpecificationKind": ExceptionSpecificationKind,46            "CXLanguageKind": LanguageKind,47            "CXLinkageKind": LinkageKind,48            "CXPrintingPolicyProperty": PrintingPolicyProperty,49            "CXRefQualifierKind": RefQualifierKind,50            "CXTemplateArgumentKind": TemplateArgumentKind,51            "CXTLSKind": TLSKind,52            "CXTokenKind": TokenKind,53            "CXTypeKind": TypeKind,54        }55 56        indexheader = (57            Path(__file__).parent.parent.parent.parent.parent58            / "include/clang-c/Index.h"59        )60        # FIXME: Index.h is a C file, but we read it as a C++ file because we61        # don't get ENUM_CONSTANT_DECL cursors otherwise, which we need here62        # See bug report: https://github.com/llvm/llvm-project/issues/15907563        tu = TranslationUnit.from_source(indexheader, ["-x", "c++"])64 65        enum_variant_map = {}66        # For all enums in self.enums, extract all enum variants defined in Index.h67        for cursor in tu.cursor.walk_preorder():68            if cursor.kind == CursorKind.ENUM_CONSTANT_DECL:69                python_enum = cenum_to_pythonenum.get(cursor.type.spelling)70                if python_enum not in enum_variant_map:71                    enum_variant_map[python_enum] = dict()72                enum_variant_map[python_enum][cursor.enum_value] = cursor.spelling73 74        for enum in self.enums:75            with self.subTest(enum):76                # This ensures only the custom assert message below is printed77                self.longMessage = False78 79                python_kinds = set([kind.value for kind in enum])80                num_to_c_kind = enum_variant_map[enum]81                c_kinds = set(num_to_c_kind.keys())82                # Defined in Index.h but not in cindex.py83                missing_python_kinds = c_kinds - python_kinds84                missing_names = set(85                    [num_to_c_kind[kind] for kind in missing_python_kinds]86                )87                self.assertEqual(88                    missing_names,89                    set(),90                    f"{missing_names} variants are missing. "91                    f"Please ensure these are defined in {enum} in cindex.py.",92                )93                # Defined in cindex.py but not in Index.h94                superfluous_python_kinds = python_kinds - c_kinds95                missing_names = set(96                    [enum.from_id(kind) for kind in superfluous_python_kinds]97                )98                self.assertEqual(99                    missing_names,100                    set(),101                    f"{missing_names} variants only exist in the Python bindings. "102                    f"Please ensure that all {enum} kinds defined in cindex.py have an equivalent in Index.h",103                )104