Skip to content

Commit

Permalink
format: fix indentation of comments
Browse files Browse the repository at this point in the history
Fixes mesonbuild#13508

- Fix indentation of comments in arrays
- Fix indentation of comments in dicts
- Fix indentation of comments in if clauses
- Fix indentation of comments in foreach clauses
  • Loading branch information
bruchar1 authored and dcbaker committed Aug 20, 2024
1 parent 18f4a05 commit d9ba422
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 5 deletions.
31 changes: 26 additions & 5 deletions mesonbuild/mformat.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,8 @@ def visit_ArrayNode(self, node: mparser.ArrayNode) -> None:
if node.args.arguments and not node.args.is_multiline and self.config.space_array:
self.add_space_after(node.lbracket)
self.add_space_after(node.args)
if not node.args.arguments:
self.move_whitespaces(node.lbracket, node.args)

def visit_DictNode(self, node: mparser.DictNode) -> None:
super().visit_DictNode(node)
Expand All @@ -388,6 +390,7 @@ def visit_CodeBlockNode(self, node: mparser.CodeBlockNode) -> None:
self.in_block_comments = False
else:
node.pre_whitespaces = mparser.WhitespaceNode(mparser.Token('whitespace', node.filename, 0, 0, 0, (0, 0), ''))
node.pre_whitespaces.block_indent = True

for i in node.lines:
i.accept(self)
Expand All @@ -398,7 +401,9 @@ def visit_CodeBlockNode(self, node: mparser.CodeBlockNode) -> None:
else:
node.whitespaces.value = node.pre_whitespaces.value + node.whitespaces.value
node.pre_whitespaces.value = ''
self.in_block_comments = True
node.whitespaces.accept(self)
self.in_block_comments = False

if node.condition_level == 0 and self.config.insert_final_newline:
self.add_nl_after(node, force=True)
Expand Down Expand Up @@ -453,6 +458,7 @@ def visit_ForeachClauseNode(self, node: mparser.ForeachClauseNode) -> None:
self.add_space_after(node.colon)

node.block.whitespaces.value += node.condition_level * self.config.indent_by
node.block.whitespaces.block_indent = True

self.move_whitespaces(node.endforeach, node)

Expand All @@ -468,11 +474,19 @@ def visit_IfClauseNode(self, node: mparser.IfClauseNode) -> None:
def visit_IfNode(self, node: mparser.IfNode) -> None:
super().visit_IfNode(node)
self.add_space_after(node.if_)
self.in_block_comments = True
self.move_whitespaces(node.block, node)
self.in_block_comments = False
node.whitespaces.condition_level = node.condition_level + 1
node.whitespaces.block_indent = True

def visit_ElseNode(self, node: mparser.ElseNode) -> None:
super().visit_ElseNode(node)
self.in_block_comments = True
self.move_whitespaces(node.block, node)
self.in_block_comments = False
node.whitespaces.condition_level = node.condition_level + 1
node.whitespaces.block_indent = True

def visit_TernaryNode(self, node: mparser.TernaryNode) -> None:
super().visit_TernaryNode(node)
Expand Down Expand Up @@ -554,22 +568,28 @@ def visit_ArrayNode(self, node: mparser.ArrayNode) -> None:
self.enter_node(node)
if node.args.is_multiline:
self.level += 1
self.add_nl_after(node.lbracket, indent=self.level)
if node.args.arguments:
self.add_nl_after(node.lbracket, indent=self.level)
node.lbracket.accept(self)
self.is_function_arguments = False
node.args.accept(self)
if node.args.is_multiline:
self.level -= 1
node.rbracket.accept(self)
self.exit_node(node)

def visit_DictNode(self, node: mparser.DictNode) -> None:
self.enter_node(node)
if node.args.is_multiline:
self.level += 1
self.add_nl_after(node.lcurl, indent=self.level)
if node.args.kwargs:
self.add_nl_after(node.lcurl, indent=self.level)
node.lcurl.accept(self)
self.is_function_arguments = False
node.args.accept(self)
if node.args.is_multiline:
self.level -= 1
node.rcurl.accept(self)
self.exit_node(node)

def visit_MethodNode(self, node: mparser.MethodNode) -> None:
Expand Down Expand Up @@ -599,8 +619,8 @@ def visit_WhitespaceNode(self, node: mparser.WhitespaceNode) -> None:
lines = node.value.splitlines(keepends=True)
if lines:
indent = (node.condition_level + self.level) * self.config.indent_by
node.value = lines[0]
for line in lines[1:]:
node.value = '' if node.block_indent else lines.pop(0)
for line in lines:
if '#' in line and not line.startswith(indent):
node.value += indent
node.value += line
Expand Down Expand Up @@ -650,7 +670,8 @@ def visit_ArgumentNode(self, node: mparser.ArgumentNode) -> None:

for comma in node.commas[arg_index:-1]:
self.add_nl_after(comma, self.level)
self.add_nl_after(node, self.level - 1)
if node.arguments or node.kwargs:
self.add_nl_after(node, self.level - 1)

else:
if has_trailing_comma and not (node.commas[-1].whitespaces and node.commas[-1].whitespaces.value):
Expand Down
1 change: 1 addition & 0 deletions mesonbuild/mparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ def __init__(self, token: Token[str]):
super().__init__(token.lineno, token.colno, token.filename)
self.value = ''
self.append(token)
self.block_indent = False

def append(self, token: Token[str]) -> None:
self.value += token.value
Expand Down
17 changes: 17 additions & 0 deletions test cases/format/1 default/indentation.meson
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ project(
)

a = [
# comment
# comment
1,
# comment
2,
3,
[
Expand All @@ -36,8 +39,13 @@ a = [
d = {}

if meson.project_version().version_compare('>1.2')
# comment
# comment
if meson.version().version_compare('>1.0')
# comment
# comment
foreach i : a
# comment
e = {
'a': 'a',
'b': 'b',
Expand Down Expand Up @@ -69,9 +77,18 @@ if meson.project_version().version_compare('>1.2')
],
}
endforeach

foreach j : a
# comment
# comment
# comment
endforeach
elif 42 in d
d += {'foo': 43}
else # ensure else is correctly indented (issue #13316)
# comment
k = 'k'
# comment
# comment
endif
endif
15 changes: 15 additions & 0 deletions unittests/platformagnostictests.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,21 @@ def test_format_empty_file(self) -> None:
for code in ('', '\n'):
formatted = formatter.format(code, Path())
self.assertEqual('\n', formatted)

def test_format_indent_comment_in_brackets(self) -> None:
"""Ensure comments in arrays and dicts are correctly indented"""
formatter = Formatter(None, use_editor_config=False, fetch_subdirs=False)
code = 'a = [\n # comment\n]\n'
formatted = formatter.format(code, Path())
self.assertEqual(code, formatted)

code = 'a = [\n # comment\n 1,\n]\n'
formatted = formatter.format(code, Path())
self.assertEqual(code, formatted)

code = 'a = {\n # comment\n}\n'
formatted = formatter.format(code, Path())
self.assertEqual(code, formatted)

def test_error_configuring_subdir(self):
testdir = os.path.join(self.common_test_dir, '152 index customtarget')
Expand Down

0 comments on commit d9ba422

Please sign in to comment.