From ad33f8411aae277addf7a9ef1de1e2e60d111457 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 27 Oct 2024 16:56:18 -0400 Subject: [PATCH] Handle nil case typechecking @!parse blocks I hit this on some real-world code, reproduced it with a spec and fixed it: ``` 1) Solargraph::TypeChecker strict level complains on @!parse blocks too Failure/Error: stringified_comments[rng.start.line] ||= begin buff = associated_comments[rng.start.line] buff ? stringify_comment_array(buff) : nil NoMethodError: undefined method `start' for nil:NilClass stringified_comments[rng.start.line] ||= begin ^^^^^^ # ./lib/solargraph/source.rb:256:in `comments_for' # ./lib/solargraph/type_checker.rb:546:in `block in without_ignored' # ./lib/solargraph/type_checker.rb:543:in `reject' # ./lib/solargraph/type_checker.rb:543:in `without_ignored' # ./lib/solargraph/type_checker.rb:43:in `problems' # ./spec/type_checker/levels/strict_spec.rb:15:in `block (3 levels) in ' ``` --- lib/solargraph/type_checker.rb | 2 +- spec/type_checker/levels/strict_spec.rb | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/solargraph/type_checker.rb b/lib/solargraph/type_checker.rb index 059caaeff..9fbbe24d2 100644 --- a/lib/solargraph/type_checker.rb +++ b/lib/solargraph/type_checker.rb @@ -542,7 +542,7 @@ def fake_args_for(pin) def without_ignored problems problems.reject do |problem| node = source_map.source.node_at(problem.location.range.start.line, problem.location.range.start.column) - source_map.source.comments_for(node)&.include?('@sg-ignore') + node && source_map.source.comments_for(node)&.include?('@sg-ignore') end end end diff --git a/spec/type_checker/levels/strict_spec.rb b/spec/type_checker/levels/strict_spec.rb index 22bbd3631..60c8efeae 100644 --- a/spec/type_checker/levels/strict_spec.rb +++ b/spec/type_checker/levels/strict_spec.rb @@ -4,6 +4,18 @@ def type_checker(code) Solargraph::TypeChecker.load_string(code, 'test.rb', :strict) end + it 'complains on @!parse blocks too' do + checker = type_checker(%( + # @!parse + # class Foo + # # @return [Bar] + # def baz; end + # end + )) + expect(checker.problems).to be_one + expect(checker.problems.first.message).to include('Unresolved return type Bar for Foo#baz') + end + it 'ignores method calls with inferred types' do checker = type_checker(%( String.new.upcase