aboutsummaryrefslogtreecommitdiffstats
path: root/tools/qtpy2cpp_lib/visitor.py
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2022-05-27 15:08:45 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2022-06-01 16:17:41 +0200
commit869ae24b2da002a3a02e7d2bbecef42d08772be8 (patch)
treeb6d928cde24b3b530a8b1a53a4b668d0dc325bac /tools/qtpy2cpp_lib/visitor.py
parent4a229aca8f8347c470f174f1290731175584b8c4 (diff)
qtpy2cpp: Improve construction of Qt classes
Check if a variable assignment is likely a construction of a Qt class. Add some smartness there, construct some classes on stack and add "new" for the others. Store stack variables per function scope in a list for future use. Task-number: PYSIDE-1945 Pick-to: 6.3 Change-Id: Id71d1a8c14e57f3bfaf32fc202b260d390589382 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Diffstat (limited to 'tools/qtpy2cpp_lib/visitor.py')
-rw-r--r--tools/qtpy2cpp_lib/visitor.py49
1 files changed, 47 insertions, 2 deletions
diff --git a/tools/qtpy2cpp_lib/visitor.py b/tools/qtpy2cpp_lib/visitor.py
index f2274daed..c120a4fb9 100644
--- a/tools/qtpy2cpp_lib/visitor.py
+++ b/tools/qtpy2cpp_lib/visitor.py
@@ -14,6 +14,26 @@ from .formatter import (CppFormatter, format_for_loop, format_literal,
from .nodedump import debug_format_node
+_QT_STACK_CLASSES = ["QApplication", "QColorDialog", "QCoreApplication",
+ "QFile", "QFileDialog", "QFileInfo", "QFontDialog",
+ "QGuiApplication", "QIcon", "QLine", "QLineF",
+ "QMessageBox", "QPainter", "QPixmap", "QPoint", "QPointF",
+ "QQmlApplicationEngine", "QQmlComponent", "QQmlEngine",
+ "QQuickView", "QRect", "QRectF", "QSaveFile", "QSettings",
+ "QSize", "QSizeF", "QTextStream"]
+
+
+def _is_qt_constructor(assign_node):
+ """Is this assignment node a plain construction of a Qt class?
+ 'f = QFile(name)'. Returns the class_name."""
+ call = assign_node.value
+ if (isinstance(call, ast.Call) and isinstance(call.func, ast.Name)):
+ func = call.func.id
+ if func.startswith("Q"):
+ return func
+ return None
+
+
class ConvertVisitor(ast.NodeVisitor, CppFormatter):
"""AST visitor printing out C++
Note on implementation:
@@ -33,6 +53,7 @@ class ConvertVisitor(ast.NodeVisitor, CppFormatter):
self._file_name = file_name
self._class_scope = [] # List of class names
self._stack = [] # nodes
+ self._stack_variables = [] # variables instantiated on stack
self._debug_indent = 0
@staticmethod
@@ -66,6 +87,24 @@ class ConvertVisitor(ast.NodeVisitor, CppFormatter):
def visit_Assign(self, node):
self.INDENT()
+
+ qt_class = _is_qt_constructor(node)
+ on_stack = qt_class and qt_class in _QT_STACK_CLASSES
+
+ # Is this a free variable and not a member assignment? Instantiate
+ # on stack or give a type
+ if len(node.targets) == 1 and isinstance(node.targets[0], ast.Name):
+ if qt_class:
+ if on_stack:
+ # "QFile f(args)"
+ var = node.targets[0].id
+ self._stack_variables.append(var)
+ self._output_file.write(f"{qt_class} {var}(")
+ self._write_function_args(node.value.args)
+ self._output_file.write(");\n")
+ return
+ self._output_file.write("auto *")
+
line_no = node.lineno if hasattr(node, 'lineno') else -1
for target in node.targets:
if isinstance(target, ast.Tuple):
@@ -77,6 +116,8 @@ class ConvertVisitor(ast.NodeVisitor, CppFormatter):
else:
self._output_file.write(format_reference(target))
self._output_file.write(' = ')
+ if qt_class and not on_stack:
+ self._output_file.write("new ")
self.visit(node.value)
self._output_file.write(';\n')
@@ -101,12 +142,15 @@ class ConvertVisitor(ast.NodeVisitor, CppFormatter):
def visit_Call(self, node):
self._output_file.write(format_start_function_call(node))
+ self._write_function_args(node.args)
+ self._output_file.write(')')
+
+ def _write_function_args(self, args_node):
# Manually do visit(), skip the children of func
- for i, arg in enumerate(node.args):
+ for i, arg in enumerate(args_node):
if i > 0:
self._output_file.write(', ')
self.visit(arg)
- self._output_file.write(')')
def visit_ClassDef(self, node):
# Manually do visit() to skip over base classes
@@ -154,6 +198,7 @@ class ConvertVisitor(ast.NodeVisitor, CppFormatter):
self.generic_visit(node)
self.dedent()
self.indent_line('}')
+ self._stack_variables.clear()
def visit_If(self, node):
# Manually do visit() to get the indentation right. Note: