[clang] Move SPELLING_CACHE into CodeCompletion (PR #177586)
Jannick Kremer via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 23 05:38:16 PST 2026
https://github.com/DeinAlptraum created https://github.com/llvm/llvm-project/pull/177586
This adresses point 2 from https://github.com/llvm/llvm-project/issues/156680.
Also add a dummy object that serves as an alias to `SPELLING_CACHE`, used to replicate the old behavior and throw a `DeprecationWarning`.
>From b09ada5630e379f3a673d8cb426f82d3c0fc5483 Mon Sep 17 00:00:00 2001
From: Jannick Kremer <jannick.kremer at mailbox.org>
Date: Fri, 23 Jan 2026 22:17:35 +0900
Subject: [PATCH 1/4] Move SPELLING_CACHE into CompletionChunk
Also use Enums as keys instead of values
---
clang/bindings/python/clang/cindex.py | 150 +++++++++++++-------------
1 file changed, 74 insertions(+), 76 deletions(-)
diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py
index 9dce404a183aa..45036c849b183 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -3024,82 +3024,6 @@ class _CXUnsavedFile(Structure):
_fields_ = [("name", c_char_p), ("contents", c_char_p), ("length", c_ulong)]
-# Functions calls through the python interface are rather slow. Fortunately,
-# for most symbols, we do not need to perform a function call. Their spelling
-# never changes and is consequently provided by this spelling cache.
-SPELLING_CACHE = {
- # 0: CompletionChunk.Kind("Optional"),
- # 1: CompletionChunk.Kind("TypedText"),
- # 2: CompletionChunk.Kind("Text"),
- # 3: CompletionChunk.Kind("Placeholder"),
- # 4: CompletionChunk.Kind("Informative"),
- # 5 : CompletionChunk.Kind("CurrentParameter"),
- 6: "(", # CompletionChunk.Kind("LeftParen"),
- 7: ")", # CompletionChunk.Kind("RightParen"),
- 8: "[", # CompletionChunk.Kind("LeftBracket"),
- 9: "]", # CompletionChunk.Kind("RightBracket"),
- 10: "{", # CompletionChunk.Kind("LeftBrace"),
- 11: "}", # CompletionChunk.Kind("RightBrace"),
- 12: "<", # CompletionChunk.Kind("LeftAngle"),
- 13: ">", # CompletionChunk.Kind("RightAngle"),
- 14: ", ", # CompletionChunk.Kind("Comma"),
- # 15: CompletionChunk.Kind("ResultType"),
- 16: ":", # CompletionChunk.Kind("Colon"),
- 17: ";", # CompletionChunk.Kind("SemiColon"),
- 18: "=", # CompletionChunk.Kind("Equal"),
- 19: " ", # CompletionChunk.Kind("HorizontalSpace"),
- # 20: CompletionChunk.Kind("VerticalSpace")
-}
-
-
-class CompletionChunk:
- __kind_id: int
-
- def __init__(self, completionString: CObjP, key: int):
- self.cs = completionString
- self.key = key
-
- def __repr__(self) -> str:
- return "{'" + self.spelling + "', " + str(self.kind) + "}"
-
- @CachedProperty
- def spelling(self) -> str:
- kind_id = conf.lib.clang_getCompletionChunkKind(self.cs, self.key)
- if kind_id in SPELLING_CACHE:
- return SPELLING_CACHE[kind_id]
- return _CXString.from_result(
- conf.lib.clang_getCompletionChunkText(self.cs, self.key)
- )
-
- @CachedProperty
- def kind(self) -> CompletionChunkKind:
- return CompletionChunkKind.from_id(
- conf.lib.clang_getCompletionChunkKind(self.cs, self.key)
- )
-
- @CachedProperty
- def string(self) -> CompletionString | None:
- res = conf.lib.clang_getCompletionChunkCompletionString(self.cs, self.key)
-
- if not res:
- return None
- return CompletionString(res)
-
- def isKindOptional(self) -> bool:
- return self.kind == CompletionChunkKind.OPTIONAL
-
- def isKindTypedText(self) -> bool:
- return self.kind == CompletionChunkKind.TYPED_TEXT
-
- def isKindPlaceHolder(self) -> bool:
- return self.kind == CompletionChunkKind.PLACEHOLDER
-
- def isKindInformative(self) -> bool:
- return self.kind == CompletionChunkKind.INFORMATIVE
-
- def isKindResultType(self) -> bool:
- return self.kind == CompletionChunkKind.RESULT_TYPE
-
### Completion Chunk Kinds ###
class CompletionChunkKind(BaseEnumeration):
"""
@@ -3149,6 +3073,80 @@ def __str__(self) -> str:
VERTICAL_SPACE = 20
+class CompletionChunk:
+ # Functions calls through the python interface are rather slow. Fortunately,
+ # for most symbols, we do not need to perform a function call. Their spelling
+ # never changes and is consequently provided by this spelling cache.
+ SPELLING_CACHE = {
+ # 0: CompletionChunkKind.OPTIONAL
+ # 1: CompletionChunkKind.TYPED_TEXT
+ # 2: CompletionChunkKind.TEXT
+ # 3: CompletionChunkKind.PLACEHOLDER
+ # 4: CompletionChunkKind.INFORMATIVE
+ # 5: CompletionChunkKind.CURRENT_PARAMETER
+ CompletionChunkKind.LEFT_PAREN: "(", # 6
+ CompletionChunkKind.RIGHT_PAREN: ")", # 7
+ CompletionChunkKind.LEFT_BRACKET: "[", # 8
+ CompletionChunkKind.RIGHT_BRACKET: "]", # 9
+ CompletionChunkKind.LEFT_BRACE: "{", # 10
+ CompletionChunkKind.RIGHT_BRACE: "}", # 11
+ CompletionChunkKind.LEFT_ANGLE: "<", # 12
+ CompletionChunkKind.RIGHT_ANGLE: ">", # 13
+ CompletionChunkKind.COMMA: ", ", # 14
+ # 15: CompletionChunkKind.RESULT_TYPE
+ CompletionChunkKind.COLON: ":", # 16
+ CompletionChunkKind.SEMI_COLON: ";", # 17
+ CompletionChunkKind.EQUAL: "=", # 18
+ CompletionChunkKind.HORIZONTAL_SPACE: " ", # 19
+ # 20: CompletionChunkKind.VERTICAL_SPACE
+ }
+
+ def __init__(self, completionString: CObjP, key: int):
+ self.cs = completionString
+ self.key = key
+
+ def __repr__(self) -> str:
+ return "{'" + self.spelling + "', " + str(self.kind) + "}"
+
+ @CachedProperty
+ def spelling(self) -> str:
+ kind = self.kind
+ if kind in CompletionChunk.SPELLING_CACHE:
+ return CompletionChunk.SPELLING_CACHE[kind]
+ return _CXString.from_result(
+ conf.lib.clang_getCompletionChunkText(self.cs, self.key)
+ )
+
+ @CachedProperty
+ def kind(self) -> CompletionChunkKind:
+ return CompletionChunkKind.from_id(
+ conf.lib.clang_getCompletionChunkKind(self.cs, self.key)
+ )
+
+ @CachedProperty
+ def string(self) -> CompletionString | None:
+ res = conf.lib.clang_getCompletionChunkCompletionString(self.cs, self.key)
+
+ if not res:
+ return None
+ return CompletionString(res)
+
+ def isKindOptional(self) -> bool:
+ return self.kind == CompletionChunkKind.OPTIONAL
+
+ def isKindTypedText(self) -> bool:
+ return self.kind == CompletionChunkKind.TYPED_TEXT
+
+ def isKindPlaceHolder(self) -> bool:
+ return self.kind == CompletionChunkKind.PLACEHOLDER
+
+ def isKindInformative(self) -> bool:
+ return self.kind == CompletionChunkKind.INFORMATIVE
+
+ def isKindResultType(self) -> bool:
+ return self.kind == CompletionChunkKind.RESULT_TYPE
+
+
class CompletionString(ClangObject):
# AvailabilityKindCompat is an exact copy of AvailabilityKind, except for __str__.
# This is a temporary measure to keep the string representation the same
>From 67e8349cbff7325daac4f941abb54aee4f2ab43a Mon Sep 17 00:00:00 2001
From: Jannick Kremer <jannick.kremer at mailbox.org>
Date: Fri, 23 Jan 2026 22:20:42 +0900
Subject: [PATCH 2/4] Add SPELLING_CACHE alias
---
clang/bindings/python/clang/cindex.py | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py
index 45036c849b183..4282977fc7bb6 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -3074,6 +3074,27 @@ def __str__(self) -> str:
class CompletionChunk:
+ class SpellingCacheAlias:
+ """
+ A temporary utility that acts as an alias to CompletionChunk.SPELLING_CACHE.
+ This will be removed without deprecation warning in a future release.
+ Please do not use it directly!
+ """
+ def __getitem__(self, value: int):
+ warnings.warn(
+ "'SPELLING_CACHE' has been moved into the scope of 'CompletionChunk' "
+ "and adapted to use 'CompletionChunkKind's as keys instea of their "
+ "enum values. Please adapt all uses of 'SPELLING_CACHE' to use "
+ "'CompletionChunk.SPELLING_CACHE' instead. The old 'SPELLING_CACHE' "
+ "will be removed in a future release.",
+ DeprecationWarning,
+ )
+ return CompletionChunk.SPELLING_CACHE[CompletionChunkKind.from_id(value)]
+
+ def __contains__(self, value: int):
+ return CompletionChunkKind.from_id(value) in CompletionChunk.SPELLING_CACHE
+
+
# Functions calls through the python interface are rather slow. Fortunately,
# for most symbols, we do not need to perform a function call. Their spelling
# never changes and is consequently provided by this spelling cache.
@@ -3147,6 +3168,9 @@ def isKindResultType(self) -> bool:
return self.kind == CompletionChunkKind.RESULT_TYPE
+SPELLING_CACHE = CompletionChunk.SpellingCacheAlias()
+
+
class CompletionString(ClangObject):
# AvailabilityKindCompat is an exact copy of AvailabilityKind, except for __str__.
# This is a temporary measure to keep the string representation the same
>From c78f00382a068ae5ef22b7120e2a7773392f5b4e Mon Sep 17 00:00:00 2001
From: Jannick Kremer <jannick.kremer at mailbox.org>
Date: Fri, 23 Jan 2026 22:25:56 +0900
Subject: [PATCH 3/4] Add release note
---
clang/docs/ReleaseNotes.rst | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a734804865c57..081a4773009f7 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -72,6 +72,11 @@ Clang Python Bindings Potentially Breaking Changes
These representations will be changed in a future release to match other enums.
- Remove ``completionChunkKindMap``. In this release, uses of ``completionChunkKindMap``
need to be replaced by ``CompletionChunkKind``.
+- Move ``SPELLING_CACHE`` into ``CompletionChunk`` and change it to use
+ ``CompletionChunkKind`` instances as keys, instead of the enum values.
+ An alias is kept in the form of a ``SPELLING_CACHE`` variable, but it only supports
+ ``__getitem__`` and ``__contains__``. It will be removed in a future release.
+ Please migrate to using ``CompletionChunk.SPELLING_CACHE`` instead.
What's New in Clang |release|?
==============================
>From e40e64dc5badfaa128dc5fea4eee9011946709cf Mon Sep 17 00:00:00 2001
From: Jannick Kremer <jannick.kremer at mailbox.org>
Date: Fri, 23 Jan 2026 22:37:29 +0900
Subject: [PATCH 4/4] Add additional deprecation warning
---
clang/bindings/python/clang/cindex.py | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py
index 4282977fc7bb6..f76fb38de6a7f 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -3080,18 +3080,21 @@ class SpellingCacheAlias:
This will be removed without deprecation warning in a future release.
Please do not use it directly!
"""
+
+ deprecation_message = (
+ "'SPELLING_CACHE' has been moved into the scope of 'CompletionChunk' "
+ "and adapted to use 'CompletionChunkKind's as keys instead of their "
+ "enum values. Please adapt all uses of 'SPELLING_CACHE' to use "
+ "'CompletionChunk.SPELLING_CACHE' instead. The old 'SPELLING_CACHE' "
+ "will be removed in a future release."
+ )
+
def __getitem__(self, value: int):
- warnings.warn(
- "'SPELLING_CACHE' has been moved into the scope of 'CompletionChunk' "
- "and adapted to use 'CompletionChunkKind's as keys instea of their "
- "enum values. Please adapt all uses of 'SPELLING_CACHE' to use "
- "'CompletionChunk.SPELLING_CACHE' instead. The old 'SPELLING_CACHE' "
- "will be removed in a future release.",
- DeprecationWarning,
- )
+ warnings.warn(self.deprecation_message, DeprecationWarning)
return CompletionChunk.SPELLING_CACHE[CompletionChunkKind.from_id(value)]
def __contains__(self, value: int):
+ warnings.warn(self.deprecation_message, DeprecationWarning)
return CompletionChunkKind.from_id(value) in CompletionChunk.SPELLING_CACHE
More information about the cfe-commits
mailing list