Skip to content
This repository was archived by the owner on Jan 13, 2026. It is now read-only.

Commit 320e543

Browse files
committed
Make static methods top-level functions
1 parent cc5bc07 commit 320e543

File tree

1 file changed

+116
-94
lines changed

1 file changed

+116
-94
lines changed

rewrite/rewrite/python/format/spaces_visitor.py

Lines changed: 116 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
from typing import Optional, cast, List
1+
from typing import Optional, cast, List, TypeVar
22

33
import rewrite.java as j
4-
from rewrite import Tree
4+
from rewrite import Tree, list_map
55
from rewrite.java import J, Assignment, JLeftPadded, AssignmentOperation, MemberReference, MethodInvocation, \
6-
MethodDeclaration, Empty, ArrayAccess, Space, If, Block, ClassDeclaration
6+
MethodDeclaration, Empty, ArrayAccess, Space, If, Block, ClassDeclaration, VariableDeclarations, JRightPadded
77
from rewrite.python import PythonVisitor, SpacesStyle, Binary, ChainedAssignment
88
from rewrite.visitor import P
99

@@ -20,7 +20,7 @@ def visit_class_declaration(self, class_declaration: ClassDeclaration, p: P) ->
2020
# Handle space before parentheses for class declaration e.g. class A () <-> class A()
2121
if c.padding.implements is not None:
2222
c = c.padding.with_implements(
23-
self.space_before_container(c.padding.implements, self._style.before_parentheses.method_call)
23+
space_before_container(c.padding.implements, self._style.before_parentheses.method_call)
2424
)
2525

2626
param_size = len(c.padding.implements.elements)
@@ -29,14 +29,14 @@ def visit_class_declaration(self, class_declaration: ClassDeclaration, p: P) ->
2929
# TODO: Refactor to remove duplicate code.
3030
def _process_argument(index, arg, args_size):
3131
if index == 0:
32-
arg = arg.with_element(self.space_before(arg.element, use_space))
32+
arg = arg.with_element(space_before(arg.element, use_space))
3333
else:
34-
arg = arg.with_element(self.space_before(arg.element, self._style.other.after_comma))
34+
arg = arg.with_element(space_before(arg.element, self._style.other.after_comma))
3535

3636
if index == args_size - 1:
37-
arg = self.space_after(arg, use_space)
37+
arg = space_after(arg, use_space)
3838
else:
39-
arg = self.space_after(arg, self._style.other.before_comma)
39+
arg = space_after(arg, self._style.other.before_comma)
4040

4141
return arg
4242

@@ -53,7 +53,7 @@ def visit_method_declaration(self, method_declaration: MethodDeclaration, p: P)
5353
m: MethodDeclaration = cast(MethodDeclaration, super().visit_method_declaration(method_declaration, p))
5454

5555
m = m.padding.with_parameters(
56-
self.space_before_container(m.padding.parameters, self._style.before_parentheses.method_declaration)
56+
space_before_container(m.padding.parameters, self._style.before_parentheses.method_declaration)
5757
)
5858

5959
param_size = len(m.parameters)
@@ -62,18 +62,24 @@ def visit_method_declaration(self, method_declaration: MethodDeclaration, p: P)
6262
def _process_argument(index, arg, args_size):
6363
# TODO: Fix Type hint handling
6464
# Handle space before type hint colon e.g. foo(a: int) <-> foo(a:int)
65-
arg = arg.with_element(arg.element.with_type_expression(
66-
self.space_before(arg.element.type_expression, False)))
65+
if isinstance(arg.element, VariableDeclarations) and arg.element.type_expression:
66+
vd = cast(VariableDeclarations, arg.element)
67+
arg = arg.with_element(vd.with_type_expression(
68+
space_before(vd.type_expression, self._style.other.after_colon))
69+
.padding.with_variables(
70+
list_map(lambda v: space_after_right_padded(v, self._style.other.before_colon),
71+
vd.padding.variables))
72+
)
6773

6874
if index == 0:
69-
arg = arg.with_element(self.space_before(arg.element, use_space))
75+
arg = arg.with_element(space_before(arg.element, use_space))
7076
else:
71-
arg = arg.with_element(self.space_before(arg.element, self._style.other.after_comma))
77+
arg = arg.with_element(space_before(arg.element, self._style.other.after_comma))
7278

7379
if index == args_size - 1:
74-
arg = self.space_after(arg, use_space)
80+
arg = space_after(arg, use_space)
7581
else:
76-
arg = self.space_after(arg, self._style.other.before_comma)
82+
arg = space_after(arg, self._style.other.before_comma)
7783
return arg
7884

7985
m = m.padding.with_parameters(
@@ -95,7 +101,7 @@ def _process_argument(index, arg, args_size):
95101

96102
def visit_block(self, block: Block, p: P) -> J:
97103
b = cast(Block, super().visit_block(block, p))
98-
b = self.space_before(b, self._style.other.before_colon)
104+
b = space_before(b, self._style.other.before_colon)
99105
return b
100106

101107
def visit_method_invocation(self, method_invocation: MethodInvocation, p: P) -> J:
@@ -110,7 +116,7 @@ def visit_method_invocation(self, method_invocation: MethodInvocation, p: P) ->
110116
use_space = self._style.within.empty_method_call_parentheses
111117
m = m.padding.with_arguments(
112118
m.padding.arguments.padding.with_elements(
113-
[arg.with_element(self.space_before(arg.element, use_space)) for arg in
119+
[arg.with_element(space_before(arg.element, use_space)) for arg in
114120
m.padding.arguments.padding.elements]
115121
)
116122
)
@@ -124,14 +130,14 @@ def visit_method_invocation(self, method_invocation: MethodInvocation, p: P) ->
124130

125131
def _process_argument(index, arg, args_size, use_space):
126132
if index == 0:
127-
arg = arg.with_element(self.space_before(arg.element, use_space))
133+
arg = arg.with_element(space_before(arg.element, use_space))
128134
else:
129-
arg = arg.with_element(self.space_before(arg.element, self._style.other.after_comma))
135+
arg = arg.with_element(space_before(arg.element, self._style.other.after_comma))
130136

131137
if index == args_size - 1:
132-
arg = self.space_after(arg, use_space)
138+
arg = space_after(arg, use_space)
133139
else:
134-
arg = self.space_after(arg, self._style.other.before_comma)
140+
arg = space_after(arg, self._style.other.before_comma)
135141

136142
return arg
137143

@@ -166,10 +172,10 @@ def visit_assignment(self, assignment: Assignment, p: P) -> J:
166172
"""
167173
a: Assignment = cast(Assignment, super().visit_assignment(assignment, p))
168174
a = a.padding.with_assignment(
169-
self.space_before_jleftpadded(a.padding.assignment, self._style.around_operators.assignment))
175+
space_before_left_padded(a.padding.assignment, self._style.around_operators.assignment))
170176
a = a.padding.with_assignment(
171177
a.padding.assignment.with_element(
172-
self.space_before(a.padding.assignment.element, self._style.around_operators.assignment)))
178+
space_before(a.padding.assignment.element, self._style.around_operators.assignment)))
173179
return a
174180

175181
def visit_assignment_operation(self, assignment_operation: AssignmentOperation, p: P) -> J:
@@ -180,7 +186,7 @@ def visit_assignment_operation(self, assignment_operation: AssignmentOperation,
180186
operator: JLeftPadded = a.padding.operator
181187
a = a.padding.with_operator(
182188
operator.with_before(update_space(operator.before, self._style.around_operators.assignment)))
183-
return a.with_assignment(self.space_before(a.assignment, self._style.around_operators.assignment))
189+
return a.with_assignment(space_before(a.assignment, self._style.around_operators.assignment))
184190

185191
def visit_chained_assignment(self, chained_assignment: ChainedAssignment, p: P) -> J:
186192
"""
@@ -192,10 +198,10 @@ def visit_chained_assignment(self, chained_assignment: ChainedAssignment, p: P)
192198

193199
a = a.padding.with_variables(
194200
[v.with_element(
195-
self.space_before(v.element, self._style.around_operators.assignment if idx >= 1 else False)) for idx, v
201+
space_before(v.element, self._style.around_operators.assignment if idx >= 1 else False)) for idx, v
196202
in enumerate(a.padding.variables)])
197203

198-
return a.with_assignment(self.space_before(a.assignment, self._style.around_operators.assignment))
204+
return a.with_assignment(space_before(a.assignment, self._style.around_operators.assignment))
199205

200206
def visit_member_reference(self, member_reference: MemberReference, p: P) -> J:
201207
m: MemberReference = cast(MemberReference, super().visit_member_reference(member_reference, p))
@@ -247,96 +253,112 @@ def _apply_binary_space_around(self, binary, use_space_around: bool):
247253
binary = binary.padding.with_operator(
248254
operator.with_before(update_space(operator.before, use_space_around))
249255
)
250-
binary = binary.with_right(self.space_before(binary.right, use_space_around))
256+
binary = binary.with_right(space_before(binary.right, use_space_around))
251257
return binary
252258

253259
def visit_if(self, if_stm: If, p: P) -> J:
254260
if_: j.If = cast(If, super().visit_if(if_stm, p))
255261

256262
# Handle space before if condition e.g. if True: <-> if True:
257-
if_ = if_.with_if_condition(self.space_before(if_._if_condition, True))
263+
if_ = if_.with_if_condition(space_before(if_._if_condition, True))
258264

259265
# Handle space before if colon e.g. if True: pass <-> if True: pass
260266
if_ = if_.with_if_condition(
261267
if_.if_condition.padding.with_tree(
262-
SpacesVisitor.space_after(if_.if_condition.padding.tree, self._style.other.before_colon))
268+
space_after(if_.if_condition.padding.tree, self._style.other.before_colon))
263269
)
264270
return if_
265271

