[clang] [clang-bindings] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-01-14 Thread Jannick Kremer via cfe-commits


@@ -67,89 +67,690 @@
 import clang.enumerations
 
 import os
-import sys
-
-if sys.version_info[0] == 3:
-# Python 3 strings are unicode, translate them to/from utf8 for C-interop.
-class c_interop_string(c_char_p):
-def __init__(self, p=None):
-if p is None:
-p = ""
-if isinstance(p, str):
-p = p.encode("utf8")
-super(c_char_p, self).__init__(p)
-
-def __str__(self):
-return self.value
-
-@property
-def value(self):
-if super(c_char_p, self).value is None:
-return None
-return super(c_char_p, self).value.decode("utf8")
-
-@classmethod
-def from_param(cls, param):
-if isinstance(param, str):
-return cls(param)
-if isinstance(param, bytes):
-return cls(param)
-if param is None:
-# Support passing null to C functions expecting char arrays
-return None
-raise TypeError(
-"Cannot convert '{}' to '{}'".format(type(param).__name__, 
cls.__name__)
-)
+from enum import Enum
+
+from typing import (
+Any,
+Callable,
+cast as Tcast,
+Generic,
+Iterable,
+Iterator,
+Optional,
+Sequence,
+Type as TType,
+TypeVar,
+TYPE_CHECKING,
+Union as TUnion,
+)
+from typing_extensions import Protocol, TypeAlias
+
+if TYPE_CHECKING:
+from ctypes import _Pointer, _FuncPointer, _CArgObject
+from io import TextIOWrapper
+
+StrPath: TypeAlias = TUnion[str, os.PathLike[str]]
+InMemoryFile: TypeAlias = (
+"tuple[TUnion[str, os.PathLike[Any]], TUnion[str, TextIOWrapper]]"
+)
+LibFunc: TypeAlias = TUnion[
+"tuple[str, Optional[list[Any]]]",
+"tuple[str, Optional[list[Any]], Any]",
+"tuple[str, Optional[list[Any]], Any, Callable[..., Any]]",
+]
+CObjP: TypeAlias = _Pointer[Any]
 
-@staticmethod
-def to_python_string(x, *args):
-return x.value
+TSeq = TypeVar("TSeq", covariant=True)
 
-def b(x):
-if isinstance(x, bytes):
-return x
-return x.encode("utf8")
+class NoSliceSequence(Protocol[TSeq]):
+def __len__(self) -> int:
+...
 
-elif sys.version_info[0] == 2:
-# Python 2 strings are utf8 byte strings, no translation is needed for
-# C-interop.
-c_interop_string = c_char_p
+def __getitem__(self, key: int) -> TSeq:
+...
 
-def _to_python_string(x, *args):
-return x
 
-c_interop_string.to_python_string = staticmethod(_to_python_string)
+class ClangLib(Protocol):

DeinAlptraum wrote:

This protocol was the only working way I found to pass the type check with the 
CDLL, due to the library functions being added dynamically, but it is rather 
ugly and adds a thousand lines of bloat. If anyone has a better idea, I'm happy 
to hear it.

https://github.com/llvm/llvm-project/pull/78114
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-bindings] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-01-14 Thread Jannick Kremer via cfe-commits


@@ -67,89 +67,690 @@
 import clang.enumerations
 
 import os
-import sys
-
-if sys.version_info[0] == 3:
-# Python 3 strings are unicode, translate them to/from utf8 for C-interop.
-class c_interop_string(c_char_p):
-def __init__(self, p=None):
-if p is None:
-p = ""
-if isinstance(p, str):
-p = p.encode("utf8")
-super(c_char_p, self).__init__(p)
-
-def __str__(self):
-return self.value
-
-@property
-def value(self):
-if super(c_char_p, self).value is None:
-return None
-return super(c_char_p, self).value.decode("utf8")
-
-@classmethod
-def from_param(cls, param):
-if isinstance(param, str):
-return cls(param)
-if isinstance(param, bytes):
-return cls(param)
-if param is None:
-# Support passing null to C functions expecting char arrays
-return None
-raise TypeError(
-"Cannot convert '{}' to '{}'".format(type(param).__name__, 
cls.__name__)
-)
+from enum import Enum
+
+from typing import (
+Any,

DeinAlptraum wrote:

I used Any (mostly) to label ununused arguments. More specific annotations 
would have been possible in some cases, but I did not find this worth the 
effort. 

https://github.com/llvm/llvm-project/pull/78114
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-bindings] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-01-14 Thread Jannick Kremer via cfe-commits


@@ -642,51 +1259,29 @@ def register(value, name):
 
 
 ### Cursor Kinds ###
-class BaseEnumeration(object):
-"""
-Common base class for named enumerations held in sync with Index.h values.
+TEnum = TypeVar("TEnum", bound="BaseEnumeration")
 
-Subclasses must define their own _kinds and _name_map members, as:
-_kinds = []
-_name_map = None
-These values hold the per-subclass instances and value-to-name mappings,
-respectively.
 
+class BaseEnumeration(Enum):
+"""
+Common base class for named enumerations held in sync with Index.h values.
 """
 
-def __init__(self, value):
-if value >= len(self.__class__._kinds):
-self.__class__._kinds += [None] * (value - 
len(self.__class__._kinds) + 1)
-if self.__class__._kinds[value] is not None:
-raise ValueError(
-"{0} value {1} already loaded".format(str(self.__class__), 
value)
-)
-self.value = value
-self.__class__._kinds[value] = self
-self.__class__._name_map = None
+value: int
 
-def from_param(self):
+def from_param(self) -> int:
 return self.value
 
-@property
-def name(self):
-"""Get the enumeration name of this cursor kind."""
-if self._name_map is None:
-self._name_map = {}
-for key, value in self.__class__.__dict__.items():
-if isinstance(value, self.__class__):
-self._name_map[value] = key
-return self._name_map[self]
-
 @classmethod
-def from_id(cls, id):
-if id >= len(cls._kinds) or cls._kinds[id] is None:
-raise ValueError("Unknown template argument kind %d" % id)
-return cls._kinds[id]
+def from_id(cls: type[TEnum], id: int) -> TEnum:
+try:
+return cls(id)
+except ValueError:
+raise ValueError("Unknown %s %d" % (cls.__class__, id))

DeinAlptraum wrote:

This also resolves behavior that I would consider a bug: for negative IDs, if 
you pass e.g. -1, this would return the last element of `_kinds` (due to Python 
list syntax) instea dof raising the appropriate value error.

https://github.com/llvm/llvm-project/pull/78114
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-bindings] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-01-14 Thread Jannick Kremer via cfe-commits


@@ -642,51 +1259,29 @@ def register(value, name):
 
 
 ### Cursor Kinds ###
-class BaseEnumeration(object):
-"""
-Common base class for named enumerations held in sync with Index.h values.
+TEnum = TypeVar("TEnum", bound="BaseEnumeration")
 
-Subclasses must define their own _kinds and _name_map members, as:
-_kinds = []
-_name_map = None
-These values hold the per-subclass instances and value-to-name mappings,
-respectively.
 
+class BaseEnumeration(Enum):

DeinAlptraum wrote:

Since I've collected the shared functionality of all enums into this class, 
including e.g. `__repr__` definitions, some of them may differ slightly in 
output.
E.g. the representation of a `TemplateArgumentKind.INTEGRAL` is exactly 
`TemplateArgumentKind.INTEGRAL`, compared to 
`'clang.cindex.TemplateArgumentKind'>.INTEGRAL`, which is consistent with the 
representation of most other enums.

https://github.com/llvm/llvm-project/pull/78114
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-bindings] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-01-14 Thread Jannick Kremer via cfe-commits


@@ -3968,7 +4500,7 @@ def function_exists(self, name):
 return True
 
 
-def register_enumerations():
+def register_enumerations() -> None:

DeinAlptraum wrote:

This implementation dynamically adds the TokenKind variants, which means it 
also suffers from the same problems as the previoius "manual" implementation of 
enums: if you write e.g. `TokenKind.PUNCTUATION` in a program and typecheck it, 
it will throw an error since it doesn't recognize `PUNCTUATION` as a member of 
`TokenKind`.
I'm not sure why this one enum is outsourced to a different file and 
implemented via this dynamic registering approach. I'd be in favor of removing 
that and handling it just like the other enums.

https://github.com/llvm/llvm-project/pull/78114
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-bindings] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-01-14 Thread Jannick Kremer via cfe-commits


@@ -232,13 +840,16 @@ class _CXString(Structure):
 
 _fields_ = [("spelling", c_char_p), ("free", c_int)]
 
-def __del__(self):
+def __del__(self) -> None:
 conf.lib.clang_disposeString(self)
 
 @staticmethod
-def from_result(res, fn=None, args=None):
+def from_result(res: _CXString, fn: Any = None, args: Any = None) -> str:
 assert isinstance(res, _CXString)
-return conf.lib.clang_getCString(res)
+pystr = conf.lib.clang_getCString(res)
+if pystr is None:
+return ""
+return pystr

DeinAlptraum wrote:

`conf.lib.clang_getCString` may sometimes (though seemingly rarely) return 
`None` instead of a Python `str`. This is used in a lot of places throughout 
this file, and while parts of it seem to be aware of this (e.g. doc string 
saying that this may return `None`) other places are not (e.g. calling `len` on 
the return value, which will crash if it is `None`). Many parts of the 
interface also directly return the result of this function, and having to check 
for `None` in all of these places seems potentially impractical, so I went for 
returning empty strings instead of `None` instead.
But due to the inconsistent usage throughout this file, I'm not sure how far 
this corresponds more or less to the original intention.

https://github.com/llvm/llvm-project/pull/78114
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-bindings] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-01-14 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum edited 
https://github.com/llvm/llvm-project/pull/78114
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-bindings] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-01-14 Thread Jannick Kremer via cfe-commits


@@ -67,89 +67,690 @@
 import clang.enumerations
 
 import os
-import sys
-
-if sys.version_info[0] == 3:
-# Python 3 strings are unicode, translate them to/from utf8 for C-interop.
-class c_interop_string(c_char_p):
-def __init__(self, p=None):
-if p is None:
-p = ""
-if isinstance(p, str):
-p = p.encode("utf8")
-super(c_char_p, self).__init__(p)
-
-def __str__(self):
-return self.value
-
-@property
-def value(self):
-if super(c_char_p, self).value is None:
-return None
-return super(c_char_p, self).value.decode("utf8")
-
-@classmethod
-def from_param(cls, param):
-if isinstance(param, str):
-return cls(param)
-if isinstance(param, bytes):
-return cls(param)
-if param is None:
-# Support passing null to C functions expecting char arrays
-return None
-raise TypeError(
-"Cannot convert '{}' to '{}'".format(type(param).__name__, 
cls.__name__)
-)
+from enum import Enum
+
+from typing import (
+Any,
+Callable,
+cast as Tcast,
+Generic,
+Iterable,
+Iterator,
+Optional,
+Sequence,
+Type as TType,
+TypeVar,
+TYPE_CHECKING,
+Union as TUnion,
+)
+from typing_extensions import Protocol, TypeAlias
+
+if TYPE_CHECKING:
+from ctypes import _Pointer, _FuncPointer, _CArgObject
+from io import TextIOWrapper
+
+StrPath: TypeAlias = TUnion[str, os.PathLike[str]]
+InMemoryFile: TypeAlias = (
+"tuple[TUnion[str, os.PathLike[Any]], TUnion[str, TextIOWrapper]]"
+)
+LibFunc: TypeAlias = TUnion[
+"tuple[str, Optional[list[Any]]]",
+"tuple[str, Optional[list[Any]], Any]",
+"tuple[str, Optional[list[Any]], Any, Callable[..., Any]]",
+]
+CObjP: TypeAlias = _Pointer[Any]
 
-@staticmethod
-def to_python_string(x, *args):
-return x.value
+TSeq = TypeVar("TSeq", covariant=True)
 
-def b(x):
-if isinstance(x, bytes):
-return x
-return x.encode("utf8")
+class NoSliceSequence(Protocol[TSeq]):
+def __len__(self) -> int:
+...
 
-elif sys.version_info[0] == 2:
-# Python 2 strings are utf8 byte strings, no translation is needed for
-# C-interop.
-c_interop_string = c_char_p
+def __getitem__(self, key: int) -> TSeq:
+...
 
-def _to_python_string(x, *args):
-return x
 
-c_interop_string.to_python_string = staticmethod(_to_python_string)
+class ClangLib(Protocol):
+def clang_annotateTokens(
+self, tu: TranslationUnit, token: _CArgObject, num: int, cursor: 
_CArgObject
+) -> None:
+...
 
-def b(x):
-return x
+def clang_CompilationDatabase_dispose(self, cdb: CompilationDatabase) -> 
None:
+...
+
+def clang_CompilationDatabase_fromDirectory(
+self, buildDir: str, errorCode: _CArgObject
+) -> CompilationDatabase:
+...
+
+def clang_CompilationDatabase_getAllCompileCommands(
+self, cdb: CompilationDatabase
+) -> CompileCommands:
+...
+
+def clang_CompilationDatabase_getCompileCommands(
+self, cdb: CompilationDatabase, filename: str
+) -> CompileCommands:
+...
+
+def clang_CompileCommands_dispose(self, ccmds: CObjP) -> None:
+...
+
+def clang_CompileCommands_getCommand(self, ccmds: CObjP, key: int) -> 
CObjP:
+...
+
+def clang_CompileCommands_getSize(self, ccmds: CObjP) -> c_uint:
+...
+
+def clang_CompileCommand_getArg(self, cmd: CObjP, key: int) -> str:
+...
+
+def clang_CompileCommand_getDirectory(self, cmd: CObjP) -> str:
+...
+
+def clang_CompileCommand_getFilename(self, cmd: CObjP) -> str:
+...
+
+def clang_CompileCommand_getNumArgs(self, cmd: CObjP) -> int:

DeinAlptraum wrote:

According to the definitions in `functionList`, all library functions return C 
types for number (`c_int, c_uint, c_longlong, c_ulonglong`). However, checking 
the types of the return values tells me that in all cases where I looked, these 
actually returned Python `int`s. According to the `ctypes` docs, you need 
explicit conversion i.e. calling `c_uint(https://github.com/llvm/llvm-project/pull/78114
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-bindings] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-01-14 Thread Jannick Kremer via cfe-commits


@@ -67,89 +67,690 @@
 import clang.enumerations
 
 import os
-import sys
-
-if sys.version_info[0] == 3:
-# Python 3 strings are unicode, translate them to/from utf8 for C-interop.
-class c_interop_string(c_char_p):
-def __init__(self, p=None):
-if p is None:
-p = ""
-if isinstance(p, str):
-p = p.encode("utf8")
-super(c_char_p, self).__init__(p)
-
-def __str__(self):
-return self.value
-
-@property
-def value(self):
-if super(c_char_p, self).value is None:
-return None
-return super(c_char_p, self).value.decode("utf8")
-
-@classmethod
-def from_param(cls, param):
-if isinstance(param, str):
-return cls(param)
-if isinstance(param, bytes):
-return cls(param)
-if param is None:
-# Support passing null to C functions expecting char arrays
-return None
-raise TypeError(
-"Cannot convert '{}' to '{}'".format(type(param).__name__, 
cls.__name__)
-)
+from enum import Enum
+
+from typing import (
+Any,
+Callable,
+cast as Tcast,
+Generic,
+Iterable,
+Iterator,
+Optional,
+Sequence,
+Type as TType,
+TypeVar,
+TYPE_CHECKING,
+Union as TUnion,
+)
+from typing_extensions import Protocol, TypeAlias
+
+if TYPE_CHECKING:
+from ctypes import _Pointer, _FuncPointer, _CArgObject
+from io import TextIOWrapper
+
+StrPath: TypeAlias = TUnion[str, os.PathLike[str]]
+InMemoryFile: TypeAlias = (
+"tuple[TUnion[str, os.PathLike[Any]], TUnion[str, TextIOWrapper]]"
+)
+LibFunc: TypeAlias = TUnion[
+"tuple[str, Optional[list[Any]]]",
+"tuple[str, Optional[list[Any]], Any]",
+"tuple[str, Optional[list[Any]], Any, Callable[..., Any]]",
+]
+CObjP: TypeAlias = _Pointer[Any]
 
-@staticmethod
-def to_python_string(x, *args):
-return x.value
+TSeq = TypeVar("TSeq", covariant=True)
 
-def b(x):
-if isinstance(x, bytes):
-return x
-return x.encode("utf8")
+class NoSliceSequence(Protocol[TSeq]):
+def __len__(self) -> int:
+...
 
-elif sys.version_info[0] == 2:
-# Python 2 strings are utf8 byte strings, no translation is needed for
-# C-interop.
-c_interop_string = c_char_p
+def __getitem__(self, key: int) -> TSeq:
+...
 
-def _to_python_string(x, *args):
-return x
 
-c_interop_string.to_python_string = staticmethod(_to_python_string)
+class ClangLib(Protocol):
+def clang_annotateTokens(
+self, tu: TranslationUnit, token: _CArgObject, num: int, cursor: 
_CArgObject
+) -> None:
+...
 
-def b(x):
-return x
+def clang_CompilationDatabase_dispose(self, cdb: CompilationDatabase) -> 
None:
+...
+
+def clang_CompilationDatabase_fromDirectory(
+self, buildDir: str, errorCode: _CArgObject
+) -> CompilationDatabase:
+...
+
+def clang_CompilationDatabase_getAllCompileCommands(
+self, cdb: CompilationDatabase
+) -> CompileCommands:
+...
+
+def clang_CompilationDatabase_getCompileCommands(
+self, cdb: CompilationDatabase, filename: str
+) -> CompileCommands:
+...
+
+def clang_CompileCommands_dispose(self, ccmds: CObjP) -> None:
+...
+
+def clang_CompileCommands_getCommand(self, ccmds: CObjP, key: int) -> 
CObjP:
+...
+
+def clang_CompileCommands_getSize(self, ccmds: CObjP) -> c_uint:
+...
+
+def clang_CompileCommand_getArg(self, cmd: CObjP, key: int) -> str:
+...
+
+def clang_CompileCommand_getDirectory(self, cmd: CObjP) -> str:
+...
+
+def clang_CompileCommand_getFilename(self, cmd: CObjP) -> str:
+...
+
+def clang_CompileCommand_getNumArgs(self, cmd: CObjP) -> int:
+...
+
+def clang_codeCompleteAt(
+self,
+tu: TranslationUnit,
+filename: str,
+line: int,
+column: int,
+unsaved_files: TUnion[int, Array[_CXUnsavedFile]],
+num_unsaved_files: int,
+options: int,
+) -> _Pointer[CCRStructure]:
+...
+
+def clang_codeCompleteGetDiagnostic(
+self, ccrs: CodeCompletionResults, key: int
+) -> Diagnostic:
+...
+
+def clang_codeCompleteGetNumDiagnostics(self, ccrs: CodeCompletionResults) 
-> c_int:
+...
+
+def clang_createIndex(self, excludeDecls: int, displayDiagnostics: int) -> 
CObjP:
+...
+
+def clang_createTranslationUnit(self, index: Index, filename: str) -> 
CObjP:
+...
+
+def clang_CXXConstructor_isConvertingConstructor(self, cursor: Cursor) -> 
bool:
+...
+
+def clang_CXXConstructor_isCopyConstructor(self, cursor: Cursor) -> bool:
+  

[clang] [clang-bindings] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-01-14 Thread Jannick Kremer via cfe-commits


@@ -2341,30 +2830,32 @@ class Type(Structure):
 
 _fields_ = [("_kind_id", c_int), ("data", c_void_p * 2)]
 
+_tu: TranslationUnit
+
 @property
-def kind(self):
+def kind(self) -> TypeKind:
 """Return the kind of this type."""
 return TypeKind.from_id(self._kind_id)
 
-def argument_types(self):
+def argument_types(self) -> NoSliceSequence[Type]:
 """Retrieve a container for the non-variadic arguments for this type.
 
 The returned object is iterable and indexable. Each item in the
 container is a Type instance.
 """
 
-class ArgumentsIterator(collections_abc.Sequence):
-def __init__(self, parent):
+class ArgumentsIterator:

DeinAlptraum wrote:

Removed the inheritance here, since ArgumentsIterator doesn't actually 
implement everything needed by the protocol anyway (which is precisely why I 
had to add the `NoSliceSequence` protocol)

https://github.com/llvm/llvm-project/pull/78114
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-bindings] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-01-14 Thread Jannick Kremer via cfe-commits


@@ -67,89 +67,690 @@
 import clang.enumerations
 
 import os
-import sys
-
-if sys.version_info[0] == 3:
-# Python 3 strings are unicode, translate them to/from utf8 for C-interop.
-class c_interop_string(c_char_p):
-def __init__(self, p=None):
-if p is None:
-p = ""
-if isinstance(p, str):
-p = p.encode("utf8")
-super(c_char_p, self).__init__(p)
-
-def __str__(self):
-return self.value
-
-@property
-def value(self):
-if super(c_char_p, self).value is None:
-return None
-return super(c_char_p, self).value.decode("utf8")
-
-@classmethod
-def from_param(cls, param):
-if isinstance(param, str):
-return cls(param)
-if isinstance(param, bytes):
-return cls(param)
-if param is None:
-# Support passing null to C functions expecting char arrays
-return None
-raise TypeError(
-"Cannot convert '{}' to '{}'".format(type(param).__name__, 
cls.__name__)
-)
+from enum import Enum
+
+from typing import (
+Any,
+Callable,
+cast as Tcast,
+Generic,
+Iterable,
+Iterator,
+Optional,
+Sequence,
+Type as TType,
+TypeVar,
+TYPE_CHECKING,
+Union as TUnion,
+)
+from typing_extensions import Protocol, TypeAlias
+
+if TYPE_CHECKING:
+from ctypes import _Pointer, _FuncPointer, _CArgObject
+from io import TextIOWrapper
+
+StrPath: TypeAlias = TUnion[str, os.PathLike[str]]
+InMemoryFile: TypeAlias = (
+"tuple[TUnion[str, os.PathLike[Any]], TUnion[str, TextIOWrapper]]"
+)
+LibFunc: TypeAlias = TUnion[
+"tuple[str, Optional[list[Any]]]",
+"tuple[str, Optional[list[Any]], Any]",
+"tuple[str, Optional[list[Any]], Any, Callable[..., Any]]",
+]
+CObjP: TypeAlias = _Pointer[Any]
 
-@staticmethod
-def to_python_string(x, *args):
-return x.value
+TSeq = TypeVar("TSeq", covariant=True)
 
-def b(x):
-if isinstance(x, bytes):
-return x
-return x.encode("utf8")
+class NoSliceSequence(Protocol[TSeq]):
+def __len__(self) -> int:
+...
 
-elif sys.version_info[0] == 2:
-# Python 2 strings are utf8 byte strings, no translation is needed for
-# C-interop.
-c_interop_string = c_char_p
+def __getitem__(self, key: int) -> TSeq:
+...
 
-def _to_python_string(x, *args):
-return x
 
-c_interop_string.to_python_string = staticmethod(_to_python_string)
+class ClangLib(Protocol):
+def clang_annotateTokens(
+self, tu: TranslationUnit, token: _CArgObject, num: int, cursor: 
_CArgObject
+) -> None:
+...
 
-def b(x):
-return x
+def clang_CompilationDatabase_dispose(self, cdb: CompilationDatabase) -> 
None:
+...
+
+def clang_CompilationDatabase_fromDirectory(
+self, buildDir: str, errorCode: _CArgObject
+) -> CompilationDatabase:
+...
+
+def clang_CompilationDatabase_getAllCompileCommands(
+self, cdb: CompilationDatabase
+) -> CompileCommands:
+...
+
+def clang_CompilationDatabase_getCompileCommands(
+self, cdb: CompilationDatabase, filename: str
+) -> CompileCommands:
+...
+
+def clang_CompileCommands_dispose(self, ccmds: CObjP) -> None:
+...
+
+def clang_CompileCommands_getCommand(self, ccmds: CObjP, key: int) -> 
CObjP:
+...
+
+def clang_CompileCommands_getSize(self, ccmds: CObjP) -> c_uint:
+...
+
+def clang_CompileCommand_getArg(self, cmd: CObjP, key: int) -> str:
+...
+
+def clang_CompileCommand_getDirectory(self, cmd: CObjP) -> str:
+...
+
+def clang_CompileCommand_getFilename(self, cmd: CObjP) -> str:
+...
+
+def clang_CompileCommand_getNumArgs(self, cmd: CObjP) -> int:
+...
+
+def clang_codeCompleteAt(
+self,
+tu: TranslationUnit,
+filename: str,
+line: int,
+column: int,
+unsaved_files: TUnion[int, Array[_CXUnsavedFile]],
+num_unsaved_files: int,
+options: int,
+) -> _Pointer[CCRStructure]:
+...
+
+def clang_codeCompleteGetDiagnostic(
+self, ccrs: CodeCompletionResults, key: int
+) -> Diagnostic:
+...
+
+def clang_codeCompleteGetNumDiagnostics(self, ccrs: CodeCompletionResults) 
-> c_int:
+...
+
+def clang_createIndex(self, excludeDecls: int, displayDiagnostics: int) -> 
CObjP:
+...
+
+def clang_createTranslationUnit(self, index: Index, filename: str) -> 
CObjP:
+...
+
+def clang_CXXConstructor_isConvertingConstructor(self, cursor: Cursor) -> 
bool:
+...
+
+def clang_CXXConstructor_isCopyConstructor(self, cursor: Cursor) -> bool:
+  

[clang] [clang-bindings] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-01-14 Thread Jannick Kremer via cfe-commits


@@ -1722,23 +2300,23 @@ def location(self):
 return self._loc
 
 @property
-def linkage(self):
+def linkage(self) -> LinkageKind:
 """Return the linkage of this cursor."""
 if not hasattr(self, "_linkage"):
 self._linkage = conf.lib.clang_getCursorLinkage(self)
 
 return LinkageKind.from_id(self._linkage)
 
 @property
-def tls_kind(self):
+def tls_kind(self) -> TLSKind:
 """Return the thread-local storage (TLS) kind of this cursor."""
 if not hasattr(self, "_tls_kind"):
 self._tls_kind = conf.lib.clang_getCursorTLSKind(self)

DeinAlptraum wrote:

The `conf.lib.clang_getCursorTLSKind()` call leads to segmentation faults on my 
system (even before I changed anything) so I wasn't able to test this.

https://github.com/llvm/llvm-project/pull/78114
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-bindings] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-01-14 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum edited 
https://github.com/llvm/llvm-project/pull/78114
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-bindings] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-01-14 Thread Jannick Kremer via cfe-commits

DeinAlptraum wrote:

@AaronBallman could you review this or recommend reviewers? I didn't see any 
category in `clang/CodeOwners.rst` that seems to cover the bindings.

https://github.com/llvm/llvm-project/pull/78114
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-bindings] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-01-15 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum converted_to_draft 
https://github.com/llvm/llvm-project/pull/78114
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-bindings] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-01-15 Thread Jannick Kremer via cfe-commits

DeinAlptraum wrote:

I was just made aware of 
[some](https://github.com/llvm/llvm-project/pull/77219) 
[changes](https://github.com/llvm/llvm-project/pull/77228) by @linux4life798 
that seem reasonable to merge before this, so I've returned this  to draft 
status for now. Sorry for the confusion.

https://github.com/llvm/llvm-project/pull/78114
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Refactor enum usage (PR #95608)

2024-07-01 Thread Jannick Kremer via cfe-commits

DeinAlptraum wrote:

\*Ping*

@boomanaiden154 @linux4life798 a review/feedback would be appreciated!

https://github.com/llvm/llvm-project/pull/95608
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Refactor enum usage (PR #95608)

2024-07-01 Thread Jannick Kremer via cfe-commits


@@ -10,26 +10,6 @@
 
 
 class TestTokenKind(unittest.TestCase):
-def test_constructor(self):

DeinAlptraum wrote:

thNot really:
- `test_constructor`: this tests the ability to add enum variants "on the fly", 
which is not possible with the Python stdlib's `Enum` class
- `test_bad_register`: the `Enum` class tests for this on initialization, so if 
you define a duplicate `Enum` variant, you will get a failure on import 
already. This makes the test both a) effectively covered by that and b) you 
couldn't import the module to run such a test anyway in a case where there's a 
duplicate
- `test_unknown_value`: this is covered in `test_from_id` in `test_enums.py` 
since I added the `TokenKind` class to the test there 

https://github.com/llvm/llvm-project/pull/95608
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Refactor enum usage (PR #95608)

2024-07-01 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum edited 
https://github.com/llvm/llvm-project/pull/95608
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Refactor enum usage (PR #95608)

2024-07-01 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum edited 
https://github.com/llvm/llvm-project/pull/95608
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Refactor enum usage (PR #95608)

2024-07-01 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum updated 
https://github.com/llvm/llvm-project/pull/95608

>From 35bfcfbc69ee812c59350440b7b15c5e23ad1307 Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Fri, 14 Jun 2024 22:12:09 +0100
Subject: [PATCH 1/3] [libclang/python] Refactor enum usage

Use Python's builtin enum class instead of writing our own.

This is preparation for strict typing in PR #78114
---
 clang/bindings/python/clang/cindex.py | 1670 -
 .../python/tests/cindex/test_enums.py |   14 +-
 2 files changed, 768 insertions(+), 916 deletions(-)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index b3d51e4d2a668..aacfc333723c4 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -68,6 +68,7 @@
 
 import collections.abc
 import os
+from enum import Enum
 
 
 # Python 3 strings are unicode, translate them to/from utf8 for C-interop.
@@ -611,51 +612,25 @@ def register(value, name):
 
 
 ### Cursor Kinds ###
-class BaseEnumeration:
+class BaseEnumeration(Enum):
 """
 Common base class for named enumerations held in sync with Index.h values.
-
-Subclasses must define their own _kinds and _name_map members, as:
-_kinds = []
-_name_map = None
-These values hold the per-subclass instances and value-to-name mappings,
-respectively.
-
 """
 
-def __init__(self, value):
-if value >= len(self.__class__._kinds):
-self.__class__._kinds += [None] * (value - 
len(self.__class__._kinds) + 1)
-if self.__class__._kinds[value] is not None:
-raise ValueError(
-"{0} value {1} already loaded".format(str(self.__class__), 
value)
-)
-self.value = value
-self.__class__._kinds[value] = self
-self.__class__._name_map = None
 
 def from_param(self):
 return self.value
 
-@property
-def name(self):
-"""Get the enumeration name of this cursor kind."""
-if self._name_map is None:
-self._name_map = {}
-for key, value in self.__class__.__dict__.items():
-if isinstance(value, self.__class__):
-self._name_map[value] = key
-return self._name_map[self]
-
 @classmethod
 def from_id(cls, id):
-if id < 0 or id >= len(cls._kinds) or cls._kinds[id] is None:
-raise ValueError("Unknown template argument kind %d" % id)
-return cls._kinds[id]
+try:
+return cls(id)
+except ValueError:
+raise ValueError("Unknown %s %d" % (cls.__name__, id)) from None
 
 def __repr__(self):
 return "%s.%s" % (
-self.__class__,
+self.__class__.__name__,
 self.name,
 )
 
@@ -665,14 +640,10 @@ class CursorKind(BaseEnumeration):
 A CursorKind describes the kind of entity that a cursor points to.
 """
 
-# The required BaseEnumeration declarations.
-_kinds = []
-_name_map = None
-
 @staticmethod
 def get_all_kinds():
 """Return all CursorKind enumeration instances."""
-return [x for x in CursorKind._kinds if not x is None]
+return list(CursorKind)
 
 def is_declaration(self):
 """Test if this is a declaration kind."""
@@ -710,822 +681,820 @@ def is_unexposed(self):
 """Test if this is an unexposed kind."""
 return conf.lib.clang_isUnexposed(self)
 
-def __repr__(self):
-return "CursorKind.%s" % (self.name,)
-
 
-###
-# Declaration Kinds
+###
+# Declaration Kinds
 
-# A declaration whose specific kind is not exposed via this interface.
-#
-# Unexposed declarations have the same operations as any other kind of
-# declaration; one can extract their location information, spelling, find their
-# definitions, etc. However, the specific kind of the declaration is not
-# reported.
-CursorKind.UNEXPOSED_DECL = CursorKind(1)
+# A declaration whose specific kind is not exposed via this interface.
+#
+# Unexposed declarations have the same operations as any other kind of
+# declaration; one can extract their location information, spelling, find
+# their definitions, etc. However, the specific kind of the declaration is
+# not reported.
+UNEXPOSED_DECL = 1
 
-# A C or C++ struct.
-CursorKind.STRUCT_DECL = CursorKind(2)
+# A C or C++ struct.
+STRUCT_DECL = 2
 
-# A C or C++ union.
-CursorKind.UNION_DECL = CursorKind(3)
+# A C or C++ union.
+UNION_DECL = 3
 
-# A C++ class.
-CursorKind.CLASS_DECL = CursorKind(4)
+# A C++ class.
+CLASS_DECL = 4
 
-# An enumeration.
-CursorKind.ENUM_DECL = CursorKind(5)
+# An enumeration.
+ENUM_DECL = 5
 
-# A field (in C) or non-static data member (in C++) in a struct, union, or C++
-# class.
-CursorKind.FIELD_DECL = CursorKind(6)
+# A field (in C) or non-static data member (in C++) in a struct, union, or
+# C++ class.

[clang] [libclang/python] Refactor enum usage (PR #95608)

2024-07-01 Thread Jannick Kremer via cfe-commits


@@ -10,26 +10,6 @@
 
 
 class TestTokenKind(unittest.TestCase):
-def test_constructor(self):

DeinAlptraum wrote:

So the existing "custom" enum implementation included a sort of constructor, as 
we see in this test, that takes a number and name and then adds that as a new 
variant to the existing enum. No such constructor exists for the builtin `Enum` 
class, so there isn't really an equivalent for this test under the new 
implementation.
We could test that it is impossible for the user to add their own variants 
dynamically at runtime by doing something like `TokenKind.NEW_VARIANT = 6`, but 
that doesn't really seem like our problem, and was also possible under the old 
implementation

Your comment did however raise another question for me: while we've covered 
that there are no duplicate names with different IDs, we haven't covered that 
there are no duplicate IDs with different names, and this is indeed possible in 
the enum class, and not covered by our current tests so I just added one.

https://github.com/llvm/llvm-project/pull/95608
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Refactor enum usage (PR #95608)

2024-07-01 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum edited 
https://github.com/llvm/llvm-project/pull/95608
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Refactor enum usage (PR #95608)

2024-07-01 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum edited 
https://github.com/llvm/llvm-project/pull/95608
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Refactor enum usage (PR #95608)

2024-07-04 Thread Jannick Kremer via cfe-commits

DeinAlptraum wrote:

@Endilll do you think this needs a second review?
If not, could you merge this? Since I don't have commit access

https://github.com/llvm/llvm-project/pull/95608
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Fix bug in `SourceRange.__contains__`, add tests (PR #101802)

2024-08-09 Thread Jannick Kremer via cfe-commits


@@ -386,6 +386,10 @@ def __contains__(self, other):
 # same file, in between lines
 if self.start.line < other.line < self.end.line:
 return True
+# between columns in one-liner range
+elif self.start.line == other.line == self.end.line:

DeinAlptraum wrote:

Clarification because I probably expressed myself inaccurately:
On C-side, in `SourceLocation.h` we implement `operator==`, `operator<=` both 
as direct comparisons on the raw encoding (`SourceLocation::getRawEncoding()`). 
This is not file-sensitive.*
On the C/Python _bindings_ side, we already expose `clang_equalLocations`, 
which looks like this:
```
unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) {
  return (loc1.ptr_data[0] == loc2.ptr_data[0] &&
  loc1.ptr_data[1] == loc2.ptr_data[1] &&
  loc1.int_data == loc2.int_data);
}
```
This _is_ file sensitive. The problem arises because this function is used 
already to implement `SourceLocation.__eq__` on the Python bindings side. This 
means that the internal `SourceLocation::operator==` is inconsistent with the 
bindings' `SourceLocation.__eq__` (the latter is file-sensitive, the former is 
not). The C-bindings are not affected by this as they do not implement 
`CXSourceLocation::opreraor==` or `CXSourceLocation::opreraor<=`.


*Note that this is not obvious from the code (at least to me) and I'm not 
familiar with the C side yet, so I tested this manually in Python, by exposing 
these operators to the Python bindings (pls don't judge me)

https://github.com/llvm/llvm-project/pull/101802
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Fix bug in `SourceRange.__contains__`, add tests (PR #101802)

2024-08-09 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum edited 
https://github.com/llvm/llvm-project/pull/101802
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Fix bug in `SourceRange.__contains__`, add tests (PR #101802)

2024-08-09 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum edited 
https://github.com/llvm/llvm-project/pull/101802
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Fix bug in `SourceRange.__contains__`, add tests (PR #101802)

2024-08-09 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum edited 
https://github.com/llvm/llvm-project/pull/101802
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Fix bug in `SourceRange.__contains__`, add tests (PR #101802)

2024-08-10 Thread Jannick Kremer via cfe-commits


@@ -386,6 +386,10 @@ def __contains__(self, other):
 # same file, in between lines
 if self.start.line < other.line < self.end.line:
 return True
+# between columns in one-liner range
+elif self.start.line == other.line == self.end.line:

DeinAlptraum wrote:

Okay, that was my mistake: when testing this, I created two separate TUs for 
the two files, and _that_ is apparently where it's sensitive. So no issue on 
the C-side here after al.

Going back to the Python bindings: we are now left with a pre-existing 
`SourceLocation.__eq__` that _is_ file-sensitive, and in order to have a clean 
implementation, we would like a `SourceLocation.__le__` / 
`SourceLOcation.__lt__` that is _not_ file-sensitive, so it can be used for 
`SourceRange.__contains__`. 
Exposing something like this would be ugly due to inconsistency. So I guess it 
would be the easiest to implement such an `operator<=` function just locally 
inside `SourceRange.__contains__` to simplify the logic there, and not expose 
any new functionality at all. What do you think?

https://github.com/llvm/llvm-project/pull/101802
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Fix bug in `SourceRange.__contains__`, add tests (PR #101802)

2024-08-10 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum edited 
https://github.com/llvm/llvm-project/pull/101802
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] #101784 part 2: fix error handling of TranslationUnit.reparse (PR #102410)

2024-08-11 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum commented:

A couple minor comments, and the code formatting should be fixed (see output of 
the failing CI run), and then this is good to go!

https://github.com/llvm/llvm-project/pull/102410
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] #101784 part 2: fix error handling of TranslationUnit.reparse (PR #102410)

2024-08-11 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum edited 
https://github.com/llvm/llvm-project/pull/102410
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] #101784 part 2: fix error handling of TranslationUnit.reparse (PR #102410)

2024-08-11 Thread Jannick Kremer via cfe-commits


@@ -161,7 +161,34 @@ class TranslationUnitLoadError(Exception):
 FIXME: Make libclang expose additional error information in this scenario.

DeinAlptraum wrote:

I would say your change resolves the `FIXME` here. Thanks for expanding this to 
the `create`/`parse` functions as well!

https://github.com/llvm/llvm-project/pull/102410
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] #101784 part 2: fix error handling of TranslationUnit.reparse (PR #102410)

2024-08-11 Thread Jannick Kremer via cfe-commits


@@ -59,6 +59,9 @@ Clang Python Bindings Potentially Breaking Changes
 - Calling a property on the `CompletionChunk` or `CompletionString` class
   statically now leads to an error, instead of returning a `CachedProperty` 
object
   that is used internally. Properties are only available on instances.
+- `TranslationUnitLoadError` now contains an error code in `error_code`
+  attribute. Also, `TranslationUnit.reparse` will throw 
`TranslationUnitLoadError`
+  when operation fails.

DeinAlptraum wrote:

Code highlighting should be in double ` (yes the example above that did it 
incorrectly... will fix)

