solargraph 0.51.2 → 0.54.2

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 (183) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/plugins.yml +40 -0
  3. data/.github/workflows/rspec.yml +1 -3
  4. data/.github/workflows/typecheck.yml +34 -0
  5. data/.yardopts +2 -2
  6. data/CHANGELOG.md +127 -5
  7. data/README.md +13 -16
  8. data/SPONSORS.md +1 -7
  9. data/lib/solargraph/api_map/cache.rb +50 -20
  10. data/lib/solargraph/api_map/source_to_yard.rb +17 -10
  11. data/lib/solargraph/api_map/store.rb +60 -15
  12. data/lib/solargraph/api_map.rb +282 -123
  13. data/lib/solargraph/bench.rb +3 -2
  14. data/lib/solargraph/cache.rb +29 -5
  15. data/lib/solargraph/complex_type/type_methods.rb +122 -39
  16. data/lib/solargraph/complex_type/unique_type.rb +310 -76
  17. data/lib/solargraph/complex_type.rb +166 -44
  18. data/lib/solargraph/convention.rb +0 -1
  19. data/lib/solargraph/converters/dd.rb +5 -0
  20. data/lib/solargraph/converters/dl.rb +3 -0
  21. data/lib/solargraph/converters/dt.rb +3 -0
  22. data/lib/solargraph/diagnostics/rubocop.rb +8 -7
  23. data/lib/solargraph/diagnostics/rubocop_helpers.rb +1 -0
  24. data/lib/solargraph/diagnostics/type_check.rb +1 -0
  25. data/lib/solargraph/diagnostics.rb +2 -2
  26. data/lib/solargraph/doc_map.rb +187 -0
  27. data/lib/solargraph/gem_pins.rb +72 -0
  28. data/lib/solargraph/language_server/host/diagnoser.rb +2 -2
  29. data/lib/solargraph/language_server/host/dispatch.rb +22 -5
  30. data/lib/solargraph/language_server/host/message_worker.rb +49 -5
  31. data/lib/solargraph/language_server/host/sources.rb +8 -65
  32. data/lib/solargraph/language_server/host.rb +65 -84
  33. data/lib/solargraph/language_server/message/base.rb +19 -12
  34. data/lib/solargraph/language_server/message/completion_item/resolve.rb +3 -1
  35. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +13 -1
  36. data/lib/solargraph/language_server/message/initialize.rb +19 -2
  37. data/lib/solargraph/language_server/message/text_document/completion.rb +0 -3
  38. data/lib/solargraph/language_server/message/text_document/definition.rb +3 -3
  39. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +3 -3
  40. data/lib/solargraph/language_server/message/text_document/formatting.rb +1 -0
  41. data/lib/solargraph/language_server/message/text_document/hover.rb +3 -1
  42. data/lib/solargraph/language_server/message/text_document/type_definition.rb +3 -3
  43. data/lib/solargraph/language_server/message/text_document.rb +0 -1
  44. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +5 -0
  45. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +2 -2
  46. data/lib/solargraph/language_server/progress.rb +135 -0
  47. data/lib/solargraph/language_server/transport/adapter.rb +16 -1
  48. data/lib/solargraph/language_server/transport/data_reader.rb +2 -0
  49. data/lib/solargraph/language_server.rb +1 -0
  50. data/lib/solargraph/library.rb +207 -111
  51. data/lib/solargraph/location.rb +15 -1
  52. data/lib/solargraph/page.rb +6 -0
  53. data/lib/solargraph/parser/comment_ripper.rb +4 -0
  54. data/lib/solargraph/parser/node_methods.rb +47 -7
  55. data/lib/solargraph/parser/node_processor/base.rb +11 -1
  56. data/lib/solargraph/parser/node_processor.rb +1 -0
  57. data/lib/solargraph/parser/{legacy → parser_gem}/class_methods.rb +31 -9
  58. data/lib/solargraph/parser/{legacy → parser_gem}/flawed_builder.rb +3 -1
  59. data/lib/solargraph/parser/{legacy → parser_gem}/node_chainer.rb +62 -43
  60. data/lib/solargraph/parser/parser_gem/node_methods.rb +495 -0
  61. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/alias_node.rb +1 -1
  62. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +57 -0
  63. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/begin_node.rb +1 -1
  64. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/block_node.rb +3 -2
  65. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/casgn_node.rb +2 -2
  66. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/cvasgn_node.rb +1 -1
  67. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/def_node.rb +7 -20
  68. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/defs_node.rb +2 -2
  69. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/gvasgn_node.rb +1 -1
  70. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/ivasgn_node.rb +2 -2
  71. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/lvasgn_node.rb +4 -4
  72. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +53 -0
  73. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/namespace_node.rb +2 -2
  74. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/orasgn_node.rb +1 -1
  75. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/resbody_node.rb +3 -3
  76. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/sclass_node.rb +1 -1
  77. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/send_node.rb +8 -6
  78. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/sym_node.rb +1 -1
  79. data/lib/solargraph/parser/parser_gem/node_processors.rb +56 -0
  80. data/lib/solargraph/parser/parser_gem.rb +12 -0
  81. data/lib/solargraph/parser/region.rb +1 -1
  82. data/lib/solargraph/parser/snippet.rb +2 -0
  83. data/lib/solargraph/parser.rb +8 -12
  84. data/lib/solargraph/pin/base.rb +78 -10
  85. data/lib/solargraph/pin/base_variable.rb +40 -7
  86. data/lib/solargraph/pin/block.rb +69 -46
  87. data/lib/solargraph/pin/callable.rb +147 -0
  88. data/lib/solargraph/pin/closure.rb +23 -3
  89. data/lib/solargraph/pin/common.rb +6 -6
  90. data/lib/solargraph/pin/conversions.rb +36 -5
  91. data/lib/solargraph/pin/delegated_method.rb +6 -2
  92. data/lib/solargraph/pin/documenting.rb +25 -32
  93. data/lib/solargraph/pin/instance_variable.rb +6 -2
  94. data/lib/solargraph/pin/local_variable.rb +13 -1
  95. data/lib/solargraph/pin/method.rb +205 -32
  96. data/lib/solargraph/pin/namespace.rb +20 -7
  97. data/lib/solargraph/pin/parameter.rb +41 -36
  98. data/lib/solargraph/pin/proxy_type.rb +1 -1
  99. data/lib/solargraph/pin/reference/override.rb +2 -2
  100. data/lib/solargraph/pin/reference.rb +8 -0
  101. data/lib/solargraph/pin/search.rb +3 -3
  102. data/lib/solargraph/pin/signature.rb +8 -14
  103. data/lib/solargraph/pin.rb +4 -2
  104. data/lib/solargraph/range.rb +4 -6
  105. data/lib/solargraph/rbs_map/conversions.rb +326 -76
  106. data/lib/solargraph/rbs_map/core_fills.rb +16 -33
  107. data/lib/solargraph/rbs_map/core_map.rb +3 -13
  108. data/lib/solargraph/rbs_map/stdlib_map.rb +2 -8
  109. data/lib/solargraph/rbs_map.rb +32 -13
  110. data/lib/solargraph/shell.rb +95 -72
  111. data/lib/solargraph/source/chain/array.rb +33 -0
  112. data/lib/solargraph/source/chain/block_symbol.rb +13 -0
  113. data/lib/solargraph/source/chain/block_variable.rb +1 -1
  114. data/lib/solargraph/source/chain/call.rb +152 -69
  115. data/lib/solargraph/source/chain/constant.rb +15 -1
  116. data/lib/solargraph/source/chain/if.rb +23 -0
  117. data/lib/solargraph/source/chain/link.rb +17 -2
  118. data/lib/solargraph/source/chain/or.rb +2 -2
  119. data/lib/solargraph/source/chain/z_super.rb +3 -3
  120. data/lib/solargraph/source/chain.rb +85 -26
  121. data/lib/solargraph/source/change.rb +3 -0
  122. data/lib/solargraph/source/cursor.rb +16 -2
  123. data/lib/solargraph/source/source_chainer.rb +8 -5
  124. data/lib/solargraph/source/updater.rb +1 -0
  125. data/lib/solargraph/source.rb +120 -148
  126. data/lib/solargraph/source_map/clip.rb +16 -27
  127. data/lib/solargraph/source_map/data.rb +30 -0
  128. data/lib/solargraph/source_map/mapper.rb +15 -3
  129. data/lib/solargraph/source_map.rb +48 -24
  130. data/lib/solargraph/type_checker/checks.rb +10 -2
  131. data/lib/solargraph/type_checker/rules.rb +6 -1
  132. data/lib/solargraph/type_checker.rb +150 -39
  133. data/lib/solargraph/version.rb +1 -1
  134. data/lib/solargraph/views/environment.erb +3 -5
  135. data/lib/solargraph/workspace/config.rb +9 -6
  136. data/lib/solargraph/workspace.rb +30 -3
  137. data/lib/solargraph/yard_map/cache.rb +6 -0
  138. data/lib/solargraph/yard_map/helpers.rb +1 -1
  139. data/lib/solargraph/yard_map/mapper/to_method.rb +16 -3
  140. data/lib/solargraph/yard_map/mapper.rb +1 -1
  141. data/lib/solargraph/yard_map/to_method.rb +11 -4
  142. data/lib/solargraph/yard_map.rb +1 -292
  143. data/lib/solargraph/yard_tags.rb +20 -0
  144. data/lib/solargraph/yardoc.rb +52 -0
  145. data/lib/solargraph.rb +6 -4
  146. data/solargraph.gemspec +7 -6
  147. metadata +71 -82
  148. data/lib/solargraph/api_map/bundler_methods.rb +0 -22
  149. data/lib/solargraph/documentor.rb +0 -76
  150. data/lib/solargraph/language_server/host/cataloger.rb +0 -56
  151. data/lib/solargraph/parser/legacy/node_methods.rb +0 -325
  152. data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +0 -23
  153. data/lib/solargraph/parser/legacy/node_processors/args_node.rb +0 -50
  154. data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +0 -15
  155. data/lib/solargraph/parser/legacy/node_processors/sym_node.rb +0 -18
  156. data/lib/solargraph/parser/legacy/node_processors.rb +0 -55
  157. data/lib/solargraph/parser/legacy.rb +0 -12
  158. data/lib/solargraph/parser/rubyvm/class_methods.rb +0 -153
  159. data/lib/solargraph/parser/rubyvm/node_chainer.rb +0 -160
  160. data/lib/solargraph/parser/rubyvm/node_methods.rb +0 -317
  161. data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +0 -85
  162. data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +0 -42
  163. data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +0 -33
  164. data/lib/solargraph/parser/rubyvm/node_processors/cvasgn_node.rb +0 -23
  165. data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +0 -75
  166. data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +0 -68
  167. data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +0 -23
  168. data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +0 -38
  169. data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +0 -39
  170. data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +0 -20
  171. data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +0 -27
  172. data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +0 -39
  173. data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +0 -26
  174. data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +0 -15
  175. data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +0 -51
  176. data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +0 -32
  177. data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +0 -15
  178. data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +0 -279
  179. data/lib/solargraph/parser/rubyvm/node_processors.rb +0 -64
  180. data/lib/solargraph/parser/rubyvm/node_wrapper.rb +0 -47
  181. data/lib/solargraph/parser/rubyvm.rb +0 -40
  182. data/lib/solargraph/rbs_map/core_signs.rb +0 -33
  183. data/lib/yard-solargraph.rb +0 -33