266272
def visit_else(self, else_: If.Else, p: P) -> J:
267273
e: j.If.Else = cast(j.If.Else, super().visit_else(else_, p))
268-
e = e.padding.with_body(self.space_before_right_padded_element(e.padding.body, self._style.other.before_colon))
274+
e = e.padding.with_body(space_before_right_padded_element(e.padding.body, self._style.other.before_colon))
269275

270276
return e
271277

272-
@staticmethod
273-
def space_before(j: J, space_before: bool) -> J:
274-
space: Space = cast(Space, j.prefix)
275-
if space.comments or '\\' in space.whitespace:
276-
# don't touch whitespaces with comments or continuation characters
277-
return j
278-
279-
return j.with_prefix(Space.SINGLE_SPACE if space_before else Space.EMPTY)
280-
281-
@staticmethod
282-
def space_before_container(container: j.JContainer, space_before: bool) -> j.JContainer:
283-
if container.before.comments:
284-
# Perform the space rule for the suffix of the last comment only. Same as IntelliJ.
285-
comments: List[j.Comment] = SpacesVisitor.space_last_comment_suffix(container.before.comments, space_before)
286-
return container.with_before(container.before.with_comments(comments))
287-
288-
if space_before and not_single_space(container.before.whitespace):
289-
return container.with_before(container.before.with_whitespace(" "))
290-
elif not space_before and only_spaces_and_not_empty(container.before.whitespace):
291-
return container.with_before(container.before.with_whitespace(""))
292-
else:
293-
return container
294-
295-
@staticmethod
296-
def space_before_right_padded_element(container: j.JRightPadded, space_before: bool) -> j.JRightPadded:
297-
return container.with_element(SpacesVisitor.space_before(container.element, space_before))
298-
299-
@staticmethod
300-
def space_last_comment_suffix(comments: List[j.Comment], space_suffix: bool) -> List[j.Comment]:
301-
return [SpacesVisitor.space_suffix(comment, space_suffix) if i == len(comments) - 1 else comment for i, comment
302-
in
303-
enumerate(comments)]
304-
305-
@staticmethod
306-
def space_suffix(comment: j.Comment, space_suffix: bool) -> j.Comment:
307-
if space_suffix and not_single_space(comment.suffix):
308-
return comment.with_suffix(" ")
309-
elif not space_suffix and only_spaces_and_not_empty(comment.suffix):
310-
return comment.with_suffix("")
311-
else:
312-
return comment
313-
314-
@staticmethod
315-
def space_before_jleftpadded(j: JLeftPadded[J], space_before) -> JLeftPadded[J]:
316-
space: Space = cast(Space, j.before)
317-
if space.comments or '\\' in space.whitespace:
318-
# don't touch whitespaces with comments or continuation characters
319-
return j
320-
321-
if space_before and not_single_space(space.whitespace):
322-
return j.with_before(space.with_whitespace(" "))
323-
elif not space_before and only_spaces_and_not_empty(space.whitespace):
324-
return j.with_before(space.with_whitespace(""))
278+
279+
J2 = TypeVar('J2', bound=j.J)
280+
281+
282+
def space_before(j: J2, add_space: bool) -> J2:
283+
space: Space = cast(Space, j.prefix)
284+
if space.comments or '\\' in space.whitespace:
285+
# don't touch whitespaces with comments or continuation characters
286+
return j
287+
288+
return j.with_prefix(Space.SINGLE_SPACE if add_space else Space.EMPTY)
289+
290+
291+
def space_before_container(container: j.JContainer, add_space: bool) -> j.JContainer:
292+
if container.before.comments:
293+
# Perform the space rule for the suffix of the last comment only. Same as IntelliJ.
294+
comments: List[j.Comment] = space_last_comment_suffix(container.before.comments, add_space)
295+
return container.with_before(container.before.with_comments(comments))
296+
297+
if add_space and not_single_space(container.before.whitespace):
298+
return container.with_before(container.before.with_whitespace(" "))
299+
elif not add_space and only_spaces_and_not_empty(container.before.whitespace):
300+
return container.with_before(container.before.with_whitespace(""))
301+
else:
302+
return container
303+
304+
305+
def space_before_right_padded_element(container: j.JRightPadded, add_space: bool) -> j.JRightPadded:
306+
return container.with_element(space_before(container.element, add_space))
307+
308+
309+
def space_last_comment_suffix(comments: List[j.Comment], add_space: bool) -> List[j.Comment]:
310+
return [space_suffix(comment, add_space) if i == len(comments) - 1 else comment for i, comment
311+
in
312+
enumerate(comments)]
313+
314+
315+
def space_suffix(comment: j.Comment, add_space: bool) -> j.Comment:
316+
if add_space and not_single_space(comment.suffix):
317+
return comment.with_suffix(" ")
318+
elif not add_space and only_spaces_and_not_empty(comment.suffix):
319+
return comment.with_suffix("")
320+
else:
321+
return comment
322+
323+
324+
def space_before_left_padded(j: JLeftPadded[J2], add_space) -> JLeftPadded[J2]:
325+
space: Space = cast(Space, j.before)
326+
if space.comments or '\\' in space.whitespace:
327+
# don't touch whitespaces with comments or continuation characters
325328
return j
326329