https://github.com/llvm/llvm-project/pull/102410
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] #101784 part 2: fix error handling of TranslationUnit.reparse (PR #102410)

2024-08-11 Thread Jannick Kremer via cfe-commits


@@ -161,7 +161,34 @@ class TranslationUnitLoadError(Exception):
 FIXME: Make libclang expose additional error information in this scenario.
 """
 
-pass
+# A generic error code, no further details are available.
+#
+# Errors of this kind can get their own specific error codes in future
+# libclang versions.
+ERROR_FAILURE = 1
+
+# libclang crashed while performing the requested operation.
+ERROR_CRASHED = 2
+
+# The function detected that the arguments violate the function
+# contract.
+ERROR_INVALID_ARGUMENTS = 3
+
+# An AST deserialization error has occurred.
+ERROR_AST_READ_ERROR = 4
+
+def __init__(self, enumeration: int, message: str):
+assert isinstance(enumeration, int)
+
+if enumeration < 1 or enumeration > 4:
+raise Exception(
+"Encountered undefined CXError "
+"constant: %d. Please file a bug to have this "
+"value supported." % enumeration
+)
+
+self.error_code = enumeration
+Exception.__init__(self, "Error %d: %s" % (enumeration or 0, message))

DeinAlptraum wrote:

What do you need the `or 0` for?

https://github.com/llvm/llvm-project/pull/102410
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] #101784 part 2: fix error handling of TranslationUnit.reparse (PR #102410)

2024-08-11 Thread Jannick Kremer via cfe-commits


@@ -149,8 +149,8 @@ def b(x: str | bytes) -> bytes:
 # this by marshalling object arguments as void**.
 c_object_p: TType[_Pointer[Any]] = POINTER(c_void_p)
 
-### Exception Classes ###
 
+### Exception Classes ###

DeinAlptraum wrote:

Unnecessary whitespace changes

https://github.com/llvm/llvm-project/pull/102410
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [NFC][libclang/python] Fix code highlighting in release notes (PR #102807)

2024-08-11 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum created 
https://github.com/llvm/llvm-project/pull/102807

This corrects a release note introduced in #98745

>From 64212e4c8afe2ad75144bf36a1212c4e417dd8c9 Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Sun, 11 Aug 2024 11:00:52 +0200
Subject: [PATCH] [NFC][libclang/python] Fix code highlighting in release notes

This corrects a release note introduced in #98745
---
 clang/docs/ReleaseNotes.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index d002a9c747dd6..6796a619ba97f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -61,9 +61,9 @@ Clang Frontend Potentially Breaking Changes
 Clang Python Bindings Potentially Breaking Changes
 --
 - Parts of the interface returning string results will now return
-  the empty string `""` when no result is available, instead of `None`.
-- Calling a property on the `CompletionChunk` or `CompletionString` class
-  statically now leads to an error, instead of returning a `CachedProperty` 
object
+  the empty string ``""`` when no result is available, instead of ``None``.
+- Calling a property on the ``CompletionChunk`` or ``CompletionString`` class
+  statically now leads to an error, instead of returning a ``CachedProperty`` 
object
   that is used internally. Properties are only available on instances.
 
 What's New in Clang |release|?

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [NFC][libclang/python] Fix code highlighting in release notes (PR #102807)

2024-08-11 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum closed 
https://github.com/llvm/llvm-project/pull/102807
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [NFC][libclang/python] Fix code highlighting in release notes (PR #102807)

2024-08-11 Thread Jannick Kremer via cfe-commits

DeinAlptraum wrote:

Unrelated, this change only touched release notes

https://github.com/llvm/llvm-project/pull/102807
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Improve error reporting of `TranslationUnit` creating functions (PR #102410)

2024-08-11 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum edited 
https://github.com/llvm/llvm-project/pull/102410
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Improve error reporting of `TranslationUnit` creating functions (PR #102410)

2024-08-11 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum edited 
https://github.com/llvm/llvm-project/pull/102410
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Improve error reporting of `TranslationUnit` creating functions (PR #102410)

2024-08-11 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum approved this pull request.

LGTM. Thanks for adding better error handling!
@Endilll do you also want to take a look at this before it is merged? 
Otherwise, this is good to go imo.

https://github.com/llvm/llvm-project/pull/102410
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Improve error reporting of `TranslationUnit` creating functions (PR #102410)

2024-08-11 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum edited 
https://github.com/llvm/llvm-project/pull/102410
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Fix bug in `SourceRange.__contains__`, add tests (PR #101802)

2024-08-14 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum updated 
https://github.com/llvm/llvm-project/pull/101802

>From 572b1be0b204561fdbb049f0c17f065d17198ac0 Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Sat, 3 Aug 2024 09:28:02 +0100
Subject: [PATCH 1/3] [libclang/python] Fix bug in SourceRange.__contains__,
 add tests

---
 clang/bindings/python/clang/cindex.py |  4 ++
 .../python/tests/cindex/test_source_range.py  | 56 +++
 2 files changed, 60 insertions(+)
 create mode 100644 clang/bindings/python/tests/cindex/test_source_range.py

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index c251c46a04adf4..5fd7cc64810732 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -386,6 +386,10 @@ def __contains__(self, other):
 # same file, in between lines
 if self.start.line < other.line < self.end.line:
 return True
+# between columns in one-liner range
+elif self.start.line == other.line == self.end.line:
+if self.start.column <= other.column <= self.end.column:
+return True
 elif self.start.line == other.line:
 # same file first line
 if self.start.column <= other.column:
diff --git a/clang/bindings/python/tests/cindex/test_source_range.py 
b/clang/bindings/python/tests/cindex/test_source_range.py
new file mode 100644
index 00..9f76848e890207
--- /dev/null
+++ b/clang/bindings/python/tests/cindex/test_source_range.py
@@ -0,0 +1,56 @@
+import unittest
+
+from clang.cindex import SourceLocation, SourceRange
+
+from .util import get_tu
+
+
+def create_location(tu, line, column):
+return SourceLocation.from_position(tu, tu.get_file(tu.spelling), line, 
column)
+
+
+def create_range(tu, line1, column1, line2, column2):
+return SourceRange.from_locations(
+create_location(tu, line1, column1), create_location(tu, line2, 
column2)
+)
+
+
+class TestSourceRange(unittest.TestCase):
+def test_contains(self):
+tu = get_tu(
+"""a
+a
+a
+a"""
+)
+
+l13 = create_location(tu, 1, 3)
+l21 = create_location(tu, 2, 1)
+l22 = create_location(tu, 2, 2)
+l23 = create_location(tu, 2, 3)
+l24 = create_location(tu, 2, 4)
+l25 = create_location(tu, 2, 5)
+l33 = create_location(tu, 3, 3)
+l31 = create_location(tu, 3, 1)
+r22_24 = create_range(tu, 2, 2, 2, 4)
+r23_23 = create_range(tu, 2, 3, 2, 3)
+r24_32 = create_range(tu, 2, 4, 3, 2)
+r14_32 = create_range(tu, 1, 4, 3, 2)
+
+assert l13 not in r22_24  # Line before start
+assert l21 not in r22_24  # Column before start
+assert l22 in r22_24  # Colum on start
+assert l23 in r22_24  # Column in range
+assert l24 in r22_24  # Column on end
+assert l25 not in r22_24  # Column after end
+assert l33 not in r22_24  # Line after end
+
+assert l23 in r23_23  # In one-column range
+
+assert l23 not in r24_32  # Outside range in first line
+assert l33 not in r24_32  # Outside range in last line
+assert l25 in r24_32  # In range in first line
+assert l31 in r24_32  # In range in last line
+
+assert l21 in r14_32  # In range at start of center line
+assert l25 in r14_32  # In range at end of center line

>From e27cf4b01f61dd6cf7ee8fa86857c566716eabfb Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Wed, 7 Aug 2024 19:54:35 +0200
Subject: [PATCH 2/3] Implement SourceRange.__contains__ via
 SourceLocation.__le__

---
 clang/bindings/python/clang/cindex.py | 25 +
 clang/docs/ReleaseNotes.rst   |  2 ++
 2 files changed, 11 insertions(+), 16 deletions(-)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index 5fd7cc64810732..162ed786607550 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -270,6 +270,14 @@ def _get_instantiation(self):
 self._data = (f, int(l.value), int(c.value), int(o.value))
 return self._data
 
+def __le__(self, other):
+if self.line < other.line:
+return True
+if self.line == other.line and self.column <= other.column:
+return True
+# when self.line > other.line
+return False
+
 @staticmethod
 def from_position(tu, file, line, column):
 """
@@ -383,22 +391,7 @@ def __contains__(self, other):
 ):
 # same file name
 return False
-# same file, in between lines
-if self.start.line < other.line < self.end.line:
-return True
-# between columns in one-liner range
-elif self.start.line == other.line == self.end.line:
-if self.start.column <= other.column <= self.end.column:
-return True

