Cache generated comments
This commit is contained in:
parent
257f7193fa
commit
e4340f5c3e
66
black.py
66
black.py
@ -2045,6 +2045,10 @@ def is_split_before_delimiter(leaf: Leaf, previous: Leaf = None) -> int:
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
FMT_OFF = {"# fmt: off", "# fmt:off", "# yapf: disable"}
|
||||||
|
FMT_ON = {"# fmt: on", "# fmt:on", "# yapf: enable"}
|
||||||
|
|
||||||
|
|
||||||
def generate_comments(leaf: LN) -> Iterator[Leaf]:
|
def generate_comments(leaf: LN) -> Iterator[Leaf]:
|
||||||
"""Clean the prefix of the `leaf` and generate comments from it, if any.
|
"""Clean the prefix of the `leaf` and generate comments from it, if any.
|
||||||
|
|
||||||
@ -2064,16 +2068,37 @@ def generate_comments(leaf: LN) -> Iterator[Leaf]:
|
|||||||
Inline comments are emitted as regular token.COMMENT leaves. Standalone
|
Inline comments are emitted as regular token.COMMENT leaves. Standalone
|
||||||
are emitted with a fake STANDALONE_COMMENT token identifier.
|
are emitted with a fake STANDALONE_COMMENT token identifier.
|
||||||
"""
|
"""
|
||||||
p = leaf.prefix
|
for pc in list_comments(leaf.prefix, is_endmarker=leaf.type == token.ENDMARKER):
|
||||||
if not p:
|
yield Leaf(pc.type, pc.value, prefix="\n" * pc.newlines)
|
||||||
return
|
if pc.value in FMT_ON:
|
||||||
|
raise FormatOn(pc.consumed)
|
||||||
|
|
||||||
if "#" not in p:
|
if pc.value in FMT_OFF:
|
||||||
return
|
if pc.type == STANDALONE_COMMENT:
|
||||||
|
raise FormatOff(pc.consumed)
|
||||||
|
|
||||||
|
prev = preceding_leaf(leaf)
|
||||||
|
if not prev or prev.type in WHITESPACE: # standalone comment in disguise
|
||||||
|
raise FormatOff(pc.consumed)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ProtoComment:
|
||||||
|
type: int # token.COMMENT or STANDALONE_COMMENT
|
||||||
|
value: str # content of the comment
|
||||||
|
newlines: int # how many newlines before the comment
|
||||||
|
consumed: int # how many characters of the original leaf's prefix did we consume
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache(maxsize=4096)
|
||||||
|
def list_comments(prefix: str, is_endmarker: bool) -> List[ProtoComment]:
|
||||||
|
result: List[ProtoComment] = []
|
||||||
|
if not prefix or "#" not in prefix:
|
||||||
|
return result
|
||||||
|
|
||||||
consumed = 0
|
consumed = 0
|
||||||
nlines = 0
|
nlines = 0
|
||||||
for index, line in enumerate(p.split("\n")):
|
for index, line in enumerate(prefix.split("\n")):
|
||||||
consumed += len(line) + 1 # adding the length of the split '\n'
|
consumed += len(line) + 1 # adding the length of the split '\n'
|
||||||
line = line.lstrip()
|
line = line.lstrip()
|
||||||
if not line:
|
if not line:
|
||||||
@ -2081,25 +2106,18 @@ def generate_comments(leaf: LN) -> Iterator[Leaf]:
|
|||||||
if not line.startswith("#"):
|
if not line.startswith("#"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if index == 0 and leaf.type != token.ENDMARKER:
|
if index == 0 and not is_endmarker:
|
||||||
comment_type = token.COMMENT # simple trailing comment
|
comment_type = token.COMMENT # simple trailing comment
|
||||||
else:
|
else:
|
||||||
comment_type = STANDALONE_COMMENT
|
comment_type = STANDALONE_COMMENT
|
||||||
comment = make_comment(line)
|
comment = make_comment(line)
|
||||||
yield Leaf(comment_type, comment, prefix="\n" * nlines)
|
result.append(
|
||||||
|
ProtoComment(
|
||||||
if comment in {"# fmt: on", "# yapf: enable"}:
|
type=comment_type, value=comment, newlines=nlines, consumed=consumed
|
||||||
raise FormatOn(consumed)
|
)
|
||||||
|
)
|
||||||
if comment in {"# fmt: off", "# yapf: disable"}:
|
|
||||||
if comment_type == STANDALONE_COMMENT:
|
|
||||||
raise FormatOff(consumed)
|
|
||||||
|
|
||||||
prev = preceding_leaf(leaf)
|
|
||||||
if not prev or prev.type in WHITESPACE: # standalone comment in disguise
|
|
||||||
raise FormatOff(consumed)
|
|
||||||
|
|
||||||
nlines = 0
|
nlines = 0
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
def make_comment(content: str) -> str:
|
def make_comment(content: str) -> str:
|
||||||
@ -2586,10 +2604,10 @@ def normalize_invisible_parens(node: Node, parens_after: Set[str]) -> None:
|
|||||||
Standardizes on visible parentheses for single-element tuples, and keeps
|
Standardizes on visible parentheses for single-element tuples, and keeps
|
||||||
existing visible parentheses for other tuples and generator expressions.
|
existing visible parentheses for other tuples and generator expressions.
|
||||||
"""
|
"""
|
||||||
try:
|
for pc in list_comments(node.prefix, is_endmarker=False):
|
||||||
list(generate_comments(node))
|
if pc.value in FMT_OFF:
|
||||||
except FormatOff:
|
# This `node` has a prefix with `# fmt: off`, don't mess with parens.
|
||||||
return # This `node` has a prefix with `# fmt: off`, don't mess with parens.
|
return
|
||||||
|
|
||||||
check_lpar = False
|
check_lpar = False
|
||||||
for index, child in enumerate(list(node.children)):
|
for index, child in enumerate(list(node.children)):
|
||||||
|
Loading…
Reference in New Issue
Block a user