solargraph 0.47.2 → 0.50.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +1 -0
  3. data/.github/workflows/rspec.yml +1 -1
  4. data/CHANGELOG.md +40 -0
  5. data/LICENSE +1 -1
  6. data/README.md +9 -3
  7. data/SPONSORS.md +4 -4
  8. data/lib/solargraph/api_map/store.rb +13 -1
  9. data/lib/solargraph/api_map.rb +30 -12
  10. data/lib/solargraph/cache.rb +53 -0
  11. data/lib/solargraph/complex_type/type_methods.rb +10 -6
  12. data/lib/solargraph/complex_type/unique_type.rb +57 -0
  13. data/lib/solargraph/complex_type.rb +32 -3
  14. data/lib/solargraph/convention/rakefile.rb +17 -0
  15. data/lib/solargraph/convention.rb +2 -0
  16. data/lib/solargraph/diagnostics/rubocop.rb +17 -3
  17. data/lib/solargraph/diagnostics/rubocop_helpers.rb +3 -1
  18. data/lib/solargraph/language_server/host/cataloger.rb +1 -1
  19. data/lib/solargraph/language_server/host.rb +22 -18
  20. data/lib/solargraph/language_server/message/extended/download_core.rb +1 -5
  21. data/lib/solargraph/language_server/message/initialize.rb +2 -0
  22. data/lib/solargraph/language_server/message/text_document/formatting.rb +1 -1
  23. data/lib/solargraph/language_server/message/text_document/signature_help.rb +1 -6
  24. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +10 -3
  25. data/lib/solargraph/library.rb +25 -20
  26. data/lib/solargraph/parser/legacy/node_processors/casgn_node.rb +12 -2
  27. data/lib/solargraph/parser/legacy/node_processors/sclass_node.rb +24 -3
  28. data/lib/solargraph/parser/rubyvm/class_methods.rb +6 -1
  29. data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +13 -2
  30. data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +20 -8
  31. data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +14 -3
  32. data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +14 -3
  33. data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +4 -2
  34. data/lib/solargraph/parser/rubyvm/node_wrapper.rb +47 -0
  35. data/lib/solargraph/pin/base.rb +5 -2
  36. data/lib/solargraph/pin/base_variable.rb +1 -1
  37. data/lib/solargraph/pin/conversions.rb +2 -6
  38. data/lib/solargraph/pin/method.rb +100 -10
  39. data/lib/solargraph/pin/namespace.rb +4 -1
  40. data/lib/solargraph/pin/parameter.rb +8 -3
  41. data/lib/solargraph/pin/signature.rb +23 -0
  42. data/lib/solargraph/pin.rb +1 -0
  43. data/lib/solargraph/rbs_map/conversions.rb +394 -0
  44. data/lib/solargraph/rbs_map/core_fills.rb +61 -0
  45. data/lib/solargraph/rbs_map/core_map.rb +38 -0
  46. data/lib/solargraph/rbs_map/core_signs.rb +33 -0
  47. data/lib/solargraph/rbs_map/stdlib_map.rb +36 -0
  48. data/lib/solargraph/rbs_map.rb +73 -0
  49. data/lib/solargraph/shell.rb +50 -32
  50. data/lib/solargraph/source/chain/call.rb +35 -24
  51. data/lib/solargraph/source/chain.rb +22 -7
  52. data/lib/solargraph/source_map/clip.rb +5 -0
  53. data/lib/solargraph/source_map/mapper.rb +8 -4
  54. data/lib/solargraph/type_checker.rb +71 -65
  55. data/lib/solargraph/version.rb +1 -1
  56. data/lib/solargraph/views/environment.erb +2 -2
  57. data/lib/solargraph/workspace.rb +11 -14
  58. data/lib/solargraph/yard_map/mapper/to_method.rb +7 -4
  59. data/lib/solargraph/yard_map.rb +35 -194
  60. data/lib/solargraph.rb +2 -2
  61. data/solargraph.gemspec +11 -6
  62. metadata +46 -37
  63. data/.travis.yml +0 -19
  64. data/lib/solargraph/compat.rb +0 -37
  65. data/lib/solargraph/yard_map/core_docs.rb +0 -170
  66. data/lib/solargraph/yard_map/core_fills.rb +0 -208
  67. data/lib/solargraph/yard_map/core_gen.rb +0 -76
  68. data/lib/solargraph/yard_map/rdoc_to_yard.rb +0 -140
  69. data/lib/solargraph/yard_map/stdlib_fills.rb +0 -43
  70. data/yardoc/2.2.2.tar.gz +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9d35030ae56f6aaff108a24e4fb06713f911ba4366feb2223b24ad0ea4568522
4
- data.tar.gz: a9eeaee16171bc762922ac55d10c61d53bcfe6ef1df0b20623c81e0978a80c7d
3
+ metadata.gz: 3a6e7990068e276537a53e6af24d45685d73aba32af134def16d8a66ea671f64
4
+ data.tar.gz: 57292437f34d43394a161fe4909eb27931d5d33e1b367276faecc7b0132525e9
5
5
  SHA512:
6
- metadata.gz: 0b13ae6284def50f72c9aaed3cad6f89e879306dc8421b1c13f622e18181e6d9aaecf4f57ffa56601a00c92066557bb798d3e8ee6a397920ff0072f909e05463
7
- data.tar.gz: 9a0366309ebe9a4a784c2933a8452e2084c376ff9aa3cd6c3bf555f4d6ce046f11245679c688bef43c6c1e67d94b70afb4250149c9b01b80fc525b80a80b6486
6
+ metadata.gz: 1d751b364593fa60cc51c3b9a67086c7a8006dcfe37107daaba4ca1db3f001da28eb289978d81fbe7e84c3a5c9add902417731479517be61269acd958456a057
7
+ data.tar.gz: 1c38faac70a696f81c5063d5ef64341a41a8d244c47c070ab557dbef8e4ca2180f5c22d5d0338c4b6f24598ea27850895bed2eab7c4d747b7bb2efeb71309eb2
@@ -0,0 +1 @@
1
+ patreon: castwide
@@ -22,7 +22,7 @@ jobs:
22
22
  runs-on: ubuntu-latest
23
23
  strategy:
24
24
  matrix:
25
- ruby-version: ['2.4', '2.5', '2.6', '2.7', '3.0']
25
+ ruby-version: ['2.6', '2.7', '3.0', '3.1']
26
26
 
27
27
  steps:
28
28
  - uses: actions/checkout@v3
data/CHANGELOG.md CHANGED
@@ -1,3 +1,43 @@
1
+ ## 0.50.0 - December 5, 2023
2
+ - Remove .travis.yml as its not longer used (#627)
3
+ - Fix empty string case when processing requires (#644)
4
+ - Fix scope() method call on wrong object (#670)
5
+ - Parse comments that start with multiple hashes (#667)
6
+ - Use XDG_CACHE_HOME if it exists (#664)
7
+ - Add rbs mention to readme (#693)
8
+ - Remove Atom from the readme (#692)
9
+ - Add more metadata to the gemspec (#691)
10
+ - Do not deprecate clear command
11
+ - Library#locate_ref returns nil for unresolved requires (#675)
12
+ - Hide deprecated commands
13
+ - List command
14
+ - Fixes (or ignores) ffi crash (#676)
15
+ - increase sleep time on cataloger (#677)
16
+ - YardMap ignores absolute paths (#678)
17
+ - Clarify macros vs. directives
18
+ - Infer complex types from method calls
19
+ - Default cache uses XDG_CACHE_HOME default (#664)
20
+
21
+ ## 0.49.0 - April 9, 2023
22
+ - Better union type handling
23
+ - First version of RBS support
24
+ - Dependency updates
25
+ - Update RuboCop config options
26
+ - RBS core and stdlib mapping
27
+ - Anonymous splats and multisig arity
28
+ - Infinite loop when checking if a class is a superclass (#641)
29
+
30
+ ## 0.48.0 - December 19, 2022
31
+ - Add Sublime Text to README (#604)
32
+ - Map nested constant assignments
33
+ - Handle rest/kwrest modifiers on overload arguments (#601)
34
+ - Make rubocop info severity Severity::HINT (#576)
35
+ - Process non-self singleton classes (#581)
36
+ - Fix nest gemspec dependency (#599)
37
+ - Strip 'file ' prefix from all filenames in RdocToYard (#585)
38
+ - Show why rubocop fails (#605)
39
+ - Link solargraph-rails (#611)
40
+
1
41
  ## 0.47.2 - September 30, 2022
2
42
  - Fix complex type inference (#578)
3
43
  - Off-by-one diagnostic (#595)
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2017-2019 by Fred Snyder for Castwide Technologies
3
+ Copyright (c) 2017-2023 by Fred Snyder for Castwide Technologies
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -28,9 +28,10 @@ Plug-ins and extensions are available for the following editors:
28
28
  * Extension: https://marketplace.visualstudio.com/items?itemName=castwide.solargraph
29
29
  * GitHub: https://github.com/castwide/vscode-solargraph
30
30
 
31
- * **Atom**
32
- * Package: https://atom.io/packages/ruby-solargraph
33
- * GitHub: https://github.com/castwide/atom-solargraph
31
+ * **Sublime Text**
32
+ * Extension: https://packagecontrol.io/packages/LSP
33
+ * GitHub: https://github.com/sublimelsp/LSP
34
+ * Instructions: https://lsp.sublimetext.io/language_servers/#solargraph
34
35
 
35
36
  * **Vim**
36
37
  * GitHub: `LanguageClient-neovim`, https://github.com/autozimu/LanguageClient-neovim
@@ -49,6 +50,9 @@ Plug-ins and extensions are available for the following editors:
49
50
 
50
51
  Solargraph's behavior can be controlled via optional [configuration](https://solargraph.org/guides/configuration) files. The highest priority file is a `.solargraph.yml` file at the root of the project. If not present, any global configuration at `~/.config/solargraph/config.yml` will apply. The path to the global configuration can be overridden with the `SOLARGRAPH_GLOBAL_CONFIG` environment variable.
51
52
 
53
+ ### Rails Support
54
+ For better Rails support, please consider using [solargraph-rails](https://github.com/iftheshoefritz/solargraph-rails/)
55
+
52
56
  ### Gem Support
53
57
 
54
58
  Solargraph is capable of providing code completion and documentation for gems that have YARD documentation. You can make sure your gems are documented by running `yard gems` from the command line. (YARD is included as one of Solargraph's gem dependencies. The first time you run it might take a while if you have a lot of gems installed).
@@ -63,6 +67,8 @@ As of version 0.33.0, Solargraph includes a [type checker](https://github.com/ca
63
67
 
64
68
  ### Updating Core Documentation
65
69
 
70
+ As of version 0.49.0, Solargraph uses [rbs](https://github.com/ruby/rbs) for core and stdlib documentation. The following only applies to prior versions.
71
+
66
72
  The Solargraph gem ships with documentation for Ruby 2.2.2. You can download documentation for other Ruby versions from the command line.
67
73
 
68
74
  $ solargraph list-cores # List the installed documentation versions
data/SPONSORS.md CHANGED
@@ -7,11 +7,11 @@ The following people and organizations provide funding or other resources. [Beco
7
7
  ## Linked Sponsors
8
8
 
9
9
  - **[Calyptix Security](https://www.calyptix.com/)**
10
+ - **[Lightward](https://lightward.com)**
10
11
 
11
12
  ## Named Sponsors
12
13
 
13
- - Tom de Grunt
14
14
  - Akira Yamada
15
- - Erlend Finvåg
16
- - Matt Massicotte
17
- - Oscar Rivas
15
+ - Jesus Castello
16
+ - Joel Drapper
17
+ - Spencer
@@ -247,10 +247,22 @@ module Solargraph
247
247
  end
248
248
  ovr.tags.each do |tag|
249
249
  pin.docstring.add_tag(tag)
250
- new_pin.docstring.add_tag(tag) if new_pin
250
+ redefine_return_type pin, tag
251
+ if new_pin
252
+ new_pin.docstring.add_tag(tag)
253
+ redefine_return_type new_pin, tag
254
+ end
251
255
  end
252
256
  end
253
257
  end
258
+
259
+ def redefine_return_type pin, tag
260
+ return unless pin && tag.tag_name == 'return'
261
+ pin.instance_variable_set(:@return_type, ComplexType.try_parse(tag.type))
262
+ pin.signatures.each do |sig|
263
+ sig.instance_variable_set(:@return_type, ComplexType.try_parse(tag.type))
264
+ end
265
+ end
254
266
  end
255
267
  end
256
268
  end
@@ -21,6 +21,8 @@ module Solargraph
21
21
  # @return [Array<String>]
22
22
  attr_reader :unresolved_requires
23
23
 
24
+ @@core_map = RbsMap::CoreMap.new
25
+
24
26
  # @return [Array<String>]
25
27
  attr_reader :missing_docs
26
28
 
@@ -40,7 +42,7 @@ module Solargraph
40
42
  @source_map_hash = {}
41
43
  implicit.clear
42
44
  cache.clear
43
- @store = Store.new(yard_map.pins + pins)
45
+ @store = Store.new(@@core_map.pins + pins)
44
46
  self
45
47
  end
46
48
 
@@ -68,8 +70,10 @@ module Solargraph
68
70
  end
69
71
  external_requires.merge implicit.requires
70
72
  external_requires.merge bench.workspace.config.required
71
- yard_map.change(external_requires, bench.workspace.directory, bench.workspace.source_gems)
72
- @store = Store.new(yard_map.pins + implicit.pins + pins)
73
+ @rbs_maps = external_requires.map { |r| load_rbs_map(r) }
74
+ unresolved_requires = @rbs_maps.reject(&:resolved?).map(&:library)
75
+ yard_map.change(unresolved_requires, bench.workspace.directory, bench.workspace.source_gems)
76
+ @store = Store.new(@@core_map.pins + @rbs_maps.flat_map(&:pins) + yard_map.pins + implicit.pins + pins)
73
77
  @unresolved_requires = yard_map.unresolved_requires
74
78
  @missing_docs = yard_map.missing_docs
75
79
  @rebindable_method_names = nil
@@ -77,6 +81,14 @@ module Solargraph
77
81
  self
78
82
  end
79
83
 
84
+ def core_pins
85
+ @@core_map.pins
86
+ end
87
+
88
+ def yard_map
89
+ @yard_map ||= YardMap.new
90
+ end
91
+
80
92
  # @param name [String]
81
93
  # @return [YARD::Tags::MacroDirective, nil]
82
94
  def named_macro name
@@ -132,7 +144,8 @@ module Solargraph
132
144
 
133
145
  def rebindable_method_names
134
146
  @rebindable_method_names ||= begin
135
- result = yard_map.rebindable_method_names
147
+ # result = yard_map.rebindable_method_names
148
+ result = ['instance_eval', 'instance_exec', 'class_eval', 'class_exec', 'module_eval', 'module_exec', 'define_method'].to_set
136
149
  source_maps.each do |map|
137
150
  result.merge map.rebindable_method_names
138
151
  end
@@ -191,7 +204,7 @@ module Solargraph
191
204
  #
192
205
  # @param namespace [String, nil] The namespace to match
193
206
  # @param context [String] The context to search
194
- # @return [String]
207
+ # @return [String, nil]
195
208
  def qualify namespace, context = ''
196
209
  return namespace if ['self', nil].include?(namespace)
197
210
  cached = cache.get_qualified_namespace(namespace, context)
@@ -447,18 +460,15 @@ module Solargraph
447
460
  def super_and_sub?(sup, sub)
448
461
  fqsup = qualify(sup)
449
462
  cls = qualify(sub)
450
- until fqsup.nil? || cls.nil?
463
+ tested = []
464
+ until fqsup.nil? || cls.nil? || tested.include?(cls)
451
465
  return true if cls == fqsup
466
+ tested.push cls
452
467
  cls = qualify_superclass(cls)
453
468
  end
454
469
  false
455
470
  end
456
471
 
457
- # @return [YardMap]
458
- def yard_map
459
- @yard_map ||= YardMap.new
460
- end
461
-
462
472
  # Check if the host class includes the specified module.
463
473
  #
464
474
  # @param host [String] The class
@@ -475,6 +485,14 @@ module Solargraph
475
485
  # @return [Hash{String => SourceMap}]
476
486
  attr_reader :source_map_hash
477
487
 
488
+ # @param library [String]
489
+ # @return [RbsMap]
490
+ def load_rbs_map library
491
+ # map = RbsMap.load(library)
492
+ # return map if map.resolved?
493
+ RbsMap::StdlibMap.load(library)
494
+ end
495
+
478
496
  # @return [ApiMap::Store]
479
497
  def store
480
498
  @store ||= Store.new
@@ -677,7 +695,7 @@ module Solargraph
677
695
  comments: origin.comments,
678
696
  scope: origin.scope,
679
697
  visibility: origin.visibility,
680
- parameters: origin.parameters,
698
+ signatures: origin.signatures,
681
699
  attribute: origin.attribute?
682
700
  }
683
701
  Pin::Method.new **args
@@ -0,0 +1,53 @@
1
+ require 'fileutils'
2
+
3
+ module Solargraph
4
+ module Cache
5
+ class << self
6
+ # The base directory where cached documentation is installed.
7
+ #
8
+ # @return [String]
9
+ def base_dir
10
+ # The directory is not stored in a variable so it can be overridden
11
+ # in specs.
12
+ ENV['SOLARGRAPH_CACHE'] ||
13
+ ENV['XDG_CACHE_HOME'] ? File.join(ENV['XDG_CACHE_HOME'], 'solargraph') :
14
+ File.join(Dir.home, '.cache', 'solargraph')
15
+ end
16
+
17
+ # The working directory for the current Ruby and Solargraph versions.
18
+ #
19
+ # @return [String]
20
+ def work_dir
21
+ # The directory is not stored in a variable so it can be overridden
22
+ # in specs.
23
+ File.join(base_dir, "ruby-#{RUBY_VERSION}", "rbs-#{RBS::VERSION}", "solargraph-#{Solargraph::VERSION}")
24
+ end
25
+
26
+ # @return [Array<Solargraph::Pin::Base>, nil]
27
+ def load *path
28
+ file = File.join(work_dir, *path)
29
+ return nil unless File.file?(file)
30
+ Marshal.load(File.read(file, mode: 'rb'))
31
+ rescue StandardError => e
32
+ Solargraph.logger.warn "Failed to load cached file #{file}: [#{e.class}] #{e.message}"
33
+ FileUtils.rm_f file
34
+ nil
35
+ end
36
+
37
+ # @return [Boolean]
38
+ def save *path, pins
39
+ return false if pins.empty?
40
+ file = File.join(work_dir, *path)
41
+ base = File.dirname(file)
42
+ FileUtils.mkdir_p base unless File.directory?(base)
43
+ ser = Marshal.dump(pins)
44
+ File.write file, ser, mode: 'wb'
45
+ true
46
+ end
47
+
48
+ def clear
49
+ FileUtils.rm_rf base_dir, secure: true
50
+ end
51
+ end
52
+ end
53
+ end
@@ -101,6 +101,7 @@ module Solargraph
101
101
  # @param context [String] The namespace from which to resolve names
102
102
  # @return [ComplexType] The generated ComplexType
103
103
  def qualify api_map, context = ''
104
+ return self if name == 'param'
104
105
  return ComplexType.new([self]) if duck_type? || void? || undefined?
105
106
  recon = (rooted? ? '' : context)
106
107
  fqns = api_map.qualify(name, recon)
@@ -109,12 +110,8 @@ module Solargraph
109
110
  return UniqueType::UNDEFINED
110
111
  end
111
112
  fqns = "::#{fqns}" # Ensure the resulting complex type is rooted
112
- ltypes = key_types.map do |t|
113
- t.qualify api_map, context
114
- end
115
- rtypes = value_types.map do |t|
116
- t.qualify api_map, context
117
- end
113
+ ltypes = key_types.map { |t| t.qualify api_map, context }.uniq
114
+ rtypes = value_types.map { |t| t.qualify api_map, context }.uniq
118
115
  if list_parameters?
119
116
  Solargraph::ComplexType.parse("#{fqns}<#{rtypes.map(&:tag).join(', ')}>")
120
117
  elsif fixed_parameters?
@@ -125,6 +122,13 @@ module Solargraph
125
122
  Solargraph::ComplexType.parse(fqns)
126
123
  end
127
124
  end
125
+
126
+ # @yieldparam [UniqueType]
127
+ # @return [Enumerator<UniqueType>]
128
+ def each_unique_type &block
129
+ return enum_for(__method__) unless block_given?
130
+ yield self
131
+ end
128
132
  end
129
133
  end
130
134
  end
@@ -8,6 +8,8 @@ module Solargraph
8
8
  class UniqueType
9
9
  include TypeMethods
10
10
 
11
+ attr_reader :all_params
12
+
11
13
  # Create a UniqueType with the specified name and an optional substring.
12
14
  # The substring is the parameter section of a parametrized type, e.g.,
13
15
  # for the type `Array<String>`, the name is `Array` and the substring is
@@ -27,6 +29,7 @@ module Solargraph
27
29
  @tag = @name + substring
28
30
  @key_types = []
29
31
  @subtypes = []
32
+ @all_params = []
30
33
  return unless parameters?
31
34
  if @substring.start_with?('<(') && @substring.end_with?(')>')
32
35
  subs = ComplexType.parse(substring[2..-3], partial: true)
@@ -40,12 +43,66 @@ module Solargraph
40
43
  else
41
44
  @subtypes.concat subs
42
45
  end
46
+ @all_params.concat @key_types
47
+ @all_params.concat @subtypes
43
48
  end
44
49
 
45
50
  def to_s
46
51
  tag
47
52
  end
48
53
 
54
+ def to_rbs
55
+ "#{namespace}#{parameters? ? "[#{subtypes.map { |s| s.to_rbs }.join(', ')}]" : ''}"
56
+ end
57
+
58
+ def parameterized?
59
+ name == 'param' || all_params.any?(&:parameterized?)
60
+ end
61
+
62
+ def resolve_parameters definitions, context
63
+ new_name = if name == 'param'
64
+ idx = definitions.parameters.index(subtypes.first.name)
65
+ return ComplexType::UNDEFINED if idx.nil?
66
+ param_type = context.return_type.all_params[idx]
67
+ return ComplexType::UNDEFINED unless param_type
68
+ param_type.to_s
69
+ else
70
+ name
71
+ end
72
+ new_key_types = if name != 'param'
73
+ @key_types.map { |t| t.resolve_parameters(definitions, context) }.select(&:defined?)
74
+ else
75
+ []
76
+ end
77
+ new_subtypes = if name != 'param'
78
+ @subtypes.map { |t| t.resolve_parameters(definitions, context) }.select(&:defined?)
79
+ else
80
+ []
81
+ end
82
+ if name != 'param' && !(new_key_types.empty? && new_subtypes.empty?)
83
+ if hash_parameters?
84
+ UniqueType.new(new_name, "{#{new_key_types.join(', ')} => #{new_subtypes.join(', ')}}")
85
+ elsif parameters?
86
+ if @substring.start_with?'<('
87
+ UniqueType.new(new_name, "<(#{new_subtypes.join(', ')})>")
88
+ else
89
+ UniqueType.new(new_name, "<#{new_subtypes.join(', ')}>")
90
+ end
91
+ else
92
+ UniqueType.new(new_name)
93
+ end
94
+ else
95
+ UniqueType.new(new_name)
96
+ end
97
+
98
+ # idx = definitions.parameters.index(subtypes.first.name)
99
+ # STDERR.puts "Index: #{idx}"
100
+ # return ComplexType::UNDEFINED if idx.nil?
101
+ # param_type = context.return_type.all_params[idx]
102
+ # return ComplexType::UNDEFINED unless param_type
103
+ # ComplexType.try_parse(param_type.to_s)
104
+ end
105
+
49
106
  def self_to dst
50
107
  return self unless selfy?
51
108
  new_name = (@name == 'self' ? dst : @name)
@@ -30,6 +30,12 @@ module Solargraph
30
30
  @items.first
31
31
  end
32
32
 
33
+ def to_rbs
34
+ ((@items.length > 1 ? '(' : '') + @items.map do |item|
35
+ "#{item.namespace}#{item.parameters? ? "[#{item.subtypes.map { |s| s.to_rbs }.join(', ')}]" : ''}"
36
+ end.join(' | ') + (@items.length > 1 ? ')' : '')).gsub(/undefined/, 'untyped')
37
+ end
38
+
33
39
  def map &block
34
40
  @items.map &block
35
41
  end
@@ -40,6 +46,16 @@ module Solargraph
40
46
  @items.each &block
41
47
  end
42
48
 
49
+ # @yieldparam [UniqueType]
50
+ # @return [Enumerator<UniqueType>]
51
+ def each_unique_type &block
52
+ return enum_for(__method__) unless block_given?
53
+
54
+ @items.each do |item|
55
+ item.each_unique_type &block
56
+ end
57
+ end
58
+
43
59
  def length
44
60
  @items.length
45
61
  end
@@ -75,26 +91,39 @@ module Solargraph
75
91
  end
76
92
 
77
93
  def any? &block
78
- @items.any? &block
94
+ @items.compact.any? &block
79
95
  end
80
96
 
81
97
  def selfy?
82
98
  @items.any?(&:selfy?)
83
99
  end
84
100
 
101
+ def parameterized?
102
+ any?(&:parameterized?)
103
+ end
104
+
105
+ def resolve_parameters definitions, context
106
+ result = @items.map { |i| i.resolve_parameters(definitions, context) }
107
+ ComplexType.parse(*result.map(&:tag))
108
+ end
109
+
85
110
  # @param dst [String]
86
111
  # @return [ComplexType]
87
112
  def self_to dst
88
113
  return self unless selfy?
89
114
  red = reduce_class(dst)
90
115
  result = @items.map { |i| i.self_to red }
91
- ComplexType.parse(*result.map(&:tag))
116
+ ComplexType.parse(*result.map(&:to_s))
92
117
  end
93
118
 
94
119
  def nullable?
95
120
  @items.any?(&:nil_type?)
96
121
  end
97
122
 
123
+ def all_params
124
+ @items.first.all_params || []
125
+ end
126
+
98
127
  private
99
128
 
100
129
  # @todo This is a quick and dirty hack that forces `self` keywords
@@ -140,7 +169,7 @@ module Solargraph
140
169
  paren_stack = 0
141
170
  base = String.new
142
171
  subtype_string = String.new
143
- type_string.each_char do |char|
172
+ type_string&.each_char do |char|
144
173
  if char == '='
145
174
  #raise ComplexTypeError, "Invalid = in type #{type_string}" unless curly_stack > 0
146
175
  elsif char == '<'
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Convention
5
+ class Rakefile < Base
6
+ def local source_map
7
+ basename = File.basename(source_map.filename)
8
+ return EMPTY_ENVIRON unless basename.end_with?('.rake') || basename == 'Rakefile'
9
+
10
+ @environ ||= Environ.new(
11
+ requires: ['rake'],
12
+ domains: ['Rake::DSL']
13
+ )
14
+ end
15
+ end
16
+ end
17
+ end
@@ -11,6 +11,7 @@ module Solargraph
11
11
  autoload :Gemfile, 'solargraph/convention/gemfile'
12
12
  autoload :Rspec, 'solargraph/convention/rspec'
13
13
  autoload :Gemspec, 'solargraph/convention/gemspec'
14
+ autoload :Rakefile, 'solargraph/convention/rakefile'
14
15
 
15
16
  @@conventions = Set.new
16
17
 
@@ -43,5 +44,6 @@ module Solargraph
43
44
  register Gemfile
44
45
  register Gemspec
45
46
  register Rspec
47
+ register Rakefile
46
48
  end
47
49
  end
@@ -11,6 +11,7 @@ module Solargraph
11
11
 
12
12
  # Conversion of RuboCop severity names to LSP constants
13
13
  SEVERITIES = {
14
+ 'info' => Severities::HINT,
14
15
  'refactor' => Severities::HINT,
15
16
  'convention' => Severities::INFORMATION,
16
17
  'warning' => Severities::WARNING,
@@ -22,16 +23,20 @@ module Solargraph
22
23
  # @param _api_map [Solargraph::ApiMap]
23
24
  # @return [Array<Hash>]
24
25
  def diagnose source, _api_map
26
+ @source = source
25
27
  require_rubocop(rubocop_version)
26
28
  options, paths = generate_options(source.filename, source.code)
27
29
  store = RuboCop::ConfigStore.new
28
30
  runner = RuboCop::Runner.new(options, store)
29
31
  result = redirect_stdout{ runner.run(paths) }
32
+
33
+ return [] if result.empty?
34
+
30
35
  make_array JSON.parse(result)
31
36
  rescue RuboCop::ValidationError, RuboCop::ConfigNotFoundError => e
32
37
  raise DiagnosticsError, "Error in RuboCop configuration: #{e.message}"
33
- rescue JSON::ParserError
34
- raise DiagnosticsError, 'RuboCop returned invalid data'
38
+ rescue JSON::ParserError => e
39
+ raise DiagnosticsError, "RuboCop returned invalid data: #{e.message}"
35
40
  end
36
41
 
37
42
  private
@@ -88,8 +93,17 @@ module Solargraph
88
93
  if off['location']['start_line'] != off['location']['last_line']
89
94
  Position.new(off['location']['start_line'], 0)
90
95
  else
96
+ start_line = off['location']['start_line'] - 1
97
+ last_column = off['location']['last_column']
98
+ line = @source.code.lines[start_line]
99
+ col_off = if line.nil? || line.empty?
100
+ 1
101
+ else
102
+ 0
103
+ end
104
+
91
105
  Position.new(
92
- off['location']['start_line'] - 1, off['location']['last_column'] - 1
106
+ start_line, last_column - col_off
93
107
  )
94
108
  end
95
109
  end
@@ -10,13 +10,15 @@ module Solargraph
10
10
  # Requires a specific version of rubocop, or the latest installed version
11
11
  # if _version_ is `nil`.
12
12
  #
13
- # @param version [String]
13
+ # @param version [String, nil]
14
14
  # @raise [InvalidRubocopVersionError] if _version_ is not installed
15
15
  def require_rubocop(version = nil)
16
16
  begin
17
17
  gem_path = Gem::Specification.find_by_name('rubocop', version).full_gem_path
18
18
  gem_lib_path = File.join(gem_path, 'lib')
19
19
  $LOAD_PATH.unshift(gem_lib_path) unless $LOAD_PATH.include?(gem_lib_path)
20
+ # @todo Gem::MissingSpecVersionError is undocumented for some reason
21
+ # @sg-ignore
20
22
  rescue Gem::MissingSpecVersionError => e
21
23
  raise InvalidRubocopVersionError,
22
24
  "could not find '#{e.name}' (#{e.requirement}) - "\
@@ -34,7 +34,7 @@ module Solargraph
34
34
  Thread.new do
35
35
  until stopped?
36
36
  tick
37
- sleep 0.01
37
+ sleep 0.1
38
38
  end
39
39
  end
40
40
  end