33from typing import Optional , TypeVar , cast
44
55from rewrite import Tree , P , Cursor
6- from rewrite .java import J , Space , Statement
6+ from rewrite .java import J , Space , Statement , JRightPadded
77from rewrite .python import PythonVisitor , BlankLinesStyle , CompilationUnit
88from rewrite .visitor import T
99
@@ -27,7 +27,7 @@ def visit_statement(self, statement: Statement, p: P) -> J:
2727 parent_cursor = self .cursor .parent_tree_cursor ()
2828 top_level = isinstance (parent_cursor .value , CompilationUnit )
2929 if top_level and statement != cast (CompilationUnit , parent_cursor .value ).statements [0 ]:
30- statement = statement . with_prefix (statement . prefix . with_whitespace ( ' \n \n ' ) )
30+ statement = minimum_lines_for_tree (statement , self . _style . minimum . around_top_level_classes_functions )
3131 elif top_level :
3232 statement = statement .with_prefix (statement .prefix .with_whitespace ('' ))
3333 return statement
@@ -39,3 +39,39 @@ def post_visit(self, tree: T, p: P) -> Optional[T]:
3939
4040 def visit (self , tree : Optional [Tree ], p : P , parent : Optional [Cursor ] = None ) -> Optional [T ]:
4141 return tree if self ._stop else super ().visit (tree , p , parent )
42+
43+
44+ def minimum_lines_for_right_padded (tree : JRightPadded [J2 ], min_lines ) -> JRightPadded [J2 ]:
45+ return tree .with_element (minimum_lines_for_tree (tree .element , min_lines ))
46+
47+
48+ def minimum_lines_for_tree (tree : J , min_lines ) -> J :
49+ return tree .with_prefix (minimum_lines_for_space (tree .prefix , min_lines ))
50+
51+
52+ def minimum_lines_for_space (prefix : Space , min_lines ) -> Space :
53+ if min_lines == 0 :
54+ return prefix
55+ if not prefix .comments or \
56+ '\n ' in prefix .whitespace or \
57+ (prefix .comments [0 ].multiline and '\n ' in prefix .comments [0 ].text ):
58+ return prefix .with_whitespace (minimum_lines_for_string (prefix .whitespace , min_lines ))
59+
60+ # the first comment is a trailing comment on the previous line
61+ c0 = prefix .comments [0 ].with_suffix (minimum_lines_for_string (prefix .comments [0 ].suffix , min_lines ))
62+ return prefix if c0 is prefix .comments [0 ] else prefix .with_comments ([c0 ] + prefix .comments [1 :])
63+
64+
65+ def minimum_lines_for_string (whitespace , min_lines ):
66+ if min_lines == 0 :
67+ return whitespace
68+
69+ min_whitespace = whitespace
70+ for _ in range (min_lines - get_new_line_count (whitespace ) + 1 ):
71+ min_whitespace = '\n ' + min_whitespace
72+
73+ return min_whitespace
74+
75+
76+ def get_new_line_count (whitespace ):
77+ return whitespace .count ('\n ' )
0 commit comments