https://github.com/jimmy-zx updated https://github.com/llvm/llvm-project/pull/71341
>From 887751e365ca72515679f61d0734b1631ac38335 Mon Sep 17 00:00:00 2001 From: Jimmy Z <51149050+jimmy...@users.noreply.github.com> Date: Mon, 6 Nov 2023 00:25:39 +0000 Subject: [PATCH 1/3] [libclang/python] Expose Rewriter to the libclang python binding. --- clang/bindings/python/clang/cindex.py | 62 ++++++++++++++++ .../python/tests/cindex/test_rewrite.py | 74 +++++++++++++++++++ 2 files changed, 136 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 6a16f3a9ef6e957..e51d558ab73fbce 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. + """ + 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 000000000000000..eb697f72a923030 --- /dev/null +++ b/clang/bindings/python/tests/cindex/test_rewrite.py @@ -0,0 +1,74 @@ +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; +} +''' + + @classmethod + def setUpClass(cls): + Config.set_compatibility_check(False) + + 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 <cstdio>\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( + SourceLocation.from_offset(self.tu, self.file, offset), + SourceLocation.from_offset(self.tu, self.file, offset + len(pattern)) + ) + self.rew.replaceText(pattern_range, replacement) + self.rew.overwriteChangedFiles() + + with open(self.tmp.name, 'r', encoding='utf-8') as f: + self.assertEqual(f.read(), TestRewrite.code.replace(pattern, replacement)) + + + def test_remove(self): + pattern = 'int c' + + offset = TestRewrite.code.find(pattern) + pattern_range = SourceRange.from_locations( + SourceLocation.from_offset(self.tu, self.file, offset), + SourceLocation.from_offset(self.tu, self.file, offset + len(pattern)) + ) + self.rew.removeText(pattern_range) + self.rew.overwriteChangedFiles() + + with open(self.tmp.name, 'r', encoding='utf-8') as f: + self.assertEqual(f.read(), TestRewrite.code.replace(pattern, '')) >From 27cb50dce8496d24b76cd982eb812f51dbe72af5 Mon Sep 17 00:00:00 2001 From: Jimmy Z <51149050+jimmy...@users.noreply.github.com> Date: Mon, 6 Nov 2023 00:31:03 +0000 Subject: [PATCH 2/3] removed setup for compatability check --- clang/bindings/python/tests/cindex/test_rewrite.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/clang/bindings/python/tests/cindex/test_rewrite.py b/clang/bindings/python/tests/cindex/test_rewrite.py index eb697f72a923030..8c0e6ce9a811c10 100644 --- a/clang/bindings/python/tests/cindex/test_rewrite.py +++ b/clang/bindings/python/tests/cindex/test_rewrite.py @@ -16,10 +16,6 @@ class TestRewrite(unittest.TestCase): } ''' - @classmethod - def setUpClass(cls): - Config.set_compatibility_check(False) - def setUp(self): self.tmp = tempfile.NamedTemporaryFile(suffix='.cpp', buffering=0) self.tmp.write(TestRewrite.code.encode('utf-8')) >From cdc4eb10cb5ef5738b9f13cb1e3d4ece5c30bc26 Mon Sep 17 00:00:00 2001 From: Jimmy Z <51149050+jimmy...@users.noreply.github.com> Date: Mon, 6 Nov 2023 00:44:09 +0000 Subject: [PATCH 3/3] fix formatting --- clang/bindings/python/clang/cindex.py | 2 -- clang/bindings/python/tests/cindex/test_rewrite.py | 5 ++++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py index e51d558ab73fbce..8695cf61cb8bb03 100644 --- a/clang/bindings/python/clang/cindex.py +++ b/clang/bindings/python/clang/cindex.py @@ -3584,8 +3584,6 @@ def writeMainFileToStdOut(self): conf.lib.clang_CXRewriter_writeMainFileToStdOut(self) - - # Now comes the plumbing to hook up the C library. # Register callback types in common container. diff --git a/clang/bindings/python/tests/cindex/test_rewrite.py b/clang/bindings/python/tests/cindex/test_rewrite.py index 8c0e6ce9a811c10..eff200c1a9bdd76 100644 --- a/clang/bindings/python/tests/cindex/test_rewrite.py +++ b/clang/bindings/python/tests/cindex/test_rewrite.py @@ -3,7 +3,10 @@ import unittest import tempfile -from clang.cindex import Rewriter, TranslationUnit, Config, File, SourceLocation, SourceRange +from clang.cindex import ( + Rewriter, TranslationUnit, Config, File, SourceLocation, SourceRange + ) + class TestRewrite(unittest.TestCase): code = ''' _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits