Author: Jannick Kremer Date: 2026-01-17T23:37:51+09:00 New Revision: dc3a902abed72c58577950cc5c909d7670e4caa8
URL: https://github.com/llvm/llvm-project/commit/dc3a902abed72c58577950cc5c909d7670e4caa8 DIFF: https://github.com/llvm/llvm-project/commit/dc3a902abed72c58577950cc5c909d7670e4caa8.diff LOG: Use existing AvailabilityKind enum for code completion availability (#160296) This adresses point 4 from #156680. This is a necessary step before `CompletionChunk.Kind` can be removed. The `ChunkCompletion.Kind` implements `__str__` and `__repr__` differently from our other enum classes. I have adapted the `__repr__` of `CompletionString` to stringify the availability of the chunk differently so that it still looks the same as before. Also introduce a temporary `AvailabilityKindCompat` to ensure that `__str__` returns the same format, while also leaving a deprecation warning that this will be removed in a future release. --------- Co-authored-by: Vlad Serebrennikov <[email protected]> Added: Modified: clang/bindings/python/clang/cindex.py clang/bindings/python/tests/cindex/test_code_completion.py clang/bindings/python/tests/cindex/test_enums.py clang/docs/ReleaseNotes.rst Removed: ################################################################################ diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py index 2b6ab00c88219..29c35628cf60c 100644 --- a/clang/bindings/python/clang/cindex.py +++ b/clang/bindings/python/clang/cindex.py @@ -84,6 +84,7 @@ import os import sys from enum import Enum +import warnings from typing import ( Any, @@ -3143,15 +3144,51 @@ def isKindResultType(self) -> bool: class CompletionString(ClangObject): - class Availability: - def __init__(self, name): - self.name = name + # AvailabilityKindCompat is an exact copy of AvailabilityKind, except for __str__. + # This is a temporary measure to keep the string representation the same + # until we change CompletionString.availability to return AvailabilityKind, + # like Cursor.availability does. + # Note that deriving from AvailabilityKind directly is not possible. + class AvailabilityKindCompat(BaseEnumeration): + """ + Describes the availability of an entity. + It is deprecated in favor of AvailabilityKind. + """ - def __str__(self): - return self.name + # Ensure AvailabilityKindCompat is comparable with AvailabilityKind + def __eq__(self, other: object) -> bool: + if isinstance( + other, (AvailabilityKind, CompletionString.AvailabilityKindCompat) + ): + return self.value == other.value + else: + return NotImplemented - def __repr__(self): - return "<Availability: %s>" % self + def __str__(self) -> str: + """ + Converts enum value to string in the old camelCase format. + This is a temporary measure that will be changed in the future release + to return string in ALL_CAPS format, like for other enums. + """ + + warnings.warn( + "String representation of 'CompletionString.availability' will be " + "changed in a future release from 'camelCase' to 'ALL_CAPS' to " + "match other enums. 'CompletionString.availability' can be " + "compared to 'AvailabilityKind' directly, " + "without conversion to string.", + DeprecationWarning, + ) + # Remove underscores + components = self.name.split("_") + # Upper-camel case each split component + components = [component.lower().capitalize() for component in components] + return "".join(components) + + AVAILABLE = 0 + DEPRECATED = 1 + NOT_AVAILABLE = 2 + NOT_ACCESSIBLE = 3 def __len__(self) -> int: return self.num_chunks @@ -3177,9 +3214,9 @@ def priority(self) -> int: return conf.lib.clang_getCompletionPriority(self.obj) # type: ignore [no-any-return] @property - def availability(self) -> CompletionChunk.Kind: + def availability(self) -> AvailabilityKindCompat: res = conf.lib.clang_getCompletionAvailability(self.obj) - return availabilityKinds[res] + return CompletionString.AvailabilityKindCompat.from_id(res) @property def briefComment(self) -> str: @@ -3197,14 +3234,6 @@ def __repr__(self) -> str: ) -availabilityKinds = { - 0: CompletionChunk.Kind("Available"), - 1: CompletionChunk.Kind("Deprecated"), - 2: CompletionChunk.Kind("NotAvailable"), - 3: CompletionChunk.Kind("NotAccessible"), -} - - class CodeCompletionResult(Structure): _fields_ = [("cursorKind", c_int), ("completionString", c_object_p)] diff --git a/clang/bindings/python/tests/cindex/test_code_completion.py b/clang/bindings/python/tests/cindex/test_code_completion.py index 32b75eb1ae029..4c0ecca85e4f4 100644 --- a/clang/bindings/python/tests/cindex/test_code_completion.py +++ b/clang/bindings/python/tests/cindex/test_code_completion.py @@ -1,5 +1,4 @@ -from clang.cindex import TranslationUnit - +from clang.cindex import AvailabilityKind, CompletionString, TranslationUnit import unittest from pathlib import Path @@ -137,3 +136,41 @@ class Q : public P { "{'void', ResultType} | {'~P', TypedText} | {'(', LeftParen} | {')', RightParen} || Priority: 79 || Availability: Available || Brief comment: ", ] self.check_completion_results(cr, expected) + + def test_availability_kind_compat_(self): + numKinds = len(CompletionString.AvailabilityKindCompat) + + # Compare with regular kind + for compatKind in CompletionString.AvailabilityKindCompat: + commonKind = AvailabilityKind.from_id(compatKind.value) + nextKindId = (compatKind.value + 1) % numKinds + commonKindUnequal = AvailabilityKind.from_id(nextKindId) + self.assertEqual(commonKind, compatKind) + self.assertEqual(compatKind, commonKind) + self.assertNotEqual(commonKindUnequal, compatKind) + self.assertNotEqual(compatKind, commonKindUnequal) + + # Compare two compat kinds + for compatKind in CompletionString.AvailabilityKindCompat: + compatKind2 = CompletionString.AvailabilityKindCompat.from_id( + compatKind.value + ) + nextKindId = (compatKind.value + 1) % numKinds + compatKind2Unequal = CompletionString.AvailabilityKindCompat.from_id( + nextKindId + ) + self.assertEqual(compatKind, compatKind2) + self.assertEqual(compatKind2, compatKind) + self.assertNotEqual(compatKind2Unequal, compatKind) + self.assertNotEqual(compatKind, compatKind2Unequal) + + def test_compat_str(self): + kindStringMap = { + 0: "Available", + 1: "Deprecated", + 2: "NotAvailable", + 3: "NotAccessible", + } + for id, string in kindStringMap.items(): + kind = CompletionString.AvailabilityKindCompat.from_id(id) + self.assertEqual(str(kind), string) diff --git a/clang/bindings/python/tests/cindex/test_enums.py b/clang/bindings/python/tests/cindex/test_enums.py index 0d3453e602edf..f50bd219cee77 100644 --- a/clang/bindings/python/tests/cindex/test_enums.py +++ b/clang/bindings/python/tests/cindex/test_enums.py @@ -5,6 +5,7 @@ AccessSpecifier, AvailabilityKind, BinaryOperator, + CompletionString, CursorKind, ExceptionSpecificationKind, LanguageKind, @@ -22,7 +23,10 @@ class TestEnums(unittest.TestCase): + # Test all enum classes, except for AvailabilityKindCompat since it is + # just a copy of AvailabilityKind and has no corresponding C-class enums = BaseEnumeration.__subclasses__() + enums.remove(CompletionString.AvailabilityKindCompat) def test_from_id(self): """Check that kinds can be constructed from valid IDs""" diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 4d886c3d55e7c..b75715e873c50 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -54,6 +54,17 @@ Clang Frontend Potentially Breaking Changes Clang Python Bindings Potentially Breaking Changes -------------------------------------------------- +- Remove ``CompletionString.Availability``. No libclang interfaces returned instances of it. +- ``CompletionString.availability`` now returns instances of ``CompletionString.AvailabilityKindCompat``. + + Instances of ``AvailabilityKindCompat`` have the same ``__str__`` representation + as the previous ``CompletionChunk.Kind``s and are equality-comparable with + the existing ``AvailabilityKind`` enum. It will be replaced by ``AvailabilityKind`` + in a future release. When this happens, the return type of ``CompletionString.availability`` + will change to ``AvailabilityKind``, so it is recommended to use ``AvailabilityKind`` + to compare with the return values of ``CompletionString.availability``. +- Remove ``availabilityKinds``. In this release, uses of ``availabilityKinds`` + need to be replaced by ``CompletionString.AvailabilityKind``. What's New in Clang |release|? ============================== _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
