solargraph 0.58.0 → 0.59.0.dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc +3 -0
  3. data/.gitattributes +2 -0
  4. data/.github/workflows/linting.yml +4 -5
  5. data/.github/workflows/plugins.yml +40 -36
  6. data/.github/workflows/rspec.yml +45 -13
  7. data/.github/workflows/typecheck.yml +2 -2
  8. data/.rubocop_todo.yml +27 -49
  9. data/CHANGELOG.md +3 -0
  10. data/README.md +3 -3
  11. data/Rakefile +1 -0
  12. data/bin/solargraph +8 -8
  13. data/lib/solargraph/api_map/cache.rb +110 -110
  14. data/lib/solargraph/api_map/constants.rb +289 -279
  15. data/lib/solargraph/api_map/index.rb +204 -193
  16. data/lib/solargraph/api_map/source_to_yard.rb +109 -97
  17. data/lib/solargraph/api_map/store.rb +387 -384
  18. data/lib/solargraph/api_map.rb +1000 -945
  19. data/lib/solargraph/complex_type/conformance.rb +176 -0
  20. data/lib/solargraph/complex_type/type_methods.rb +242 -228
  21. data/lib/solargraph/complex_type/unique_type.rb +632 -482
  22. data/lib/solargraph/complex_type.rb +549 -444
  23. data/lib/solargraph/convention/data_definition/data_definition_node.rb +93 -91
  24. data/lib/solargraph/convention/data_definition.rb +108 -105
  25. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +62 -61
  26. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +103 -102
  27. data/lib/solargraph/convention/struct_definition.rb +168 -164
  28. data/lib/solargraph/diagnostics/require_not_found.rb +54 -53
  29. data/lib/solargraph/diagnostics/rubocop.rb +119 -118
  30. data/lib/solargraph/diagnostics/rubocop_helpers.rb +70 -68
  31. data/lib/solargraph/diagnostics/type_check.rb +56 -55
  32. data/lib/solargraph/doc_map.rb +200 -439
  33. data/lib/solargraph/equality.rb +34 -34
  34. data/lib/solargraph/gem_pins.rb +97 -98
  35. data/lib/solargraph/language_server/host/dispatch.rb +131 -130
  36. data/lib/solargraph/language_server/host/message_worker.rb +113 -112
  37. data/lib/solargraph/language_server/host/sources.rb +100 -99
  38. data/lib/solargraph/language_server/host.rb +883 -878
  39. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +109 -114
  40. data/lib/solargraph/language_server/message/extended/document.rb +24 -23
  41. data/lib/solargraph/language_server/message/text_document/completion.rb +58 -56
  42. data/lib/solargraph/language_server/message/text_document/definition.rb +42 -40
  43. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +28 -26
  44. data/lib/solargraph/language_server/message/text_document/formatting.rb +150 -148
  45. data/lib/solargraph/language_server/message/text_document/hover.rb +60 -58
  46. data/lib/solargraph/language_server/message/text_document/signature_help.rb +25 -24
  47. data/lib/solargraph/language_server/message/text_document/type_definition.rb +27 -25
  48. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +25 -23
  49. data/lib/solargraph/library.rb +729 -683
  50. data/lib/solargraph/location.rb +87 -82
  51. data/lib/solargraph/logging.rb +57 -37
  52. data/lib/solargraph/parser/comment_ripper.rb +76 -69
  53. data/lib/solargraph/parser/flow_sensitive_typing.rb +483 -255
  54. data/lib/solargraph/parser/node_processor/base.rb +122 -92
  55. data/lib/solargraph/parser/node_processor.rb +63 -62
  56. data/lib/solargraph/parser/parser_gem/class_methods.rb +167 -149
  57. data/lib/solargraph/parser/parser_gem/node_chainer.rb +191 -166
  58. data/lib/solargraph/parser/parser_gem/node_methods.rb +506 -486
  59. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -22
  60. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +61 -59
  61. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +24 -15
  62. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +46 -46
  63. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +60 -53
  64. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +53 -23
  65. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +41 -40
  66. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +30 -29
  67. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +61 -59
  68. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -98
  69. data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
  70. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +17 -17
  71. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +39 -38
  72. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +53 -52
  73. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +296 -291
  74. data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
  75. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +33 -29
  76. data/lib/solargraph/parser/parser_gem/node_processors.rb +74 -70
  77. data/lib/solargraph/parser/region.rb +75 -69
  78. data/lib/solargraph/parser/snippet.rb +17 -17
  79. data/lib/solargraph/pin/base.rb +761 -729
  80. data/lib/solargraph/pin/base_variable.rb +418 -126
  81. data/lib/solargraph/pin/block.rb +126 -104
  82. data/lib/solargraph/pin/breakable.rb +13 -9
  83. data/lib/solargraph/pin/callable.rb +278 -231
  84. data/lib/solargraph/pin/closure.rb +68 -72
  85. data/lib/solargraph/pin/common.rb +94 -79
  86. data/lib/solargraph/pin/compound_statement.rb +55 -0
  87. data/lib/solargraph/pin/conversions.rb +124 -123
  88. data/lib/solargraph/pin/delegated_method.rb +131 -120
  89. data/lib/solargraph/pin/documenting.rb +115 -114
  90. data/lib/solargraph/pin/instance_variable.rb +38 -34
  91. data/lib/solargraph/pin/keyword.rb +16 -20
  92. data/lib/solargraph/pin/local_variable.rb +31 -75
  93. data/lib/solargraph/pin/method.rb +720 -672
  94. data/lib/solargraph/pin/method_alias.rb +42 -34
  95. data/lib/solargraph/pin/namespace.rb +121 -115
  96. data/lib/solargraph/pin/parameter.rb +338 -275
  97. data/lib/solargraph/pin/proxy_type.rb +40 -39
  98. data/lib/solargraph/pin/reference/override.rb +47 -47
  99. data/lib/solargraph/pin/reference/superclass.rb +17 -15
  100. data/lib/solargraph/pin/reference.rb +41 -39
  101. data/lib/solargraph/pin/search.rb +62 -61
  102. data/lib/solargraph/pin/signature.rb +69 -61
  103. data/lib/solargraph/pin/symbol.rb +53 -53
  104. data/lib/solargraph/pin/until.rb +18 -18
  105. data/lib/solargraph/pin/while.rb +18 -18
  106. data/lib/solargraph/pin.rb +46 -44
  107. data/lib/solargraph/pin_cache.rb +665 -245
  108. data/lib/solargraph/position.rb +118 -119
  109. data/lib/solargraph/range.rb +112 -112
  110. data/lib/solargraph/rbs_map/conversions.rb +846 -823
  111. data/lib/solargraph/rbs_map/core_map.rb +65 -58
  112. data/lib/solargraph/rbs_map/stdlib_map.rb +72 -43
  113. data/lib/solargraph/rbs_map.rb +217 -163
  114. data/lib/solargraph/shell.rb +397 -352
  115. data/lib/solargraph/source/chain/call.rb +372 -337
  116. data/lib/solargraph/source/chain/constant.rb +28 -26
  117. data/lib/solargraph/source/chain/hash.rb +35 -34
  118. data/lib/solargraph/source/chain/if.rb +29 -28
  119. data/lib/solargraph/source/chain/instance_variable.rb +34 -13
  120. data/lib/solargraph/source/chain/literal.rb +53 -48
  121. data/lib/solargraph/source/chain/or.rb +31 -23
  122. data/lib/solargraph/source/chain.rb +294 -291
  123. data/lib/solargraph/source/change.rb +89 -82
  124. data/lib/solargraph/source/cursor.rb +172 -166
  125. data/lib/solargraph/source/encoding_fixes.rb +23 -23
  126. data/lib/solargraph/source/source_chainer.rb +204 -194
  127. data/lib/solargraph/source/updater.rb +59 -55
  128. data/lib/solargraph/source.rb +524 -498
  129. data/lib/solargraph/source_map/clip.rb +237 -226
  130. data/lib/solargraph/source_map/data.rb +37 -34
  131. data/lib/solargraph/source_map/mapper.rb +282 -259
  132. data/lib/solargraph/source_map.rb +220 -212
  133. data/lib/solargraph/type_checker/problem.rb +34 -32
  134. data/lib/solargraph/type_checker/rules.rb +157 -84
  135. data/lib/solargraph/type_checker.rb +895 -814
  136. data/lib/solargraph/version.rb +5 -5
  137. data/lib/solargraph/workspace/config.rb +257 -255
  138. data/lib/solargraph/workspace/gemspecs.rb +367 -0
  139. data/lib/solargraph/workspace/require_paths.rb +98 -97
  140. data/lib/solargraph/workspace.rb +362 -220
  141. data/lib/solargraph/yard_map/helpers.rb +45 -44
  142. data/lib/solargraph/yard_map/mapper/to_method.rb +134 -130
  143. data/lib/solargraph/yard_map/mapper/to_namespace.rb +32 -31
  144. data/lib/solargraph/yard_map/mapper.rb +84 -79
  145. data/lib/solargraph/yardoc.rb +97 -87
  146. data/lib/solargraph.rb +126 -105
  147. data/rbs/fills/rubygems/0/dependency.rbs +193 -0
  148. data/rbs/fills/tuple/tuple.rbs +28 -0
  149. data/rbs/shims/ast/0/node.rbs +5 -0
  150. data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
  151. data/rbs_collection.yaml +1 -1
  152. data/solargraph.gemspec +2 -1
  153. metadata +23 -17
  154. data/lib/solargraph/type_checker/checks.rb +0 -124
  155. data/lib/solargraph/type_checker/param_def.rb +0 -37
  156. data/lib/solargraph/yard_map/to_method.rb +0 -89
  157. data/sig/shims/ast/0/node.rbs +0 -5
  158. /data/{sig → rbs}/shims/ast/2.4/.rbs_meta.yaml +0 -0
  159. /data/{sig → rbs}/shims/ast/2.4/ast.rbs +0 -0
  160. /data/{sig → rbs}/shims/parser/3.2.0.1/builders/default.rbs +0 -0
  161. /data/{sig → rbs}/shims/parser/3.2.0.1/manifest.yaml +0 -0
  162. /data/{sig → rbs}/shims/parser/3.2.0.1/parser.rbs +0 -0
  163. /data/{sig → rbs}/shims/parser/3.2.0.1/polyfill.rbs +0 -0
  164. /data/{sig → rbs}/shims/thor/1.2.0.1/.rbs_meta.yaml +0 -0
  165. /data/{sig → rbs}/shims/thor/1.2.0.1/manifest.yaml +0 -0
  166. /data/{sig → rbs}/shims/thor/1.2.0.1/thor.rbs +0 -0