@@ -16,39 +16,23 @@ module Solargraph
16
16
  ].map { |k| Pin::Keyword.new(k) }
17
17
 
18
18
  MISSING = [
19
- Solargraph::Pin::Method.new(name: 'tap', scope: :instance, closure: Solargraph::Pin::Namespace.new(name: 'Object')),
20
- Solargraph::Pin::Method.new(name: 'class', scope: :instance, closure: Solargraph::Pin::Namespace.new(name: 'Object'), comments: '@return [Class<self>]')
19
+ Solargraph::Pin::Method.new(name: 'tap', scope: :instance,
20
+ closure: Solargraph::Pin::Namespace.new(name: 'Object')),
21
+ Solargraph::Pin::Method.new(name: 'class', scope: :instance,
22
+ closure: Solargraph::Pin::Namespace.new(name: 'Object'), comments: '@return [::Class<self>]')
21
23
  ]
22
24
 
23
- YIELDPARAMS = [
24
- Override.from_comment('Object#tap', %(
25
- @return [self]
26
- @yieldparam [self]
27
- )),
28
- Override.from_comment('String#each_line', %(
29
- @yieldparam [String]
30
- )),
31
- ]
32
-
33
- methods_with_yieldparam_subtypes = %w[
34
- Array#each Array#map Array#map! Array#any? Array#all? Array#index
35
- Array#keep_if Array#delete_if
36
- Enumerable#each_entry Enumerable#map Enumerable#any? Enumerable#all?
37
- Enumerable#select Enumerable#reject
38
- Set#each
39
- ]
40
-
41
- YIELDPARAM_SINGLE_PARAMETERS = methods_with_yieldparam_subtypes.map do |path|
42
- Override.from_comment(path, %(
43
- @yieldparam_single_parameter
44
- ))
45
- end
46
-
47
- CLASS_RETURN_TYPES = [
48
- Override.method_return('Class#new', 'self'),
49
- Override.method_return('Class.new', 'Class<BasicObject>'),
50
- Override.method_return('Class#allocate', 'self'),
51
- Override.method_return('Class.allocate', 'Class<BasicObject>'),
25
+ OVERRIDES = [
26
+ Override.from_comment('BasicObject#instance_eval', '@yieldreceiver [self]'),
27
+ Override.from_comment('BasicObject#instance_exec', '@yieldreceiver [self]'),
28
+ Override.from_comment('Module#define_method', '@yieldreceiver [::Object<self>]'),
29
+ Override.from_comment('Module#class_eval', '@yieldreceiver [::Class<self>]'),
30
+ Override.from_comment('Module#class_exec', '@yieldreceiver [::Class<self>]'),
31
+ Override.from_comment('Module#module_eval', '@yieldreceiver [::Module<self>]'),
32
+ Override.from_comment('Module#module_exec', '@yieldreceiver [::Module<self>]'),
33
+ # RBS does not define Class with a generic, so all calls to
34
+ # generic() return an 'untyped'. We can do better:
35
+ Override.method_return('Class#allocate', 'self')
52
36
  ]
53
37
 
54
38
  # HACK: Add Errno exception classes
@@ -60,8 +44,7 @@ module Solargraph
60
44
  end
61
45
  ERRNOS = errnos
62
46
 
63
- ALL = KEYWORDS + MISSING + YIELDPARAMS + YIELDPARAM_SINGLE_PARAMETERS + CLASS_RETURN_TYPES + ERRNOS
47
+ ALL = KEYWORDS + MISSING + OVERRIDES + ERRNOS
64
48
  end
65
49
  end
66
50
  end
67
-
@@ -13,26 +13,16 @@ module Solargraph
13
13
  pins.replace cache
14
14
  else
15
15
  loader = RBS::EnvironmentLoader.new(repository: RBS::Repository.new(no_stdlib: false))
16
- environment = RBS::Environment.from_loader(loader).resolve_type_names
17
- environment.declarations.each { |decl| convert_decl_to_pin(decl, Solargraph::Pin::ROOT_PIN) }
16
+ RBS::Environment.from_loader(loader).resolve_type_names
17
+ load_environment_to_pins(loader)
18
18
  pins.concat RbsMap::CoreFills::ALL
19
19
  processed = ApiMap::Store.new(pins).pins.reject { |p| p.is_a?(Solargraph::Pin::Reference::Override) }
20
+ processed.each { |pin| pin.source = :rbs }
20
21
  pins.replace processed
21
22
 
22
23
  Cache.save('core.ser', pins)
23
24
  end
24
25
  end
25
-
26
- def method_def_to_sigs decl, pin
27
- stubs = CoreSigns.sign(pin.path)
28
- return super unless stubs
29
- stubs.map do |stub|
30
- Pin::Signature.new(
31
- [],
32
- ComplexType.try_parse(stub.return_type)
33
- )
34
- end
35
- end
36
26
  end
37
27
  end
38
28
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'rbs'
4
- require 'set'
5
4
 
6
5
  module Solargraph
7
6
  class RbsMap
@@ -16,11 +15,10 @@ module Solargraph
16
15
  cache = Cache.load('stdlib', "#{library}.ser")
17
16
  if cache
18
17
  pins.replace cache
18
+ @resolved = true
19
19
  else
20
20
  super
21
- if library == 'yaml'
22
- pins.push Solargraph::Pin::Constant.new(name: 'YAML', comments: '@return [Module<Psych>]', closure: Pin::ROOT_PIN)
23
- end
21
+ return unless resolved?
24
22
  Cache.save('stdlib', "#{library}.ser", pins)
25
23
  end
26
24
  end
@@ -30,10 +28,6 @@ module Solargraph
30
28
  def self.load library
31
29
  @stdlib_maps_hash[library] ||= StdlibMap.new(library)
32
30
  end
33
-
34
- def repository
35
- @repository ||= RBS::Repository.new
36
- end
37
31
  end
38
32
  end
39
33
  end
@@ -1,14 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'pathname'
3
4
  require 'rbs'
4
- require 'set'
5
5
 
6
6
  module Solargraph
7
7
  class RbsMap
8
8
  autoload :Conversions, 'solargraph/rbs_map/conversions'
9
9
  autoload :CoreMap, 'solargraph/rbs_map/core_map'
10
10
  autoload :CoreFills, 'solargraph/rbs_map/core_fills'
11
- autoload :CoreSigns, 'solargraph/rbs_map/core_signs'
12
11
  autoload :StdlibMap, 'solargraph/rbs_map/stdlib_map'
13
12
 
14
13
  include Conversions
@@ -19,19 +18,30 @@ module Solargraph
19
18
  attr_reader :library
20
19
 
21
20
  # @param library [String]
22
- def initialize library
21
+ # @param version [String, nil]
22
+ # @param directories [Array<Pathname, String>]
23
+ def initialize library, version = nil, directories: []
23
24
  @library = library
25
+ @version = version
26
+ @collection = nil
27
+ @directories = directories
24
28
  loader = RBS::EnvironmentLoader.new(core_root: nil, repository: repository)
25
- add_library loader, library
29
+ add_library loader, library, version
26
30
  return unless resolved?
27
- environment = RBS::Environment.from_loader(loader).resolve_type_names
28
- environment.declarations.each { |decl| convert_decl_to_pin(decl, Solargraph::Pin::ROOT_PIN) }
31
+ load_environment_to_pins(loader)
29
32
  end
30
33
 
31
- def path_pin path
32
- pins.find { |p| p.path == path }
34
+ # @generic T
35
+ # @param path [String]
36
+ # @param klass [Class<generic<T>>]
37
+ # @return [generic<T>, nil]
38
+ def path_pin path, klass = Pin::Base
39
+ pin = pins.find { |p| p.path == path }
40
+ pin if pin&.is_a?(klass)
33
41
  end
34
42
 
43
+ # @param path [String]
44
+ # @return [Array<Pin::Base>]
35
45
  def path_pins path
36
46
  pins.select { |p| p.path == path }
37
47
  end
@@ -40,14 +50,22 @@ module Solargraph
40
50
  @resolved
41
51
  end
42
52
 
53
+ def repository
54
+ @repository ||= RBS::Repository.new(no_stdlib: false).tap do |repo|
55
+ # @todo Temporarily ignoring external directories due to issues with
56
+ # incomplete/broken gem_rbs_collection installations
57
+ # @directories.each { |dir| repo.add(Pathname.new(dir)) }
58
+ end
59
+ end
60
+
43
61
  # @param library [String]
44
62
  # @return [RbsMap]
45
63
  def self.load library
46
64
  @@rbs_maps_hash[library] ||= RbsMap.new(library)
47
65
  end
48
66
 
49
- def repository
50
- @repository ||= RBS::Repository.new(no_stdlib: true)
67
+ def self.from_gemspec(gemspec)
68
+ RbsMap.new(gemspec.name, gemspec.version)
51
69
  end
52
70
 
53
71
  private
@@ -55,9 +73,9 @@ module Solargraph
55
73
  # @param loader [RBS::EnvironmentLoader]
56
74
  # @param library [String]
57
75
  # @return [Boolean] true if adding the library succeeded
58
- def add_library loader, library
59
- @resolved = if loader.has_library?(library: library, version: nil)
60
- loader.add library: library
76
+ def add_library loader, library, version
77
+ @resolved = if loader.has_library?(library: library, version: version)
78
+ loader.add library: library, version: version
61
79
  Solargraph.logger.info "#{short_name} successfully loaded library #{library}"
62
80
  true
63
81
  else
@@ -66,6 +84,7 @@ module Solargraph
66
84
  end
67
85
  end
68
86
 
87
+ # @return [String]
69
88
  def short_name
70
89
  self.class.name.split('::').last
71
90
  end
@@ -1,14 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'benchmark'
3
4
  require 'thor'
5
+ require 'yard'
4
6
 
5
7
  module Solargraph
6
8
  class Shell < Thor
7
9
  include Solargraph::ServerMethods
8
10
 
11
+ # Tell Thor to ensure the process exits with status 1 if any error happens.
12
+ def self.exit_on_failure?
13
+ true
14
+ end
15
+
9
16
  map %w[--version -v] => :version
10
17
 
11
18
  desc "--version, -v", "Print the version"
19
+ # @return [void]
12
20
  def version
13
21
  puts Solargraph::VERSION
14
22
  end
@@ -16,6 +24,7 @@ module Solargraph
16
24
  desc 'socket', 'Run a Solargraph socket server'
17
25
  option :host, type: :string, aliases: :h, desc: 'The server host', default: '127.0.0.1'
18
26
  option :port, type: :numeric, aliases: :p, desc: 'The server port', default: 7658
27
+ # @return [void]
19
28
  def socket
20
29
  require 'backport'
21
30
  port = options[:port]
@@ -33,6 +42,7 @@ module Solargraph
33
42
  end
34
43
 
35
44
  desc 'stdio', 'Run a Solargraph stdio server'
45
+ # @return [void]
36
46
  def stdio
37
47
  require 'backport'
38
48
  Backport.run do
@@ -49,6 +59,8 @@ module Solargraph
49
59
 
50
60
  desc 'config [DIRECTORY]', 'Create or overwrite a default configuration file'
51
61
  option :extensions, type: :boolean, aliases: :e, desc: 'Add installed extensions', default: true
62
+ # @param directory [String]
63
+ # @return [void]
52
64
  def config(directory = '.')
53
65
  matches = []
54
66
  if options[:extensions]
@@ -71,62 +83,72 @@ module Solargraph
71
83
  STDOUT.puts "Configuration file initialized."
72
84
  end
73
85
 
74
- desc 'download-core [VERSION]', 'Download core documentation [deprecated]', hide: true
75
- long_desc %(
76
- The `download-core` command is deprecated. Current versions of Solargraph
77
- use RBS for core and stdlib documentation.
78
- )
79
- # @deprecated
80
- def download_core _version = nil
81
- puts 'The `download-core` command is deprecated.'
82
- puts 'Current versions of Solargraph use RBS for core and stdlib documentation.'
83
- end
84
-
85
- desc 'list-cores', 'List the local documentation versions [deprecated]', hide: true
86
- long_desc %(
87
- The `list-cores` command is deprecated. Current versions of Solargraph use
88
- RBS for core and stdlib documentation.
89
- )
90
- # @deprecated
91
- def list_cores
92
- puts 'The `list-cores` command is deprecated.'
93
- puts 'Current versions of Solargraph use RBS for core and stdlib documentation.'
94
- end
95
-
96
- desc 'available-cores', 'List available documentation versions [deprecated]', hide: true
97
- long_desc %(
98
- The `available-cores` command is deprecated. Current versions of Solargraph
99
- use RBS for core and stdlib documentation.
100
- )
101
- # @deprecated
102
- def available_cores
103
- puts 'The `available-cores` command is deprecated.'
104
- puts 'Current versions of Solargraph use RBS for core and stdlib documentation.'
105
- end
106
-
107
86
  desc 'clear', 'Delete all cached documentation'
108
87
  long_desc %(
109
88
  This command will delete all core and gem documentation from the cache.
110
89
  )
90
+ # @return [void]
111
91
  def clear
112
- puts "Deleting the cached documentation"
92
+ puts "Deleting all cached documentation (gems, core and stdlib)"
113
93
  Solargraph::Cache.clear
114
94
  end
115
95
  map 'clear-cache' => :clear
116
96
  map 'clear-cores' => :clear
117
97
 
118
- desc 'uncache GEM [...GEM]', "Delete cached gem documentation"
98
+ desc 'cache', 'Cache a gem', hide: true
99
+ # @return [void]
100
+ # @param gem [String]
101
+ # @param version [String, nil]
102
+ def cache gem, version = nil
103
+ spec = Gem::Specification.find_by_name(gem, version)
104
+ pins = GemPins.build(spec)
105
+ Cache.save('gems', "#{spec.name}-#{spec.version}.ser", pins)
106
+ end
107
+
108
+ desc 'uncache GEM [...GEM]', "Delete specific cached gem documentation"
109
+ long_desc %(
110
+ Specify one or more gem names to clear. 'core' or 'stdlib' may
111
+ also be specified to clear cached system documentation.
112
+ Documentation will be regenerated as needed.
113
+ )
114
+ # @return [void]
119
115
  def uncache *gems
120
116
  raise ArgumentError, 'No gems specified.' if gems.empty?
121
117
  gems.each do |gem|
122
- Dir[File.join(Solargraph::YardMap::CoreDocs.cache_dir, 'gems', "#{gem}-*")].each do |dir|
123
- puts "Deleting cache: #{dir}"
124
- FileUtils.remove_entry_secure dir
118
+ if gem == 'core'
119
+ Cache.uncache("core.ser")
120
+ next
121
+ end
122
+
123
+ if gem == 'stdlib'
124
+ Cache.uncache("stdlib")
125
+ next
126
+ end
127
+
128
+ spec = Gem::Specification.find_by_name(gem)
129
+ Cache.uncache('gems', "#{spec.name}-#{spec.version}.ser")
130
+ Cache.uncache('gems', "#{spec.name}-#{spec.version}.yardoc")
131
+ end
132
+ end
133
+
134
+ desc 'gems [GEM[=VERSION]]', 'Cache documentation for installed gems'
135
+ option :rebuild, type: :boolean, desc: 'Rebuild existing documentation', default: false
136
+ # @return [void]
137
+ def gems *names
138
+ if names.empty?
139
+ Gem::Specification.to_a.each { |spec| do_cache spec }
140
+ else
141
+ names.each do |name|
142
+ spec = Gem::Specification.find_by_name(*name.split('='))
143
+ do_cache spec
144
+ rescue Gem::MissingSpecError
145
+ warn "Gem '#{name}' not found"
125
146
  end
126
147
  end
127
148
  end
128
149
 
129
150
  desc 'reporters', 'Get a list of diagnostics reporters'
151
+ # @return [void]
130
152
  def reporters
131
153
  puts Solargraph::Diagnostics.reporters
132
154
  end
@@ -140,26 +162,33 @@ module Solargraph
140
162
  )
