[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-29 Thread Aaron Ballman via cfe-commits

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


[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-29 Thread Jimmy Z via cfe-commits

jimmy-zx wrote:

Ping. Can one of you press the merge button?

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


[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-27 Thread Craig Hesling via cfe-commits

linux4life798 wrote:

> @linux4life798 Can you review the last update?

This change LGTM (I don't actually have reviewer rights).

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


[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-27 Thread Craig Hesling via cfe-commits

linux4life798 wrote:

> Added flush before calling `writeMainFileToStdOut`.

I think that's reasonable.

> Personally I didn't find this function particularly useful: I was hoping to 
> perform rewriting without creating new files, but seems like capturing stdout 
> from a shared library requires some complex operation (`dup2` stuff).
> 
> `Rewriter::getRewrittenText()` might be a more interesting interface to 
> interact with, which returns the rewritten content as a string. (This is 
> defined in clang but not exposed by libclang yet).
> 
> https://github.com/llvm/llvm-project/blob/179ba129f50aefe6e670800aec7091d958aa6f90/clang/lib/Rewrite/Rewriter.cpp#L180

I agree. This should probably be exposed to libclang (and then to this python 
binding).

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


[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-24 Thread Vlad Serebrennikov via cfe-commits

Endilll wrote:

@linux4life798 Can you review the last update?

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


[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-23 Thread Jimmy Z via cfe-commits

jimmy-zx wrote:

Added flush before calling `writeMainFileToStdOut`.

Personally I didn't find this function particularly useful: I was hoping to 
perform rewriting without creating new files, but seems like capturing stdout 
from a shared library requires some complex operation (`dup2` stuff).

`Rewriter::getRewrittenText()` might be a more interesting interface to 
interact with, which returns the rewritten content as a string. (This is 
defined in clang but not exposed by libclang yet).

https://github.com/llvm/llvm-project/blob/179ba129f50aefe6e670800aec7091d958aa6f90/clang/lib/Rewrite/Rewriter.cpp#L180

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


[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-23 Thread Jimmy Z via cfe-commits

https://github.com/jimmy-zx updated 
https://github.com/llvm/llvm-project/pull/77269

>From a5379ca876d9531d48b37b9ad9c864db98c7dcd6 Mon Sep 17 00:00:00 2001
From: Jimmy Z <51149050+jimmy...@users.noreply.github.com>
Date: Mon, 8 Jan 2024 04:36:27 +
Subject: [PATCH 1/5] [libclang/python] Expose Rewriter to the python binding

---
 clang/bindings/python/clang/cindex.py | 62 +++
 .../python/tests/cindex/test_rewrite.py   | 75 +++
 2 files changed, 137 insertions(+)
 create mode 100644 clang/bindings/python/tests/cindex/test_rewrite.py

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index d780ee353a133cb..ced449180d98fca 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -3531,6 +3531,61 @@ def cursor(self):
 return cursor
 
 
+class Rewriter(ClangObject):
+"""
+The Rewriter is a wrapper class around clang::Rewriter
+
+It enables rewriting buffers.
+"""
+
+@staticmethod
+def create(tu):
+"""
+Creates a new Rewriter
+Parameters:
+tu -- The translation unit for the target AST.
+"""
+return Rewriter(conf.lib.clang_CXRewriter_create(tu))
+
+def __init__(self, ptr):
+ClangObject.__init__(self, ptr)
+
+def __del__(self):
+conf.lib.clang_CXRewriter_dispose(self)
+
+def insertTextBefore(self, loc, insert):
+"""
+Insert the specified string at the specified location in the original 
buffer.
+"""
+conf.lib.clang_CXRewriter_insertTextBefore(self, loc, insert)
+
+def replaceText(self, toBeReplaced, replacement):
+"""
+This method replaces a range of characters in the input buffer with a 
new string.
+"""
+conf.lib.clang_CXRewriter_replaceText(self, toBeReplaced, replacement)
+
+def removeText(self, toBeRemoved):
+"""
+Remove the specified text region.
+"""
+conf.lib.clang_CXRewriter_removeText(self, toBeRemoved)
+
+def overwriteChangedFiles(self):
+"""
+Save all changed files to disk.
+
+Returns 1 if any files were not saved successfully, returns 0 
otherwise.
+"""
+return conf.lib.clang_CXRewriter_overwriteChangedFiles(self)
+
+def writeMainFileToStdOut(self):
+"""
+Writes the main file to stdout.
+"""
+conf.lib.clang_CXRewriter_writeMainFileToStdOut(self)
+
+
 # Now comes the plumbing to hook up the C library.
 
 # Register callback types in common container.
@@ -3596,6 +3651,13 @@ def cursor(self):
 ("clang_codeCompleteGetNumDiagnostics", [CodeCompletionResults], c_int),
 ("clang_createIndex", [c_int, c_int], c_object_p),
 ("clang_createTranslationUnit", [Index, c_interop_string], c_object_p),
+("clang_CXRewriter_create", [TranslationUnit], c_object_p),
+("clang_CXRewriter_dispose", [Rewriter]),
+("clang_CXRewriter_insertTextBefore", [Rewriter, SourceLocation, 
c_interop_string]),
+("clang_CXRewriter_overwriteChangedFiles", [Rewriter], c_int),
+("clang_CXRewriter_removeText", [Rewriter, SourceRange]),
+("clang_CXRewriter_replaceText", [Rewriter, SourceRange, 
c_interop_string]),
+("clang_CXRewriter_writeMainFileToStdOut", [Rewriter]),
 ("clang_CXXConstructor_isConvertingConstructor", [Cursor], bool),
 ("clang_CXXConstructor_isCopyConstructor", [Cursor], bool),
 ("clang_CXXConstructor_isDefaultConstructor", [Cursor], bool),
diff --git a/clang/bindings/python/tests/cindex/test_rewrite.py 
b/clang/bindings/python/tests/cindex/test_rewrite.py
new file mode 100644
index 000..2c5f904ce50bdc7
--- /dev/null
+++ b/clang/bindings/python/tests/cindex/test_rewrite.py
@@ -0,0 +1,75 @@
+import sys
+import io
+import unittest
+import tempfile
+
+from clang.cindex import (
+Rewriter,
+TranslationUnit,
+Config,
+File,
+SourceLocation,
+SourceRange,
+)
+
+
+class TestRewrite(unittest.TestCase):
+code = """
+int test1;
+
+void test2(void);
+
+int f(int c) {
+return c;
+}
+"""
+
+def setUp(self):
+self.tmp = tempfile.NamedTemporaryFile(suffix=".cpp", buffering=0)
+self.tmp.write(TestRewrite.code.encode("utf-8"))
+self.tmp.flush()
+self.tu = TranslationUnit.from_source(self.tmp.name)
+self.rew = Rewriter.create(self.tu)
+self.file = File.from_name(self.tu, self.tmp.name)
+
+def tearDown(self):
+self.tmp.close()
+
+def test_insert(self):
+snip = "#include \n"
+
+beginning = SourceLocation.from_offset(self.tu, self.file, 0)
+self.rew.insertTextBefore(beginning, snip)
+self.rew.overwriteChangedFiles()
+
+with open(self.tmp.name, "r", encoding="utf-8") as f:
+self.assertEqual(f.read(), snip + TestRewrite.code)
+
+def test_replace(self):
+pattern = "test2"
+replacement = "func"
+
+

[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-22 Thread Vlad Serebrennikov via cfe-commits

Endilll wrote:

@linux4life798 Do you mind filing issues for the points you highlighted? Feel 
free to skip this step if you (or someone else) plan to submit PRs that address 
them.

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


[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-22 Thread Craig Hesling via cfe-commits

linux4life798 wrote:

I don't think this needs to block this change, but another concern I have about 
this API is that it is writing to stdout from C++ intermixed with Python 
writing to its own buffered stdout. This means that the user may see 
inconsistent output. This is somewhat a deficiency of [libclang Rewrite 
API](https://clang.llvm.org/doxygen/Rewrite_8h.html), since there is only one 
specific function to "write the main file out" and that is through stdout.

In an attempt to keep the world consistent, we may want to consider flushing 
the Python stdout buffer (`sys.stdout.flush()`) before calling 
`clang_CXRewriter_writeMainFileToStdOut`. I would hope that 
`clang_CXRewriter_writeMainFileToStdOut` flushes its own C++ stdout buffer 
after writing the file contents, but I honestly haven't looked at the code.

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


[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-22 Thread Craig Hesling via cfe-commits

linux4life798 wrote:

> @linux4life798 Nice catch! I see that so far only CompilationDatabase and 
> CompletionChunk expose functions in camelCase. It would be nice to change 
> them, too, but those are decade-old APIs that I think we promise stability 
> for, so it might not be possible.

Yep. Of course unrelated to this change, we might be able to add the snake_case 
equivalent binding and marking the old ones as depreciated.

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


[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-22 Thread Vlad Serebrennikov via cfe-commits

Endilll wrote:

@linux4life798 Nice catch! I see that so far only `CompilationDatabase` and 
`CompletionChunk` expose functions in camelCase. It would be nice to change 
them, too, but those are decade-old APIs that _I think_ we promise stability 
for, so it might not be possible.

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


[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-21 Thread Craig Hesling via cfe-commits

linux4life798 wrote:

Thanks!

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


[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-21 Thread Jimmy Z via cfe-commits

jimmy-zx wrote:

@linux4life798 Thanks for pointing out! I've updated the naming to conform 
snake_case.

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


[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-21 Thread Jimmy Z via cfe-commits

https://github.com/jimmy-zx updated 
https://github.com/llvm/llvm-project/pull/77269

>From a5379ca876d9531d48b37b9ad9c864db98c7dcd6 Mon Sep 17 00:00:00 2001
From: Jimmy Z <51149050+jimmy...@users.noreply.github.com>
Date: Mon, 8 Jan 2024 04:36:27 +
Subject: [PATCH 1/4] [libclang/python] Expose Rewriter to the python binding

---
 clang/bindings/python/clang/cindex.py | 62 +++
 .../python/tests/cindex/test_rewrite.py   | 75 +++
 2 files changed, 137 insertions(+)
 create mode 100644 clang/bindings/python/tests/cindex/test_rewrite.py

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index d780ee353a133cb..ced449180d98fca 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -3531,6 +3531,61 @@ def cursor(self):
 return cursor
 
 
+class Rewriter(ClangObject):
+"""
+The Rewriter is a wrapper class around clang::Rewriter
+
+It enables rewriting buffers.
+"""
+
+@staticmethod
+def create(tu):
+"""
+Creates a new Rewriter
+Parameters:
+tu -- The translation unit for the target AST.
+"""
+return Rewriter(conf.lib.clang_CXRewriter_create(tu))
+
+def __init__(self, ptr):
+ClangObject.__init__(self, ptr)
+
+def __del__(self):
+conf.lib.clang_CXRewriter_dispose(self)
+
+def insertTextBefore(self, loc, insert):
+"""
+Insert the specified string at the specified location in the original 
buffer.
+"""
+conf.lib.clang_CXRewriter_insertTextBefore(self, loc, insert)
+
+def replaceText(self, toBeReplaced, replacement):
+"""
+This method replaces a range of characters in the input buffer with a 
new string.
+"""
+conf.lib.clang_CXRewriter_replaceText(self, toBeReplaced, replacement)
+
+def removeText(self, toBeRemoved):
+"""
+Remove the specified text region.
+"""
+conf.lib.clang_CXRewriter_removeText(self, toBeRemoved)
+
+def overwriteChangedFiles(self):
+"""
+Save all changed files to disk.
+
+Returns 1 if any files were not saved successfully, returns 0 
otherwise.
+"""
+return conf.lib.clang_CXRewriter_overwriteChangedFiles(self)
+
+def writeMainFileToStdOut(self):
+"""
+Writes the main file to stdout.
+"""
+conf.lib.clang_CXRewriter_writeMainFileToStdOut(self)
+
+
 # Now comes the plumbing to hook up the C library.
 
 # Register callback types in common container.
@@ -3596,6 +3651,13 @@ def cursor(self):
 ("clang_codeCompleteGetNumDiagnostics", [CodeCompletionResults], c_int),
 ("clang_createIndex", [c_int, c_int], c_object_p),
 ("clang_createTranslationUnit", [Index, c_interop_string], c_object_p),
+("clang_CXRewriter_create", [TranslationUnit], c_object_p),
+("clang_CXRewriter_dispose", [Rewriter]),
+("clang_CXRewriter_insertTextBefore", [Rewriter, SourceLocation, 
c_interop_string]),
+("clang_CXRewriter_overwriteChangedFiles", [Rewriter], c_int),
+("clang_CXRewriter_removeText", [Rewriter, SourceRange]),
+("clang_CXRewriter_replaceText", [Rewriter, SourceRange, 
c_interop_string]),
+("clang_CXRewriter_writeMainFileToStdOut", [Rewriter]),
 ("clang_CXXConstructor_isConvertingConstructor", [Cursor], bool),
 ("clang_CXXConstructor_isCopyConstructor", [Cursor], bool),
 ("clang_CXXConstructor_isDefaultConstructor", [Cursor], bool),
diff --git a/clang/bindings/python/tests/cindex/test_rewrite.py 
b/clang/bindings/python/tests/cindex/test_rewrite.py
new file mode 100644
index 000..2c5f904ce50bdc7
--- /dev/null
+++ b/clang/bindings/python/tests/cindex/test_rewrite.py
@@ -0,0 +1,75 @@
+import sys
+import io
+import unittest
+import tempfile
+
+from clang.cindex import (
+Rewriter,
+TranslationUnit,
+Config,
+File,
+SourceLocation,
+SourceRange,
+)
+
+
+class TestRewrite(unittest.TestCase):
+code = """
+int test1;
+
+void test2(void);
+
+int f(int c) {
+return c;
+}
+"""
+
+def setUp(self):
+self.tmp = tempfile.NamedTemporaryFile(suffix=".cpp", buffering=0)
+self.tmp.write(TestRewrite.code.encode("utf-8"))
+self.tmp.flush()
+self.tu = TranslationUnit.from_source(self.tmp.name)
+self.rew = Rewriter.create(self.tu)
+self.file = File.from_name(self.tu, self.tmp.name)
+
+def tearDown(self):
+self.tmp.close()
+
+def test_insert(self):
+snip = "#include \n"
+
+beginning = SourceLocation.from_offset(self.tu, self.file, 0)
+self.rew.insertTextBefore(beginning, snip)
+self.rew.overwriteChangedFiles()
+
+with open(self.tmp.name, "r", encoding="utf-8") as f:
+self.assertEqual(f.read(), snip + TestRewrite.code)
+
+def test_replace(self):
+pattern = "test2"
+replacement = "func"
+
+

[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-21 Thread Craig Hesling via cfe-commits

linux4life798 wrote:

Hi all, sorry for jumping in late. Minor nit here.

It looks like this change is introducing camelCase methods, but the majority of 
the existing Python file uses snake_case, even though the underlying libclang 
interface is camelCase. For consistency, can we make these interface functions 
snake_case or is there some overriding style guide that wants camelCase?

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


[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-21 Thread Jimmy Z via cfe-commits

jimmy-zx wrote:

Just updated the description a bit and I believe it's all set for merging.

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


[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-21 Thread Jimmy Z via cfe-commits

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


[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-21 Thread Vlad Serebrennikov via cfe-commits

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

LGTM
PR description is going to become a commit message after merging. Let me know 
when it's ready.

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


[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-21 Thread Jimmy Z via cfe-commits

jimmy-zx wrote:

Both tests are just invoking the functionalities of the rewriter on a sample 
code. I think additional tests for libclang does not provide extra coverage (as 
it is just the front-end). Thus I mirrored the tests back to the Python binding 
in 7a4ebf9c8c9ffa29d7f7f863d9a19bfe53432348.

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


[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-21 Thread Vlad Serebrennikov via cfe-commits

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


[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-21 Thread Vlad Serebrennikov via cfe-commits

Endilll wrote:

> I have reviewed the tests for libclang and it appears that there are already 
> tests for the rewriter, which are more extensive than the ones I wrote. 
> Therefore, I have decided to mirror the tests from libclang in the Python 
> binding. Please let me know if this approach is appropriate.

If you think that existing tests fully cover yours, then it's appropriate. 
Otherwise, we'd benefit from additional test coverage, but it's not necessarily 
in the scope of this PR.

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


[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-20 Thread Jimmy Z via cfe-commits

jimmy-zx wrote:

> Looks good overall. It's good that you wrote your own tests, but it would 
> also be nice to mirror tests in `clang/unittests/libclang/LibclangTest.cpp` 
> which test the same API. This way we can identify issues in binding layer 
> itself (when C++ tests pass, but Python tests don't, or vise versa,)

I have reviewed the tests for libclang and it appears that there are already 
tests for the rewriter, which are more extensive than the ones I wrote. 
Therefore, I have decided to mirror the tests from libclang in the Python 
binding. Please let me know if this approach is appropriate.

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


[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-20 Thread Jimmy Z via cfe-commits

https://github.com/jimmy-zx updated 
https://github.com/llvm/llvm-project/pull/77269

>From a5379ca876d9531d48b37b9ad9c864db98c7dcd6 Mon Sep 17 00:00:00 2001
From: Jimmy Z <51149050+jimmy...@users.noreply.github.com>
Date: Mon, 8 Jan 2024 04:36:27 +
Subject: [PATCH 1/3] [libclang/python] Expose Rewriter to the python binding

---
 clang/bindings/python/clang/cindex.py | 62 +++
 .../python/tests/cindex/test_rewrite.py   | 75 +++
 2 files changed, 137 insertions(+)
 create mode 100644 clang/bindings/python/tests/cindex/test_rewrite.py

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index d780ee353a133c..ced449180d98fc 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -3531,6 +3531,61 @@ def cursor(self):
 return cursor
 
 
+class Rewriter(ClangObject):
+"""
+The Rewriter is a wrapper class around clang::Rewriter
+
+It enables rewriting buffers.
+"""
+
+@staticmethod
+def create(tu):
+"""
+Creates a new Rewriter
+Parameters:
+tu -- The translation unit for the target AST.
+"""
+return Rewriter(conf.lib.clang_CXRewriter_create(tu))
+
+def __init__(self, ptr):
+ClangObject.__init__(self, ptr)
+
+def __del__(self):
+conf.lib.clang_CXRewriter_dispose(self)
+
+def insertTextBefore(self, loc, insert):
+"""
+Insert the specified string at the specified location in the original 
buffer.
+"""
+conf.lib.clang_CXRewriter_insertTextBefore(self, loc, insert)
+
+def replaceText(self, toBeReplaced, replacement):
+"""
+This method replaces a range of characters in the input buffer with a 
new string.
+"""
+conf.lib.clang_CXRewriter_replaceText(self, toBeReplaced, replacement)
+
+def removeText(self, toBeRemoved):
+"""
+Remove the specified text region.
+"""
+conf.lib.clang_CXRewriter_removeText(self, toBeRemoved)
+
+def overwriteChangedFiles(self):
+"""
+Save all changed files to disk.
+
+Returns 1 if any files were not saved successfully, returns 0 
otherwise.
+"""
+return conf.lib.clang_CXRewriter_overwriteChangedFiles(self)
+
+def writeMainFileToStdOut(self):
+"""
+Writes the main file to stdout.
+"""
+conf.lib.clang_CXRewriter_writeMainFileToStdOut(self)
+
+
 # Now comes the plumbing to hook up the C library.
 
 # Register callback types in common container.
@@ -3596,6 +3651,13 @@ def cursor(self):
 ("clang_codeCompleteGetNumDiagnostics", [CodeCompletionResults], c_int),
 ("clang_createIndex", [c_int, c_int], c_object_p),
 ("clang_createTranslationUnit", [Index, c_interop_string], c_object_p),
+("clang_CXRewriter_create", [TranslationUnit], c_object_p),
+("clang_CXRewriter_dispose", [Rewriter]),
+("clang_CXRewriter_insertTextBefore", [Rewriter, SourceLocation, 
c_interop_string]),
+("clang_CXRewriter_overwriteChangedFiles", [Rewriter], c_int),
+("clang_CXRewriter_removeText", [Rewriter, SourceRange]),
+("clang_CXRewriter_replaceText", [Rewriter, SourceRange, 
c_interop_string]),
+("clang_CXRewriter_writeMainFileToStdOut", [Rewriter]),
 ("clang_CXXConstructor_isConvertingConstructor", [Cursor], bool),
 ("clang_CXXConstructor_isCopyConstructor", [Cursor], bool),
 ("clang_CXXConstructor_isDefaultConstructor", [Cursor], bool),
diff --git a/clang/bindings/python/tests/cindex/test_rewrite.py 
b/clang/bindings/python/tests/cindex/test_rewrite.py
new file mode 100644
index 00..2c5f904ce50bdc
--- /dev/null
+++ b/clang/bindings/python/tests/cindex/test_rewrite.py
@@ -0,0 +1,75 @@
+import sys
+import io
+import unittest
+import tempfile
+
+from clang.cindex import (
+Rewriter,
+TranslationUnit,
+Config,
+File,
+SourceLocation,
+SourceRange,
+)
+
+
+class TestRewrite(unittest.TestCase):
+code = """
+int test1;
+
+void test2(void);
+
+int f(int c) {
+return c;
+}
+"""
+
+def setUp(self):
+self.tmp = tempfile.NamedTemporaryFile(suffix=".cpp", buffering=0)
+self.tmp.write(TestRewrite.code.encode("utf-8"))
+self.tmp.flush()
+self.tu = TranslationUnit.from_source(self.tmp.name)
+self.rew = Rewriter.create(self.tu)
+self.file = File.from_name(self.tu, self.tmp.name)
+
+def tearDown(self):
+self.tmp.close()
+
+def test_insert(self):
+snip = "#include \n"
+
+beginning = SourceLocation.from_offset(self.tu, self.file, 0)
+self.rew.insertTextBefore(beginning, snip)
+self.rew.overwriteChangedFiles()
+
+with open(self.tmp.name, "r", encoding="utf-8") as f:
+self.assertEqual(f.read(), snip + TestRewrite.code)
+
+def test_replace(self):
+pattern = "test2"
+replacement = "func"
+
+

[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-17 Thread Vlad Serebrennikov via cfe-commits

https://github.com/Endilll commented:

Looks good overall.
It's good that you wrote your own tests, but it would also be nice to mirror 
tests in `clang/unittests/libclang/LibclangTest.cpp` which test the same API. 
This way we can identify issues in binding layer itself (when C++ tests pass, 
but Python tests don't, or vise versa,)

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


[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-17 Thread Jimmy Z via cfe-commits

https://github.com/jimmy-zx updated 
https://github.com/llvm/llvm-project/pull/77269

>From a5379ca876d9531d48b37b9ad9c864db98c7dcd6 Mon Sep 17 00:00:00 2001
From: Jimmy Z <51149050+jimmy...@users.noreply.github.com>
Date: Mon, 8 Jan 2024 04:36:27 +
Subject: [PATCH 1/2] [libclang/python] Expose Rewriter to the python binding

---
 clang/bindings/python/clang/cindex.py | 62 +++
 .../python/tests/cindex/test_rewrite.py   | 75 +++
 2 files changed, 137 insertions(+)
 create mode 100644 clang/bindings/python/tests/cindex/test_rewrite.py

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index d780ee353a133cb..ced449180d98fca 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -3531,6 +3531,61 @@ def cursor(self):
 return cursor
 
 
+class Rewriter(ClangObject):
+"""
+The Rewriter is a wrapper class around clang::Rewriter
+
+It enables rewriting buffers.
+"""
+
+@staticmethod
+def create(tu):
+"""
+Creates a new Rewriter
+Parameters:
+tu -- The translation unit for the target AST.
+"""
+return Rewriter(conf.lib.clang_CXRewriter_create(tu))
+
+def __init__(self, ptr):
+ClangObject.__init__(self, ptr)
+
+def __del__(self):
+conf.lib.clang_CXRewriter_dispose(self)
+
+def insertTextBefore(self, loc, insert):
+"""
+Insert the specified string at the specified location in the original 
buffer.
+"""
+conf.lib.clang_CXRewriter_insertTextBefore(self, loc, insert)
+
+def replaceText(self, toBeReplaced, replacement):
+"""
+This method replaces a range of characters in the input buffer with a 
new string.
+"""
+conf.lib.clang_CXRewriter_replaceText(self, toBeReplaced, replacement)
+
+def removeText(self, toBeRemoved):
+"""
+Remove the specified text region.
+"""
+conf.lib.clang_CXRewriter_removeText(self, toBeRemoved)
+
+def overwriteChangedFiles(self):
+"""
+Save all changed files to disk.
+
+Returns 1 if any files were not saved successfully, returns 0 
otherwise.
+"""
+return conf.lib.clang_CXRewriter_overwriteChangedFiles(self)
+
+def writeMainFileToStdOut(self):
+"""
+Writes the main file to stdout.
+"""
+conf.lib.clang_CXRewriter_writeMainFileToStdOut(self)
+
+
 # Now comes the plumbing to hook up the C library.
 
 # Register callback types in common container.
@@ -3596,6 +3651,13 @@ def cursor(self):
 ("clang_codeCompleteGetNumDiagnostics", [CodeCompletionResults], c_int),
 ("clang_createIndex", [c_int, c_int], c_object_p),
 ("clang_createTranslationUnit", [Index, c_interop_string], c_object_p),
+("clang_CXRewriter_create", [TranslationUnit], c_object_p),
+("clang_CXRewriter_dispose", [Rewriter]),
+("clang_CXRewriter_insertTextBefore", [Rewriter, SourceLocation, 
c_interop_string]),
+("clang_CXRewriter_overwriteChangedFiles", [Rewriter], c_int),
+("clang_CXRewriter_removeText", [Rewriter, SourceRange]),
+("clang_CXRewriter_replaceText", [Rewriter, SourceRange, 
c_interop_string]),
+("clang_CXRewriter_writeMainFileToStdOut", [Rewriter]),
 ("clang_CXXConstructor_isConvertingConstructor", [Cursor], bool),
 ("clang_CXXConstructor_isCopyConstructor", [Cursor], bool),
 ("clang_CXXConstructor_isDefaultConstructor", [Cursor], bool),
diff --git a/clang/bindings/python/tests/cindex/test_rewrite.py 
b/clang/bindings/python/tests/cindex/test_rewrite.py
new file mode 100644
index 000..2c5f904ce50bdc7
--- /dev/null
+++ b/clang/bindings/python/tests/cindex/test_rewrite.py
@@ -0,0 +1,75 @@
+import sys
+import io
+import unittest
+import tempfile
+
+from clang.cindex import (
+Rewriter,
+TranslationUnit,
+Config,
+File,
+SourceLocation,
+SourceRange,
+)
+
+
+class TestRewrite(unittest.TestCase):
+code = """
+int test1;
+
+void test2(void);
+
+int f(int c) {
+return c;
+}
+"""
+
+def setUp(self):
+self.tmp = tempfile.NamedTemporaryFile(suffix=".cpp", buffering=0)
+self.tmp.write(TestRewrite.code.encode("utf-8"))
+self.tmp.flush()
+self.tu = TranslationUnit.from_source(self.tmp.name)
+self.rew = Rewriter.create(self.tu)
+self.file = File.from_name(self.tu, self.tmp.name)
+
+def tearDown(self):
+self.tmp.close()
+
+def test_insert(self):
+snip = "#include \n"
+
+beginning = SourceLocation.from_offset(self.tu, self.file, 0)
+self.rew.insertTextBefore(beginning, snip)
+self.rew.overwriteChangedFiles()
+
+with open(self.tmp.name, "r", encoding="utf-8") as f:
+self.assertEqual(f.read(), snip + TestRewrite.code)
+
+def test_replace(self):
+pattern = "test2"
+replacement = "func"
+
+

[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-16 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman commented:

The changes look reasonable to me as far as they go, but I don't have much 
expertise in Python. I added @Endilll to hopefully help give it a second set of 
eyes.

You should add a release note (clang/docs/ReleaseNotes.rst) about the new 
bindings so others know that they've been improved.

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


[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-09 Thread Jimmy Z via cfe-commits

jimmy-zx wrote:

Pinging @AaronBallman and @jyknight for review. (sorry if I chose the wrong 
people)

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


[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-07 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Jimmy Z (jimmy-zx)


Changes

Exposes `CXRewriter` API to the python binding as in 
https://github.com/llvm/llvm-project/commit/69e5abb57b70570cf04671a93246e5e624023650.

---
Full diff: https://github.com/llvm/llvm-project/pull/77269.diff


2 Files Affected:

- (modified) clang/bindings/python/clang/cindex.py (+62) 
- (added) clang/bindings/python/tests/cindex/test_rewrite.py (+75) 


``diff
diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index d780ee353a133c..ced449180d98fc 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -3531,6 +3531,61 @@ def cursor(self):
 return cursor
 
 
+class Rewriter(ClangObject):
+"""
+The Rewriter is a wrapper class around clang::Rewriter
+
+It enables rewriting buffers.
+"""
+
+@staticmethod
+def create(tu):
+"""
+Creates a new Rewriter
+Parameters:
+tu -- The translation unit for the target AST.
+"""
+return Rewriter(conf.lib.clang_CXRewriter_create(tu))
+
+def __init__(self, ptr):
+ClangObject.__init__(self, ptr)
+
+def __del__(self):
+conf.lib.clang_CXRewriter_dispose(self)
+
+def insertTextBefore(self, loc, insert):
+"""
+Insert the specified string at the specified location in the original 
buffer.
+"""
+conf.lib.clang_CXRewriter_insertTextBefore(self, loc, insert)
+
+def replaceText(self, toBeReplaced, replacement):
+"""
+This method replaces a range of characters in the input buffer with a 
new string.
+"""
+conf.lib.clang_CXRewriter_replaceText(self, toBeReplaced, replacement)
+
+def removeText(self, toBeRemoved):
+"""
+Remove the specified text region.
+"""
+conf.lib.clang_CXRewriter_removeText(self, toBeRemoved)
+
+def overwriteChangedFiles(self):
+"""
+Save all changed files to disk.
+
+Returns 1 if any files were not saved successfully, returns 0 
otherwise.
+"""
+return conf.lib.clang_CXRewriter_overwriteChangedFiles(self)
+
+def writeMainFileToStdOut(self):
+"""
+Writes the main file to stdout.
+"""
+conf.lib.clang_CXRewriter_writeMainFileToStdOut(self)
+
+
 # Now comes the plumbing to hook up the C library.
 
 # Register callback types in common container.
@@ -3596,6 +3651,13 @@ def cursor(self):
 ("clang_codeCompleteGetNumDiagnostics", [CodeCompletionResults], c_int),
 ("clang_createIndex", [c_int, c_int], c_object_p),
 ("clang_createTranslationUnit", [Index, c_interop_string], c_object_p),
+("clang_CXRewriter_create", [TranslationUnit], c_object_p),
+("clang_CXRewriter_dispose", [Rewriter]),
+("clang_CXRewriter_insertTextBefore", [Rewriter, SourceLocation, 
c_interop_string]),
+("clang_CXRewriter_overwriteChangedFiles", [Rewriter], c_int),
+("clang_CXRewriter_removeText", [Rewriter, SourceRange]),
+("clang_CXRewriter_replaceText", [Rewriter, SourceRange, 
c_interop_string]),
+("clang_CXRewriter_writeMainFileToStdOut", [Rewriter]),
 ("clang_CXXConstructor_isConvertingConstructor", [Cursor], bool),
 ("clang_CXXConstructor_isCopyConstructor", [Cursor], bool),
 ("clang_CXXConstructor_isDefaultConstructor", [Cursor], bool),
diff --git a/clang/bindings/python/tests/cindex/test_rewrite.py 
b/clang/bindings/python/tests/cindex/test_rewrite.py
new file mode 100644
index 00..2c5f904ce50bdc
--- /dev/null
+++ b/clang/bindings/python/tests/cindex/test_rewrite.py
@@ -0,0 +1,75 @@
+import sys
+import io
+import unittest
+import tempfile
+
+from clang.cindex import (
+Rewriter,
+TranslationUnit,
+Config,
+File,
+SourceLocation,
+SourceRange,
+)
+
+
+class TestRewrite(unittest.TestCase):
+code = """
+int test1;
+
+void test2(void);
+
+int f(int c) {
+return c;
+}
+"""
+
+def setUp(self):
+self.tmp = tempfile.NamedTemporaryFile(suffix=".cpp", buffering=0)
+self.tmp.write(TestRewrite.code.encode("utf-8"))
+self.tmp.flush()
+self.tu = TranslationUnit.from_source(self.tmp.name)
+self.rew = Rewriter.create(self.tu)
+self.file = File.from_name(self.tu, self.tmp.name)
+
+def tearDown(self):
+self.tmp.close()
+
+def test_insert(self):
+snip = "#include \n"
+
+beginning = SourceLocation.from_offset(self.tu, self.file, 0)
+self.rew.insertTextBefore(beginning, snip)
+self.rew.overwriteChangedFiles()
+
+with open(self.tmp.name, "r", encoding="utf-8") as f:
+self.assertEqual(f.read(), snip + TestRewrite.code)
+
+def test_replace(self):
+pattern = "test2"
+replacement = "func"
+
+offset = TestRewrite.code.find(pattern)
+pattern_range = SourceRange.from_locations(
+

[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-07 Thread via cfe-commits

github-actions[bot] wrote:

Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be
notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this 
page.

If this is not working for you, it is probably because you do not have write
permissions for the repository. In which case you can instead tag reviewers by
name in a comment by using `@` followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review
by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate
is once a week. Please remember that you are asking for valuable time from 
other developers.

If you have further questions, they may be answered by the [LLVM GitHub User 
Guide](https://llvm.org/docs/GitHub.html).

You can also ask questions in a comment on this PR, on the [LLVM 
Discord](https://discord.com/invite/xS7Z362) or on the 
[forums](https://discourse.llvm.org/).

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


[clang] [libclang/python] Expose Rewriter to the python binding (PR #77269)

2024-01-07 Thread Jimmy Z via cfe-commits

https://github.com/jimmy-zx created 
https://github.com/llvm/llvm-project/pull/77269

Exposes `CXRewriter` API to the python binding as in 
https://github.com/llvm/llvm-project/commit/69e5abb57b70570cf04671a93246e5e624023650.

>From a5379ca876d9531d48b37b9ad9c864db98c7dcd6 Mon Sep 17 00:00:00 2001
From: Jimmy Z <51149050+jimmy...@users.noreply.github.com>
Date: Mon, 8 Jan 2024 04:36:27 +
Subject: [PATCH] [libclang/python] Expose Rewriter to the python binding

---
 clang/bindings/python/clang/cindex.py | 62 +++
 .../python/tests/cindex/test_rewrite.py   | 75 +++
 2 files changed, 137 insertions(+)
 create mode 100644 clang/bindings/python/tests/cindex/test_rewrite.py

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index d780ee353a133c..ced449180d98fc 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -3531,6 +3531,61 @@ def cursor(self):
 return cursor
 
 
+class Rewriter(ClangObject):
+"""
+The Rewriter is a wrapper class around clang::Rewriter
+
+It enables rewriting buffers.
+"""
+
+@staticmethod
+def create(tu):
+"""
+Creates a new Rewriter
+Parameters:
+tu -- The translation unit for the target AST.
+"""
+return Rewriter(conf.lib.clang_CXRewriter_create(tu))
+
+def __init__(self, ptr):
+ClangObject.__init__(self, ptr)
+
+def __del__(self):
+conf.lib.clang_CXRewriter_dispose(self)
+
+def insertTextBefore(self, loc, insert):
+"""
+Insert the specified string at the specified location in the original 
buffer.
+"""
+conf.lib.clang_CXRewriter_insertTextBefore(self, loc, insert)
+
+def replaceText(self, toBeReplaced, replacement):
+"""
+This method replaces a range of characters in the input buffer with a 
new string.
+"""
+conf.lib.clang_CXRewriter_replaceText(self, toBeReplaced, replacement)
+
+def removeText(self, toBeRemoved):
+"""
+Remove the specified text region.
+"""
+conf.lib.clang_CXRewriter_removeText(self, toBeRemoved)
+
+def overwriteChangedFiles(self):
+"""
+Save all changed files to disk.
+
+Returns 1 if any files were not saved successfully, returns 0 
otherwise.
+"""
+return conf.lib.clang_CXRewriter_overwriteChangedFiles(self)
+
+def writeMainFileToStdOut(self):
+"""
+Writes the main file to stdout.
+"""
+conf.lib.clang_CXRewriter_writeMainFileToStdOut(self)
+
+
 # Now comes the plumbing to hook up the C library.
 
 # Register callback types in common container.
@@ -3596,6 +3651,13 @@ def cursor(self):
 ("clang_codeCompleteGetNumDiagnostics", [CodeCompletionResults], c_int),
 ("clang_createIndex", [c_int, c_int], c_object_p),
 ("clang_createTranslationUnit", [Index, c_interop_string], c_object_p),
+("clang_CXRewriter_create", [TranslationUnit], c_object_p),
+("clang_CXRewriter_dispose", [Rewriter]),
+("clang_CXRewriter_insertTextBefore", [Rewriter, SourceLocation, 
c_interop_string]),
+("clang_CXRewriter_overwriteChangedFiles", [Rewriter], c_int),
+("clang_CXRewriter_removeText", [Rewriter, SourceRange]),
+("clang_CXRewriter_replaceText", [Rewriter, SourceRange, 
c_interop_string]),
+("clang_CXRewriter_writeMainFileToStdOut", [Rewriter]),
 ("clang_CXXConstructor_isConvertingConstructor", [Cursor], bool),
 ("clang_CXXConstructor_isCopyConstructor", [Cursor], bool),
 ("clang_CXXConstructor_isDefaultConstructor", [Cursor], bool),
diff --git a/clang/bindings/python/tests/cindex/test_rewrite.py 
b/clang/bindings/python/tests/cindex/test_rewrite.py
new file mode 100644
index 00..2c5f904ce50bdc
--- /dev/null
+++ b/clang/bindings/python/tests/cindex/test_rewrite.py
@@ -0,0 +1,75 @@
+import sys
+import io
+import unittest
+import tempfile
+
+from clang.cindex import (
+Rewriter,
+TranslationUnit,
+Config,
+File,
+SourceLocation,
+SourceRange,
+)
+
+
+class TestRewrite(unittest.TestCase):
+code = """
+int test1;
+
+void test2(void);
+
+int f(int c) {
+return c;
+}
+"""
+
+def setUp(self):
+self.tmp = tempfile.NamedTemporaryFile(suffix=".cpp", buffering=0)
+self.tmp.write(TestRewrite.code.encode("utf-8"))
+self.tmp.flush()
+self.tu = TranslationUnit.from_source(self.tmp.name)
+self.rew = Rewriter.create(self.tu)
+self.file = File.from_name(self.tu, self.tmp.name)
+
+def tearDown(self):
+self.tmp.close()
+
+def test_insert(self):
+snip = "#include \n"
+
+beginning = SourceLocation.from_offset(self.tu, self.file, 0)
+self.rew.insertTextBefore(beginning, snip)
+self.rew.overwriteChangedFiles()
+
+with open(self.tmp.name, "r", encoding="utf-8") as f:
+