Skip to content

[libclang/python] Add type annotations for code completion classes #140539

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 35 additions & 31 deletions clang/bindings/python/clang/cindex.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@
"tuple[str, Optional[list[Any]], Any]",
"tuple[str, Optional[list[Any]], Any, Callable[..., Any]]",
]
CObjP: TypeAlias = _Pointer[Any]

TSeq = TypeVar("TSeq", covariant=True)

Expand Down Expand Up @@ -2960,25 +2961,25 @@ class _CXUnsavedFile(Structure):

class CompletionChunk:
class Kind:
def __init__(self, name):
def __init__(self, name: str):
self.name = name

def __str__(self):
def __str__(self) -> str:
return self.name

def __repr__(self):
def __repr__(self) -> str:
return "<ChunkKind: %s>" % self

def __init__(self, completionString, key):
def __init__(self, completionString: CObjP, key: int):
self.cs = completionString
self.key = key
self.__kindNumberCache = -1

def __repr__(self):
def __repr__(self) -> str:
return "{'" + self.spelling + "', " + str(self.kind) + "}"

@CachedProperty
def spelling(self):
def spelling(self) -> str:
if self.__kindNumber in SPELLING_CACHE:
return SPELLING_CACHE[self.__kindNumber]
return _CXString.from_result(
Expand All @@ -2989,38 +2990,38 @@ def spelling(self):
# apparently still significantly faster. Please profile carefully if you
# would like to add CachedProperty back.
@property
def __kindNumber(self):
def __kindNumber(self) -> int:
if self.__kindNumberCache == -1:
self.__kindNumberCache = conf.lib.clang_getCompletionChunkKind(
self.cs, self.key
)
return self.__kindNumberCache

@CachedProperty
def kind(self):
def kind(self) -> Kind:
return completionChunkKindMap[self.__kindNumber]

@CachedProperty
def string(self):
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):
def isKindOptional(self) -> bool:
return self.__kindNumber == 0

def isKindTypedText(self):
def isKindTypedText(self) -> bool:
return self.__kindNumber == 1

def isKindPlaceHolder(self):
def isKindPlaceHolder(self) -> bool:
return self.__kindNumber == 3

def isKindInformative(self):
def isKindInformative(self) -> bool:
return self.__kindNumber == 4

def isKindResultType(self):
def isKindResultType(self) -> bool:
return self.__kindNumber == 15


Expand Down Expand Up @@ -3060,39 +3061,39 @@ def __str__(self):
def __repr__(self):
return "<Availability: %s>" % self

def __len__(self):
def __len__(self) -> int:
return self.num_chunks

@CachedProperty
def num_chunks(self):
def num_chunks(self) -> int:
return conf.lib.clang_getNumCompletionChunks(self.obj) # type: ignore [no-any-return]

def __getitem__(self, key):
def __getitem__(self, key: int) -> CompletionChunk:
if self.num_chunks <= key:
raise IndexError
return CompletionChunk(self.obj, key)

if TYPE_CHECKING:
# Defining __getitem__ and __len__ is enough to make an iterable
# but the typechecker doesn't understand that.
def __iter__(self):
def __iter__(self) -> Iterator[CompletionChunk]:
for i in range(len(self)):
yield self[i]

@property
def priority(self):
def priority(self) -> int:
return conf.lib.clang_getCompletionPriority(self.obj) # type: ignore [no-any-return]

@property
def availability(self):
def availability(self) -> CompletionChunk.Kind:
res = conf.lib.clang_getCompletionAvailability(self.obj)
return availabilityKinds[res]

@property
def briefComment(self):
def briefComment(self) -> str:
return _CXString.from_result(conf.lib.clang_getCompletionBriefComment(self.obj))

def __repr__(self):
def __repr__(self) -> str:
return (
" | ".join([str(a) for a in self])
+ " || Priority: "
Expand All @@ -3115,44 +3116,47 @@ def __repr__(self):
class CodeCompletionResult(Structure):
_fields_ = [("cursorKind", c_int), ("completionString", c_object_p)]

def __repr__(self):
def __repr__(self) -> str:
return str(CompletionString(self.completionString))

@property
def kind(self):
def kind(self) -> CursorKind:
return CursorKind.from_id(self.cursorKind)

@property
def string(self):
def string(self) -> CompletionString:
return CompletionString(self.completionString)


class CCRStructure(Structure):
_fields_ = [("results", POINTER(CodeCompletionResult)), ("numResults", c_int)]

def __len__(self):
results: NoSliceSequence[CodeCompletionResult]
numResults: int

def __len__(self) -> int:
return self.numResults

def __getitem__(self, key):
def __getitem__(self, key: int) -> CodeCompletionResult:
if len(self) <= key:
raise IndexError

return self.results[key]


class CodeCompletionResults(ClangObject):
def __init__(self, ptr):
def __init__(self, ptr: _Pointer[CCRStructure]):
assert isinstance(ptr, POINTER(CCRStructure)) and ptr
self.ptr = self._as_parameter_ = ptr

def from_param(self):
def from_param(self) -> _Pointer[CCRStructure]:
return self._as_parameter_

def __del__(self):
def __del__(self) -> None:
conf.lib.clang_disposeCodeCompleteResults(self)

@property
def results(self):
def results(self) -> CCRStructure:
return self.ptr.contents

@property
Expand Down
Loading