141
163
  option :level, type: :string, aliases: [:mode, :m, :l], desc: 'Type checking level', default: 'normal'
142
164
  option :directory, type: :string, aliases: :d, desc: 'The workspace directory', default: '.'
165
+ # @return [void]
143
166
  def typecheck *files
144
167
  directory = File.realpath(options[:directory])
145
- api_map = Solargraph::ApiMap.load(directory)
168
+ api_map = Solargraph::ApiMap.load_with_cache(directory, $stdout)
169
+ probcount = 0
146
170
  if files.empty?
147
171
  files = api_map.source_maps.map(&:filename)
148
172
  else
149
173
  files.map! { |file| File.realpath(file) }
150
174
  end
151
- probcount = 0
152
175
  filecount = 0
153
- files.each do |file|
154
- checker = TypeChecker.new(file, api_map: api_map, level: options[:level].to_sym)
155
- problems = checker.problems
156
- next if problems.empty?
157
- problems.sort! { |a, b| a.location.range.start.line <=> b.location.range.start.line }
158
- puts problems.map { |prob| "#{prob.location.filename}:#{prob.location.range.start.line + 1} - #{prob.message}" }.join("\n")
159
- filecount += 1
160
- probcount += problems.length
161
- end
176
+
177
+ time = Benchmark.measure {
178
+ files.each do |file|
179
+ checker = TypeChecker.new(file, api_map: api_map, level: options[:level].to_sym)
180
+ problems = checker.problems
181
+ next if problems.empty?
182
+ problems.sort! { |a, b| a.location.range.start.line <=> b.location.range.start.line }
183
+ puts problems.map { |prob| "#{prob.location.filename}:#{prob.location.range.start.line + 1} - #{prob.message}" }.join("\n")
184
+ filecount += 1
185
+ probcount += problems.length
186
+ end
187
+ # "
188
+ }
189
+ puts "Typecheck finished in #{time.real} seconds."
162
190
  puts "#{probcount} problem#{probcount != 1 ? 's' : ''} found#{files.length != 1 ? " in #{filecount} of #{files.length} files" : ''}."
