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
7 changes: 1 addition & 6 deletions lib/ruby_lsp/listeners/document_link.rb
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,6 @@ def parse_package_url(uri_string)
return unless path

gem_name = purl.name
return unless gem_name

file_path = self.class.gem_paths.dig(gem_name, gem_version, CGI.unescape(path))
return if file_path.nil?

Expand All @@ -160,10 +158,7 @@ def parse_source_uri(uri_string)
path = uri.path
return unless path

gem_name = uri.gem_name
return unless gem_name

file_path = self.class.gem_paths.dig(gem_name, gem_version, CGI.unescape(path))
file_path = self.class.gem_paths.dig(uri.gem_name, gem_version, CGI.unescape(path))
return if file_path.nil?

[file_path, uri.line_number || "0"]
Expand Down
13 changes: 7 additions & 6 deletions lib/ruby_lsp/requests/support/source_uri.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

module URI
# Must be kept in sync with the one in Tapioca
# https://github.com/Shopify/tapioca/blob/main/lib/tapioca/helpers/source_uri.rb
class Source < URI::File
COMPONENT = [
:scheme,
Expand All @@ -21,16 +22,14 @@ class Source < URI::File
# have the uri gem in their own bundle and thus not use a compatible version.
PARSER = const_defined?(:RFC2396_PARSER) ? RFC2396_PARSER : DEFAULT_PARSER #: RFC2396_Parser

self #: as untyped # rubocop:disable Style/RedundantSelf
.alias_method(:gem_name, :host)
self #: as untyped # rubocop:disable Style/RedundantSelf
.alias_method(:line_number, :fragment)
alias_method(:gem_name, :host)
alias_method(:line_number, :fragment)

#: String?
attr_reader :gem_version

class << self
#: (gem_name: String, gem_version: String?, path: String, line_number: String?) -> URI::Source
#: (gem_name: String, gem_version: String?, path: String, line_number: String?) -> instance
def build(gem_name:, gem_version:, path:, line_number:)
super(
{
Expand Down Expand Up @@ -67,12 +66,14 @@ def check_host(v)

#: -> String
def to_s
"source://#{gem_name}/#{gem_version}#{path}##{line_number}"
"source://#{gem_name}/#{gem_version}/#{path}##{line_number}"
end

if URI.respond_to?(:register_scheme)
# Handle URI 0.11.0 and newer https://github.com/ruby/uri/pull/26
URI.register_scheme("SOURCE", self)
else
# Fallback for URI <0.11.0
@@schemes = @@schemes #: Hash[String, untyped] # rubocop:disable Style/ClassVars
@@schemes["SOURCE"] = self
end
Expand Down
11 changes: 4 additions & 7 deletions sorbet/rbi/shims/uri.rbi
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,13 @@ module URI
end

class Source
sig { returns(String) }
attr_reader :host
# These are inherited from `URI::File`.
# We need to repeat them so Sorbet statically knows about them, so they can be aliased.

sig { returns(String) }
attr_reader :fragment

sig { returns(T.nilable(String)) }
attr_accessor :line_number
attr_reader :host

sig { returns(T.nilable(String)) }
attr_accessor :gem_name
attr_reader :fragment
end
end
30 changes: 30 additions & 0 deletions test/fixtures/source_comment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,33 @@ module Foo
# source://deleted//lib/foo.rb.rb#1
def baz
end

# Various URIs crafted to attempt to make `URI::Source#host` nil.
# All of these will be filtered out, and not appear in the expectation file.

# source:+1-800-555-5555
def attempt_to_make_empty_host_1; end

# source:
def attempt_to_make_empty_host_2; end

# source:/
def attempt_to_make_empty_host_3; end

# source://
def attempt_to_make_empty_host_4; end

# source:///
def attempt_to_make_empty_host_5; end

# source:#123
def attempt_to_make_empty_host_6; end

# source:/#123
def attempt_to_make_empty_host_7; end

# source://#123
def attempt_to_make_empty_host_8; end

# source:///#123
def attempt_to_make_empty_host_9; end