Skip to content

Commit a82f116

Browse files
committed
Add support for variadic functions, fixes #399
1 parent 1eee0cb commit a82f116

File tree

13 files changed

+91
-11
lines changed

13 files changed

+91
-11
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
### Added
66
- Added support for @abstract functions
7+
- Added support for variadic functions
78

89
### Changed
910
- Fixed formatting of `@warning_ignore_start` and `@warning_ignore_restore`

gdtoolkit/common/ast.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,13 @@ def __repr__(self):
7272
class Parameter:
7373
"""Abstract representation of function parameter"""
7474

75-
def __init__(self, node: Tree):
76-
self.name = node.children[0].value
75+
def __init__(self, parameter_node: Tree):
76+
if parameter_node.data == "func_arg_variadic":
77+
self.name = parameter_node.children[0].children[0].value
78+
self.variadic = True
79+
else:
80+
self.name = parameter_node.children[0].value
81+
self.variadic = False
7782

7883

7984
# pylint: disable-next=too-few-public-methods

gdtoolkit/formatter/expression.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,9 @@ def _format_foldable_to_multiple_lines(
155155
"lambda_header": _format_lambda_header_to_multiple_lines,
156156
# fake expressions:
157157
"func_args": _format_args_to_multiple_lines,
158+
"func_arg_variadic": lambda e, ec, c: _append_to_expression_context_and_pass(
159+
"...", e.children[0], ec, c
160+
),
158161
"func_arg_regular": _format_func_arg_to_multiple_lines,
159162
"func_arg_inf": _format_func_arg_to_multiple_lines,
160163
"func_arg_typed": _format_func_arg_to_multiple_lines,
@@ -332,12 +335,12 @@ def _format_func_arg_to_multiple_lines(
332335
expression.children[0], expression_context, context
333336
)
334337
if expression.data == "func_arg_typed" and len(expression.children) == 2:
335-
return [
336-
(
337-
get_line(expression.children[1]),
338-
f"{context.indent_string}{expression_to_str(expression)}",
339-
)
340-
]
338+
return _append_to_expression_context_and_pass(
339+
f"{expression.children[0].value}: ",
340+
expression.children[1],
341+
expression_context,
342+
context,
343+
)
341344
template = {
342345
"func_arg_regular": "{} = ",
343346
"func_arg_inf": "{} := ",

gdtoolkit/formatter/expression_to_str.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ def expression_to_str(expression: Node) -> str:
9292
"lambda_header": _lambda_header_to_str,
9393
# fake expressions:
9494
"func_args": _args_to_str,
95+
"func_arg_variadic": lambda e: f"...{expression_to_str(e.children[0])}",
9596
"func_arg_regular": lambda e: "{}{}".format(
9697
e.children[0].value,
9798
" = {}".format(standalone_expression_to_str(e.children[1]))

gdtoolkit/linter/basic_checks.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,11 @@ def _unused_argument_check(parse_tree: Tree) -> List[Problem]:
129129
argument_tokens = {}
130130
func_args = func_header.children[1]
131131
for func_arg in [r for r in func_args.children if not is_trailing_comma(r)]:
132-
arg_name_token = find_name_token_among_children(func_arg)
132+
arg_name_token = find_name_token_among_children(
133+
func_arg
134+
if func_arg.data != "func_arg_variadic"
135+
else func_arg.children[0]
136+
)
133137
arg_name = arg_name_token.value # type: ignore
134138
argument_definitions[arg_name] = (
135139
argument_definitions.get(arg_name, 0) + 1

gdtoolkit/parser/gdscript.lark

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,13 @@ func_def: func_header _func_suite
7575
abstract_func_def: abstract_func_header
7676
func_header: "func" NAME func_args ["->" TYPE_HINT] ":"
7777
abstract_func_header: "func" NAME func_args ["->" TYPE_HINT]
78+
// TODO: Accept func_arg_variadic as last one only.
7879
func_args: "(" [func_arg ("," func_arg)* [trailing_comma]] ")"
79-
?func_arg: func_arg_regular
80+
?func_arg: func_arg_variadic
81+
| func_arg_regular
8082
| func_arg_inf
8183
| func_arg_typed
84+
func_arg_variadic: "..." (func_arg_regular | func_arg_typed)
8285
func_arg_regular: NAME ["=" expr]
8386
func_arg_inf: NAME ":" "=" expr
8487
func_arg_typed: NAME ":" TYPE_HINT ["=" expr]

tests/common.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import os
22

33

4-
GODOT_SERVER = "godot4-latest"
4+
GODOT_SERVER = "godot4.5"
55

66

77
def write_file(a_dir, file_name, code):
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
func foo(...args):
2+
pass
3+
func bar(a,...args):
4+
pass
5+
func baz(a,...args,):
6+
pass
7+
func bat(a,...args:Array):
8+
pass
9+
func ban(a,...args:Array,):
10+
pass
11+
func bak(a,...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:Array):
12+
pass
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
func foo(...args):
2+
pass
3+
4+
5+
func bar(a, ...args):
6+
pass
7+
8+
9+
func baz(
10+
a,
11+
...args,
12+
):
13+
pass
14+
15+
16+
func bat(a, ...args: Array):
17+
pass
18+
19+
20+
func ban(
21+
a,
22+
...args: Array,
23+
):
24+
pass
25+
26+
27+
func bak(
28+
a,
29+
...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: Array
30+
):
31+
pass

tests/gd2py/input-output-pairs/class_level_statements.in.gd

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,7 @@ func foo():
3535

3636
static func bar():
3737
pass
38+
39+
40+
func baz(a,b,...c):
41+
pass

0 commit comments

Comments
 (0)