Skip to content

Commit c4c5692

Browse files
mameclaude
andcommitted
Support # typeprof:ignore:start / :end block form
For suppressing diagnostics across multiple lines, support a block form bracketed by `# typeprof:ignore:start` and `# typeprof:ignore:end` comments: # typeprof:ignore:start foo(1, 2) bar(1, 2) # typeprof:ignore:end An unmatched `:start` extends to the end of the file. The keywords follow Steep's `# steep:ignore:start`/`:end` convention. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 0fc7cfa commit c4c5692

5 files changed

Lines changed: 84 additions & 3 deletions

File tree

lib/typeprof/core/ast.rb

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,37 @@ def self.parse_rb(path, src)
2222

2323
# Collect line ranges marked with `# typeprof:ignore` comments.
2424
# Each range is suppressed in ProgramNode#each_diagnostic.
25-
IGNORE_RE = /\A#\s*typeprof:ignore\s*\z/
25+
#
26+
# Inline form (suppresses the line containing the comment):
27+
# foo(1, 2) # typeprof:ignore
28+
#
29+
# Block form (suppresses lines between :start and :end):
30+
# # typeprof:ignore:start
31+
# foo(1, 2)
32+
# # typeprof:ignore:end
33+
#
34+
# An unmatched `:start` extends to the end of the file.
35+
IGNORE_RE = /\A#\s*typeprof:ignore\s*\z/
36+
IGNORE_START_RE = /\A#\s*typeprof:ignore:start\s*\z/
37+
IGNORE_END_RE = /\A#\s*typeprof:ignore:end\s*\z/
2638
def self.collect_ignore_ranges(prism_result)
2739
ranges = []
40+
start_line = nil
2841
prism_result.comments.each do |c|
29-
next unless c.location.slice.match?(IGNORE_RE)
42+
text = c.location.slice
3043
line = c.location.start_line
31-
ranges << (line..line)
44+
if text.match?(IGNORE_START_RE)
45+
start_line ||= line
46+
elsif text.match?(IGNORE_END_RE)
47+
if start_line
48+
ranges << (start_line..line)
49+
start_line = nil
50+
end
51+
elsif text.match?(IGNORE_RE)
52+
ranges << (line..line)
53+
end
3254
end
55+
ranges << (start_line..Float::INFINITY) if start_line
3356
ranges
3457
end
3558

test/cli_test.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,17 @@ def check: -> :ok
5858
END
5959
end
6060

61+
def test_e2e_ignore_directive_block
62+
assert_equal(<<~END, test_run("ignore_directive_block", ["--show-error", "."]))
63+
# TypeProf #{ TypeProf::VERSION }
64+
65+
# ./ignore_directive_block.rb
66+
class Object
67+
def check: -> :ok
68+
end
69+
END
70+
end
71+
6172
def test_e2e_syntax_error
6273
assert_equal(<<~END, test_run("syntax_error", ["."]))
6374
# TypeProf #{ TypeProf::VERSION }
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
def check
2+
# typeprof:ignore:start
3+
Foo.new.accept_int("str")
4+
Foo.new.accept_int("str")
5+
# typeprof:ignore:end
6+
end
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class Foo
2+
def accept_int: (Integer) -> :ok
3+
end

test/lsp/lsp_test.rb

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,44 @@ def foo(nnn)
232232
end
233233
end
234234

235+
def test_diagnostics_ignore_directive_block
236+
init("basic")
237+
238+
notify(
239+
"textDocument/didOpen",
240+
textDocument: { uri: @folder + "basic.rb", version: 0, text: <<-END },
241+
def foo(nnn)
242+
nnn
243+
end
244+
245+
# typeprof:ignore:start
246+
foo(1, 2)
247+
foo(1, 2)
248+
# typeprof:ignore:end
249+
foo(1, 2)
250+
END
251+
)
252+
253+
expect_notification("typeprof.enableToggleButton") {|json| }
254+
expect_request("workspace/codeLens/refresh") {|json| }
255+
expect_notification("textDocument/publishDiagnostics") do |json|
256+
assert_equal({
257+
uri: @folder + "basic.rb",
258+
diagnostics: [
259+
{
260+
message: "wrong number of arguments (2 for 1)",
261+
range: {
262+
start: { line: 8, character: 0 },
263+
end: { line: 8, character: 3 },
264+
},
265+
severity: 1,
266+
source: "TypeProf",
267+
}
268+
],
269+
}, json)
270+
end
271+
end
272+
235273
def test_diagnostics2
236274
init("basic")
237275

0 commit comments

Comments
 (0)