@@ -1,34 +1,34 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- # @abstract This mixin relies on these -
5
- # methods:
6
- # equality_fields()
7
- module Equality
8
- # @!method equality_fields
9
- # @return [Array]
10
-
11
- # @param other [Object]
12
- # @return [Boolean]
13
- def eql?(other)
14
- self.class.eql?(other.class) &&
15
- # @sg-ignore https://github.com/castwide/solargraph/pull/1114
16
- equality_fields.eql?(other.equality_fields)
17
- end
18
-
19
- # @param other [Object]
20
- # @return [Boolean]
21
- def ==(other)
22
- self.eql?(other)
23
- end
24
-
25
- def hash
26
- equality_fields.hash
27
- end
28
-
29
- def freeze
30
- equality_fields.each(&:freeze)
31
- super
32
- end
33
- end
34
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ # @abstract This mixin relies on these -
5
+ # methods:
6
+ # equality_fields()
7
+ module Equality
8
+ # @!method equality_fields
9
+ # @return [Array]
10
+
11
+ # @param other [Object]
12
+ # @return [Boolean]
13
+ def eql?(other)
14
+ self.class.eql?(other.class) &&
15
+ # @sg-ignore flow sensitive typing should support .class == .class
16
+ equality_fields.eql?(other.equality_fields)
17
+ end
18
+
19
+ # @param other [Object]
20
+ # @return [Boolean]
21
+ def ==(other)
22
+ self.eql?(other)
23
+ end
24
+
25
+ def hash
26
+ equality_fields.hash
27
+ end
28
+
29
+ def freeze
30
+ equality_fields.each(&:freeze)
31
+ super
32
+ end
33
+ end
34
+ end
@@ -1,98 +1,97 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rbs'
4
-
5
- module Solargraph
6
- # A utility for building gem pins from a combination of YARD and RBS
7
- # documentation.
8
- #
9
- module GemPins
10
- class << self
11
- include Logging
12
- end
13
-
14
- # @param pins [Array<Pin::Base>]
15
- # @return [Array<Pin::Base>]
16
- def self.combine_method_pins_by_path(pins)
17
- method_pins, alias_pins = pins.partition { |pin| pin.class == Pin::Method }
18
- by_path = method_pins.group_by(&:path)
19
- by_path.transform_values! do |pins|
20
- GemPins.combine_method_pins(*pins)
21
- end
22
- by_path.values + alias_pins
23
- end
24
-
25
- # @param pins [Array<Pin::Method>]
26
- # @return [Pin::Method, nil]
27
- def self.combine_method_pins(*pins)
28
- # @type [Pin::Method, nil]
29
- combined_pin = nil
30
- # @param memo [Pin::Method, nil]
31
- # @param pin [Pin::Method]
32
- out = pins.reduce(combined_pin) do |memo, pin|
33
- next pin if memo.nil?
34
- if memo == pin && memo.source != :combined
35
- # @todo we should track down situations where we are handled
36
- # the same pin from the same source here and eliminate them -
37
- # this is an efficiency workaround for now
38
- next memo
39
- end
40
- memo.combine_with(pin)
41
- end
42
- logger.debug { "GemPins.combine_method_pins(pins.length=#{pins.length}, pins=#{pins}) => #{out.inspect}" }
43
- out
44
- end
45
-
46
- # @param yard_plugins [Array<String>] The names of YARD plugins to use.
47
- # @param gemspec [Gem::Specification]
48
- # @return [Array<Pin::Base>]
49
- def self.build_yard_pins(yard_plugins, gemspec)
50
- Yardoc.cache(yard_plugins, gemspec) unless Yardoc.cached?(gemspec)
51
- return [] unless Yardoc.cached?(gemspec)
52
- yardoc = Yardoc.load!(gemspec)
53
- YardMap::Mapper.new(yardoc, gemspec).map
54
- end
55
-
56
- # @param yard_pins [Array<Pin::Base>]
57
- # @param rbs_pins [Array<Pin::Base>]
58
- #
59
- # @return [Array<Pin::Base>]
60
- def self.combine(yard_pins, rbs_pins)
61
- in_yard = Set.new
62
- rbs_api_map = Solargraph::ApiMap.new(pins: rbs_pins)
63
- combined = yard_pins.map do |yard_pin|
64
- in_yard.add yard_pin.path
65
- rbs_pin = rbs_api_map.get_path_pins(yard_pin.path).filter { |pin| pin.is_a? Pin::Method }.first
66
- next yard_pin unless rbs_pin && yard_pin.class == Pin::Method
67
-
68
- unless rbs_pin
69
- # @sg-ignore https://github.com/castwide/solargraph/pull/1114
70
- logger.debug { "GemPins.combine: No rbs pin for #{yard_pin.path} - using YARD's '#{yard_pin.inspect} (return_type=#{yard_pin.return_type}; signatures=#{yard_pin.signatures})" }
71
- next yard_pin
72
- end
73
-
74
- out = combine_method_pins(rbs_pin, yard_pin)
75
- logger.debug { "GemPins.combine: Combining yard.path=#{yard_pin.path} - rbs=#{rbs_pin.inspect} with yard=#{yard_pin.inspect} into #{out}" }
76
- out
77
- end
78
- in_rbs_only = rbs_pins.select do |pin|
79
- pin.path.nil? || !in_yard.include?(pin.path)
80
- end
81
- out = combined + in_rbs_only
82
- logger.debug { "GemPins#combine: Returning #{out.length} combined pins" }
83
- out
84
- end
85
-
86
- class << self
87
- private
88
-
89
- # Select the first defined type.
90
- #
91
- # @param choices [Array<ComplexType>]
92
- # @return [ComplexType]
93
- def best_return_type *choices
94
- choices.find { |pin| pin.defined? } || choices.first || ComplexType::UNDEFINED
95
- end
96
- end
97
- end
98
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'rbs'
4
+
5
+ module Solargraph
6
+ # A utility for building gem pins from a combination of YARD and RBS
7
+ # documentation.
8
+ #
9
+ module GemPins
10
+ class << self
11
+ include Logging
12
+ end
13
+
14
+ # @param pins [Array<Pin::Base>]
15
+ # @return [Array<Pin::Base>]
16
+ def self.combine_method_pins_by_path(pins)
17
+ method_pins, alias_pins = pins.partition { |pin| pin.class == Pin::Method }
18
+ by_path = method_pins.group_by(&:path)
19
+ by_path.transform_values! do |pins|
20
+ GemPins.combine_method_pins(*pins)
21
+ end
22
+ by_path.values + alias_pins
23
+ end
24
+
25
+ # @param pins [Array<Pin::Method>]
26
+ # @return [Pin::Method, nil]
27
+ def self.combine_method_pins(*pins)
28
+ # @type [Pin::Method, nil]
29
+ combined_pin = nil
30
+ # @param memo [Pin::Method, nil]
31
+ # @param pin [Pin::Method]
32
+ out = pins.reduce(combined_pin) do |memo, pin|
33
+ next pin if memo.nil?
34
+ if memo == pin && memo.source != :combined
35
+ # @todo we should track down situations where we are handled
36
+ # the same pin from the same source here and eliminate them -
37
+ # this is an efficiency workaround for now
38
+ next memo
39
+ end
40
+ memo.combine_with(pin)
41
+ end
42
+ logger.debug { "GemPins.combine_method_pins(pins.length=#{pins.length}, pins=#{pins}) => #{out.inspect}" }
43
+ out
44
+ end
45
+
46
+ # @param yard_pins [Array<Pin::Base>]
47
+ # @param rbs_pins [Array<Pin::Base>]
48
+ #
49
+ # @return [Array<Pin::Base>]
50
+ def self.combine(yard_pins, rbs_pins)
51
+ in_yard = Set.new
52
+ rbs_store = Solargraph::ApiMap::Store.new(rbs_pins)
53
+ combined = yard_pins.map do |yard_pin|
54
+ in_yard.add yard_pin.path
55
+ rbs_pin = rbs_store.get_path_pins(yard_pin.path).filter { |pin| pin.is_a? Pin::Method }.first
56
+
57
+ next yard_pin unless rbs_pin && yard_pin.is_a?(Pin::Method)
58
+
59
+ unless rbs_pin
60
+ logger.debug { "GemPins.combine: No rbs pin for #{yard_pin.path} - using YARD's '#{yard_pin.inspect} (return_type=#{yard_pin.return_type}; signatures=#{yard_pin.signatures})" }
61
+ next yard_pin
62
+ end
63
+
64
+ # at this point both yard_pins and rbs_pins are methods or
65
+ # method aliases. if not plain methods, prefer the YARD one
66
+ next yard_pin if rbs_pin.class != Pin::Method
67
+
68
+ next rbs_pin if yard_pin.class != Pin::Method
69
+
70
+ # both are method pins
71
+ out = combine_method_pins(rbs_pin, yard_pin)
72
+ logger.debug do
73
+ "GemPins.combine: Combining yard.path=#{yard_pin.path} - rbs=#{rbs_pin.inspect} with yard=#{yard_pin.inspect} into #{out}"
74
+ end
75
+ out
76
+ end
77
+ in_rbs_only = rbs_pins.select do |pin|
78
+ pin.path.nil? || !in_yard.include?(pin.path)
79
+ end
80
+ out = combined + in_rbs_only
81
+ logger.debug { "GemPins#combine: Returning #{out.length} combined pins" }
82
+ out
83
+ end
84
+
85
+ class << self
86
+ private
87
+
88
+ # Select the first defined type.
89
+ #
90
+ # @param choices [Array<ComplexType>]
91
+ # @return [ComplexType]
92
+ def best_return_type *choices
93
+ choices.find { |pin| pin.defined? } || choices.first || ComplexType::UNDEFINED
94
+ end
95
+ end
96
+ end
97
+ end
@@ -1,130 +1,131 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- module LanguageServer
5
- class Host
6
- # Methods for associating sources with libraries via URIs.
7
- #
8
- module Dispatch
9
- # @abstract
10
- # @return [Host::Diagnoser]
11
- def diagnoser
12
- raise NotImplementedError, 'Host::Dispatch requires a diagnoser method'
13
- end
14
-
15
- # @return [Sources]
16
- def sources
17
- @sources ||= begin
18
- src = Sources.new
19
- src.add_observer self, :update_libraries
20
- src
21
- end
22
- end
23
-
24
- # @return [::Array<Library>]
25
- def libraries
26
- @libraries ||= []
27
- end
28
-
29
- # The Sources observer callback that merges a source into the host's
30
- # libraries when it gets updated.
31
- #
32
- # @param uri [String]
33
- # @return [void]
34
- def update_libraries uri
35
- src = sources.find(uri)
36
- using = libraries.select { |lib| lib.contain?(src.filename) }
37
- using.push library_for(uri) if using.empty?
38
- using.each { |lib| lib.merge src }
39
- diagnoser.schedule uri
40
- end
41
-
42
- # Find the best libary match for the given URI.
43
- #
44
- # @param uri [String]
45
- # @return [Library]
46
- def library_for uri
47
- result = explicit_library_for(uri) ||
48
- implicit_library_for(uri) ||
49
- generic_library_for(uri)
50
- # previous library for already call attach. avoid call twice
51
- # result.attach sources.find(uri) if sources.include?(uri)
52
- result
53
- end
54
-
55
- # Find an explicit library match for the given URI. An explicit match
56
- # means the libary's workspace includes the file.
57
- #
58
- # If a matching library is found, the source corresponding to the URI
59
- # gets attached to it.
60
- #
61
- # @raise [FileNotFoundError] if the source could not be attached.
62
- #
63
- # @param uri [String]
64
- # @return [Library, nil]
65
- def explicit_library_for uri
66
- filename = UriHelpers.uri_to_file(uri)
67
- libraries.each do |lib|
68
- if lib.contain?(filename)
69
- lib.attach sources.find(uri) if sources.include?(uri)
70
- return lib
71
- end
72
- end
73
- nil
74
- end
75
-
76
- # Find an implicit library match for the given URI. An implicit match
77
- # means the file is located inside the library's workspace directory,
78
- # regardless of whether the workspace is configured to include it.
79
- #
80
- # If a matching library is found, the source corresponding to the URI
81
- # gets attached to it.
82
- #
83
- # @raise [FileNotFoundError] if the source could not be attached.
84
- #
85
- # @param uri [String]
86
- # @return [Library, nil]
87
- def implicit_library_for uri
88
- filename = UriHelpers.uri_to_file(uri)
89
- libraries.each do |lib|
90
- if filename.start_with?(lib.workspace.directory)
91
- lib.attach sources.find(uri)
92
- return lib
93
- end
94
- end
95
- nil
96
- end
97
-
98
- # @return [Hash{String => undefined}]
99
- def options
100
- @options ||= {}.freeze
101
- end
102
-
103
- # Get a generic library for the given URI and attach the corresponding
104
- # source.
105
- #
106
- # @raise [FileNotFoundError] if the source could not be attached.
107
- #
108
- # @param uri [String]
109
- # @return [Library]
110
- def generic_library_for uri
111
- generic_library.attach sources.find(uri)
112
- generic_library
113
- end
114
-
115
- # @return [Library]
116
- def generic_library
117
- @generic_library ||= Solargraph::Library.new(Solargraph::Workspace.new('', nil, options), nil)
118
- .tap { |lib| lib.add_observer self }
119
- end
120
-
121
- # @param library [Solargraph::Library]
122
- # @param progress [Solargraph::LanguageServer::Progress, nil]
123
- # @return [void]
124
- def update progress
125
- progress&.send(self)
126
- end
127
- end
128
- end
129
- end
130
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module LanguageServer
5
+ class Host
6
+ # Methods for associating sources with libraries via URIs.
7
+ #
8
+ module Dispatch
9
+ # @abstract
10
+ # @return [Host::Diagnoser]
11
+ def diagnoser
12
+ raise NotImplementedError, 'Host::Dispatch requires a diagnoser method'
13
+ end
14
+
15
+ # @return [Sources]
16
+ def sources
17
+ @sources ||= begin
18
+ src = Sources.new
19
+ src.add_observer self, :update_libraries
20
+ src
21
+ end
22
+ end
23
+
24
+ # @return [::Array<Library>]
25
+ def libraries
26
+ @libraries ||= []
27
+ end
28
+
29
+ # The Sources observer callback that merges a source into the host's
30
+ # libraries when it gets updated.
31
+ #
32
+ # @param uri [String]
33
+ # @return [void]
34
+ def update_libraries uri
35
+ src = sources.find(uri)
36
+ # @sg-ignore Need to add nil check here
37
+ using = libraries.select { |lib| lib.contain?(src.filename) }
38
+ using.push library_for(uri) if using.empty?
39
+ using.each { |lib| lib.merge src }
40
+ diagnoser.schedule uri
41
+ end
42
+
43
+ # Find the best libary match for the given URI.
44
+ #
45
+ # @param uri [String]
46
+ # @return [Library]
47
+ def library_for uri
48
+ result = explicit_library_for(uri) ||
49
+ implicit_library_for(uri) ||
50
+ generic_library_for(uri)
51
+ # previous library for already call attach. avoid call twice
52
+ # result.attach sources.find(uri) if sources.include?(uri)
53
+ result
54
+ end
55
+
56
+ # Find an explicit library match for the given URI. An explicit match
57
+ # means the libary's workspace includes the file.
58
+ #
59
+ # If a matching library is found, the source corresponding to the URI
60
+ # gets attached to it.
61
+ #
62
+ # @raise [FileNotFoundError] if the source could not be attached.
63
+ #
64
+ # @param uri [String]
65
+ # @return [Library, nil]
66
+ def explicit_library_for uri
67
+ filename = UriHelpers.uri_to_file(uri)
68
+ libraries.each do |lib|
69
+ if lib.contain?(filename)
70
+ lib.attach sources.find(uri) if sources.include?(uri)
71
+ return lib
72
+ end
73
+ end
74
+ nil
75
+ end
76
+
77
+ # Find an implicit library match for the given URI. An implicit match
78
+ # means the file is located inside the library's workspace directory,
79
+ # regardless of whether the workspace is configured to include it.
80
+ #
81
+ # If a matching library is found, the source corresponding to the URI
82
+ # gets attached to it.
83
+ #
84
+ # @raise [FileNotFoundError] if the source could not be attached.
85
+ #
86
+ # @param uri [String]
87
+ # @return [Library, nil]
88
+ def implicit_library_for uri
89
+ filename = UriHelpers.uri_to_file(uri)
90
+ libraries.each do |lib|
91
+ if filename.start_with?(lib.workspace.directory)
92
+ lib.attach sources.find(uri)
93
+ return lib
94
+ end
95
+ end
96
+ nil
97
+ end
98
+
99
+ # @return [Hash{String => undefined}]
100
+ def options
101
+ @options ||= {}.freeze
102
+ end
103
+
104
+ # Get a generic library for the given URI and attach the corresponding
105
+ # source.
106
+ #
107
+ # @raise [FileNotFoundError] if the source could not be attached.
108
+ #
109
+ # @param uri [String]
110
+ # @return [Library]
111
+ def generic_library_for uri
112
+ generic_library.attach sources.find(uri)
113
+ generic_library
114
+ end
115
+
116
+ # @return [Library]
117
+ def generic_library
118
+ @generic_library ||= Solargraph::Library.new(Solargraph::Workspace.new('', nil, options), nil)
119
+ .tap { |lib| lib.add_observer self }
120
+ end
121
+
122
+ # @param library [Solargraph::Library]
123
+ # @param progress [Solargraph::LanguageServer::Progress, nil]
124
+ # @return [void]
125
+ def update progress
126
+ progress&.send(self)
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end