Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion scripts/prose_lint.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -383,11 +383,19 @@ def extracted_comments(path: Path, lines: list[str]) -> list[tuple[int, str, boo
closing = '' if end >= 0 else closing
continue
masked = strip_strings(line, spec['quotes'])
# A line comment runs to end of line, so a block opener after one is text.
# Left unbounded it opens a block that swallows the code lines below.
Comment thread
ptr727 marked this conversation as resolved.
# A documentation comment bounds it too, being exempt from linting rather than from here.
line_at = len(line)
for marker in spec['line']:
at = masked.find(marker)
if 0 <= at < line_at:
line_at = at
cut = len(line)
leading = True
for opener, closer in spec['block']:
at = masked.find(opener)
if 0 <= at < cut:
if 0 <= at < min(cut, line_at):
if any(line[at:].startswith(d) for d in spec['doc']):
continue
cut, leading = at, not line[:at].strip()
Expand Down
12 changes: 12 additions & 0 deletions scripts/test_prose_lint.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -368,6 +368,18 @@ def test_a_comment_inside_a_fenced_block_is_skipped(self) -> None:
self.assertEqual(['comment-wrap'],
self.flag('a.md', 'Prose.\n\n<!-- One thing. Another thing. -->\n'))

def test_a_block_opener_inside_a_line_comment_is_text(self) -> None:
"""Read as a real opener it opens a block, and the code lines below are linted as prose.

The documentation form is the same case: exempting it from linting must not leave the
ceiling unbounded, or the syntax whose doc marker is a line comment reopens the defect.
"""
for name, text in (('a.cs', '// Match a /* opener here\nvar x = 1; // Two things. Here.\n'),
('a.cs', '/// See a /* opener here\nvar x = 1; // Two things. Here.\n'),
('a.ps1', '# Match a <# opener here\n$x = 1 # Two things. Here.\n')):
with self.subTest(file=name, line=text.split('\n')[0]):
self.assertEqual(['comment-wrap'], self.flag(name, text))

def test_css_has_block_comments_only(self) -> None:
"""A `//` in CSS is the scheme separator of a URL, not a comment marker."""
self.assertEqual([], self.flag('a.css', 'a { background: url(http://x/y. Z); }\n'))
Expand Down
Loading