327-
@staticmethod
328-
def space_after(j: J, space_after: bool) -> J:
329-
space: Space = cast(Space, j.after)
330-
if space.comments or '\\' in space.whitespace:
331-
# don't touch whitespaces with comments or continuation characters
332-
return j
333-
334-
if space_after and not_single_space(space.whitespace):
335-
return j.with_after(space.with_whitespace(" "))
336-
elif not space_after and only_spaces_and_not_empty(space.whitespace):
337-
return j.with_after(space.with_whitespace(""))
330+
if add_space and not_single_space(space.whitespace):
331+
return j.with_before(space.with_whitespace(" "))
332+
elif not add_space and only_spaces_and_not_empty(space.whitespace):
333+
return j.with_before(space.with_whitespace(""))
334+
return j
335+
336+
337+
def space_after(j: J2, add_space: bool) -> J2:
338+
space: Space = cast(Space, j.after)
339+
if space.comments or '\\' in space.whitespace:
340+
# don't touch whitespaces with comments or continuation characters
338341
return j
339342

343+
if add_space and not_single_space(space.whitespace):
344+
return j.with_after(space.with_whitespace(" "))
345+
elif not add_space and only_spaces_and_not_empty(space.whitespace):
346+
return j.with_after(space.with_whitespace(""))
347+
return j
348+
349+
350+
def space_after_right_padded(right: JRightPadded[J2], add_space: bool) -> JRightPadded[J2]:
351+
space: Space = right.after
352+
if space.comments or '\\' in space.whitespace:
353+
# don't touch whitespaces with comments or continuation characters
354+
return right
355+
356+
if add_space and not_single_space(space.whitespace):
357+
return right.with_after(space.with_whitespace(" "))
358+
elif not add_space and only_spaces_and_not_empty(space.whitespace):
359+
return right.with_after(space.with_whitespace(""))
360+
return right
361+
340362

341363
def update_space(s: Space, have_space: bool) -> Space:
342364
if s.comments:

0 commit comments

Comments
 (0)