191
+ # "
163
192
  exit 1 if probcount > 0
164
193
  end
165
194
 
@@ -172,12 +201,12 @@ module Solargraph
172
201
  )
173
202
  option :directory, type: :string, aliases: :d, desc: 'The workspace directory', default: '.'
174
203
  option :verbose, type: :boolean, aliases: :v, desc: 'Verbose output', default: false
204
+ # @return [void]
175
205
  def scan
176
- require 'benchmark'
177
206
  directory = File.realpath(options[:directory])
178
207
  api_map = nil
179
208
  time = Benchmark.measure {
180
- api_map = Solargraph::ApiMap.load(directory)
209
+ api_map = Solargraph::ApiMap.load_with_cache(directory, $stdout)
181
210
  api_map.pins.each do |pin|
182
211
  begin
183
212
  puts pin_description(pin) if options[:verbose]
@@ -197,32 +226,13 @@ module Solargraph
197
226
  desc 'list', 'List the files in the workspace and the total count'
198
227
  option :count, type: :boolean, aliases: :c, desc: 'Display the file count only', default: false
199
228
  option :directory, type: :string, aliases: :d, desc: 'The directory to read', default: '.'
229
+ # @return [void]
200
230
  def list
201
231
  workspace = Solargraph::Workspace.new(options[:directory])
202
- unless options[:count]
203
- workspace.filenames.each { |f| puts f }
204
- end
232
+ puts workspace.filenames unless options[:count]
205
233
  puts "#{workspace.filenames.length} files total."
206
234
  end
207
235
 
208
- desc 'bundle', 'Generate documentation for bundled gems [deprecated]', hide: true
209
- long_desc %(
210
- The `bundle` command is deprecated. Solargraph currently uses RBS instead.
211
- )
212
- option :directory, type: :string, aliases: :d, desc: 'The workspace directory', default: '.'
213
- option :rebuild, type: :boolean, aliases: :r, desc: 'Rebuild existing documentation', default: false
214
- def bundle
215
- puts 'The `bundle` command is deprecated. Solargraph currently uses RBS instead.'
216
- end
217
-
218
- desc 'rdoc GEM [VERSION]', 'Use RDoc to cache documentation [deprecated]', hide: true
219
- long_desc %(
220
- The `rdoc` command is deprecated. Solargraph currently uses RBS instead.
221
- )
222
- def rdoc _gem, _version = '>= 0'
223
- puts 'The `rdoc` command is deprecated. Solargraph currently uses RBS instead.'
224
- end
225
-
226
236
  private
227
237
 
228
238
  # @param pin [Solargraph::Pin::Base]
@@ -240,5 +250,18 @@ module Solargraph
240
250
  desc += " (#{pin.location.filename} #{pin.location.range.start.line})" if pin.location
241
251
  desc
242
252
  end
253
+
254
+ # @param gemspec [Gem::Specification]
255
+ # @return [void]
256
+ def do_cache gemspec
257
+ cached = Yardoc.cached?(gemspec)
258
+ if cached && !options.rebuild
259
+ puts "Cache already exists for #{gemspec.name} #{gemspec.version}"
260
+ else
261
+ puts "#{cached ? 'Rebuilding' : 'Caching'} gem documentation for #{gemspec.name} #{gemspec.version}"
262
+ pins = GemPins.build(gemspec)
263
+ Cache.save('gems', "#{gemspec.name}-#{gemspec.version}.ser", pins)
264
+ end
265
+ end
243
266
  end
244
267
  end
@@ -0,0 +1,33 @@
1
+ module Solargraph
2
+ class Source
3
+ class Chain
4
+ class Array < Literal
5
+ # @param children [::Array<Chain>]
6
+ def initialize children
7
+ super('::Array')
8
+ @children = children
9
+ end
10
+
11
+ def word
12
+ @word ||= "<#{@type}>"
13
+ end
14
+
15
+ # @param api_map [ApiMap]
16
+ # @param name_pin [Pin::Base]
17
+ # @param locals [Enumerable<Pin::LocalVariable>]
18
+ def resolve api_map, name_pin, locals
19
+ child_types = @children.map do |child|
20
+ child.infer(api_map, name_pin, locals)
21
+ end
22
+
23
+ type = if child_types.uniq.length == 1 && child_types.first.defined?
24
+ ComplexType::UniqueType.new('Array', [], child_types.uniq, rooted: true, parameters_type: :list)
25
+ else
26
+ ComplexType::UniqueType.new('Array', rooted: true)
27
+ end
28
+ [Pin::ProxyType.anonymous(type)]
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class Source
5
+ class Chain
6
+ class BlockSymbol < Link
7
+ def resolve api_map, name_pin, locals
8
+ [Pin::ProxyType.anonymous(ComplexType.try_parse('::Proc'))]
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -5,7 +5,7 @@ module Solargraph
5
5
  class Chain
6
6
  class BlockVariable < Link
7
7
  def resolve api_map, name_pin, locals
8
- [Pin::ProxyType.anonymous(ComplexType.try_parse('Proc'))]
8
+ [Pin::ProxyType.anonymous(ComplexType.try_parse('::Proc'))]
9
9
  end
10
10
  end
11
11
  end