[clang] [libclang/python] Fix bug in `SourceRange.__contains__`, add tests (PR #101802)

2024-08-14 Thread Jannick Kremer via cfe-commits


@@ -386,6 +386,10 @@ def __contains__(self, other):
 # same file, in between lines
 if self.start.line < other.line < self.end.line:
 return True
+# between columns in one-liner range
+elif self.start.line == other.line == self.end.line:

DeinAlptraum wrote:

I've exposed a `clang_lessThanLocations` function on C-side, similar to the 
`clang_equalLocations` function, and used this to implement the operators on 
Python side. Hope that resolves this case.

https://github.com/llvm/llvm-project/pull/101802
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Fix bug in `SourceRange.__contains__`, add tests (PR #101802)

2024-08-14 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum updated 
https://github.com/llvm/llvm-project/pull/101802

>From 572b1be0b204561fdbb049f0c17f065d17198ac0 Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Sat, 3 Aug 2024 09:28:02 +0100
Subject: [PATCH 1/3] [libclang/python] Fix bug in SourceRange.__contains__,
 add tests

---
 clang/bindings/python/clang/cindex.py |  4 ++
 .../python/tests/cindex/test_source_range.py  | 56 +++
 2 files changed, 60 insertions(+)
 create mode 100644 clang/bindings/python/tests/cindex/test_source_range.py

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index c251c46a04adf4..5fd7cc64810732 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -386,6 +386,10 @@ def __contains__(self, other):
 # same file, in between lines
 if self.start.line < other.line < self.end.line:
 return True
+# between columns in one-liner range
+elif self.start.line == other.line == self.end.line:
+if self.start.column <= other.column <= self.end.column:
+return True
 elif self.start.line == other.line:
 # same file first line
 if self.start.column <= other.column:
diff --git a/clang/bindings/python/tests/cindex/test_source_range.py 
b/clang/bindings/python/tests/cindex/test_source_range.py
new file mode 100644
index 00..9f76848e890207
--- /dev/null
+++ b/clang/bindings/python/tests/cindex/test_source_range.py
@@ -0,0 +1,56 @@
+import unittest
+
+from clang.cindex import SourceLocation, SourceRange
+
+from .util import get_tu
+
+
+def create_location(tu, line, column):
+return SourceLocation.from_position(tu, tu.get_file(tu.spelling), line, 
column)
+
+
+def create_range(tu, line1, column1, line2, column2):
+return SourceRange.from_locations(
+create_location(tu, line1, column1), create_location(tu, line2, 
column2)
+)
+
+
+class TestSourceRange(unittest.TestCase):
+def test_contains(self):
+tu = get_tu(
+"""a
+a
+a
+a"""
+)
+
+l13 = create_location(tu, 1, 3)
+l21 = create_location(tu, 2, 1)
+l22 = create_location(tu, 2, 2)
+l23 = create_location(tu, 2, 3)
+l24 = create_location(tu, 2, 4)
+l25 = create_location(tu, 2, 5)
+l33 = create_location(tu, 3, 3)
+l31 = create_location(tu, 3, 1)
+r22_24 = create_range(tu, 2, 2, 2, 4)
+r23_23 = create_range(tu, 2, 3, 2, 3)
+r24_32 = create_range(tu, 2, 4, 3, 2)
+r14_32 = create_range(tu, 1, 4, 3, 2)
+
+assert l13 not in r22_24  # Line before start
+assert l21 not in r22_24  # Column before start
+assert l22 in r22_24  # Colum on start
+assert l23 in r22_24  # Column in range
+assert l24 in r22_24  # Column on end
+assert l25 not in r22_24  # Column after end
+assert l33 not in r22_24  # Line after end
+
+assert l23 in r23_23  # In one-column range
+
+assert l23 not in r24_32  # Outside range in first line
+assert l33 not in r24_32  # Outside range in last line
+assert l25 in r24_32  # In range in first line
+assert l31 in r24_32  # In range in last line
+
+assert l21 in r14_32  # In range at start of center line
+assert l25 in r14_32  # In range at end of center line

>From e27cf4b01f61dd6cf7ee8fa86857c566716eabfb Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Wed, 7 Aug 2024 19:54:35 +0200
Subject: [PATCH 2/3] Implement SourceRange.__contains__ via
 SourceLocation.__le__

---
 clang/bindings/python/clang/cindex.py | 25 +
 clang/docs/ReleaseNotes.rst   |  2 ++
 2 files changed, 11 insertions(+), 16 deletions(-)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index 5fd7cc64810732..162ed786607550 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -270,6 +270,14 @@ def _get_instantiation(self):
 self._data = (f, int(l.value), int(c.value), int(o.value))
 return self._data
 
+def __le__(self, other):
+if self.line < other.line:
+return True
+if self.line == other.line and self.column <= other.column:
+return True
+# when self.line > other.line
+return False
+
 @staticmethod
 def from_position(tu, file, line, column):
 """
@@ -383,22 +391,7 @@ def __contains__(self, other):
 ):
 # same file name
 return False
-# same file, in between lines
-if self.start.line < other.line < self.end.line:
-return True
-# between columns in one-liner range
-elif self.start.line == other.line == self.end.line:
-if self.start.column <= other.column <= self.end.column:
-return True

[clang] [libclang/python] Fix bug in `SourceRange.__contains__`, add tests (PR #101802)

2024-08-14 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum updated 
https://github.com/llvm/llvm-project/pull/101802

>From 572b1be0b204561fdbb049f0c17f065d17198ac0 Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Sat, 3 Aug 2024 09:28:02 +0100
Subject: [PATCH 1/4] [libclang/python] Fix bug in SourceRange.__contains__,
 add tests

---
 clang/bindings/python/clang/cindex.py |  4 ++
 .../python/tests/cindex/test_source_range.py  | 56 +++
 2 files changed, 60 insertions(+)
 create mode 100644 clang/bindings/python/tests/cindex/test_source_range.py

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index c251c46a04adf4..5fd7cc64810732 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -386,6 +386,10 @@ def __contains__(self, other):
 # same file, in between lines
 if self.start.line < other.line < self.end.line:
 return True
+# between columns in one-liner range
+elif self.start.line == other.line == self.end.line:
+if self.start.column <= other.column <= self.end.column:
+return True
 elif self.start.line == other.line:
 # same file first line
 if self.start.column <= other.column:
diff --git a/clang/bindings/python/tests/cindex/test_source_range.py 
b/clang/bindings/python/tests/cindex/test_source_range.py
new file mode 100644
index 00..9f76848e890207
--- /dev/null
+++ b/clang/bindings/python/tests/cindex/test_source_range.py
@@ -0,0 +1,56 @@
+import unittest
+
+from clang.cindex import SourceLocation, SourceRange
+
+from .util import get_tu
+
+
+def create_location(tu, line, column):
+return SourceLocation.from_position(tu, tu.get_file(tu.spelling), line, 
column)
+
+
+def create_range(tu, line1, column1, line2, column2):
+return SourceRange.from_locations(
+create_location(tu, line1, column1), create_location(tu, line2, 
column2)
+)
+
+
+class TestSourceRange(unittest.TestCase):
+def test_contains(self):
+tu = get_tu(
+"""a
+a
+a
+a"""
+)
+
+l13 = create_location(tu, 1, 3)
+l21 = create_location(tu, 2, 1)
+l22 = create_location(tu, 2, 2)
+l23 = create_location(tu, 2, 3)
+l24 = create_location(tu, 2, 4)
+l25 = create_location(tu, 2, 5)
+l33 = create_location(tu, 3, 3)
+l31 = create_location(tu, 3, 1)
+r22_24 = create_range(tu, 2, 2, 2, 4)
+r23_23 = create_range(tu, 2, 3, 2, 3)
+r24_32 = create_range(tu, 2, 4, 3, 2)
+r14_32 = create_range(tu, 1, 4, 3, 2)
+
+assert l13 not in r22_24  # Line before start
+assert l21 not in r22_24  # Column before start
+assert l22 in r22_24  # Colum on start
+assert l23 in r22_24  # Column in range
+assert l24 in r22_24  # Column on end
+assert l25 not in r22_24  # Column after end
+assert l33 not in r22_24  # Line after end
+
+assert l23 in r23_23  # In one-column range
+
+assert l23 not in r24_32  # Outside range in first line
+assert l33 not in r24_32  # Outside range in last line
+assert l25 in r24_32  # In range in first line
+assert l31 in r24_32  # In range in last line
+
+assert l21 in r14_32  # In range at start of center line
+assert l25 in r14_32  # In range at end of center line

>From e27cf4b01f61dd6cf7ee8fa86857c566716eabfb Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Wed, 7 Aug 2024 19:54:35 +0200
Subject: [PATCH 2/4] Implement SourceRange.__contains__ via
 SourceLocation.__le__

---
 clang/bindings/python/clang/cindex.py | 25 +
 clang/docs/ReleaseNotes.rst   |  2 ++
 2 files changed, 11 insertions(+), 16 deletions(-)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index 5fd7cc64810732..162ed786607550 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -270,6 +270,14 @@ def _get_instantiation(self):
 self._data = (f, int(l.value), int(c.value), int(o.value))
 return self._data
 
+def __le__(self, other):
+if self.line < other.line:
+return True
+if self.line == other.line and self.column <= other.column:
+return True
+# when self.line > other.line
+return False
+
 @staticmethod
 def from_position(tu, file, line, column):
 """
@@ -383,22 +391,7 @@ def __contains__(self, other):
 ):
 # same file name
 return False
-# same file, in between lines
-if self.start.line < other.line < self.end.line:
-return True
-# between columns in one-liner range
-elif self.start.line == other.line == self.end.line:
-if self.start.column <= other.column <= self.end.column:
-return True

[clang] [libclang/python] Fix bug in `SourceRange.__contains__`, add tests (PR #101802)

2024-08-14 Thread Jannick Kremer via cfe-commits


@@ -50,6 +50,18 @@ unsigned clang_equalLocations(CXSourceLocation loc1, 
CXSourceLocation loc2) {
   loc1.int_data == loc2.int_data);
 }
 
+unsigned clang_lessThanLocations(CXSourceLocation loc1, CXSourceLocation loc2) 
{
+  const SourceLocation Loc1 = 
SourceLocation::getFromRawEncoding(loc1.int_data);
+  const SourceLocation Loc2 = 
SourceLocation::getFromRawEncoding(loc2.int_data);
+
+  const SourceManager &SM =
+  *static_cast(loc1.ptr_data[0]);
+  if (!SM.isWrittenInSameFile(Loc1, Loc2))

DeinAlptraum wrote:

Good point, went with `isBeforeInTranslationUnit`

https://github.com/llvm/llvm-project/pull/101802
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Fix bug in `SourceRange.__contains__`, add tests (PR #101802)

2024-08-14 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum updated 
https://github.com/llvm/llvm-project/pull/101802

>From 572b1be0b204561fdbb049f0c17f065d17198ac0 Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Sat, 3 Aug 2024 09:28:02 +0100
Subject: [PATCH 1/4] [libclang/python] Fix bug in SourceRange.__contains__,
 add tests

---
 clang/bindings/python/clang/cindex.py |  4 ++
 .../python/tests/cindex/test_source_range.py  | 56 +++
 2 files changed, 60 insertions(+)
 create mode 100644 clang/bindings/python/tests/cindex/test_source_range.py

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index c251c46a04adf4..5fd7cc64810732 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -386,6 +386,10 @@ def __contains__(self, other):
 # same file, in between lines
 if self.start.line < other.line < self.end.line:
 return True
+# between columns in one-liner range
+elif self.start.line == other.line == self.end.line:
+if self.start.column <= other.column <= self.end.column:
+return True
 elif self.start.line == other.line:
 # same file first line
 if self.start.column <= other.column:
diff --git a/clang/bindings/python/tests/cindex/test_source_range.py 
b/clang/bindings/python/tests/cindex/test_source_range.py
new file mode 100644
index 00..9f76848e890207
--- /dev/null
+++ b/clang/bindings/python/tests/cindex/test_source_range.py
@@ -0,0 +1,56 @@
+import unittest
+
+from clang.cindex import SourceLocation, SourceRange
+
+from .util import get_tu
+
+
+def create_location(tu, line, column):
+return SourceLocation.from_position(tu, tu.get_file(tu.spelling), line, 
column)
+
+
+def create_range(tu, line1, column1, line2, column2):
+return SourceRange.from_locations(
+create_location(tu, line1, column1), create_location(tu, line2, 
column2)
+)
+
+
+class TestSourceRange(unittest.TestCase):
+def test_contains(self):
+tu = get_tu(
+"""a
+a
+a
+a"""
+)
+
+l13 = create_location(tu, 1, 3)
+l21 = create_location(tu, 2, 1)
+l22 = create_location(tu, 2, 2)
+l23 = create_location(tu, 2, 3)
+l24 = create_location(tu, 2, 4)
+l25 = create_location(tu, 2, 5)
+l33 = create_location(tu, 3, 3)
+l31 = create_location(tu, 3, 1)
+r22_24 = create_range(tu, 2, 2, 2, 4)
+r23_23 = create_range(tu, 2, 3, 2, 3)
+r24_32 = create_range(tu, 2, 4, 3, 2)
+r14_32 = create_range(tu, 1, 4, 3, 2)
+
+assert l13 not in r22_24  # Line before start
+assert l21 not in r22_24  # Column before start
+assert l22 in r22_24  # Colum on start
+assert l23 in r22_24  # Column in range
+assert l24 in r22_24  # Column on end
+assert l25 not in r22_24  # Column after end
+assert l33 not in r22_24  # Line after end
+
+assert l23 in r23_23  # In one-column range
+
+assert l23 not in r24_32  # Outside range in first line
+assert l33 not in r24_32  # Outside range in last line
+assert l25 in r24_32  # In range in first line
+assert l31 in r24_32  # In range in last line
+
+assert l21 in r14_32  # In range at start of center line
+assert l25 in r14_32  # In range at end of center line

>From e27cf4b01f61dd6cf7ee8fa86857c566716eabfb Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Wed, 7 Aug 2024 19:54:35 +0200
Subject: [PATCH 2/4] Implement SourceRange.__contains__ via
 SourceLocation.__le__

---
 clang/bindings/python/clang/cindex.py | 25 +
 clang/docs/ReleaseNotes.rst   |  2 ++
 2 files changed, 11 insertions(+), 16 deletions(-)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index 5fd7cc64810732..162ed786607550 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -270,6 +270,14 @@ def _get_instantiation(self):
 self._data = (f, int(l.value), int(c.value), int(o.value))
 return self._data
 
+def __le__(self, other):
+if self.line < other.line:
+return True
+if self.line == other.line and self.column <= other.column:
+return True
+# when self.line > other.line
+return False
+
 @staticmethod
 def from_position(tu, file, line, column):
 """
@@ -383,22 +391,7 @@ def __contains__(self, other):
 ):
 # same file name
 return False
-# same file, in between lines
-if self.start.line < other.line < self.end.line:
-return True
-# between columns in one-liner range
-elif self.start.line == other.line == self.end.line:
-if self.start.column <= other.column <= self.end.column:
-return True

[clang] [libclang/python] Fix bug in `SourceRange.__contains__`, add tests (PR #101802)

2024-08-14 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum updated 
https://github.com/llvm/llvm-project/pull/101802

>From 572b1be0b204561fdbb049f0c17f065d17198ac0 Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Sat, 3 Aug 2024 09:28:02 +0100
Subject: [PATCH 1/5] [libclang/python] Fix bug in SourceRange.__contains__,
 add tests

---
 clang/bindings/python/clang/cindex.py |  4 ++
 .../python/tests/cindex/test_source_range.py  | 56 +++
 2 files changed, 60 insertions(+)
 create mode 100644 clang/bindings/python/tests/cindex/test_source_range.py

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index c251c46a04adf4..5fd7cc64810732 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -386,6 +386,10 @@ def __contains__(self, other):
 # same file, in between lines
 if self.start.line < other.line < self.end.line:
 return True
+# between columns in one-liner range
+elif self.start.line == other.line == self.end.line:
+if self.start.column <= other.column <= self.end.column:
+return True
 elif self.start.line == other.line:
 # same file first line
 if self.start.column <= other.column:
diff --git a/clang/bindings/python/tests/cindex/test_source_range.py 
b/clang/bindings/python/tests/cindex/test_source_range.py
new file mode 100644
index 00..9f76848e890207
--- /dev/null
+++ b/clang/bindings/python/tests/cindex/test_source_range.py
@@ -0,0 +1,56 @@
+import unittest
+
+from clang.cindex import SourceLocation, SourceRange
+
+from .util import get_tu
+
+
+def create_location(tu, line, column):
+return SourceLocation.from_position(tu, tu.get_file(tu.spelling), line, 
column)
+
+
+def create_range(tu, line1, column1, line2, column2):
+return SourceRange.from_locations(
+create_location(tu, line1, column1), create_location(tu, line2, 
column2)
+)
+
+
+class TestSourceRange(unittest.TestCase):
+def test_contains(self):
+tu = get_tu(
+"""a
+a
+a
+a"""
+)
+
+l13 = create_location(tu, 1, 3)
+l21 = create_location(tu, 2, 1)
+l22 = create_location(tu, 2, 2)
+l23 = create_location(tu, 2, 3)
+l24 = create_location(tu, 2, 4)
+l25 = create_location(tu, 2, 5)
+l33 = create_location(tu, 3, 3)
+l31 = create_location(tu, 3, 1)
+r22_24 = create_range(tu, 2, 2, 2, 4)
+r23_23 = create_range(tu, 2, 3, 2, 3)
+r24_32 = create_range(tu, 2, 4, 3, 2)
+r14_32 = create_range(tu, 1, 4, 3, 2)
+
+assert l13 not in r22_24  # Line before start
+assert l21 not in r22_24  # Column before start
+assert l22 in r22_24  # Colum on start
+assert l23 in r22_24  # Column in range
+assert l24 in r22_24  # Column on end
+assert l25 not in r22_24  # Column after end
+assert l33 not in r22_24  # Line after end
+
+assert l23 in r23_23  # In one-column range
+
+assert l23 not in r24_32  # Outside range in first line
+assert l33 not in r24_32  # Outside range in last line
+assert l25 in r24_32  # In range in first line
+assert l31 in r24_32  # In range in last line
+
+assert l21 in r14_32  # In range at start of center line
+assert l25 in r14_32  # In range at end of center line

>From e27cf4b01f61dd6cf7ee8fa86857c566716eabfb Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Wed, 7 Aug 2024 19:54:35 +0200
Subject: [PATCH 2/5] Implement SourceRange.__contains__ via
 SourceLocation.__le__

---
 clang/bindings/python/clang/cindex.py | 25 +
 clang/docs/ReleaseNotes.rst   |  2 ++
 2 files changed, 11 insertions(+), 16 deletions(-)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index 5fd7cc64810732..162ed786607550 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -270,6 +270,14 @@ def _get_instantiation(self):
 self._data = (f, int(l.value), int(c.value), int(o.value))
 return self._data
 
+def __le__(self, other):
+if self.line < other.line:
+return True
+if self.line == other.line and self.column <= other.column:
+return True
+# when self.line > other.line
+return False
+
 @staticmethod
 def from_position(tu, file, line, column):
 """
@@ -383,22 +391,7 @@ def __contains__(self, other):
 ):
 # same file name
 return False
-# same file, in between lines
-if self.start.line < other.line < self.end.line:
-return True
-# between columns in one-liner range
-elif self.start.line == other.line == self.end.line:
-if self.start.column <= other.column <= self.end.column:
-return True

[clang] [libclang/python] Fix bug in `SourceRange.__contains__`, add tests (PR #101802)

2024-08-14 Thread Jannick Kremer via cfe-commits

DeinAlptraum wrote:

Implemented all your suggestions

https://github.com/llvm/llvm-project/pull/101802
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Fix bug in `SourceRange.__contains__`, add tests (PR #101802)

2024-08-15 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum updated 
https://github.com/llvm/llvm-project/pull/101802

>From 572b1be0b204561fdbb049f0c17f065d17198ac0 Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Sat, 3 Aug 2024 09:28:02 +0100
Subject: [PATCH 1/6] [libclang/python] Fix bug in SourceRange.__contains__,
 add tests

---
 clang/bindings/python/clang/cindex.py |  4 ++
 .../python/tests/cindex/test_source_range.py  | 56 +++
 2 files changed, 60 insertions(+)
 create mode 100644 clang/bindings/python/tests/cindex/test_source_range.py

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index c251c46a04adf4..5fd7cc64810732 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -386,6 +386,10 @@ def __contains__(self, other):
 # same file, in between lines
 if self.start.line < other.line < self.end.line:
 return True
+# between columns in one-liner range
+elif self.start.line == other.line == self.end.line:
+if self.start.column <= other.column <= self.end.column:
+return True
 elif self.start.line == other.line:
 # same file first line
 if self.start.column <= other.column:
diff --git a/clang/bindings/python/tests/cindex/test_source_range.py 
b/clang/bindings/python/tests/cindex/test_source_range.py
new file mode 100644
index 00..9f76848e890207
--- /dev/null
+++ b/clang/bindings/python/tests/cindex/test_source_range.py
@@ -0,0 +1,56 @@
+import unittest
+
+from clang.cindex import SourceLocation, SourceRange
+
+from .util import get_tu
+
+
+def create_location(tu, line, column):
+return SourceLocation.from_position(tu, tu.get_file(tu.spelling), line, 
column)
+
+
+def create_range(tu, line1, column1, line2, column2):
+return SourceRange.from_locations(
+create_location(tu, line1, column1), create_location(tu, line2, 
column2)
+)
+
+
+class TestSourceRange(unittest.TestCase):
+def test_contains(self):
+tu = get_tu(
+"""a
+a
+a
+a"""
+)
+
+l13 = create_location(tu, 1, 3)
+l21 = create_location(tu, 2, 1)
+l22 = create_location(tu, 2, 2)
+l23 = create_location(tu, 2, 3)
+l24 = create_location(tu, 2, 4)
+l25 = create_location(tu, 2, 5)
+l33 = create_location(tu, 3, 3)
+l31 = create_location(tu, 3, 1)
+r22_24 = create_range(tu, 2, 2, 2, 4)
+r23_23 = create_range(tu, 2, 3, 2, 3)
+r24_32 = create_range(tu, 2, 4, 3, 2)
+r14_32 = create_range(tu, 1, 4, 3, 2)
+
+assert l13 not in r22_24  # Line before start
+assert l21 not in r22_24  # Column before start
+assert l22 in r22_24  # Colum on start
+assert l23 in r22_24  # Column in range
+assert l24 in r22_24  # Column on end
+assert l25 not in r22_24  # Column after end
+assert l33 not in r22_24  # Line after end
+
+assert l23 in r23_23  # In one-column range
+
+assert l23 not in r24_32  # Outside range in first line
+assert l33 not in r24_32  # Outside range in last line
+assert l25 in r24_32  # In range in first line
+assert l31 in r24_32  # In range in last line
+
+assert l21 in r14_32  # In range at start of center line
+assert l25 in r14_32  # In range at end of center line

>From e27cf4b01f61dd6cf7ee8fa86857c566716eabfb Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Wed, 7 Aug 2024 19:54:35 +0200
Subject: [PATCH 2/6] Implement SourceRange.__contains__ via
 SourceLocation.__le__

---
 clang/bindings/python/clang/cindex.py | 25 +
 clang/docs/ReleaseNotes.rst   |  2 ++
 2 files changed, 11 insertions(+), 16 deletions(-)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index 5fd7cc64810732..162ed786607550 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -270,6 +270,14 @@ def _get_instantiation(self):
 self._data = (f, int(l.value), int(c.value), int(o.value))
 return self._data
 
+def __le__(self, other):
+if self.line < other.line:
+return True
+if self.line == other.line and self.column <= other.column:
+return True
+# when self.line > other.line
+return False
+
 @staticmethod
 def from_position(tu, file, line, column):
 """
@@ -383,22 +391,7 @@ def __contains__(self, other):
 ):
 # same file name
 return False
-# same file, in between lines
-if self.start.line < other.line < self.end.line:
-return True
-# between columns in one-liner range
-elif self.start.line == other.line == self.end.line:
-if self.start.column <= other.column <= self.end.column:
-return True

[clang] [libclang/python] Fix bug in `SourceRange.__contains__`, add tests (PR #101802)

2024-08-15 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum updated 
https://github.com/llvm/llvm-project/pull/101802

>From 572b1be0b204561fdbb049f0c17f065d17198ac0 Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Sat, 3 Aug 2024 09:28:02 +0100
Subject: [PATCH 1/6] [libclang/python] Fix bug in SourceRange.__contains__,
 add tests

---
 clang/bindings/python/clang/cindex.py |  4 ++
 .../python/tests/cindex/test_source_range.py  | 56 +++
 2 files changed, 60 insertions(+)
 create mode 100644 clang/bindings/python/tests/cindex/test_source_range.py

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index c251c46a04adf4..5fd7cc64810732 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -386,6 +386,10 @@ def __contains__(self, other):
 # same file, in between lines
 if self.start.line < other.line < self.end.line:
 return True
+# between columns in one-liner range
+elif self.start.line == other.line == self.end.line:
+if self.start.column <= other.column <= self.end.column:
+return True
 elif self.start.line == other.line:
 # same file first line
 if self.start.column <= other.column:
diff --git a/clang/bindings/python/tests/cindex/test_source_range.py 
b/clang/bindings/python/tests/cindex/test_source_range.py
new file mode 100644
index 00..9f76848e890207
--- /dev/null
+++ b/clang/bindings/python/tests/cindex/test_source_range.py
@@ -0,0 +1,56 @@
+import unittest
+
+from clang.cindex import SourceLocation, SourceRange
+
+from .util import get_tu
+
+
+def create_location(tu, line, column):
+return SourceLocation.from_position(tu, tu.get_file(tu.spelling), line, 
column)
+
+
+def create_range(tu, line1, column1, line2, column2):
+return SourceRange.from_locations(
+create_location(tu, line1, column1), create_location(tu, line2, 
column2)
+)
+
+
+class TestSourceRange(unittest.TestCase):
+def test_contains(self):
+tu = get_tu(
+"""a
+a
+a
+a"""
+)
+
+l13 = create_location(tu, 1, 3)
+l21 = create_location(tu, 2, 1)
+l22 = create_location(tu, 2, 2)
+l23 = create_location(tu, 2, 3)
+l24 = create_location(tu, 2, 4)
+l25 = create_location(tu, 2, 5)
+l33 = create_location(tu, 3, 3)
+l31 = create_location(tu, 3, 1)
+r22_24 = create_range(tu, 2, 2, 2, 4)
+r23_23 = create_range(tu, 2, 3, 2, 3)
+r24_32 = create_range(tu, 2, 4, 3, 2)
+r14_32 = create_range(tu, 1, 4, 3, 2)
+
+assert l13 not in r22_24  # Line before start
+assert l21 not in r22_24  # Column before start
+assert l22 in r22_24  # Colum on start
+assert l23 in r22_24  # Column in range
+assert l24 in r22_24  # Column on end
+assert l25 not in r22_24  # Column after end
+assert l33 not in r22_24  # Line after end
+
+assert l23 in r23_23  # In one-column range
+
+assert l23 not in r24_32  # Outside range in first line
+assert l33 not in r24_32  # Outside range in last line
+assert l25 in r24_32  # In range in first line
+assert l31 in r24_32  # In range in last line
+
+assert l21 in r14_32  # In range at start of center line
+assert l25 in r14_32  # In range at end of center line

>From e27cf4b01f61dd6cf7ee8fa86857c566716eabfb Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Wed, 7 Aug 2024 19:54:35 +0200
Subject: [PATCH 2/6] Implement SourceRange.__contains__ via
 SourceLocation.__le__

---
 clang/bindings/python/clang/cindex.py | 25 +
 clang/docs/ReleaseNotes.rst   |  2 ++
 2 files changed, 11 insertions(+), 16 deletions(-)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index 5fd7cc64810732..162ed786607550 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -270,6 +270,14 @@ def _get_instantiation(self):
 self._data = (f, int(l.value), int(c.value), int(o.value))
 return self._data
 
+def __le__(self, other):
+if self.line < other.line:
+return True
+if self.line == other.line and self.column <= other.column:
+return True
+# when self.line > other.line
+return False
+
 @staticmethod
 def from_position(tu, file, line, column):
 """
@@ -383,22 +391,7 @@ def __contains__(self, other):
 ):
 # same file name
 return False
-# same file, in between lines
-if self.start.line < other.line < self.end.line:
-return True
-# between columns in one-liner range
-elif self.start.line == other.line == self.end.line:
-if self.start.column <= other.column <= self.end.column:
-return True

[clang] [libclang/python] Fix bug in `SourceRange.__contains__`, add tests (PR #101802)

2024-08-15 Thread Jannick Kremer via cfe-commits


@@ -74,6 +74,16 @@ CINDEX_LINKAGE CXSourceLocation clang_getNullLocation(void);
 CINDEX_LINKAGE unsigned clang_equalLocations(CXSourceLocation loc1,
  CXSourceLocation loc2);
 
+/**
+ * Determine for two source locations if they refer to the same file
+ * and one of them comes strictly before the other in the source code.
+ *
+ * \returns non-zero if the source locations refer to the same file and the
+ * first one comes strictly before the second one, zero otherwise.
+ */
+CINDEX_LINKAGE unsigned clang_lessThanLocations(CXSourceLocation loc1,

DeinAlptraum wrote:

Sounds sensible; Implemented this and the other suggestions.

https://github.com/llvm/llvm-project/pull/101802
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Fix bug in `SourceRange.__contains__`, add tests (PR #101802)

2024-08-15 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum updated 
https://github.com/llvm/llvm-project/pull/101802

>From 572b1be0b204561fdbb049f0c17f065d17198ac0 Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Sat, 3 Aug 2024 09:28:02 +0100
Subject: [PATCH 1/6] [libclang/python] Fix bug in SourceRange.__contains__,
 add tests

---
 clang/bindings/python/clang/cindex.py |  4 ++
 .../python/tests/cindex/test_source_range.py  | 56 +++
 2 files changed, 60 insertions(+)
 create mode 100644 clang/bindings/python/tests/cindex/test_source_range.py

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index c251c46a04adf4..5fd7cc64810732 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -386,6 +386,10 @@ def __contains__(self, other):
 # same file, in between lines
 if self.start.line < other.line < self.end.line:
 return True
+# between columns in one-liner range
+elif self.start.line == other.line == self.end.line:
+if self.start.column <= other.column <= self.end.column:
+return True
 elif self.start.line == other.line:
 # same file first line
 if self.start.column <= other.column:
diff --git a/clang/bindings/python/tests/cindex/test_source_range.py 
b/clang/bindings/python/tests/cindex/test_source_range.py
new file mode 100644
index 00..9f76848e890207
--- /dev/null
+++ b/clang/bindings/python/tests/cindex/test_source_range.py
@@ -0,0 +1,56 @@
+import unittest
+
+from clang.cindex import SourceLocation, SourceRange
+
+from .util import get_tu
+
+
+def create_location(tu, line, column):
+return SourceLocation.from_position(tu, tu.get_file(tu.spelling), line, 
column)
+
+
+def create_range(tu, line1, column1, line2, column2):
+return SourceRange.from_locations(
+create_location(tu, line1, column1), create_location(tu, line2, 
column2)
+)
+
+
+class TestSourceRange(unittest.TestCase):
+def test_contains(self):
+tu = get_tu(
+"""a
+a
+a
+a"""
+)
+
+l13 = create_location(tu, 1, 3)
+l21 = create_location(tu, 2, 1)
+l22 = create_location(tu, 2, 2)
+l23 = create_location(tu, 2, 3)
+l24 = create_location(tu, 2, 4)
+l25 = create_location(tu, 2, 5)
+l33 = create_location(tu, 3, 3)
+l31 = create_location(tu, 3, 1)
+r22_24 = create_range(tu, 2, 2, 2, 4)
+r23_23 = create_range(tu, 2, 3, 2, 3)
+r24_32 = create_range(tu, 2, 4, 3, 2)
+r14_32 = create_range(tu, 1, 4, 3, 2)
+
+assert l13 not in r22_24  # Line before start
+assert l21 not in r22_24  # Column before start
+assert l22 in r22_24  # Colum on start
+assert l23 in r22_24  # Column in range
+assert l24 in r22_24  # Column on end
+assert l25 not in r22_24  # Column after end
+assert l33 not in r22_24  # Line after end
+
+assert l23 in r23_23  # In one-column range
+
+assert l23 not in r24_32  # Outside range in first line
+assert l33 not in r24_32  # Outside range in last line
+assert l25 in r24_32  # In range in first line
+assert l31 in r24_32  # In range in last line
+
+assert l21 in r14_32  # In range at start of center line
+assert l25 in r14_32  # In range at end of center line

>From e27cf4b01f61dd6cf7ee8fa86857c566716eabfb Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Wed, 7 Aug 2024 19:54:35 +0200
Subject: [PATCH 2/6] Implement SourceRange.__contains__ via
 SourceLocation.__le__

---
 clang/bindings/python/clang/cindex.py | 25 +
 clang/docs/ReleaseNotes.rst   |  2 ++
 2 files changed, 11 insertions(+), 16 deletions(-)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index 5fd7cc64810732..162ed786607550 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -270,6 +270,14 @@ def _get_instantiation(self):
 self._data = (f, int(l.value), int(c.value), int(o.value))
 return self._data
 
+def __le__(self, other):
+if self.line < other.line:
+return True
+if self.line == other.line and self.column <= other.column:
+return True
+# when self.line > other.line
+return False
+
 @staticmethod
 def from_position(tu, file, line, column):
 """
@@ -383,22 +391,7 @@ def __contains__(self, other):
 ):
 # same file name
 return False
-# same file, in between lines
-if self.start.line < other.line < self.end.line:
-return True
-# between columns in one-liner range
-elif self.start.line == other.line == self.end.line:
-if self.start.column <= other.column <= self.end.column:
-return True

[clang] [libclang/python] Fix bug in `SourceRange.__contains__`, add tests (PR #101802)

2024-08-15 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum updated 
https://github.com/llvm/llvm-project/pull/101802

>From 572b1be0b204561fdbb049f0c17f065d17198ac0 Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Sat, 3 Aug 2024 09:28:02 +0100
Subject: [PATCH 1/7] [libclang/python] Fix bug in SourceRange.__contains__,
 add tests

---
 clang/bindings/python/clang/cindex.py |  4 ++
 .../python/tests/cindex/test_source_range.py  | 56 +++
 2 files changed, 60 insertions(+)
 create mode 100644 clang/bindings/python/tests/cindex/test_source_range.py

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index c251c46a04adf4..5fd7cc64810732 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -386,6 +386,10 @@ def __contains__(self, other):
 # same file, in between lines
 if self.start.line < other.line < self.end.line:
 return True
+# between columns in one-liner range
+elif self.start.line == other.line == self.end.line:
+if self.start.column <= other.column <= self.end.column:
+return True
 elif self.start.line == other.line:
 # same file first line
 if self.start.column <= other.column:
diff --git a/clang/bindings/python/tests/cindex/test_source_range.py 
b/clang/bindings/python/tests/cindex/test_source_range.py
new file mode 100644
index 00..9f76848e890207
--- /dev/null
+++ b/clang/bindings/python/tests/cindex/test_source_range.py
@@ -0,0 +1,56 @@
+import unittest
+
+from clang.cindex import SourceLocation, SourceRange
+
+from .util import get_tu
+
+
+def create_location(tu, line, column):
+return SourceLocation.from_position(tu, tu.get_file(tu.spelling), line, 
column)
+
+
+def create_range(tu, line1, column1, line2, column2):
+return SourceRange.from_locations(
+create_location(tu, line1, column1), create_location(tu, line2, 
column2)
+)
+
+
+class TestSourceRange(unittest.TestCase):
+def test_contains(self):
+tu = get_tu(
+"""a
+a
+a
+a"""
+)
+
+l13 = create_location(tu, 1, 3)
+l21 = create_location(tu, 2, 1)
+l22 = create_location(tu, 2, 2)
+l23 = create_location(tu, 2, 3)
+l24 = create_location(tu, 2, 4)
+l25 = create_location(tu, 2, 5)
+l33 = create_location(tu, 3, 3)
+l31 = create_location(tu, 3, 1)
+r22_24 = create_range(tu, 2, 2, 2, 4)
+r23_23 = create_range(tu, 2, 3, 2, 3)
+r24_32 = create_range(tu, 2, 4, 3, 2)
+r14_32 = create_range(tu, 1, 4, 3, 2)
+
+assert l13 not in r22_24  # Line before start
+assert l21 not in r22_24  # Column before start
+assert l22 in r22_24  # Colum on start
+assert l23 in r22_24  # Column in range
+assert l24 in r22_24  # Column on end
+assert l25 not in r22_24  # Column after end
+assert l33 not in r22_24  # Line after end
+
+assert l23 in r23_23  # In one-column range
+
+assert l23 not in r24_32  # Outside range in first line
+assert l33 not in r24_32  # Outside range in last line
+assert l25 in r24_32  # In range in first line
+assert l31 in r24_32  # In range in last line
+
+assert l21 in r14_32  # In range at start of center line
+assert l25 in r14_32  # In range at end of center line

>From e27cf4b01f61dd6cf7ee8fa86857c566716eabfb Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Wed, 7 Aug 2024 19:54:35 +0200
Subject: [PATCH 2/7] Implement SourceRange.__contains__ via
 SourceLocation.__le__

---
 clang/bindings/python/clang/cindex.py | 25 +
 clang/docs/ReleaseNotes.rst   |  2 ++
 2 files changed, 11 insertions(+), 16 deletions(-)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index 5fd7cc64810732..162ed786607550 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -270,6 +270,14 @@ def _get_instantiation(self):
 self._data = (f, int(l.value), int(c.value), int(o.value))
 return self._data
 
+def __le__(self, other):
+if self.line < other.line:
+return True
+if self.line == other.line and self.column <= other.column:
+return True
+# when self.line > other.line
+return False
+
 @staticmethod
 def from_position(tu, file, line, column):
 """
@@ -383,22 +391,7 @@ def __contains__(self, other):
 ):
 # same file name
 return False
-# same file, in between lines
-if self.start.line < other.line < self.end.line:
-return True
-# between columns in one-liner range
-elif self.start.line == other.line == self.end.line:
-if self.start.column <= other.column <= self.end.column:
-return True

[clang] [libclang/python] Fix bug in `SourceRange.__contains__`, add tests (PR #101802)

2024-08-15 Thread Jannick Kremer via cfe-commits


@@ -65,6 +65,9 @@ Clang Python Bindings Potentially Breaking Changes
 - Calling a property on the ``CompletionChunk`` or ``CompletionString`` class
   statically now leads to an error, instead of returning a ``CachedProperty`` 
object
   that is used internally. Properties are only available on instances.
+- For a single-line ``SourceRange`` and a ``SourceLocation`` in the same line,

DeinAlptraum wrote:

Thanks for the reviews, and added 👍🏼 

https://github.com/llvm/llvm-project/pull/101802
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Fix bug in `SourceRange.__contains__`, add tests (PR #101802)

2024-08-15 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum closed 
https://github.com/llvm/llvm-project/pull/101802
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-bindings] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-06-09 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum edited 
https://github.com/llvm/llvm-project/pull/78114
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-bindings] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-06-09 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum edited 
https://github.com/llvm/llvm-project/pull/78114
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-bindings] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-06-09 Thread Jannick Kremer via cfe-commits


@@ -665,867 +1312,858 @@ class CursorKind(BaseEnumeration):
 A CursorKind describes the kind of entity that a cursor points to.
 """
 
-# The required BaseEnumeration declarations.
-_kinds = []
-_name_map = None
-
 @staticmethod
-def get_all_kinds():
+def get_all_kinds() -> list[CursorKind]:
 """Return all CursorKind enumeration instances."""
-return [x for x in CursorKind._kinds if not x is None]
+return [x for x in CursorKind]
 
-def is_declaration(self):
+def is_declaration(self) -> bool:
 """Test if this is a declaration kind."""
 return conf.lib.clang_isDeclaration(self)
 
-def is_reference(self):
+def is_reference(self) -> bool:
 """Test if this is a reference kind."""
 return conf.lib.clang_isReference(self)
 
-def is_expression(self):
+def is_expression(self) -> bool:
 """Test if this is an expression kind."""
 return conf.lib.clang_isExpression(self)
 
-def is_statement(self):
+def is_statement(self) -> bool:
 """Test if this is a statement kind."""
 return conf.lib.clang_isStatement(self)
 
-def is_attribute(self):
+def is_attribute(self) -> bool:
 """Test if this is an attribute kind."""
 return conf.lib.clang_isAttribute(self)
 
-def is_invalid(self):
+def is_invalid(self) -> bool:
 """Test if this is an invalid kind."""
 return conf.lib.clang_isInvalid(self)
 
-def is_translation_unit(self):
+def is_translation_unit(self) -> bool:
 """Test if this is a translation unit kind."""
 return conf.lib.clang_isTranslationUnit(self)
 
-def is_preprocessing(self):
+def is_preprocessing(self) -> bool:
 """Test if this is a preprocessing kind."""
 return conf.lib.clang_isPreprocessing(self)
 
-def is_unexposed(self):
+def is_unexposed(self) -> bool:
 """Test if this is an unexposed kind."""
 return conf.lib.clang_isUnexposed(self)
 
-def __repr__(self):
-return "CursorKind.%s" % (self.name,)
+###
+# Declaration Kinds
 
+# A declaration whose specific kind is not exposed via this interface.
+#
+# Unexposed declarations have the same operations as any other kind of
+# declaration; one can extract their location information, spelling, find 
their
+# definitions, etc. However, the specific kind of the declaration is not
+# reported.
+UNEXPOSED_DECL = 1
 
-###
-# Declaration Kinds
+# A C or C++ struct.
+STRUCT_DECL = 2
 
-# A declaration whose specific kind is not exposed via this interface.
-#
-# Unexposed declarations have the same operations as any other kind of
-# declaration; one can extract their location information, spelling, find their
-# definitions, etc. However, the specific kind of the declaration is not
-# reported.
-CursorKind.UNEXPOSED_DECL = CursorKind(1)
+# A C or C++ union.
+UNION_DECL = 3
 
-# A C or C++ struct.
-CursorKind.STRUCT_DECL = CursorKind(2)
+# A C++ class.
+CLASS_DECL = 4
 
-# A C or C++ union.
-CursorKind.UNION_DECL = CursorKind(3)
+# An enumeration.
+ENUM_DECL = 5
 
-# A C++ class.
-CursorKind.CLASS_DECL = CursorKind(4)
+# A field (in C) or non-static data member (in C++) in a struct, union, or 
C++
+# class.
+FIELD_DECL = 6
 
-# An enumeration.
-CursorKind.ENUM_DECL = CursorKind(5)
+# An enumerator constant.
+ENUM_CONSTANT_DECL = 7
 
-# A field (in C) or non-static data member (in C++) in a struct, union, or C++
-# class.
-CursorKind.FIELD_DECL = CursorKind(6)
+# A function.
+FUNCTION_DECL = 8
 
-# An enumerator constant.
-CursorKind.ENUM_CONSTANT_DECL = CursorKind(7)
+# A variable.
+VAR_DECL = 9
 
-# A function.
-CursorKind.FUNCTION_DECL = CursorKind(8)
+# A function or method parameter.
+PARM_DECL = 10
 
-# A variable.
-CursorKind.VAR_DECL = CursorKind(9)
+# An Objective-C @interface.
+OBJC_INTERFACE_DECL = 11
 
-# A function or method parameter.
-CursorKind.PARM_DECL = CursorKind(10)
+# An Objective-C @interface for a category.
+OBJC_CATEGORY_DECL = 12
 
-# An Objective-C @interface.
-CursorKind.OBJC_INTERFACE_DECL = CursorKind(11)
+# An Objective-C @protocol declaration.
+OBJC_PROTOCOL_DECL = 13
 
-# An Objective-C @interface for a category.
-CursorKind.OBJC_CATEGORY_DECL = CursorKind(12)
+# An Objective-C @property declaration.
+OBJC_PROPERTY_DECL = 14
 
-# An Objective-C @protocol declaration.
-CursorKind.OBJC_PROTOCOL_DECL = CursorKind(13)
+# An Objective-C instance variable.
+OBJC_IVAR_DECL = 15
 
-# An Objective-C @property declaration.
-CursorKind.OBJC_PROPERTY_DECL = CursorKind(14)
+# An Objective-C instance method.
+OBJC_INSTANCE_METHOD_DECL = 16
 
-# An Objective-C instance variable.
-CursorKind.OBJC_IVAR_DECL = CursorKind(15)
+# An Objective-C class method.
+OBJC_CLASS_METHOD_DECL = 17
 
-# An Objectiv

[clang] [clang-bindings] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-06-09 Thread Jannick Kremer via cfe-commits


@@ -2286,192 +2869,151 @@ class TypeKind(BaseEnumeration):
 Describes the kind of type.
 """
 
-# The unique kind objects, indexed by id.
-_kinds = []
-_name_map = None
-
 @property
-def spelling(self):
+def spelling(self) -> str:
 """Retrieve the spelling of this TypeKind."""
 return conf.lib.clang_getTypeKindSpelling(self.value)
 
-def __repr__(self):
-return "TypeKind.%s" % (self.name,)
-
-
-TypeKind.INVALID = TypeKind(0)
-TypeKind.UNEXPOSED = TypeKind(1)
-TypeKind.VOID = TypeKind(2)
-TypeKind.BOOL = TypeKind(3)
-TypeKind.CHAR_U = TypeKind(4)
-TypeKind.UCHAR = TypeKind(5)
-TypeKind.CHAR16 = TypeKind(6)
-TypeKind.CHAR32 = TypeKind(7)
-TypeKind.USHORT = TypeKind(8)
-TypeKind.UINT = TypeKind(9)
-TypeKind.ULONG = TypeKind(10)
-TypeKind.ULONGLONG = TypeKind(11)
-TypeKind.UINT128 = TypeKind(12)
-TypeKind.CHAR_S = TypeKind(13)
-TypeKind.SCHAR = TypeKind(14)
-TypeKind.WCHAR = TypeKind(15)
-TypeKind.SHORT = TypeKind(16)
-TypeKind.INT = TypeKind(17)
-TypeKind.LONG = TypeKind(18)
-TypeKind.LONGLONG = TypeKind(19)
-TypeKind.INT128 = TypeKind(20)
-TypeKind.FLOAT = TypeKind(21)
-TypeKind.DOUBLE = TypeKind(22)
-TypeKind.LONGDOUBLE = TypeKind(23)
-TypeKind.NULLPTR = TypeKind(24)
-TypeKind.OVERLOAD = TypeKind(25)
-TypeKind.DEPENDENT = TypeKind(26)
-TypeKind.OBJCID = TypeKind(27)
-TypeKind.OBJCCLASS = TypeKind(28)
-TypeKind.OBJCSEL = TypeKind(29)
-TypeKind.FLOAT128 = TypeKind(30)
-TypeKind.HALF = TypeKind(31)
-TypeKind.IBM128 = TypeKind(40)
-TypeKind.COMPLEX = TypeKind(100)
-TypeKind.POINTER = TypeKind(101)
-TypeKind.BLOCKPOINTER = TypeKind(102)
-TypeKind.LVALUEREFERENCE = TypeKind(103)
-TypeKind.RVALUEREFERENCE = TypeKind(104)
-TypeKind.RECORD = TypeKind(105)
-TypeKind.ENUM = TypeKind(106)
-TypeKind.TYPEDEF = TypeKind(107)
-TypeKind.OBJCINTERFACE = TypeKind(108)
-TypeKind.OBJCOBJECTPOINTER = TypeKind(109)
-TypeKind.FUNCTIONNOPROTO = TypeKind(110)
-TypeKind.FUNCTIONPROTO = TypeKind(111)
-TypeKind.CONSTANTARRAY = TypeKind(112)
-TypeKind.VECTOR = TypeKind(113)
-TypeKind.INCOMPLETEARRAY = TypeKind(114)
-TypeKind.VARIABLEARRAY = TypeKind(115)
-TypeKind.DEPENDENTSIZEDARRAY = TypeKind(116)
-TypeKind.MEMBERPOINTER = TypeKind(117)
-TypeKind.AUTO = TypeKind(118)
-TypeKind.ELABORATED = TypeKind(119)
-TypeKind.PIPE = TypeKind(120)
-TypeKind.OCLIMAGE1DRO = TypeKind(121)
-TypeKind.OCLIMAGE1DARRAYRO = TypeKind(122)
-TypeKind.OCLIMAGE1DBUFFERRO = TypeKind(123)
-TypeKind.OCLIMAGE2DRO = TypeKind(124)
-TypeKind.OCLIMAGE2DARRAYRO = TypeKind(125)
-TypeKind.OCLIMAGE2DDEPTHRO = TypeKind(126)
-TypeKind.OCLIMAGE2DARRAYDEPTHRO = TypeKind(127)
-TypeKind.OCLIMAGE2DMSAARO = TypeKind(128)
-TypeKind.OCLIMAGE2DARRAYMSAARO = TypeKind(129)
-TypeKind.OCLIMAGE2DMSAADEPTHRO = TypeKind(130)
-TypeKind.OCLIMAGE2DARRAYMSAADEPTHRO = TypeKind(131)
-TypeKind.OCLIMAGE3DRO = TypeKind(132)
-TypeKind.OCLIMAGE1DWO = TypeKind(133)
-TypeKind.OCLIMAGE1DARRAYWO = TypeKind(134)
-TypeKind.OCLIMAGE1DBUFFERWO = TypeKind(135)
-TypeKind.OCLIMAGE2DWO = TypeKind(136)
-TypeKind.OCLIMAGE2DARRAYWO = TypeKind(137)
-TypeKind.OCLIMAGE2DDEPTHWO = TypeKind(138)
-TypeKind.OCLIMAGE2DARRAYDEPTHWO = TypeKind(139)
-TypeKind.OCLIMAGE2DMSAAWO = TypeKind(140)
-TypeKind.OCLIMAGE2DARRAYMSAAWO = TypeKind(141)
-TypeKind.OCLIMAGE2DMSAADEPTHWO = TypeKind(142)
-TypeKind.OCLIMAGE2DARRAYMSAADEPTHWO = TypeKind(143)
-TypeKind.OCLIMAGE3DWO = TypeKind(144)
-TypeKind.OCLIMAGE1DRW = TypeKind(145)
-TypeKind.OCLIMAGE1DARRAYRW = TypeKind(146)
-TypeKind.OCLIMAGE1DBUFFERRW = TypeKind(147)
-TypeKind.OCLIMAGE2DRW = TypeKind(148)
-TypeKind.OCLIMAGE2DARRAYRW = TypeKind(149)
-TypeKind.OCLIMAGE2DDEPTHRW = TypeKind(150)
-TypeKind.OCLIMAGE2DARRAYDEPTHRW = TypeKind(151)
-TypeKind.OCLIMAGE2DMSAARW = TypeKind(152)
-TypeKind.OCLIMAGE2DARRAYMSAARW = TypeKind(153)
-TypeKind.OCLIMAGE2DMSAADEPTHRW = TypeKind(154)
-TypeKind.OCLIMAGE2DARRAYMSAADEPTHRW = TypeKind(155)
-TypeKind.OCLIMAGE3DRW = TypeKind(156)
-TypeKind.OCLSAMPLER = TypeKind(157)
-TypeKind.OCLEVENT = TypeKind(158)
-TypeKind.OCLQUEUE = TypeKind(159)
-TypeKind.OCLRESERVEID = TypeKind(160)
-
-TypeKind.OBJCOBJECT = TypeKind(161)
-TypeKind.OBJCCLASS = TypeKind(162)
-TypeKind.ATTRIBUTED = TypeKind(163)
-
-TypeKind.OCLINTELSUBGROUPAVCMCEPAYLOAD = TypeKind(164)
-TypeKind.OCLINTELSUBGROUPAVCIMEPAYLOAD = TypeKind(165)
-TypeKind.OCLINTELSUBGROUPAVCREFPAYLOAD = TypeKind(166)
-TypeKind.OCLINTELSUBGROUPAVCSICPAYLOAD = TypeKind(167)
-TypeKind.OCLINTELSUBGROUPAVCMCERESULT = TypeKind(168)
-TypeKind.OCLINTELSUBGROUPAVCIMERESULT = TypeKind(169)
-TypeKind.OCLINTELSUBGROUPAVCREFRESULT = TypeKind(170)
-TypeKind.OCLINTELSUBGROUPAVCSICRESULT = TypeKind(171)
-TypeKind.OCLINTELSUBGROUPAVCIMERESULTSINGLEREFERENCESTREAMOUT = TypeKind(172)
-TypeKind.OCLINTELSUBGROUPAVCIMERESULTSDUALREFERENCESTREAMOUT = TypeKind(173)
-TypeKind.OCLINTELSUBGROUPAVCIMERESULTSSINGLEREFERENCESTREAMIN = TypeKind(174)
-TypeKind.OCLINTELSUBGROUPAVCIMEDUALREFERENCESTREAMIN = TypeKind(175)
-
-TypeKind.EXTVECTOR = TypeKind(176)
-TypeKind.ATOMIC = Type

[clang] [clang-bindings] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-06-09 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum edited 
https://github.com/llvm/llvm-project/pull/78114
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-bindings] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-06-09 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum ready_for_review 
https://github.com/llvm/llvm-project/pull/78114
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-bindings] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-06-09 Thread Jannick Kremer via cfe-commits

DeinAlptraum wrote:

Since https://github.com/llvm/llvm-project/issues/83962 is now closed and the 
minimum Python version updated to 3.8, this is now finally ready for review. 
I've updated this with the changes to the Python bindings of the past couple 
months.

I have no idea idea what the error in the test failure means, so any advice 
would be appreciated.

@AaronBallman could you review this or recommend reviewers?

https://github.com/llvm/llvm-project/pull/78114
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-06-09 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum edited 
https://github.com/llvm/llvm-project/pull/78114
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-06-10 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum edited 
https://github.com/llvm/llvm-project/pull/78114
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-06-10 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum edited 
https://github.com/llvm/llvm-project/pull/78114
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-06-10 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum edited 
https://github.com/llvm/llvm-project/pull/78114
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Add strict typing to clang Python bindings (#76664) (PR #78114)

2024-06-11 Thread Jannick Kremer via cfe-commits

DeinAlptraum wrote:

Thanks a lot for your feedback! Yup I get that the PR is pretty big and might 
still need significant changes.

> 1. I have maintainability concerns about `ClangLib` protocol [...]
I completely agree that this is ugly, but I didn't find a better solution that 
would enable a strict type check. How do you think we should handle this?
1. Do you know of another solution that would correctly annotate this? It would 
be nice if we could just reuse the types as described in `functionList` but I 
don't think this is possible
2. Alternatively, we could `type: ignore` all calls to `ClangLib` attributes. 
That would require about 180 such annotations I believe.
3. Further, we could go without a strict type-check, only fixing type errors to 
pass a non-strict typecheck, as well as annotating the user-facing interfaces

Regarding the other two points: I tried to change as little as possible here in 
order to enable type annotations or fix type errors. While there's a lot of 
places in `cindex.py` that could use refactoring etc. I held off on doing this 
_unless it was strictly necessary_ for annotations. Both

> 2. I see several bugfixes that you highlighted with your comments. I 
> believe they should be done as a separate PR, because they do something else 
> than just add typing annotations.
and
> 3. Changes to enums are massive, and feel somewhat out of place in this 
> PR as well.

were a direct result of my attempt to fix type errors or annotate interfaces 
correctly.
The enum changes were also necessary, since the implementation up to now 
"dynamically" assigned the enum variants after declaration of the class. That 
means if you use e.g. `CursorKind.UNEXPOSED_DECL` in a script, this will work 
fine but fail the type check since it doesn't recognize `UNEXPOSED_DECL` as an 
attribute of `CursorKind`. This is thus effectively part of annotating the 
user-facing interfaces.

Should I close this PR for now and split this into multiple PRs for the 
bugfixes and then several smaller, grouped changes?



https://github.com/llvm/llvm-project/pull/78114
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Fix bugs in custom enum implementation and add tests (PR #95381)

2024-06-13 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum created 
https://github.com/llvm/llvm-project/pull/95381

Do not allow initialization of enum from negative IDs (e.g. from_id(-1) 
currently produces the last known variant)
Rename duplicate enums: CursorKind.OMP_TEAMS_DISTRIBUTE_DIRECTIVE and 
TypeKind.OBJCCLASS
Add tests to cover these cases

>From 0a81be569d5a8a4ca0945310804106df70962c64 Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Thu, 13 Jun 2024 10:43:52 +0100
Subject: [PATCH] [libclang/python] Fix bugs in custom enum implementation and
 add tests

Do not allow initialization of enum from negative IDs (e.g. from_id(-1)
currently produces the last known variant)
Rename duplicate enums: CursorKind.OMP_TEAMS_DISTRIBUTE_DIRECTIVE
and TypeKind.OBJCCLASS
Add tests to cover these cases
---
 clang/bindings/python/clang/cindex.py |  8 +--
 .../python/tests/cindex/test_enums.py | 55 +++
 2 files changed, 59 insertions(+), 4 deletions(-)
 create mode 100644 clang/bindings/python/tests/cindex/test_enums.py

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index 302d99dccd77b..b3d51e4d2a668 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -649,7 +649,7 @@ def name(self):
 
 @classmethod
 def from_id(cls, id):
-if id >= len(cls._kinds) or cls._kinds[id] is None:
+if id < 0 or id >= len(cls._kinds) or cls._kinds[id] is None:
 raise ValueError("Unknown template argument kind %d" % id)
 return cls._kinds[id]
 
@@ -1336,7 +1336,7 @@ def __repr__(self):
 CursorKind.OMP_TEAMS_DISTRIBUTE_DIRECTIVE = CursorKind(271)
 
 # OpenMP teams distribute simd directive.
-CursorKind.OMP_TEAMS_DISTRIBUTE_DIRECTIVE = CursorKind(272)
+CursorKind.OMP_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE = CursorKind(272)
 
 # OpenMP teams distribute parallel for simd directive.
 CursorKind.OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE = CursorKind(273)
@@ -2215,7 +2215,7 @@ def name(self):
 
 @staticmethod
 def from_id(id):
-if id >= len(StorageClass._kinds) or not StorageClass._kinds[id]:
+if id < 0 or id >= len(StorageClass._kinds) or not 
StorageClass._kinds[id]:
 raise ValueError("Unknown storage class %d" % id)
 return StorageClass._kinds[id]
 
@@ -2395,7 +2395,7 @@ def __repr__(self):
 TypeKind.OCLRESERVEID = TypeKind(160)
 
 TypeKind.OBJCOBJECT = TypeKind(161)
-TypeKind.OBJCCLASS = TypeKind(162)
+TypeKind.OBJCTYPEPARAM = TypeKind(162)
 TypeKind.ATTRIBUTED = TypeKind(163)
 
 TypeKind.OCLINTELSUBGROUPAVCMCEPAYLOAD = TypeKind(164)
diff --git a/clang/bindings/python/tests/cindex/test_enums.py 
b/clang/bindings/python/tests/cindex/test_enums.py
new file mode 100644
index 0..425c4a8274a17
--- /dev/null
+++ b/clang/bindings/python/tests/cindex/test_enums.py
@@ -0,0 +1,55 @@
+import unittest
+
+from clang.cindex import (
+CursorKind,
+TemplateArgumentKind,
+ExceptionSpecificationKind,
+AvailabilityKind,
+AccessSpecifier,
+TypeKind,
+RefQualifierKind,
+LinkageKind,
+TLSKind,
+StorageClass,
+)
+
+
+def get_all_kinds(enum):
+"""Return all CursorKind enumeration instances."""
+return [x for x in enum._kinds if not x is None]
+
+
+class TestCursorKind(unittest.TestCase):
+enums = [
+CursorKind,
+TemplateArgumentKind,
+ExceptionSpecificationKind,
+AvailabilityKind,
+AccessSpecifier,
+TypeKind,
+RefQualifierKind,
+LinkageKind,
+TLSKind,
+StorageClass,
+]
+
+def test_from_id(self):
+"""Check that kinds can be constructed from valid IDs"""
+for enum in self.enums:
+self.assertEqual(enum.from_id(2), enum._kinds[2])
+with self.assertRaises(ValueError):
+enum.from_id(len(enum._kinds))
+with self.assertRaises(ValueError):
+enum.from_id(-1)
+
+def test_unique_kinds(self):
+"""Check that no kind name has been used multiple times"""
+for enum in self.enums:
+seen_names = set()
+for id in range(len(enum._kinds)):
+try:
+kind_name = enum.from_id(id).name
+except ValueError:
+continue
+self.assertNotIn(kind_name, seen_names)
+seen_names.add(id)

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Fix bugs in custom enum implementation and add tests (PR #95381)

2024-06-13 Thread Jannick Kremer via cfe-commits

DeinAlptraum wrote:

@Endilll I separated the fixes for the enum bugs from the strict typing PR, and 
added tests that cover these cases. I checked that the tests fail before the 
fixes and succeed now.

https://github.com/llvm/llvm-project/pull/95381
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Fix bugs in custom enum implementation and add tests (PR #95381)

2024-06-13 Thread Jannick Kremer via cfe-commits


@@ -2395,7 +2395,7 @@ def __repr__(self):
 TypeKind.OCLRESERVEID = TypeKind(160)
 
 TypeKind.OBJCOBJECT = TypeKind(161)
-TypeKind.OBJCCLASS = TypeKind(162)
+TypeKind.OBJCTYPEPARAM = TypeKind(162)

DeinAlptraum wrote:

This was a duplicate with variant 28 (OBJCCLASS). Corrected name taken from 
https://clang.llvm.org/doxygen/group__CINDEX__TYPES.html

https://github.com/llvm/llvm-project/pull/95381
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Fix bugs in custom enum implementation and add tests (PR #95381)

2024-06-13 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum updated 
https://github.com/llvm/llvm-project/pull/95381

>From bfc36e30e84c616adb8ff57754a49a5bb66d1dd9 Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Thu, 13 Jun 2024 10:43:52 +0100
Subject: [PATCH] [libclang/python] Fix bugs in custom enum implementation and
 add tests

Do not allow initialization of enum from negative IDs (e.g. from_id(-1)
currently produces the last known variant)
Rename duplicate enums: CursorKind.OMP_TEAMS_DISTRIBUTE_DIRECTIVE
and TypeKind.OBJCCLASS
Add tests to cover these cases
---
 clang/bindings/python/clang/cindex.py |  8 +--
 .../python/tests/cindex/test_enums.py | 50 +++
 2 files changed, 54 insertions(+), 4 deletions(-)
 create mode 100644 clang/bindings/python/tests/cindex/test_enums.py

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index 302d99dccd77b..b3d51e4d2a668 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -649,7 +649,7 @@ def name(self):
 
 @classmethod
 def from_id(cls, id):
-if id >= len(cls._kinds) or cls._kinds[id] is None:
+if id < 0 or id >= len(cls._kinds) or cls._kinds[id] is None:
 raise ValueError("Unknown template argument kind %d" % id)
 return cls._kinds[id]
 
@@ -1336,7 +1336,7 @@ def __repr__(self):
 CursorKind.OMP_TEAMS_DISTRIBUTE_DIRECTIVE = CursorKind(271)
 
 # OpenMP teams distribute simd directive.
-CursorKind.OMP_TEAMS_DISTRIBUTE_DIRECTIVE = CursorKind(272)
+CursorKind.OMP_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE = CursorKind(272)
 
 # OpenMP teams distribute parallel for simd directive.
 CursorKind.OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE = CursorKind(273)
@@ -2215,7 +2215,7 @@ def name(self):
 
 @staticmethod
 def from_id(id):
-if id >= len(StorageClass._kinds) or not StorageClass._kinds[id]:
+if id < 0 or id >= len(StorageClass._kinds) or not 
StorageClass._kinds[id]:
 raise ValueError("Unknown storage class %d" % id)
 return StorageClass._kinds[id]
 
@@ -2395,7 +2395,7 @@ def __repr__(self):
 TypeKind.OCLRESERVEID = TypeKind(160)
 
 TypeKind.OBJCOBJECT = TypeKind(161)
-TypeKind.OBJCCLASS = TypeKind(162)
+TypeKind.OBJCTYPEPARAM = TypeKind(162)
 TypeKind.ATTRIBUTED = TypeKind(163)
 
 TypeKind.OCLINTELSUBGROUPAVCMCEPAYLOAD = TypeKind(164)
diff --git a/clang/bindings/python/tests/cindex/test_enums.py 
b/clang/bindings/python/tests/cindex/test_enums.py
new file mode 100644
index 0..985d71a4fdcfd
--- /dev/null
+++ b/clang/bindings/python/tests/cindex/test_enums.py
@@ -0,0 +1,50 @@
+import unittest
+
+from clang.cindex import (
+CursorKind,
+TemplateArgumentKind,
+ExceptionSpecificationKind,
+AvailabilityKind,
+AccessSpecifier,
+TypeKind,
+RefQualifierKind,
+LinkageKind,
+TLSKind,
+StorageClass,
+)
+
+
+class TestCursorKind(unittest.TestCase):
+enums = [
+CursorKind,
+TemplateArgumentKind,
+ExceptionSpecificationKind,
+AvailabilityKind,
+AccessSpecifier,
+TypeKind,
+RefQualifierKind,
+LinkageKind,
+TLSKind,
+StorageClass,
+]
+
+def test_from_id(self):
+"""Check that kinds can be constructed from valid IDs"""
+for enum in self.enums:
+self.assertEqual(enum.from_id(2), enum._kinds[2])
+with self.assertRaises(ValueError):
+enum.from_id(len(enum._kinds))
+with self.assertRaises(ValueError):
+enum.from_id(-1)
+
+def test_unique_kinds(self):
+"""Check that no kind name has been used multiple times"""
+for enum in self.enums:
+seen_names = set()
+for id in range(len(enum._kinds)):
+try:
+kind_name = enum.from_id(id).name
+except ValueError:
+continue
+self.assertNotIn(kind_name, seen_names)
+seen_names.add(id)

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Fix bugs in custom enum implementation and add tests (PR #95381)

2024-06-13 Thread Jannick Kremer via cfe-commits


@@ -1336,7 +1336,7 @@ def __repr__(self):
 CursorKind.OMP_TEAMS_DISTRIBUTE_DIRECTIVE = CursorKind(271)
 
 # OpenMP teams distribute simd directive.
-CursorKind.OMP_TEAMS_DISTRIBUTE_DIRECTIVE = CursorKind(272)
+CursorKind.OMP_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE = CursorKind(272)

DeinAlptraum wrote:

This was a duplicate with variant 271. new name taken from 
https://clang.llvm.org/doxygen/Index_8h_source.html, line 2011

https://github.com/llvm/llvm-project/pull/95381
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Fix bugs in custom enum implementation and add tests (PR #95381)

2024-06-13 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum edited 
https://github.com/llvm/llvm-project/pull/95381
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Fix bugs in custom enum implementation and add tests (PR #95381)

2024-06-13 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum updated 
https://github.com/llvm/llvm-project/pull/95381

>From a3da142b0db6581581ccb135800d77b09476f385 Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Thu, 13 Jun 2024 10:43:52 +0100
Subject: [PATCH 1/2] [libclang/python] Fix bugs in custom enum implementation
 and add tests

Do not allow initialization of enum from negative IDs (e.g. from_id(-1)
currently produces the last known variant)
Rename duplicate enums: CursorKind.OMP_TEAMS_DISTRIBUTE_DIRECTIVE
and TypeKind.OBJCCLASS
Add tests to cover these cases
---
 clang/bindings/python/clang/cindex.py |  8 +--
 .../python/tests/cindex/test_enums.py | 50 +++
 2 files changed, 54 insertions(+), 4 deletions(-)
 create mode 100644 clang/bindings/python/tests/cindex/test_enums.py

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index 302d99dccd77b..b3d51e4d2a668 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -649,7 +649,7 @@ def name(self):
 
 @classmethod
 def from_id(cls, id):
-if id >= len(cls._kinds) or cls._kinds[id] is None:
+if id < 0 or id >= len(cls._kinds) or cls._kinds[id] is None:
 raise ValueError("Unknown template argument kind %d" % id)
 return cls._kinds[id]
 
@@ -1336,7 +1336,7 @@ def __repr__(self):
 CursorKind.OMP_TEAMS_DISTRIBUTE_DIRECTIVE = CursorKind(271)
 
 # OpenMP teams distribute simd directive.
-CursorKind.OMP_TEAMS_DISTRIBUTE_DIRECTIVE = CursorKind(272)
+CursorKind.OMP_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE = CursorKind(272)
 
 # OpenMP teams distribute parallel for simd directive.
 CursorKind.OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE = CursorKind(273)
@@ -2215,7 +2215,7 @@ def name(self):
 
 @staticmethod
 def from_id(id):
-if id >= len(StorageClass._kinds) or not StorageClass._kinds[id]:
+if id < 0 or id >= len(StorageClass._kinds) or not 
StorageClass._kinds[id]:
 raise ValueError("Unknown storage class %d" % id)
 return StorageClass._kinds[id]
 
@@ -2395,7 +2395,7 @@ def __repr__(self):
 TypeKind.OCLRESERVEID = TypeKind(160)
 
 TypeKind.OBJCOBJECT = TypeKind(161)
-TypeKind.OBJCCLASS = TypeKind(162)
+TypeKind.OBJCTYPEPARAM = TypeKind(162)
 TypeKind.ATTRIBUTED = TypeKind(163)
 
 TypeKind.OCLINTELSUBGROUPAVCMCEPAYLOAD = TypeKind(164)
diff --git a/clang/bindings/python/tests/cindex/test_enums.py 
b/clang/bindings/python/tests/cindex/test_enums.py
new file mode 100644
index 0..985d71a4fdcfd
--- /dev/null
+++ b/clang/bindings/python/tests/cindex/test_enums.py
@@ -0,0 +1,50 @@
+import unittest
+
+from clang.cindex import (
+CursorKind,
+TemplateArgumentKind,
+ExceptionSpecificationKind,
+AvailabilityKind,
+AccessSpecifier,
+TypeKind,
+RefQualifierKind,
+LinkageKind,
+TLSKind,
+StorageClass,
+)
+
+
+class TestCursorKind(unittest.TestCase):
+enums = [
+CursorKind,
+TemplateArgumentKind,
+ExceptionSpecificationKind,
+AvailabilityKind,
+AccessSpecifier,
+TypeKind,
+RefQualifierKind,
+LinkageKind,
+TLSKind,
+StorageClass,
+]
+
+def test_from_id(self):
+"""Check that kinds can be constructed from valid IDs"""
+for enum in self.enums:
+self.assertEqual(enum.from_id(2), enum._kinds[2])
+with self.assertRaises(ValueError):
+enum.from_id(len(enum._kinds))
+with self.assertRaises(ValueError):
+enum.from_id(-1)
+
+def test_unique_kinds(self):
+"""Check that no kind name has been used multiple times"""
+for enum in self.enums:
+seen_names = set()
+for id in range(len(enum._kinds)):
+try:
+kind_name = enum.from_id(id).name
+except ValueError:
+continue
+self.assertNotIn(kind_name, seen_names)
+seen_names.add(id)

>From 67f43ab2c26129cc6611ba58e81f6fbe6c490dbd Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Thu, 13 Jun 2024 14:18:03 +0100
Subject: [PATCH 2/2] [libclang/python] Add release notes

Also simplify the enum test
---
 clang/bindings/python/tests/cindex/test_enums.py | 7 ++-
 clang/docs/ReleaseNotes.rst  | 8 
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/clang/bindings/python/tests/cindex/test_enums.py 
b/clang/bindings/python/tests/cindex/test_enums.py
index 985d71a4fdcfd..6fc0e5ed77e3e 100644
--- a/clang/bindings/python/tests/cindex/test_enums.py
+++ b/clang/bindings/python/tests/cindex/test_enums.py
@@ -40,11 +40,8 @@ def test_from_id(self):
 def test_unique_kinds(self):
 """Check that no kind name has been used multiple times"""
 for enum in self.enums:
-seen_names = set()
 for id in range(len(enum._kinds)):

[clang] [libclang/python] Fix bugs in custom enum implementation and add tests (PR #95381)

2024-06-13 Thread Jannick Kremer via cfe-commits


@@ -0,0 +1,50 @@
+import unittest
+
+from clang.cindex import (
+CursorKind,
+TemplateArgumentKind,
+ExceptionSpecificationKind,
+AvailabilityKind,
+AccessSpecifier,
+TypeKind,
+RefQualifierKind,
+LinkageKind,
+TLSKind,
+StorageClass,
+)
+
+
+class TestCursorKind(unittest.TestCase):
+enums = [
+CursorKind,
+TemplateArgumentKind,
+ExceptionSpecificationKind,
+AvailabilityKind,
+AccessSpecifier,
+TypeKind,
+RefQualifierKind,
+LinkageKind,
+TLSKind,
+StorageClass,
+]
+
+def test_from_id(self):
+"""Check that kinds can be constructed from valid IDs"""
+for enum in self.enums:
+self.assertEqual(enum.from_id(2), enum._kinds[2])
+with self.assertRaises(ValueError):
+enum.from_id(len(enum._kinds))
+with self.assertRaises(ValueError):
+enum.from_id(-1)
+
+def test_unique_kinds(self):
+"""Check that no kind name has been used multiple times"""
+for enum in self.enums:
+seen_names = set()
+for id in range(len(enum._kinds)):
+try:
+kind_name = enum.from_id(id).name
+except ValueError:
+continue
+self.assertNotIn(kind_name, seen_names)
+seen_names.add(id)

DeinAlptraum wrote:

I only just realized that even that is not necessary, calling 
`enum.from_id(id).name` already fails for duplicate IDs, so no assertions 
needed.

https://github.com/llvm/llvm-project/pull/95381
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Fix bugs in custom enum implementation and add tests (PR #95381)

2024-06-13 Thread Jannick Kremer via cfe-commits

DeinAlptraum wrote:

These were all the bugs I'd found, so I think it is

https://github.com/llvm/llvm-project/pull/95381
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Fix bugs in custom enum implementation and add tests (PR #95381)

2024-06-13 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum updated 
https://github.com/llvm/llvm-project/pull/95381

>From a3da142b0db6581581ccb135800d77b09476f385 Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Thu, 13 Jun 2024 10:43:52 +0100
Subject: [PATCH 1/2] [libclang/python] Fix bugs in custom enum implementation
 and add tests

Do not allow initialization of enum from negative IDs (e.g. from_id(-1)
currently produces the last known variant)
Rename duplicate enums: CursorKind.OMP_TEAMS_DISTRIBUTE_DIRECTIVE
and TypeKind.OBJCCLASS
Add tests to cover these cases
---
 clang/bindings/python/clang/cindex.py |  8 +--
 .../python/tests/cindex/test_enums.py | 50 +++
 2 files changed, 54 insertions(+), 4 deletions(-)
 create mode 100644 clang/bindings/python/tests/cindex/test_enums.py

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index 302d99dccd77b..b3d51e4d2a668 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -649,7 +649,7 @@ def name(self):
 
 @classmethod
 def from_id(cls, id):
-if id >= len(cls._kinds) or cls._kinds[id] is None:
+if id < 0 or id >= len(cls._kinds) or cls._kinds[id] is None:
 raise ValueError("Unknown template argument kind %d" % id)
 return cls._kinds[id]
 
@@ -1336,7 +1336,7 @@ def __repr__(self):
 CursorKind.OMP_TEAMS_DISTRIBUTE_DIRECTIVE = CursorKind(271)
 
 # OpenMP teams distribute simd directive.
-CursorKind.OMP_TEAMS_DISTRIBUTE_DIRECTIVE = CursorKind(272)
+CursorKind.OMP_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE = CursorKind(272)
 
 # OpenMP teams distribute parallel for simd directive.
 CursorKind.OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE = CursorKind(273)
@@ -2215,7 +2215,7 @@ def name(self):
 
 @staticmethod
 def from_id(id):
-if id >= len(StorageClass._kinds) or not StorageClass._kinds[id]:
+if id < 0 or id >= len(StorageClass._kinds) or not 
StorageClass._kinds[id]:
 raise ValueError("Unknown storage class %d" % id)
 return StorageClass._kinds[id]
 
@@ -2395,7 +2395,7 @@ def __repr__(self):
 TypeKind.OCLRESERVEID = TypeKind(160)
 
 TypeKind.OBJCOBJECT = TypeKind(161)
-TypeKind.OBJCCLASS = TypeKind(162)
+TypeKind.OBJCTYPEPARAM = TypeKind(162)
 TypeKind.ATTRIBUTED = TypeKind(163)
 
 TypeKind.OCLINTELSUBGROUPAVCMCEPAYLOAD = TypeKind(164)
diff --git a/clang/bindings/python/tests/cindex/test_enums.py 
b/clang/bindings/python/tests/cindex/test_enums.py
new file mode 100644
index 0..985d71a4fdcfd
--- /dev/null
+++ b/clang/bindings/python/tests/cindex/test_enums.py
@@ -0,0 +1,50 @@
+import unittest
+
+from clang.cindex import (
+CursorKind,
+TemplateArgumentKind,
+ExceptionSpecificationKind,
+AvailabilityKind,
+AccessSpecifier,
+TypeKind,
+RefQualifierKind,
+LinkageKind,
+TLSKind,
+StorageClass,
+)
+
+
+class TestCursorKind(unittest.TestCase):
+enums = [
+CursorKind,
+TemplateArgumentKind,
+ExceptionSpecificationKind,
+AvailabilityKind,
+AccessSpecifier,
+TypeKind,
+RefQualifierKind,
+LinkageKind,
+TLSKind,
+StorageClass,
+]
+
+def test_from_id(self):
+"""Check that kinds can be constructed from valid IDs"""
+for enum in self.enums:
+self.assertEqual(enum.from_id(2), enum._kinds[2])
+with self.assertRaises(ValueError):
+enum.from_id(len(enum._kinds))
+with self.assertRaises(ValueError):
+enum.from_id(-1)
+
+def test_unique_kinds(self):
+"""Check that no kind name has been used multiple times"""
+for enum in self.enums:
+seen_names = set()
+for id in range(len(enum._kinds)):
+try:
+kind_name = enum.from_id(id).name
+except ValueError:
+continue
+self.assertNotIn(kind_name, seen_names)
+seen_names.add(id)

>From 67f43ab2c26129cc6611ba58e81f6fbe6c490dbd Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Thu, 13 Jun 2024 14:18:03 +0100
Subject: [PATCH 2/2] [libclang/python] Add release notes

Also simplify the enum test
---
 clang/bindings/python/tests/cindex/test_enums.py | 7 ++-
 clang/docs/ReleaseNotes.rst  | 8 
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/clang/bindings/python/tests/cindex/test_enums.py 
b/clang/bindings/python/tests/cindex/test_enums.py
index 985d71a4fdcfd..6fc0e5ed77e3e 100644
--- a/clang/bindings/python/tests/cindex/test_enums.py
+++ b/clang/bindings/python/tests/cindex/test_enums.py
@@ -40,11 +40,8 @@ def test_from_id(self):
 def test_unique_kinds(self):
 """Check that no kind name has been used multiple times"""
 for enum in self.enums:
-seen_names = set()
 for id in range(len(enum._kinds)):

[clang] [libclang/python] Fix bugs in custom enum implementation and add tests (PR #95381)

2024-06-13 Thread Jannick Kremer via cfe-commits

DeinAlptraum wrote:

@Endilll I merged the Python 3.8 CI into this PR and the CI run was successful 
(though it only ran on 3.8 for some reason), so can this be merged?

https://github.com/llvm/llvm-project/pull/95381
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Refactor enum usage (PR #95608)

2024-06-14 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum created 
https://github.com/llvm/llvm-project/pull/95608

Use Python's builtin enum class instead of writing our own.

This is preparation for passing a strict type check in PR #78114 , fixing 920 
out of 1341 strict typing errors

>From 35bfcfbc69ee812c59350440b7b15c5e23ad1307 Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Fri, 14 Jun 2024 22:12:09 +0100
Subject: [PATCH] [libclang/python] Refactor enum usage

Use Python's builtin enum class instead of writing our own.

This is preparation for strict typing in PR #78114
---
 clang/bindings/python/clang/cindex.py | 1670 -
 .../python/tests/cindex/test_enums.py |   14 +-
 2 files changed, 768 insertions(+), 916 deletions(-)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index b3d51e4d2a668..aacfc333723c4 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -68,6 +68,7 @@
 
 import collections.abc
 import os
+from enum import Enum
 
 
 # Python 3 strings are unicode, translate them to/from utf8 for C-interop.
@@ -611,51 +612,25 @@ def register(value, name):
 
 
 ### Cursor Kinds ###
-class BaseEnumeration:
+class BaseEnumeration(Enum):
 """
 Common base class for named enumerations held in sync with Index.h values.
-
-Subclasses must define their own _kinds and _name_map members, as:
-_kinds = []
-_name_map = None
-These values hold the per-subclass instances and value-to-name mappings,
-respectively.
-
 """
 
-def __init__(self, value):
-if value >= len(self.__class__._kinds):
-self.__class__._kinds += [None] * (value - 
len(self.__class__._kinds) + 1)
-if self.__class__._kinds[value] is not None:
-raise ValueError(
-"{0} value {1} already loaded".format(str(self.__class__), 
value)
-)
-self.value = value
-self.__class__._kinds[value] = self
-self.__class__._name_map = None
 
 def from_param(self):
 return self.value
 
-@property
-def name(self):
-"""Get the enumeration name of this cursor kind."""
-if self._name_map is None:
-self._name_map = {}
-for key, value in self.__class__.__dict__.items():
-if isinstance(value, self.__class__):
-self._name_map[value] = key
-return self._name_map[self]
-
 @classmethod
 def from_id(cls, id):
-if id < 0 or id >= len(cls._kinds) or cls._kinds[id] is None:
-raise ValueError("Unknown template argument kind %d" % id)
-return cls._kinds[id]
+try:
+return cls(id)
+except ValueError:
+raise ValueError("Unknown %s %d" % (cls.__name__, id)) from None
 
 def __repr__(self):
 return "%s.%s" % (
-self.__class__,
+self.__class__.__name__,
 self.name,
 )
 
@@ -665,14 +640,10 @@ class CursorKind(BaseEnumeration):
 A CursorKind describes the kind of entity that a cursor points to.
 """
 
-# The required BaseEnumeration declarations.
-_kinds = []
-_name_map = None
-
 @staticmethod
 def get_all_kinds():
 """Return all CursorKind enumeration instances."""
-return [x for x in CursorKind._kinds if not x is None]
+return list(CursorKind)
 
 def is_declaration(self):
 """Test if this is a declaration kind."""
@@ -710,822 +681,820 @@ def is_unexposed(self):
 """Test if this is an unexposed kind."""
 return conf.lib.clang_isUnexposed(self)
 
-def __repr__(self):
-return "CursorKind.%s" % (self.name,)
-
 
-###
-# Declaration Kinds
+###
+# Declaration Kinds
 
-# A declaration whose specific kind is not exposed via this interface.
-#
-# Unexposed declarations have the same operations as any other kind of
-# declaration; one can extract their location information, spelling, find their
-# definitions, etc. However, the specific kind of the declaration is not
-# reported.
-CursorKind.UNEXPOSED_DECL = CursorKind(1)
+# A declaration whose specific kind is not exposed via this interface.
+#
+# Unexposed declarations have the same operations as any other kind of
+# declaration; one can extract their location information, spelling, find
+# their definitions, etc. However, the specific kind of the declaration is
+# not reported.
+UNEXPOSED_DECL = 1
 
-# A C or C++ struct.
-CursorKind.STRUCT_DECL = CursorKind(2)
+# A C or C++ struct.
+STRUCT_DECL = 2
 
-# A C or C++ union.
-CursorKind.UNION_DECL = CursorKind(3)
+# A C or C++ union.
+UNION_DECL = 3
 
-# A C++ class.
-CursorKind.CLASS_DECL = CursorKind(4)
+# A C++ class.
+CLASS_DECL = 4
 
-# An enumeration.
-CursorKind.ENUM_DECL = CursorKind(5)
+# An enumeration.
+ENUM_DECL = 5
 
-# A field (in C) or non-static data member (in C++) in a

[clang] [libclang/python] Refactor enum usage (PR #95608)

2024-06-14 Thread Jannick Kremer via cfe-commits


@@ -611,51 +612,25 @@ def register(value, name):
 
 
 ### Cursor Kinds ###
-class BaseEnumeration:
+class BaseEnumeration(Enum):
 """
 Common base class for named enumerations held in sync with Index.h values.
-
-Subclasses must define their own _kinds and _name_map members, as:
-_kinds = []
-_name_map = None
-These values hold the per-subclass instances and value-to-name mappings,
-respectively.
-
 """
 
-def __init__(self, value):
-if value >= len(self.__class__._kinds):
-self.__class__._kinds += [None] * (value - 
len(self.__class__._kinds) + 1)
-if self.__class__._kinds[value] is not None:
-raise ValueError(
-"{0} value {1} already loaded".format(str(self.__class__), 
value)
-)
-self.value = value
-self.__class__._kinds[value] = self
-self.__class__._name_map = None
 
 def from_param(self):
 return self.value
 
-@property
-def name(self):
-"""Get the enumeration name of this cursor kind."""
-if self._name_map is None:
-self._name_map = {}
-for key, value in self.__class__.__dict__.items():
-if isinstance(value, self.__class__):
-self._name_map[value] = key
-return self._name_map[self]

DeinAlptraum wrote:

The `Enum` class already provides a `name` attribute that follows the exact 
same format as we had before

https://github.com/llvm/llvm-project/pull/95608
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Refactor enum usage (PR #95608)

2024-06-14 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum edited 
https://github.com/llvm/llvm-project/pull/95608
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Refactor enum usage (PR #95608)

2024-06-14 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum commented:

There is also `TokenKind`: this one does not currently inherit from 
`BaseEnumeration` and is defined somewhat differently, having all its variants 
and their IDs as a dictionary in `enumerations.py`. This seems quite arbitrary 
to me, is there any reason it is done this way? Otherwise I would also move 
this to `cindex.py` as another subclass of `BaseEnumeration`

https://github.com/llvm/llvm-project/pull/95608
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Refactor enum usage (PR #95608)

2024-06-14 Thread Jannick Kremer via cfe-commits


@@ -31,17 +31,9 @@ class TestCursorKind(unittest.TestCase):
 def test_from_id(self):
 """Check that kinds can be constructed from valid IDs"""
 for enum in self.enums:
-self.assertEqual(enum.from_id(2), enum._kinds[2])
+self.assertEqual(enum.from_id(2), enum(2))
+max_value = max([variant.value for variant in enum])
 with self.assertRaises(ValueError):
-enum.from_id(len(enum._kinds))
+enum.from_id(max_value + 1)
 with self.assertRaises(ValueError):
 enum.from_id(-1)
-
-def test_unique_kinds(self):
-"""Check that no kind name has been used multiple times"""
-for enum in self.enums:
-for id in range(len(enum._kinds)):
-try:
-enum.from_id(id).name
-except ValueError:
-pass

DeinAlptraum wrote:

This test is effectively pointless now, since the enum class errors out as soon 
as the module is loaded in case there are duplicate enum variants

https://github.com/llvm/llvm-project/pull/95608
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Refactor enum usage (PR #95608)

2024-06-14 Thread Jannick Kremer via cfe-commits


@@ -611,51 +612,25 @@ def register(value, name):
 
 
 ### Cursor Kinds ###
-class BaseEnumeration:
+class BaseEnumeration(Enum):
 """
 Common base class for named enumerations held in sync with Index.h values.
-
-Subclasses must define their own _kinds and _name_map members, as:
-_kinds = []
-_name_map = None
-These values hold the per-subclass instances and value-to-name mappings,
-respectively.
-
 """
 
-def __init__(self, value):
-if value >= len(self.__class__._kinds):
-self.__class__._kinds += [None] * (value - 
len(self.__class__._kinds) + 1)
-if self.__class__._kinds[value] is not None:
-raise ValueError(
-"{0} value {1} already loaded".format(str(self.__class__), 
value)
-)
-self.value = value
-self.__class__._kinds[value] = self
-self.__class__._name_map = None
 
 def from_param(self):
 return self.value
 
-@property
-def name(self):
-"""Get the enumeration name of this cursor kind."""
-if self._name_map is None:
-self._name_map = {}
-for key, value in self.__class__.__dict__.items():
-if isinstance(value, self.__class__):
-self._name_map[value] = key
-return self._name_map[self]
-
 @classmethod
 def from_id(cls, id):
-if id < 0 or id >= len(cls._kinds) or cls._kinds[id] is None:
-raise ValueError("Unknown template argument kind %d" % id)
-return cls._kinds[id]
+try:
+return cls(id)
+except ValueError:
+raise ValueError("Unknown %s %d" % (cls.__name__, id)) from None

DeinAlptraum wrote:

In hindsight, should the change of error message go into a separate PR? The one 
we had before, `Unknown template argument kind`, doesn't make much sense since 
this is the base class of not just `TemplateArgumentKind`.
If we don't consider changing error messages as a breaking change, then we 
could also remove the try-except part entirely since `Enum` already throws a 
meanginful error, looking like this: `ValueError: 703 is not a valid CursorKind`

https://github.com/llvm/llvm-project/pull/95608
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Refactor enum usage (PR #95608)

2024-06-14 Thread Jannick Kremer via cfe-commits


@@ -611,51 +612,25 @@ def register(value, name):
 
 
 ### Cursor Kinds ###
-class BaseEnumeration:
+class BaseEnumeration(Enum):
 """
 Common base class for named enumerations held in sync with Index.h values.
-
-Subclasses must define their own _kinds and _name_map members, as:
-_kinds = []
-_name_map = None
-These values hold the per-subclass instances and value-to-name mappings,
-respectively.
-
 """
 
-def __init__(self, value):
-if value >= len(self.__class__._kinds):
-self.__class__._kinds += [None] * (value - 
len(self.__class__._kinds) + 1)
-if self.__class__._kinds[value] is not None:
-raise ValueError(
-"{0} value {1} already loaded".format(str(self.__class__), 
value)
-)
-self.value = value
-self.__class__._kinds[value] = self
-self.__class__._name_map = None
 
 def from_param(self):
 return self.value
 
-@property
-def name(self):
-"""Get the enumeration name of this cursor kind."""
-if self._name_map is None:
-self._name_map = {}
-for key, value in self.__class__.__dict__.items():
-if isinstance(value, self.__class__):
-self._name_map[value] = key
-return self._name_map[self]
-
 @classmethod
 def from_id(cls, id):
-if id < 0 or id >= len(cls._kinds) or cls._kinds[id] is None:
-raise ValueError("Unknown template argument kind %d" % id)
-return cls._kinds[id]
+try:
+return cls(id)
+except ValueError:
+raise ValueError("Unknown %s %d" % (cls.__name__, id)) from None
 
 def __repr__(self):
 return "%s.%s" % (
-self.__class__,
+self.__class__.__name__,

DeinAlptraum wrote:

This `__repr__` was effectively unused before as each subclass defined its own. 
This change is necessary so that all subclasses still return exactly the same 
representation as they did before

https://github.com/llvm/llvm-project/pull/95608
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Refactor enum usage (PR #95608)

2024-06-14 Thread Jannick Kremer via cfe-commits

DeinAlptraum wrote:

@Endilll can I ask you for a review again?
As a next step towards the python-bindings strict typing PR, this one captures 
all the enum refactoring changes necessary towards that goal. Don't be scared 
by the LoC changed: 90% of that is just indentation changes :)

https://github.com/llvm/llvm-project/pull/95608
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Refactor enum usage (PR #95608)

2024-06-15 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum edited 
https://github.com/llvm/llvm-project/pull/95608
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Fix some type errors, add type annotations (PR #98745)

2024-07-23 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum updated 
https://github.com/llvm/llvm-project/pull/98745

>From c64b124ccc22cd9f92b0a55f60ec92d7101d0048 Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Sat, 13 Jul 2024 14:12:34 +0100
Subject: [PATCH 1/2] [libclang/python] Fix some type errors, add type
 annotations

---
 clang/bindings/python/clang/cindex.py | 195 +++---
 .../tests/cindex/test_code_completion.py  |  22 +-
 .../python/tests/cindex/test_comment.py   |   4 +-
 3 files changed, 130 insertions(+), 91 deletions(-)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index be024da5e005c..6c70588c28ffa 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -43,7 +43,7 @@
 Most object information is exposed using properties, when the underlying API
 call is efficient.
 """
-from __future__ import absolute_import, division, print_function
+from __future__ import annotations
 
 # TODO
 # 
@@ -64,48 +64,81 @@
 
 from ctypes import *
 
-import collections.abc
 import os
+import sys
 from enum import Enum
 
+from typing import (
+Any,
+Callable,
+Generic,
+Optional,
+Type as TType,
+TypeVar,
+TYPE_CHECKING,
+Union as TUnion,
+)
+
+if TYPE_CHECKING:
+from ctypes import _Pointer
+from typing_extensions import Protocol, TypeAlias
+
+StrPath: TypeAlias = TUnion[str, os.PathLike[str]]
+LibFunc: TypeAlias = TUnion[
+"tuple[str, Optional[list[Any]]]",
+"tuple[str, Optional[list[Any]], Any]",
+"tuple[str, Optional[list[Any]], Any, Callable[..., Any]]",
+]
+CObjP: TypeAlias = _Pointer[Any]
+
+TSeq = TypeVar("TSeq", covariant=True)
+
+class NoSliceSequence(Protocol[TSeq]):
+def __len__(self) -> int:
+...
+
+def __getitem__(self, key: int) -> TSeq:
+...
+
 
 # Python 3 strings are unicode, translate them to/from utf8 for C-interop.
 class c_interop_string(c_char_p):
-def __init__(self, p=None):
+def __init__(self, p: str | bytes | None = None):
 if p is None:
 p = ""
 if isinstance(p, str):
 p = p.encode("utf8")
 super(c_char_p, self).__init__(p)
 
-def __str__(self):
-return self.value
+def __str__(self) -> str:
+return self.value or ""
 
 @property
-def value(self):
-if super(c_char_p, self).value is None:
+def value(self) -> str | None:  # type: ignore [override]
+val = super(c_char_p, self).value
+if val is None:
 return None
-return super(c_char_p, self).value.decode("utf8")
+return val.decode("utf8")
 
 @classmethod
-def from_param(cls, param):
+def from_param(cls, param: str | bytes | None) -> c_interop_string:
 if isinstance(param, str):
 return cls(param)
 if isinstance(param, bytes):
 return cls(param)
 if param is None:
 # Support passing null to C functions expecting char arrays
-return None
+return cls(param)
 raise TypeError(
 "Cannot convert '{}' to '{}'".format(type(param).__name__, 
cls.__name__)
 )
 
 @staticmethod
-def to_python_string(x, *args):
+def to_python_string(x: c_interop_string, *args: Any) -> str | None:
 return x.value
 
 
-def b(x):
+def b(x: str | bytes) -> bytes:
 if isinstance(x, bytes):
 return x
 return x.encode("utf8")
@@ -115,9 +148,7 @@ def b(x):
 # object. This is a problem, because it means that from_parameter will see an
 # integer and pass the wrong value on platforms where int != void*. Work around
 # this by marshalling object arguments as void**.
-c_object_p = POINTER(c_void_p)
-
-callbacks = {}
+c_object_p: TType[CObjP] = POINTER(c_void_p)
 
 ### Exception Classes ###
 
@@ -169,8 +200,11 @@ def __init__(self, enumeration, message):
 
 ### Structures and Utility Classes ###
 
+TInstance = TypeVar("TInstance")
+TResult = TypeVar("TResult")
+
 
-class CachedProperty:
+class CachedProperty(Generic[TInstance, TResult]):
 """Decorator that lazy-loads the value of a property.
 
 The first time the property is accessed, the original property function is
@@ -178,16 +212,20 @@ class CachedProperty:
 property, replacing the original method.
 """
 
-def __init__(self, wrapped):
+def __init__(self, wrapped: Callable[[TInstance], TResult]):
 self.wrapped = wrapped
 try:
 self.__doc__ = wrapped.__doc__
 except:
 pass
 
-def __get__(self, instance, instance_type=None):
+def __get__(self, instance: TInstance, instance_type: Any = None) -> 
TResult:
 if instance is None:
-return self
+property_name = self.wrapped.__name__
+class_name = instance_type.__name__
+raise TypeError(
+f"'{property_name}' is not a stat

[clang] [libclang/python] Fix some type errors, add type annotations (PR #98745)

2024-07-23 Thread Jannick Kremer via cfe-commits

DeinAlptraum wrote:

Since the release branching is done, I've rebased on main to fix the release 
notes

https://github.com/llvm/llvm-project/pull/98745
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Export all enums (PR #100941)

2024-07-28 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum created 
https://github.com/llvm/llvm-project/pull/100941

This resolves #48212 and also adds the remaining unexposed Enums

>From c4007832c8ed7cdb56aceebcf61b24ecb75f2aa4 Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Sun, 28 Jul 2024 18:30:35 +0100
Subject: [PATCH] [libclang/python] Export all enums

---
 clang/bindings/python/clang/cindex.py | 5 +
 1 file changed, 5 insertions(+)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index be024da5e005c..d9009a8666338 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -4077,6 +4077,7 @@ def function_exists(self, name):
 conf = Config()
 
 __all__ = [
+"AccessSpecifier",
 "AvailabilityKind",
 "BinaryOperator",
 "Config",
@@ -4087,12 +4088,16 @@ def function_exists(self, name):
 "CursorKind",
 "Cursor",
 "Diagnostic",
+"ExceptionSpecificationKind",
 "File",
 "FixIt",
 "Index",
 "LinkageKind",
+"RefQualifierKind",
 "SourceLocation",
 "SourceRange",
+"StorageClass",
+"TemplateArgumentKind",
 "TLSKind",
 "TokenKind",
 "Token",

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Export all enums (PR #100941)

2024-07-28 Thread Jannick Kremer via cfe-commits

DeinAlptraum wrote:

@Endilll can I ask you for a review again?

https://github.com/llvm/llvm-project/pull/100941
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Export all enums (PR #100941)

2024-07-29 Thread Jannick Kremer via cfe-commits

DeinAlptraum wrote:

Could you also merge please? (or are you waiting for something else?)

https://github.com/llvm/llvm-project/pull/100941
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Export all enums (PR #100941)

2024-07-29 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum updated 
https://github.com/llvm/llvm-project/pull/100941

>From 4b1322b8add0a1189f0f1cbf5583841f3a591f0c Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Sun, 28 Jul 2024 18:30:35 +0100
Subject: [PATCH] [libclang/python] Export all enums

---
 clang/bindings/python/clang/cindex.py | 5 +
 1 file changed, 5 insertions(+)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index be024da5e005c..d9009a8666338 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -4077,6 +4077,7 @@ def function_exists(self, name):
 conf = Config()
 
 __all__ = [
+"AccessSpecifier",
 "AvailabilityKind",
 "BinaryOperator",
 "Config",
@@ -4087,12 +4088,16 @@ def function_exists(self, name):
 "CursorKind",
 "Cursor",
 "Diagnostic",
+"ExceptionSpecificationKind",
 "File",
 "FixIt",
 "Index",
 "LinkageKind",
+"RefQualifierKind",
 "SourceLocation",
 "SourceRange",
+"StorageClass",
+"TemplateArgumentKind",
 "TLSKind",
 "TokenKind",
 "Token",

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang/python] Fix some type errors, add type annotations (PR #98745)

2024-07-29 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum updated 
https://github.com/llvm/llvm-project/pull/98745

>From 00631fc559197d2bc6bfa9e8ccdae47f33926a37 Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Sat, 13 Jul 2024 14:12:34 +0100
Subject: [PATCH 1/2] [libclang/python] Fix some type errors, add type
 annotations

---
 clang/bindings/python/clang/cindex.py | 195 +++---
 .../tests/cindex/test_code_completion.py  |  22 +-
 .../python/tests/cindex/test_comment.py   |   4 +-
 3 files changed, 130 insertions(+), 91 deletions(-)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index be024da5e005c..6c70588c28ffa 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -43,7 +43,7 @@
 Most object information is exposed using properties, when the underlying API
 call is efficient.
 """
-from __future__ import absolute_import, division, print_function
+from __future__ import annotations
 
 # TODO
 # 
@@ -64,48 +64,81 @@
 
 from ctypes import *
 
-import collections.abc
 import os
+import sys
 from enum import Enum
 
+from typing import (
+Any,
+Callable,
+Generic,
+Optional,
+Type as TType,
+TypeVar,
+TYPE_CHECKING,
+Union as TUnion,
+)
+
+if TYPE_CHECKING:
+from ctypes import _Pointer
+from typing_extensions import Protocol, TypeAlias
+
+StrPath: TypeAlias = TUnion[str, os.PathLike[str]]
+LibFunc: TypeAlias = TUnion[
+"tuple[str, Optional[list[Any]]]",
+"tuple[str, Optional[list[Any]], Any]",
+"tuple[str, Optional[list[Any]], Any, Callable[..., Any]]",
+]
+CObjP: TypeAlias = _Pointer[Any]
+
+TSeq = TypeVar("TSeq", covariant=True)
+
+class NoSliceSequence(Protocol[TSeq]):
+def __len__(self) -> int:
+...
+
+def __getitem__(self, key: int) -> TSeq:
+...
+
 
 # Python 3 strings are unicode, translate them to/from utf8 for C-interop.
 class c_interop_string(c_char_p):
-def __init__(self, p=None):
+def __init__(self, p: str | bytes | None = None):
 if p is None:
 p = ""
 if isinstance(p, str):
 p = p.encode("utf8")
 super(c_char_p, self).__init__(p)
 
-def __str__(self):
-return self.value
+def __str__(self) -> str:
+return self.value or ""
 
 @property
-def value(self):
-if super(c_char_p, self).value is None:
+def value(self) -> str | None:  # type: ignore [override]
+val = super(c_char_p, self).value
+if val is None:
 return None
-return super(c_char_p, self).value.decode("utf8")
+return val.decode("utf8")
 
 @classmethod
-def from_param(cls, param):
+def from_param(cls, param: str | bytes | None) -> c_interop_string:
 if isinstance(param, str):
 return cls(param)
 if isinstance(param, bytes):
 return cls(param)
 if param is None:
 # Support passing null to C functions expecting char arrays
-return None
+return cls(param)
 raise TypeError(
 "Cannot convert '{}' to '{}'".format(type(param).__name__, 
cls.__name__)
 )
 
 @staticmethod
-def to_python_string(x, *args):
+def to_python_string(x: c_interop_string, *args: Any) -> str | None:
 return x.value
 
 
-def b(x):
+def b(x: str | bytes) -> bytes:
 if isinstance(x, bytes):
 return x
 return x.encode("utf8")
@@ -115,9 +148,7 @@ def b(x):
 # object. This is a problem, because it means that from_parameter will see an
 # integer and pass the wrong value on platforms where int != void*. Work around
 # this by marshalling object arguments as void**.
-c_object_p = POINTER(c_void_p)
-
-callbacks = {}
+c_object_p: TType[CObjP] = POINTER(c_void_p)
 
 ### Exception Classes ###
 
@@ -169,8 +200,11 @@ def __init__(self, enumeration, message):
 
 ### Structures and Utility Classes ###
 
+TInstance = TypeVar("TInstance")
+TResult = TypeVar("TResult")
+
 
-class CachedProperty:
+class CachedProperty(Generic[TInstance, TResult]):
 """Decorator that lazy-loads the value of a property.
 
 The first time the property is accessed, the original property function is
@@ -178,16 +212,20 @@ class CachedProperty:
 property, replacing the original method.
 """
 
-def __init__(self, wrapped):
+def __init__(self, wrapped: Callable[[TInstance], TResult]):
 self.wrapped = wrapped
 try:
 self.__doc__ = wrapped.__doc__
 except:
 pass
 
-def __get__(self, instance, instance_type=None):
+def __get__(self, instance: TInstance, instance_type: Any = None) -> 
TResult:
 if instance is None:
-return self
+property_name = self.wrapped.__name__
+class_name = instance_type.__name__
+raise TypeError(
+f"'{property_name}' is not a stat

[clang] [libclang/python] Export all enums (PR #100941)

2024-07-29 Thread Jannick Kremer via cfe-commits

DeinAlptraum wrote:

This may be my fault, I don't remember if I pulled main before branching for 
this PR, especially seeing how my last PR also had unrelated test failures

https://github.com/llvm/llvm-project/pull/100941
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Remove duplicate check in if-condition (PR #101070)

2024-07-29 Thread Jannick Kremer via cfe-commits

https://github.com/DeinAlptraum created 
https://github.com/llvm/llvm-project/pull/101070

Resolves #101041 

>From 521082f25bc42104fd436a412b2de2edb60b7b0e Mon Sep 17 00:00:00 2001
From: Jannick Kremer 
Date: Mon, 29 Jul 2024 20:24:15 +0100
Subject: [PATCH] [Clang][Sema] Remove duplicate check in if-condition

---
 clang/lib/Sema/SemaOpenMP.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 9c80b3eec914c..1d378e6b830ae 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -23087,8 +23087,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPDoacrossClause(
   if (DSAStack->getCurrentDirective() == OMPD_ordered &&
   DepType != OMPC_DOACROSS_source && DepType != OMPC_DOACROSS_sink &&
   DepType != OMPC_DOACROSS_sink_omp_cur_iteration &&
-  DepType != OMPC_DOACROSS_source_omp_cur_iteration &&
-  DepType != OMPC_DOACROSS_source) {
+  DepType != OMPC_DOACROSS_source_omp_cur_iteration) {
 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_doacross);
 return nullptr;

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


  1   2   3   4   5   >