aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2022-05-27 15:08:45 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-06-02 04:59:52 +0000
commitf46855dc42cbfd39ef4db00dcd2d09f4453a3fdc (patch)
tree8d0c20093330eb6ebe36eda0ac0896c9ee8603f9
parent6377d14cfe491d497d6ad555fdd6aade1e08211c (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 Change-Id: Id71d1a8c14e57f3bfaf32fc202b260d390589382 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io> (cherry picked from commit 869ae24b2da002a3a02e7d2bbecef42d08772be8) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-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 35d659d64..5614dc622 100644
--- a/tools/qtpy2cpp_lib/visitor.py
+++ b/tools/qtpy2cpp_lib/visitor.py
@@ -50,6 +50,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:
@@ -69,6 +89,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
@@ -102,6 +123,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):
@@ -113,6 +152,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')
@@ -137,12 +178,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
@@ -190,6 +234,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: