Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[libclang/python] Add python bindings for PrintingPolicy #120494

Merged
merged 4 commits into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions clang/bindings/python/clang/cindex.py
Original file line number Diff line number Diff line change
Expand Up @@ -1770,6 +1770,16 @@ def spelling(self):

return self._spelling

def pretty_printed(self, policy):
"""
Pretty print declarations.
Parameters:
policy -- The policy to control the entities being printed.
"""
return _CXString.from_result(
conf.lib.clang_getCursorPrettyPrinted(self, policy)
)

@property
def displayname(self):
"""
Expand Down Expand Up @@ -3699,6 +3709,72 @@ def write_main_file_to_stdout(self):
conf.lib.clang_CXRewriter_writeMainFileToStdOut(self)


class PrintingPolicyProperty(BaseEnumeration):

"""
A PrintingPolicyProperty identifies a property of a PrintingPolicy.
"""

Indentation = 0
SuppressSpecifiers = 1
SuppressTagKeyword = 2
IncludeTagDefinition = 3
SuppressScope = 4
SuppressUnwrittenScope = 5
SuppressInitializers = 6
ConstantArraySizeAsWritten = 7
AnonymousTagLocations = 8
SuppressStrongLifetime = 9
SuppressLifetimeQualifiers = 10
SuppressTemplateArgsInCXXConstructors = 11
Bool = 12
Restrict = 13
Alignof = 14
UnderscoreAlignof = 15
UseVoidForZeroParams = 16
TerseOutput = 17
PolishForDeclaration = 18
Half = 19
MSWChar = 20
IncludeNewlines = 21
MSVCFormatting = 22
ConstantsAsWritten = 23
SuppressImplicitBase = 24
FullyQualifiedName = 25


class PrintingPolicy(ClangObject):
"""
The PrintingPolicy is a wrapper class around clang::PrintingPolicy

It allows specifying how declarations, expressions, and types should be
pretty-printed.
"""

@staticmethod
def create(cursor):
"""
Creates a new PrintingPolicy
Parameters:
cursor -- Any cursor for a translation unit.
"""
return PrintingPolicy(conf.lib.clang_getCursorPrintingPolicy(cursor))

def __init__(self, ptr):
ClangObject.__init__(self, ptr)

def __del__(self):
conf.lib.clang_PrintingPolicy_dispose(self)

def get_property(self, property):
"""Get a property value for the given printing policy."""
return conf.lib.clang_PrintingPolicy_getProperty(self, property.value)

def set_property(self, property, value):
"""Set a property value for the given printing policy."""
conf.lib.clang_PrintingPolicy_setProperty(self, property.value, value)


# Now comes the plumbing to hook up the C library.

# Register callback types
Expand Down Expand Up @@ -3801,6 +3877,8 @@ def write_main_file_to_stdout(self):
("clang_getCursorExtent", [Cursor], SourceRange),
("clang_getCursorLexicalParent", [Cursor], Cursor),
("clang_getCursorLocation", [Cursor], SourceLocation),
("clang_getCursorPrettyPrinted", [Cursor, PrintingPolicy], _CXString),
("clang_getCursorPrintingPolicy", [Cursor], c_object_p),
("clang_getCursorReferenced", [Cursor], Cursor),
("clang_getCursorReferenceNameRange", [Cursor, c_uint, c_uint], SourceRange),
("clang_getCursorResultType", [Cursor], Type),
Expand Down Expand Up @@ -3924,6 +4002,9 @@ def write_main_file_to_stdout(self):
("clang_Cursor_isAnonymousRecordDecl", [Cursor], bool),
("clang_Cursor_isBitField", [Cursor], bool),
("clang_Location_isInSystemHeader", [SourceLocation], bool),
("clang_PrintingPolicy_dispose", [PrintingPolicy]),
("clang_PrintingPolicy_getProperty", [PrintingPolicy, c_int], c_uint),
("clang_PrintingPolicy_setProperty", [PrintingPolicy, c_int, c_uint]),
("clang_Type_getAlignOf", [Type], c_longlong),
("clang_Type_getClassType", [Type], Type),
("clang_Type_getNumTemplateArguments", [Type], c_int),
Expand Down Expand Up @@ -4104,6 +4185,8 @@ def function_exists(self, name: str) -> bool:
"FixIt",
"Index",
"LinkageKind",
"PrintingPolicy",
"PrintingPolicyProperty",
"RefQualifierKind",
"SourceLocation",
"SourceRange",
Expand Down
14 changes: 14 additions & 0 deletions clang/bindings/python/tests/cindex/test_cursor.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
BinaryOperator,
Config,
CursorKind,
PrintingPolicy,
PrintingPolicyProperty,
StorageClass,
TemplateArgumentKind,
TranslationUnit,
Expand Down Expand Up @@ -981,3 +983,15 @@ def test_from_result_null(self):
def test_from_cursor_result_null(self):
tu = get_tu("")
self.assertEqual(tu.cursor.semantic_parent, None)

def test_pretty_print(self):
tu = get_tu("struct X { int x; }; void f(bool x) { }", lang="cpp")
f = get_cursor(tu, "f")

self.assertEqual(f.displayname, "f(bool)")
pp = PrintingPolicy.create(f)
self.assertEqual(pp.get_property(PrintingPolicyProperty.Bool), True)
self.assertEqual(f.pretty_printed(pp), "void f(bool x) {\n}\n")
pp.set_property(PrintingPolicyProperty.Bool, False)
self.assertEqual(pp.get_property(PrintingPolicyProperty.Bool), False)
self.assertEqual(f.pretty_printed(pp), "void f(_Bool x) {\n}\n")
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1297,6 +1297,8 @@ Sanitizers
Python Binding Changes
----------------------
- Fixed an issue that led to crashes when calling ``Type.get_exception_specification_kind``.
- Added bindings for ``clang_getCursorPrettyPrinted`` and related functions,
which allow changing the formatting of pretty-printed code.
- Added binding for ``clang_Cursor_isAnonymousRecordDecl``, which allows checking if
a declaration is an anonymous union or anonymous struct.

Expand Down
Loading