Clean up comments.py preview mode
This commit is contained in:
parent
96e62c57e3
commit
f58f446640
@ -1088,7 +1088,7 @@ def _format_str_once(src_contents: str, *, mode: Mode) -> str:
|
||||
future_imports = get_future_imports(src_node)
|
||||
versions = detect_target_versions(src_node, future_imports=future_imports)
|
||||
|
||||
normalize_fmt_off(src_node, preview=mode.preview)
|
||||
normalize_fmt_off(src_node)
|
||||
lines = LineGenerator(mode=mode)
|
||||
elt = EmptyLineTracker(mode=mode)
|
||||
split_line_features = {
|
||||
|
@ -29,7 +29,7 @@
|
||||
FMT_PASS: Final = {*FMT_OFF, *FMT_SKIP}
|
||||
FMT_ON: Final = {"# fmt: on", "# fmt:on", "# yapf: enable"}
|
||||
|
||||
COMMENT_EXCEPTIONS = {True: " !:#'", False: " !:#'%"}
|
||||
COMMENT_EXCEPTIONS = " !:#'"
|
||||
|
||||
|
||||
@dataclass
|
||||
@ -50,7 +50,7 @@ class ProtoComment:
|
||||
consumed: int # how many characters of the original leaf's prefix did we consume
|
||||
|
||||
|
||||
def generate_comments(leaf: LN, *, preview: bool) -> Iterator[Leaf]:
|
||||
def generate_comments(leaf: LN) -> Iterator[Leaf]:
|
||||
"""Clean the prefix of the `leaf` and generate comments from it, if any.
|
||||
|
||||
Comments in lib2to3 are shoved into the whitespace prefix. This happens
|
||||
@ -69,16 +69,12 @@ def generate_comments(leaf: LN, *, preview: bool) -> Iterator[Leaf]:
|
||||
Inline comments are emitted as regular token.COMMENT leaves. Standalone
|
||||
are emitted with a fake STANDALONE_COMMENT token identifier.
|
||||
"""
|
||||
for pc in list_comments(
|
||||
leaf.prefix, is_endmarker=leaf.type == token.ENDMARKER, preview=preview
|
||||
):
|
||||
for pc in list_comments(leaf.prefix, is_endmarker=leaf.type == token.ENDMARKER):
|
||||
yield Leaf(pc.type, pc.value, prefix="\n" * pc.newlines)
|
||||
|
||||
|
||||
@lru_cache(maxsize=4096)
|
||||
def list_comments(
|
||||
prefix: str, *, is_endmarker: bool, preview: bool
|
||||
) -> List[ProtoComment]:
|
||||
def list_comments(prefix: str, *, is_endmarker: bool) -> List[ProtoComment]:
|
||||
"""Return a list of :class:`ProtoComment` objects parsed from the given `prefix`."""
|
||||
result: List[ProtoComment] = []
|
||||
if not prefix or "#" not in prefix:
|
||||
@ -104,7 +100,7 @@ def list_comments(
|
||||
comment_type = token.COMMENT # simple trailing comment
|
||||
else:
|
||||
comment_type = STANDALONE_COMMENT
|
||||
comment = make_comment(line, preview=preview)
|
||||
comment = make_comment(line)
|
||||
result.append(
|
||||
ProtoComment(
|
||||
type=comment_type, value=comment, newlines=nlines, consumed=consumed
|
||||
@ -114,7 +110,7 @@ def list_comments(
|
||||
return result
|
||||
|
||||
|
||||
def make_comment(content: str, *, preview: bool) -> str:
|
||||
def make_comment(content: str) -> str:
|
||||
"""Return a consistently formatted comment from the given `content` string.
|
||||
|
||||
All comments (except for "##", "#!", "#:", '#'") should have a single
|
||||
@ -135,26 +131,26 @@ def make_comment(content: str, *, preview: bool) -> str:
|
||||
and not content.lstrip().startswith("type:")
|
||||
):
|
||||
content = " " + content[1:] # Replace NBSP by a simple space
|
||||
if content and content[0] not in COMMENT_EXCEPTIONS[preview]:
|
||||
if content and content[0] not in COMMENT_EXCEPTIONS:
|
||||
content = " " + content
|
||||
return "#" + content
|
||||
|
||||
|
||||
def normalize_fmt_off(node: Node, *, preview: bool) -> None:
|
||||
def normalize_fmt_off(node: Node) -> None:
|
||||
"""Convert content between `# fmt: off`/`# fmt: on` into standalone comments."""
|
||||
try_again = True
|
||||
while try_again:
|
||||
try_again = convert_one_fmt_off_pair(node, preview=preview)
|
||||
try_again = convert_one_fmt_off_pair(node)
|
||||
|
||||
|
||||
def convert_one_fmt_off_pair(node: Node, *, preview: bool) -> bool:
|
||||
def convert_one_fmt_off_pair(node: Node) -> bool:
|
||||
"""Convert content of a single `# fmt: off`/`# fmt: on` into a standalone comment.
|
||||
|
||||
Returns True if a pair was converted.
|
||||
"""
|
||||
for leaf in node.leaves():
|
||||
previous_consumed = 0
|
||||
for comment in list_comments(leaf.prefix, is_endmarker=False, preview=preview):
|
||||
for comment in list_comments(leaf.prefix, is_endmarker=False):
|
||||
if comment.value not in FMT_PASS:
|
||||
previous_consumed = comment.consumed
|
||||
continue
|
||||
@ -169,7 +165,7 @@ def convert_one_fmt_off_pair(node: Node, *, preview: bool) -> bool:
|
||||
if comment.value in FMT_SKIP and prev.type in WHITESPACE:
|
||||
continue
|
||||
|
||||
ignored_nodes = list(generate_ignored_nodes(leaf, comment, preview=preview))
|
||||
ignored_nodes = list(generate_ignored_nodes(leaf, comment))
|
||||
if not ignored_nodes:
|
||||
continue
|
||||
|
||||
@ -214,26 +210,24 @@ def convert_one_fmt_off_pair(node: Node, *, preview: bool) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
def generate_ignored_nodes(
|
||||
leaf: Leaf, comment: ProtoComment, *, preview: bool
|
||||
) -> Iterator[LN]:
|
||||
def generate_ignored_nodes(leaf: Leaf, comment: ProtoComment) -> Iterator[LN]:
|
||||
"""Starting from the container of `leaf`, generate all leaves until `# fmt: on`.
|
||||
|
||||
If comment is skip, returns leaf only.
|
||||
Stops at the end of the block.
|
||||
"""
|
||||
if comment.value in FMT_SKIP:
|
||||
yield from _generate_ignored_nodes_from_fmt_skip(leaf, comment, preview=preview)
|
||||
yield from _generate_ignored_nodes_from_fmt_skip(leaf, comment)
|
||||
return
|
||||
container: Optional[LN] = container_of(leaf)
|
||||
while container is not None and container.type != token.ENDMARKER:
|
||||
if is_fmt_on(container, preview=preview):
|
||||
if is_fmt_on(container):
|
||||
return
|
||||
|
||||
# fix for fmt: on in children
|
||||
if children_contains_fmt_on(container, preview=preview):
|
||||
if children_contains_fmt_on(container):
|
||||
for child in container.children:
|
||||
if isinstance(child, Leaf) and is_fmt_on(child, preview=preview):
|
||||
if isinstance(child, Leaf) and is_fmt_on(child):
|
||||
if child.type in CLOSING_BRACKETS:
|
||||
# This means `# fmt: on` is placed at a different bracket level
|
||||
# than `# fmt: off`. This is an invalid use, but as a courtesy,
|
||||
@ -241,7 +235,7 @@ def generate_ignored_nodes(
|
||||
# The alternative is to fail the formatting.
|
||||
yield child
|
||||
return
|
||||
if children_contains_fmt_on(child, preview=preview):
|
||||
if children_contains_fmt_on(child):
|
||||
return
|
||||
yield child
|
||||
else:
|
||||
@ -254,14 +248,14 @@ def generate_ignored_nodes(
|
||||
|
||||
|
||||
def _generate_ignored_nodes_from_fmt_skip(
|
||||
leaf: Leaf, comment: ProtoComment, *, preview: bool
|
||||
leaf: Leaf, comment: ProtoComment
|
||||
) -> Iterator[LN]:
|
||||
"""Generate all leaves that should be ignored by the `# fmt: skip` from `leaf`."""
|
||||
prev_sibling = leaf.prev_sibling
|
||||
parent = leaf.parent
|
||||
# Need to properly format the leaf prefix to compare it to comment.value,
|
||||
# which is also formatted
|
||||
comments = list_comments(leaf.prefix, is_endmarker=False, preview=preview)
|
||||
comments = list_comments(leaf.prefix, is_endmarker=False)
|
||||
if not comments or comment.value != comments[0].value:
|
||||
return
|
||||
if prev_sibling is not None:
|
||||
@ -295,12 +289,12 @@ def _generate_ignored_nodes_from_fmt_skip(
|
||||
yield from iter(ignored_nodes)
|
||||
|
||||
|
||||
def is_fmt_on(container: LN, preview: bool) -> bool:
|
||||
def is_fmt_on(container: LN) -> bool:
|
||||
"""Determine whether formatting is switched on within a container.
|
||||
Determined by whether the last `# fmt:` comment is `on` or `off`.
|
||||
"""
|
||||
fmt_on = False
|
||||
for comment in list_comments(container.prefix, is_endmarker=False, preview=preview):
|
||||
for comment in list_comments(container.prefix, is_endmarker=False):
|
||||
if comment.value in FMT_ON:
|
||||
fmt_on = True
|
||||
elif comment.value in FMT_OFF:
|
||||
@ -308,11 +302,11 @@ def is_fmt_on(container: LN, preview: bool) -> bool:
|
||||
return fmt_on
|
||||
|
||||
|
||||
def children_contains_fmt_on(container: LN, *, preview: bool) -> bool:
|
||||
def children_contains_fmt_on(container: LN) -> bool:
|
||||
"""Determine if children have formatting switched on."""
|
||||
for child in container.children:
|
||||
leaf = first_leaf_of(child)
|
||||
if leaf is not None and is_fmt_on(leaf, preview=preview):
|
||||
if leaf is not None and is_fmt_on(leaf):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
@ -112,7 +112,7 @@ def visit_default(self, node: LN) -> Iterator[Line]:
|
||||
"""Default `visit_*()` implementation. Recurses to children of `node`."""
|
||||
if isinstance(node, Leaf):
|
||||
any_open_brackets = self.current_line.bracket_tracker.any_open_brackets()
|
||||
for comment in generate_comments(node, preview=self.mode.preview):
|
||||
for comment in generate_comments(node):
|
||||
if any_open_brackets:
|
||||
# any comment within brackets is subject to splitting
|
||||
self.current_line.append(comment)
|
||||
@ -971,7 +971,7 @@ def normalize_invisible_parens(
|
||||
Standardizes on visible parentheses for single-element tuples, and keeps
|
||||
existing visible parentheses for other tuples and generator expressions.
|
||||
"""
|
||||
for pc in list_comments(node.prefix, is_endmarker=False, preview=preview):
|
||||
for pc in list_comments(node.prefix, is_endmarker=False):
|
||||
if pc.value in FMT_OFF:
|
||||
# This `node` has a prefix with `# fmt: off`, don't mess with parens.
|
||||
return
|
||||
|
Loading…
Reference in New Issue
Block a user