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

Jannick Kremer via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 8 11:41:24 PDT 2024


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

>From 444d9480cf9629c81ae26636922af20db5bd52bf Mon Sep 17 00:00:00 2001
From: Jannick Kremer <jannick.kremer at mailbox.org>
Date: Sat, 3 Aug 2024 09:28:02 +0100
Subject: [PATCH 1/2] [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 c251c46a04adf..5fd7cc6481073 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 0000000000000..9f76848e89020
--- /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(
+            """aaaaa
+aaaaa
+aaaaa
+aaaaa"""
+        )
+
+        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 0ba52dc3a756b53fa6c62b6218625fc283107403 Mon Sep 17 00:00:00 2001
From: Jannick Kremer <jannick.kremer at mailbox.org>
Date: Wed, 7 Aug 2024 19:54:35 +0200
Subject: [PATCH 2/2] 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 5fd7cc6481073..162ed78660755 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
-        elif self.start.line == other.line:
-            # same file first line
-            if self.start.column <= other.column:
-                return True
-        elif other.line == self.end.line:
-            # same file last line
-            if other.column <= self.end.column:
-                return True
-        return False
+        return self.start <= other <= self.end
 
     def __repr__(self):
         return "<SourceRange start %r, end %r>" % (self.start, self.end)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 25f5bd37bbe94..c27f095792c4d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -303,6 +303,8 @@ Sanitizers
 Python Binding Changes
 ----------------------
 - Fixed an issue that led to crashes when calling ``Type.get_exception_specification_kind``.
+- Fixed a bug in ``SourceRange.__contains__`` that led to false positives
+  when the source range is only one line. 
 
 OpenMP Support
 --------------



More information about the cfe-commits mailing list