diff options
| author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2022-06-01 15:21:36 +0200 |
|---|---|---|
| committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2022-06-04 11:07:36 +0200 |
| commit | 987cf3c516f06b269b60364222ff97be7a7f3755 (patch) | |
| tree | 8974f44063b7599e241d946c6bf634fa9f9d6cab /tools/qtpy2cpp_lib/visitor.py | |
| parent | fba2f8dad8e1d313b4bab13950bb7607b2b8e1da (diff) | |
qtpy2cpp: Improve function definitions
- Handle type annotations in function definitions with some heuristics
how to pass typical Qt classes.
- Fix the formatting of default parameters.
- Handle Slot decorators.
- Ignore the above elements later when the parser traverses them
Introduce concenience functions for checking visitor scope.
Pick-to: 6.3
Task-number: PYSIDE-1945
Change-Id: I489088025b0d6a76d43da6154af4db58b748adbe
Reviewed-by: Christian Tismer <tismer@stackless.com>
Diffstat (limited to 'tools/qtpy2cpp_lib/visitor.py')
| -rw-r--r-- | tools/qtpy2cpp_lib/visitor.py | 53 |
1 files changed, 43 insertions, 10 deletions
diff --git a/tools/qtpy2cpp_lib/visitor.py b/tools/qtpy2cpp_lib/visitor.py index 5bb02db31..688e8ae3d 100644 --- a/tools/qtpy2cpp_lib/visitor.py +++ b/tools/qtpy2cpp_lib/visitor.py @@ -9,6 +9,7 @@ import tokenize import warnings from .formatter import (CppFormatter, format_for_loop, format_literal, + format_name_constant, format_reference, format_start_function_call, write_import, write_import_from) from .nodedump import debug_format_node @@ -128,6 +129,9 @@ class ConvertVisitor(ast.NodeVisitor, CppFormatter): def visit_Attribute(self, node): """Format a variable reference (cf visit_Name)""" + # Default parameter (like Qt::black)? + if self._ignore_function_def_node(node): + return self._output_file.write(format_reference(node)) def visit_BinOp(self, node): @@ -146,7 +150,9 @@ class ConvertVisitor(ast.NodeVisitor, CppFormatter): self._output_file.write(" | ") def _format_call(self, node): - + # Decorator list? + if self._ignore_function_def_node(node): + return f = node.func if isinstance(f, ast.Name): self._output_file.write(f.id) @@ -181,7 +187,7 @@ class ConvertVisitor(ast.NodeVisitor, CppFormatter): def visit_Call(self, node): self._format_call(node) # Context manager expression? - if self._stack and isinstance(self._stack[-1], ast.withitem): + if self._within_context_manager(): self._output_file.write(";\n") def _write_function_args(self, args_node): @@ -232,7 +238,18 @@ class ConvertVisitor(ast.NodeVisitor, CppFormatter): def visit_FunctionDef(self, node): class_context = self._class_scope[-1] if self._class_scope else None + for decorator in node.decorator_list: + func = decorator.func # (Call) + if isinstance(func, ast.Name) and func.id == "Slot": + self._output_file.write("\npublic slots:") self.write_function_def(node, class_context) + # Find stack variables + for arg in node.args.args: + if arg.annotation and isinstance(arg.annotation, ast.Name): + type_name = arg.annotation.id + flags = qt_class_flags(type_name) + if flags & ClassFlag.PASS_ON_STACK_MASK: + self._stack_variables.append(arg.arg) self.indent() self.generic_visit(node) self.dedent() @@ -302,21 +319,37 @@ class ConvertVisitor(ast.NodeVisitor, CppFormatter): self.generic_visit(node) self._output_file.write(' * ') + def _within_context_manager(self): + """Return whether we are within a context manager (with).""" + parent = self._stack[-1] if self._stack else None + return parent and isinstance(parent, ast.withitem) + + def _ignore_function_def_node(self, node): + """Should this node be ignored within a FunctionDef.""" + if not self._stack: + return False + parent = self._stack[-1] + # A type annotation or default value of an argument? + if isinstance(parent, (ast.arguments, ast.arg)): + return True + if not isinstance(parent, ast.FunctionDef): + return False + # Return type annotation or decorator call + return node == parent.returns or node in parent.decorator_list + def visit_Name(self, node): """Format a variable reference (cf visit_Attribute)""" - # Context manager variable? - if self._stack and isinstance(self._stack[-1], ast.withitem): + # Skip Context manager variables, return or argument type annotation + if self._within_context_manager() or self._ignore_function_def_node(node): return self._output_file.write(format_reference(node)) def visit_NameConstant(self, node): + # Default parameter? + if self._ignore_function_def_node(node): + return self.generic_visit(node) - if node.value is None: - self._output_file.write('nullptr') - elif not node.value: - self._output_file.write('false') - else: - self._output_file.write('true') + self._output_file.write(format_name_constant(node)) def visit_Not(self, node): self.generic_visit(node) |
