solargraph 0.40.3 → 0.42.0

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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +0 -5
  3. data/CHANGELOG.md +34 -0
  4. data/README.md +15 -0
  5. data/SPONSORS.md +1 -0
  6. data/lib/.rubocop.yml +4 -3
  7. data/lib/solargraph.rb +8 -7
  8. data/lib/solargraph/api_map.rb +40 -111
  9. data/lib/solargraph/api_map/store.rb +5 -0
  10. data/lib/solargraph/bench.rb +13 -16
  11. data/lib/solargraph/compat.rb +15 -1
  12. data/lib/solargraph/diagnostics/rubocop.rb +10 -2
  13. data/lib/solargraph/diagnostics/rubocop_helpers.rb +18 -0
  14. data/lib/solargraph/diagnostics/type_check.rb +1 -1
  15. data/lib/solargraph/language_server/host.rb +108 -7
  16. data/lib/solargraph/language_server/host/diagnoser.rb +9 -1
  17. data/lib/solargraph/language_server/host/sources.rb +1 -1
  18. data/lib/solargraph/language_server/message/completion_item/resolve.rb +1 -0
  19. data/lib/solargraph/language_server/message/extended/environment.rb +3 -3
  20. data/lib/solargraph/language_server/message/initialize.rb +37 -35
  21. data/lib/solargraph/language_server/message/text_document/formatting.rb +28 -7
  22. data/lib/solargraph/language_server/message/text_document/hover.rb +1 -1
  23. data/lib/solargraph/library.rb +132 -22
  24. data/lib/solargraph/parser/rubyvm/node_chainer.rb +0 -1
  25. data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +11 -12
  26. data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +1 -6
  27. data/lib/solargraph/shell.rb +5 -1
  28. data/lib/solargraph/source.rb +1 -1
  29. data/lib/solargraph/source/chain/head.rb +0 -16
  30. data/lib/solargraph/source/source_chainer.rb +1 -0
  31. data/lib/solargraph/source_map/mapper.rb +0 -5
  32. data/lib/solargraph/type_checker.rb +2 -2
  33. data/lib/solargraph/type_checker/checks.rb +4 -4
  34. data/lib/solargraph/version.rb +1 -1
  35. data/lib/solargraph/workspace.rb +1 -0
  36. data/lib/solargraph/workspace/config.rb +4 -3
  37. data/lib/solargraph/yard_map.rb +41 -39
  38. data/lib/solargraph/yard_map/core_fills.rb +1 -0
  39. data/solargraph.gemspec +1 -0
  40. metadata +16 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8eaae0cf888e025f51bdbeea3c414f98e7014d416f58e23d29770b4969f1eb5a
4
- data.tar.gz: 4d0b4b1d24e81953aa819b83f318767e79ce7d6ed3cfb5f6e4b1fcf6a3b5ffc0
3
+ metadata.gz: ee62ce435bde441d527641ea98d3f448d36ce67f575f35d16927c315a98f1401
4
+ data.tar.gz: 514c7a0540e0bce8b050e9da507ed6d778b0ba482c5c73bef6ebc54360d93367
5
5
  SHA512:
6
- metadata.gz: 668db64477f7249ad2d9381292e19f4007a28d607eedfb96848bbb9efd55645ec78c705976e31f765d706c47f08243a322594ccf177f54c950432f565f286789
7
- data.tar.gz: e0986273bb88005f0471c5837f979507fd8f2d13b9d45c1717e6bd77c3ebfd42c746e87aaf41fdf0271007c31849f8622fe9e5a4974e8a35bd0d9f6a4b8e9e3c
6
+ metadata.gz: fec2a060f92ba925c0911b41025033afb6821e0f5758de849c2722a03b9b102b97f437dad23097d442546e254f21ec407fdf3ca494ee311ce3d2f26396cc9e1d
7
+ data.tar.gz: 919ae0f90af0de75228cf2c42eb5ab22a9f9ef3af9c9f7003c4fdf746d0b2ee43375f006a08b926f4d5135facfd97f4cacd5df47e2a1862c3d17a96d4c11b004
data/.travis.yml CHANGED
@@ -8,15 +8,10 @@ rvm:
8
8
  - jruby-head
9
9
  matrix:
10
10
  include:
11
- - rvm: 2.4
12
- os: osx
13
- - rvm: 2.6
14
- os: osx
15
11
  - rvm: 2.7
16
12
  os: osx
17
13
  allow_failures:
18
14
  - rvm: jruby-head
19
- - rvm: 3.0
20
15
  before_install:
21
16
  - gem update --system
22
17
  - gem install bundler
data/CHANGELOG.md CHANGED
@@ -1,3 +1,37 @@
1
+ ## 0.42.0 - June 11, 2021
2
+ - Improve YardMap efficiency
3
+ - Bench includes Workspace for cataloging
4
+ - Initialize confirms static features from options (#436)
5
+ - Enable simple repairs without incremental sync (#416)
6
+ - Discard unrecognized client responses
7
+ - Notify on use of closest match for core (#390)
8
+
9
+ ## 0.41.2 - June 9, 2021
10
+ - Rescue InvalidOffset in async diagnosis
11
+ - Remove erroneous escaping from Hover
12
+
13
+ ## 0.41.1 - May 31, 2021
14
+ - ApiMap handles required bundles (#443)
15
+
16
+ ## 0.41.0 - May 30, 2021
17
+ - Chain constant at last double colon with more than two nested namespaces
18
+ - Fill Integer#times return type (#440)
19
+ - Validate included modules in type checks (#424)
20
+ - Faster language server initialization
21
+ - Server response to initialize is near immediate
22
+ - Workspace is mapped in a background thread
23
+ - Supported clients report mapping progress
24
+ - Log RuboCop corrections at info level (#426)
25
+ - Allow configuring the version of RuboCop to require (#430)
26
+ - Fix source of diagnostic (#434)
27
+ - Fix file argument in RuboCop (#435)
28
+ - Config ignores directories with .rb extension (#423)
29
+
30
+ ## 0.40.4 - March 3, 2021
31
+ - Fix optarg and blockarg ordering
32
+ - Override specialization for #initialize
33
+ - Find definitions with cursor after double colon
34
+
1
35
  ## 0.40.3 - February 7, 2021
2
36
  - Simplify and allow to configure rubocop formatter (#403)
3
37
  - Type checker shows tag in param type errors (#398)
data/README.md CHANGED
@@ -79,6 +79,21 @@ Run `bundle install` and use `bundle exec yard gems` to generate the documentati
79
79
 
80
80
  In order to make sure you're using the correct dependencies, you can start the language server with Bundler. In VS Code, there's a `solargraph.useBundler` option. Other clients will vary, but the command you probably want to run is `bundle exec solargraph socket` or `bundle exec solargraph stdio`.
81
81
 
82
+ ### Rubocop Version
83
+
84
+ If you have multiple versions of [`rubocop`](https://rubygems.org/gems/rubocop) installed and you would like to choose a version other than the latest to use, this specific version can be configured.
85
+
86
+ In `.solargraph.yml`:
87
+
88
+ ```yaml
89
+ ---
90
+ reporters:
91
+ - rubocop:version=0.61.0 # diagnostics
92
+ formatter:
93
+ rubocop:
94
+ version: 0.61.0 # formatting
95
+ ```
96
+
82
97
  ### Integrating Other Editors
83
98
 
84
99
  The [language server protocol](https://microsoft.github.io/language-server-protocol/specification) is the recommended way for integrating Solargraph into editors and IDEs. Clients can connect using either stdio or TCP. Language client developers should refer to [https://solargraph.org/guides/language-server](https://solargraph.org/guides/language-server).
data/SPONSORS.md CHANGED
@@ -13,3 +13,4 @@ The following people and organizations provide funding or other resources. [Beco
13
13
  - Emily Strickland
14
14
  - Tom de Grunt
15
15
  - Akira Yamada
16
+ - Jared White
data/lib/.rubocop.yml CHANGED
@@ -1,5 +1,5 @@
1
- Layout/EndOfLine:
2
- EnforcedStyle: lf
1
+ AllCops:
2
+ NewCops: enable
3
3
  Style/MethodDefParentheses:
4
4
  Enabled: false
5
5
  Layout/EmptyLineAfterGuardClause:
@@ -10,6 +10,8 @@ Lint/RaiseException:
10
10
  Enabled: true
11
11
  Lint/StructNewOverride:
12
12
  Enabled: true
13
+ Metrics/MethodLength:
14
+ Max: 25
13
15
  Style/ExponentialNotation:
14
16
  Enabled: true
15
17
  Style/HashEachMethods:
@@ -18,4 +20,3 @@ Style/HashTransformKeys:
18
20
  Enabled: true
19
21
  Style/HashTransformValues:
20
22
  Enabled: true
21
-
data/lib/solargraph.rb CHANGED
@@ -9,13 +9,14 @@ require 'solargraph/version'
9
9
  # static analysis, and language server libraries.
10
10
  #
11
11
  module Solargraph
12
- class InvalidOffsetError < RangeError; end
13
- class DiagnosticsError < RuntimeError; end
14
- class FileNotFoundError < RuntimeError; end
15
- class SourceNotAvailableError < StandardError; end
16
- class ComplexTypeError < StandardError; end
17
- class WorkspaceTooLargeError < RuntimeError; end
18
- class BundleNotFoundError < StandardError; end
12
+ class InvalidOffsetError < RangeError; end
13
+ class DiagnosticsError < RuntimeError; end
14
+ class FileNotFoundError < RuntimeError; end
15
+ class SourceNotAvailableError < StandardError; end
16
+ class ComplexTypeError < StandardError; end
17
+ class WorkspaceTooLargeError < RuntimeError; end
18
+ class BundleNotFoundError < StandardError; end
19
+ class InvalidRubocopVersionError < RuntimeError; end
19
20
 
20
21
  autoload :Position, 'solargraph/position'
21
22
  autoload :Range, 'solargraph/range'
@@ -17,7 +17,6 @@ module Solargraph
17
17
  autoload :BundlerMethods, 'solargraph/api_map/bundler_methods'
18
18
 
19
19
  include SourceToYard
20
- include BundlerMethods
21
20
 
22
21
  # @return [Array<String>]
23
22
  attr_reader :unresolved_requires
@@ -33,7 +32,12 @@ module Solargraph
33
32
  # @param pins [Array<Pin::Base>]
34
33
  # @return [self]
35
34
  def index pins
36
- catalog Bench.new(pins: pins)
35
+ # @todo This implementation is incomplete. It should probably create a
36
+ # Bench.
37
+ @source_map_hash = {}
38
+ implicit.clear
39
+ cache.clear
40
+ @store = Store.new(yard_map.pins + pins)
37
41
  self
38
42
  end
39
43
 
@@ -42,97 +46,39 @@ module Solargraph
42
46
  # @param source [Source]
43
47
  # @return [self]
44
48
  def map source
45
- catalog Bench.new(opened: [source])
49
+ map = Solargraph::SourceMap.map(source)
50
+ catalog Bench.new(source_maps: [map])
46
51
  self
47
52
  end
48
53
 
49
- # @param name [String]
50
- # @return [YARD::Tags::MacroDirective, nil]
51
- def named_macro name
52
- store.named_macros[name]
53
- end
54
-
55
54
  # Catalog a bench.
56
55
  #
57
56
  # @param bench [Bench]
58
- # @return [self]
59
57
  def catalog bench
60
- new_map_hash = {}
61
- # Bench always needs to be merged if it adds or removes sources
62
- merged = (bench.sources.length == source_map_hash.values.length)
63
- bench.sources.each do |source|
64
- if source_map_hash.key?(source.filename)
65
- if source_map_hash[source.filename].code == source.code &&
66
- source_map_hash[source.filename].source.synchronized? &&
67
- source.synchronized?
68
- new_map_hash[source.filename] = source_map_hash[source.filename]
69
- elsif !source.synchronized?
70
- new_map_hash[source.filename] = source_map_hash[source.filename]
71
- # @todo Smelly instance variable access
72
- new_map_hash[source.filename].instance_variable_set(:@source, source)
73
- else
74
- map = Solargraph::SourceMap.map(source)
75
- if source_map_hash[source.filename].try_merge!(map)
76
- new_map_hash[source.filename] = source_map_hash[source.filename]
77
- else
78
- new_map_hash[source.filename] = map
79
- merged = false
80
- end
81
- end
82
- else
83
- map = Solargraph::SourceMap.map(source)
84
- new_map_hash[source.filename] = map
85
- merged = false
86
- end
87
- end
88
- return self if bench.pins.empty? && @store && merged
89
58
  implicit.clear
90
- pins = []
91
- reqs = Set.new
92
- # @param map [SourceMap]
93
- new_map_hash.each_value do |map|
94
- pins.concat map.pins
95
- reqs.merge map.requires.map(&:name)
96
- end
97
- pins.concat bench.pins
98
- reqs.merge bench.workspace.config.required
99
- @required = reqs
100
- bench.sources.each do |src|
101
- implicit.merge new_map_hash[src.filename].environ
102
- end
103
- # implicit.merge Convention.for_global(self)
104
- local_path_hash.clear
105
- unless bench.workspace.require_paths.empty?
106
- file_keys = new_map_hash.keys
107
- workspace_path = Pathname.new(bench.workspace.directory)
108
- reqs.delete_if do |r|
109
- bench.workspace.require_paths.any? do |base|
110
- pn = workspace_path.join(base, "#{r}.rb").to_s
111
- if file_keys.include? pn
112
- local_path_hash[r] = pn
113
- true
114
- else
115
- false
116
- end
117
- end
118
- end
119
- end
120
- reqs.merge implicit.requires
121
- br = reqs.include?('bundler/require') ? require_from_bundle(bench.workspace.directory) : {}
122
- reqs.merge br.keys
123
- yard_map.change(reqs.to_a, br, bench.workspace.gemnames)
124
- new_store = Store.new(yard_map.pins + implicit.pins + pins)
125
59
  @cache.clear
126
- @source_map_hash = new_map_hash
127
- @store = new_store
60
+ @source_map_hash = bench.source_maps.map { |s| [s.filename, s] }.to_h
61
+ pins = bench.source_maps.map(&:pins).flatten
62
+ external_requires = bench.external_requires
63
+ source_map_hash.each_value do |map|
64
+ implicit.merge map.environ
65
+ end
66
+ external_requires.merge implicit.requires
67
+ external_requires.merge bench.workspace.config.required
68
+ yard_map.change(external_requires, bench.workspace.directory, bench.workspace.source_gems)
69
+ @store = Store.new(yard_map.pins + implicit.pins + pins)
128
70
  @unresolved_requires = yard_map.unresolved_requires
129
- workspace_filenames.clear
130
- workspace_filenames.concat bench.workspace.filenames
131
71
  @rebindable_method_names = nil
132
72
  store.block_pins.each { |blk| blk.rebind(self) }
133
73
  self
134
74
  end
135
75
 
76
+ # @param name [String]
77
+ # @return [YARD::Tags::MacroDirective, nil]
78
+ def named_macro name
79
+ store.named_macros[name]
80
+ end
81
+
136
82
  def required
137
83
  @required ||= Set.new
138
84
  end
@@ -142,11 +88,6 @@ module Solargraph
142
88
  @implicit ||= Environ.new
143
89
  end
144
90
 
145
- # @return [Hash{String => String}]
146
- def local_path_hash
147
- @local_paths ||= {}
148
- end
149
-
150
91
  # @param filename [String]
151
92
  # @param position [Position, Array(Integer, Integer)]
152
93
  # @return [Source::Cursor]
@@ -173,7 +114,10 @@ module Solargraph
173
114
  def self.load directory
174
115
  api_map = new
175
116
  workspace = Solargraph::Workspace.new(directory)
176
- api_map.catalog Bench.new(workspace: workspace)
117
+ # api_map.catalog Bench.new(workspace: workspace)
118
+ library = Library.new(workspace)
119
+ library.map!
120
+ api_map.catalog library.bench
177
121
  api_map
178
122
  end
179
123
 
@@ -490,27 +434,6 @@ module Solargraph
490
434
  source_map_hash.keys.include?(filename)
491
435
  end
492
436
 
493
- # True if the specified file is included in the workspace.
494
- #
495
- # @param filename [String]
496
- def workspaced? filename
497
- workspace_filenames.include?(filename)
498
- end
499
-
500
- # @param location [Location]
501
- # @return [Location]
502
- def require_reference_at location
503
- map = source_map(location.filename)
504
- pin = map.requires.select { |p| p.location.range.contain?(location.range.start) }.first
505
- return nil if pin.nil?
506
- if local_path_hash.key?(pin.name)
507
- return Location.new(local_path_hash[pin.name], Solargraph::Range.from_to(0, 0, 0, 0))
508
- end
509
- yard_map.require_reference(pin.name)
510
- rescue FileNotFoundError
511
- nil
512
- end
513
-
514
437
  # Check if a class is a superclass of another class.
515
438
  #
516
439
  # @param sup [String] The superclass
@@ -531,20 +454,26 @@ module Solargraph
531
454
  @yard_map ||= YardMap.new
532
455
  end
533
456
 
534
- private
535
-
536
- # @return [Array<String>]
537
- def workspace_filenames
538
- @workspace_filenames ||= []
457
+ # Check if the host class includes the specified module.
458
+ #
459
+ # @param host [String] The class
460
+ # @param mod [String] The module
461
+ # @return [Boolean]
462
+ def type_include?(host, mod)
463
+ store.get_includes(host).include?(mod)
539
464
  end
540
465
 
466
+ private
467
+
541
468
  # A hash of source maps with filename keys.
542
469
  #
543
470
  # @return [Hash{String => SourceMap}]
544
471
  attr_reader :source_map_hash
545
472
 
546
473
  # @return [ApiMap::Store]
547
- attr_reader :store
474
+ def store
475
+ @store ||= Store.new
476
+ end
548
477
 
549
478
  # @return [Solargraph::ApiMap::Cache]
550
479
  attr_reader :cache
@@ -238,11 +238,16 @@ module Solargraph
238
238
  pins_by_class(Pin::Reference::Override).each do |ovr|
239
239
  pin = get_path_pins(ovr.name).first
240
240
  next if pin.nil?
241
+ new_pin = if pin.path.end_with?('#initialize')
242
+ get_path_pins(pin.path.sub(/#initialize/, '.new')).first
243
+ end
241
244
  (ovr.tags.map(&:tag_name) + ovr.delete).uniq.each do |tag|
242
245
  pin.docstring.delete_tags tag.to_sym
246
+ new_pin.docstring.delete_tags tag.to_sym if new_pin
243
247
  end
244
248
  ovr.tags.each do |tag|
245
249
  pin.docstring.add_tag(tag)
250
+ new_pin.docstring.add_tag(tag) if new_pin
246
251
  end
247
252
  end
248
253
  end
@@ -1,30 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'set'
4
+
3
5
  module Solargraph
4
- # An aggregation of a workspace and additional sources to be cataloged in an
5
- # ApiMap.
6
+ # A container of source maps and gem specs to be cataloged in an ApiMap.
6
7
  #
7
8
  class Bench
9
+ # @return [Set<SourceMap>]
10
+ attr_reader :source_maps
11
+
8
12
  # @return [Workspace]
9
13
  attr_reader :workspace
10
14
 
11
- # @return [Array<Source>]
12
- attr_reader :opened
13
-
14
- # @return [Array<Pin::Base>]
15
- attr_reader :pins
15
+ # @return [Set<String>]
16
+ attr_reader :external_requires
16
17
 
18
+ # @param source_maps [Array<SourceMap>, Set<SourceMap>]
17
19
  # @param workspace [Workspace]
18
- # @param opened [Array<Source>]
19
- def initialize workspace: Workspace.new, opened: [], pins: []
20
+ # @param external_requires [Array<String>, Set<String>]
21
+ def initialize source_maps: [], workspace: Workspace.new, external_requires: []
22
+ @source_maps = source_maps.to_set
20
23
  @workspace = workspace
21
- @opened = opened
22
- @pins = pins
23
- end
24
-
25
- # @return [Array<Source>]
26
- def sources
27
- @sources ||= (opened + workspace.sources).uniq(&:filename)
24
+ @external_requires = external_requires.to_set
28
25
  end
29
26
  end
30
27
  end
@@ -1,9 +1,23 @@
1
+ unless Hash.method_defined?(:transform_keys)
2
+ class Hash
3
+ def transform_keys &block
4
+ result = {}
5
+ each_pair do |k, v|
6
+ result[block.call(k)] = v
7
+ end
8
+ result
9
+ end
10
+ end
11
+ end
12
+
1
13
  unless Hash.method_defined?(:transform_values)
2
14
  class Hash
3
15
  def transform_values &block
16
+ result = {}
4
17
  each_pair do |k, v|
5
- self[k] = block.call(v)
18
+ result[k] = block.call(v)
6
19
  end
20
+ result
7
21
  end
8
22
  end
9
23
  end