solargraph 0.58.1 → 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 (162) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc +3 -0
  3. data/.github/workflows/linting.yml +4 -5
  4. data/.github/workflows/plugins.yml +40 -36
  5. data/.github/workflows/rspec.yml +45 -13
  6. data/.github/workflows/typecheck.yml +2 -2
  7. data/.rubocop_todo.yml +27 -49
  8. data/README.md +3 -3
  9. data/Rakefile +1 -0
  10. data/lib/solargraph/api_map/cache.rb +110 -110
  11. data/lib/solargraph/api_map/constants.rb +289 -279
  12. data/lib/solargraph/api_map/index.rb +204 -193
  13. data/lib/solargraph/api_map/source_to_yard.rb +109 -97
  14. data/lib/solargraph/api_map/store.rb +387 -384
  15. data/lib/solargraph/api_map.rb +1000 -945
  16. data/lib/solargraph/complex_type/conformance.rb +176 -0
  17. data/lib/solargraph/complex_type/type_methods.rb +242 -228
  18. data/lib/solargraph/complex_type/unique_type.rb +632 -482
  19. data/lib/solargraph/complex_type.rb +549 -444
  20. data/lib/solargraph/convention/data_definition/data_definition_node.rb +93 -91
  21. data/lib/solargraph/convention/data_definition.rb +108 -105
  22. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +62 -61
  23. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +103 -102
  24. data/lib/solargraph/convention/struct_definition.rb +168 -164
  25. data/lib/solargraph/diagnostics/require_not_found.rb +54 -53
  26. data/lib/solargraph/diagnostics/rubocop.rb +119 -118
  27. data/lib/solargraph/diagnostics/rubocop_helpers.rb +70 -68
  28. data/lib/solargraph/diagnostics/type_check.rb +56 -55
  29. data/lib/solargraph/doc_map.rb +200 -439
  30. data/lib/solargraph/equality.rb +34 -34
  31. data/lib/solargraph/gem_pins.rb +97 -98
  32. data/lib/solargraph/language_server/host/dispatch.rb +131 -130
  33. data/lib/solargraph/language_server/host/message_worker.rb +113 -112
  34. data/lib/solargraph/language_server/host/sources.rb +100 -99
  35. data/lib/solargraph/language_server/host.rb +883 -878
  36. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +109 -114
  37. data/lib/solargraph/language_server/message/extended/document.rb +24 -23
  38. data/lib/solargraph/language_server/message/text_document/completion.rb +58 -56
  39. data/lib/solargraph/language_server/message/text_document/definition.rb +42 -40
  40. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +28 -26
  41. data/lib/solargraph/language_server/message/text_document/formatting.rb +150 -148
  42. data/lib/solargraph/language_server/message/text_document/hover.rb +60 -58
  43. data/lib/solargraph/language_server/message/text_document/signature_help.rb +25 -24
  44. data/lib/solargraph/language_server/message/text_document/type_definition.rb +27 -25
  45. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +25 -23
  46. data/lib/solargraph/library.rb +729 -683
  47. data/lib/solargraph/location.rb +87 -82
  48. data/lib/solargraph/logging.rb +57 -37
  49. data/lib/solargraph/parser/comment_ripper.rb +76 -69
  50. data/lib/solargraph/parser/flow_sensitive_typing.rb +483 -255
  51. data/lib/solargraph/parser/node_processor/base.rb +122 -92
  52. data/lib/solargraph/parser/node_processor.rb +63 -62
  53. data/lib/solargraph/parser/parser_gem/class_methods.rb +167 -149
  54. data/lib/solargraph/parser/parser_gem/node_chainer.rb +191 -166
  55. data/lib/solargraph/parser/parser_gem/node_methods.rb +506 -486
  56. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -22
  57. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +61 -59
  58. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +24 -15
  59. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +46 -46
  60. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +60 -53
  61. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +53 -23
  62. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +41 -40
  63. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +30 -29
  64. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +61 -59
  65. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -98
  66. data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
  67. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +17 -17
  68. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +39 -38
  69. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +53 -52
  70. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +296 -291
  71. data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
  72. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +33 -29
  73. data/lib/solargraph/parser/parser_gem/node_processors.rb +74 -70
  74. data/lib/solargraph/parser/region.rb +75 -69
  75. data/lib/solargraph/parser/snippet.rb +17 -17
  76. data/lib/solargraph/pin/base.rb +761 -729
  77. data/lib/solargraph/pin/base_variable.rb +418 -126
  78. data/lib/solargraph/pin/block.rb +126 -104
  79. data/lib/solargraph/pin/breakable.rb +13 -9
  80. data/lib/solargraph/pin/callable.rb +278 -231
  81. data/lib/solargraph/pin/closure.rb +68 -72
  82. data/lib/solargraph/pin/common.rb +94 -79
  83. data/lib/solargraph/pin/compound_statement.rb +55 -0
  84. data/lib/solargraph/pin/conversions.rb +124 -123
  85. data/lib/solargraph/pin/delegated_method.rb +131 -120
  86. data/lib/solargraph/pin/documenting.rb +115 -114
  87. data/lib/solargraph/pin/instance_variable.rb +38 -34
  88. data/lib/solargraph/pin/keyword.rb +16 -20
  89. data/lib/solargraph/pin/local_variable.rb +31 -75
  90. data/lib/solargraph/pin/method.rb +720 -672
  91. data/lib/solargraph/pin/method_alias.rb +42 -34
  92. data/lib/solargraph/pin/namespace.rb +121 -115
  93. data/lib/solargraph/pin/parameter.rb +338 -275
  94. data/lib/solargraph/pin/proxy_type.rb +40 -39
  95. data/lib/solargraph/pin/reference/override.rb +47 -47
  96. data/lib/solargraph/pin/reference/superclass.rb +17 -15
  97. data/lib/solargraph/pin/reference.rb +41 -39
  98. data/lib/solargraph/pin/search.rb +62 -61
  99. data/lib/solargraph/pin/signature.rb +69 -61
  100. data/lib/solargraph/pin/symbol.rb +53 -53
  101. data/lib/solargraph/pin/until.rb +18 -18
  102. data/lib/solargraph/pin/while.rb +18 -18
  103. data/lib/solargraph/pin.rb +46 -44
  104. data/lib/solargraph/pin_cache.rb +665 -245
  105. data/lib/solargraph/position.rb +118 -119
  106. data/lib/solargraph/range.rb +112 -112
  107. data/lib/solargraph/rbs_map/conversions.rb +846 -823
  108. data/lib/solargraph/rbs_map/core_map.rb +65 -58
  109. data/lib/solargraph/rbs_map/stdlib_map.rb +72 -43
  110. data/lib/solargraph/rbs_map.rb +217 -163
  111. data/lib/solargraph/shell.rb +397 -352
  112. data/lib/solargraph/source/chain/call.rb +372 -337
  113. data/lib/solargraph/source/chain/constant.rb +28 -26
  114. data/lib/solargraph/source/chain/hash.rb +35 -34
  115. data/lib/solargraph/source/chain/if.rb +29 -28
  116. data/lib/solargraph/source/chain/instance_variable.rb +34 -13
  117. data/lib/solargraph/source/chain/literal.rb +53 -48
  118. data/lib/solargraph/source/chain/or.rb +31 -23
  119. data/lib/solargraph/source/chain.rb +294 -291
  120. data/lib/solargraph/source/change.rb +89 -82
  121. data/lib/solargraph/source/cursor.rb +172 -166
  122. data/lib/solargraph/source/source_chainer.rb +204 -194
  123. data/lib/solargraph/source/updater.rb +59 -55
  124. data/lib/solargraph/source.rb +524 -498
  125. data/lib/solargraph/source_map/clip.rb +237 -226
  126. data/lib/solargraph/source_map/data.rb +37 -34
  127. data/lib/solargraph/source_map/mapper.rb +282 -259
  128. data/lib/solargraph/source_map.rb +220 -212
  129. data/lib/solargraph/type_checker/problem.rb +34 -32
  130. data/lib/solargraph/type_checker/rules.rb +157 -84
  131. data/lib/solargraph/type_checker.rb +895 -814
  132. data/lib/solargraph/version.rb +1 -1
  133. data/lib/solargraph/workspace/config.rb +257 -255
  134. data/lib/solargraph/workspace/gemspecs.rb +367 -0
  135. data/lib/solargraph/workspace/require_paths.rb +98 -97
  136. data/lib/solargraph/workspace.rb +362 -220
  137. data/lib/solargraph/yard_map/helpers.rb +45 -44
  138. data/lib/solargraph/yard_map/mapper/to_method.rb +134 -130
  139. data/lib/solargraph/yard_map/mapper/to_namespace.rb +32 -31
  140. data/lib/solargraph/yard_map/mapper.rb +84 -79
  141. data/lib/solargraph/yardoc.rb +97 -87
  142. data/lib/solargraph.rb +126 -105
  143. data/rbs/fills/rubygems/0/dependency.rbs +193 -0
  144. data/rbs/fills/tuple/tuple.rbs +28 -0
  145. data/rbs/shims/ast/0/node.rbs +5 -0
  146. data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
  147. data/rbs_collection.yaml +1 -1
  148. data/solargraph.gemspec +2 -1
  149. metadata +22 -17
  150. data/lib/solargraph/type_checker/checks.rb +0 -124
  151. data/lib/solargraph/type_checker/param_def.rb +0 -37
  152. data/lib/solargraph/yard_map/to_method.rb +0 -89
  153. data/sig/shims/ast/0/node.rbs +0 -5
  154. /data/{sig → rbs}/shims/ast/2.4/.rbs_meta.yaml +0 -0
  155. /data/{sig → rbs}/shims/ast/2.4/ast.rbs +0 -0
  156. /data/{sig → rbs}/shims/parser/3.2.0.1/builders/default.rbs +0 -0
  157. /data/{sig → rbs}/shims/parser/3.2.0.1/manifest.yaml +0 -0
  158. /data/{sig → rbs}/shims/parser/3.2.0.1/parser.rbs +0 -0
  159. /data/{sig → rbs}/shims/parser/3.2.0.1/polyfill.rbs +0 -0
  160. /data/{sig → rbs}/shims/thor/1.2.0.1/.rbs_meta.yaml +0 -0
  161. /data/{sig → rbs}/shims/thor/1.2.0.1/manifest.yaml +0 -0
  162. /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