in bigquery_etl/format_sql/formatter.py [0:0]
def inline_block_format(tokens, max_line_length=100):
"""Extend simple_format to inline each bracket block if possible.
A bracket block is a series of tokens from an opening bracket to the
matching closing bracket. To inline a block means to put it on a single
line, instead of multiple lines.
Inline a block if the result would be shorter than max_line_length.
Do not inline if block if contains a comment.
For example, this formatter may convert:
IF(
condition,
value_if_true,
value_if_false,
)
to
IF(condition, value_if_true, value_if_false)
Implementation requires simple_format to put opening brackets at the end of
the line and closing brackets at the beginning of the line, unless there is
a comment between them.
"""
# format tokens using simple_format, then group into lines
lines = [Line()]
can_format = True
for token in simple_format(tokens):
if token.value.startswith("\n"):
lines.append(Line(token, can_format))
else:
lines[-1].add(token)
if isinstance(token, Comment):
if can_format and token.format_off:
# disable formatting for current and following lines
lines[-1].can_format = False
can_format = False
elif not can_format and token.format_on:
# enable formatting for following lines
can_format = True
# combine all lines in each bracket block that fits in max_line_length
skip_lines = 0
for index, line in enumerate(lines):
if skip_lines > 0:
skip_lines -= 1
continue
yield from line.tokens
if line.can_start_inline_block:
indent_level = line.indent_level
line_length = indent_level + line.inline_length
pending_lines = 0
pending = []
open_brackets = 1
index += 1 # start on the next line
previous_line = line
for line in lines[index:]:
if not line.can_format:
break
# Line comments can't be moved into the middle of a line.
if previous_line.ends_with_line_comment:
break
if (
not previous_line.ends_with_opening_bracket
and not line.starts_with_closing_bracket
):
pending.append(Whitespace(" "))
line_length += 1
pending_lines += 1
pending.extend(line.inline_tokens)
line_length += line.inline_length
if line_length > max_line_length:
break
if line.starts_with_closing_bracket:
open_brackets -= 1
if open_brackets == 0:
# flush pending and handle next block if present
yield from pending
skip_lines += pending_lines
if line.can_start_inline_block:
pending_lines = 0
pending = []
else:
break
if line.ends_with_opening_bracket:
open_brackets += 1
previous_line = line