solargraph 0.32.5 → 0.33.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 (125) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/README.md +2 -11
  4. data/lib/solargraph.rb +1 -2
  5. data/lib/solargraph/api_map.rb +93 -63
  6. data/lib/solargraph/api_map/cache.rb +16 -1
  7. data/lib/solargraph/api_map/source_to_yard.rb +16 -7
  8. data/lib/solargraph/api_map/store.rb +55 -12
  9. data/lib/solargraph/complex_type.rb +58 -14
  10. data/lib/solargraph/complex_type/type_methods.rb +2 -2
  11. data/lib/solargraph/complex_type/unique_type.rb +33 -4
  12. data/lib/solargraph/core_fills.rb +40 -12
  13. data/lib/solargraph/diagnostics.rb +4 -3
  14. data/lib/solargraph/diagnostics/base.rb +6 -0
  15. data/lib/solargraph/diagnostics/require_not_found.rb +17 -10
  16. data/lib/solargraph/diagnostics/rubocop_helpers.rb +2 -0
  17. data/lib/solargraph/diagnostics/type_check.rb +51 -0
  18. data/lib/solargraph/diagnostics/update_errors.rb +1 -0
  19. data/lib/solargraph/language_server/host.rb +55 -25
  20. data/lib/solargraph/language_server/host/diagnoser.rb +1 -2
  21. data/lib/solargraph/language_server/host/dispatch.rb +4 -8
  22. data/lib/solargraph/language_server/host/sources.rb +1 -1
  23. data/lib/solargraph/language_server/message.rb +1 -0
  24. data/lib/solargraph/language_server/message/completion_item/resolve.rb +4 -2
  25. data/lib/solargraph/language_server/message/initialize.rb +9 -0
  26. data/lib/solargraph/language_server/message/initialized.rb +1 -0
  27. data/lib/solargraph/language_server/message/text_document.rb +1 -0
  28. data/lib/solargraph/language_server/message/text_document/code_action.rb +15 -0
  29. data/lib/solargraph/language_server/message/text_document/completion.rb +1 -1
  30. data/lib/solargraph/language_server/message/text_document/definition.rb +25 -5
  31. data/lib/solargraph/language_server/message/text_document/hover.rb +1 -1
  32. data/lib/solargraph/language_server/message/text_document/signature_help.rb +4 -0
  33. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +8 -4
  34. data/lib/solargraph/language_server/transport/adapter.rb +12 -15
  35. data/lib/solargraph/library.rb +23 -6
  36. data/lib/solargraph/location.rb +4 -0
  37. data/lib/solargraph/pin.rb +7 -3
  38. data/lib/solargraph/pin/attribute.rb +14 -13
  39. data/lib/solargraph/pin/base.rb +56 -43
  40. data/lib/solargraph/pin/base_method.rb +41 -18
  41. data/lib/solargraph/pin/base_variable.rb +17 -15
  42. data/lib/solargraph/pin/block.rb +22 -4
  43. data/lib/solargraph/pin/closure.rb +28 -0
  44. data/lib/solargraph/pin/common.rb +59 -0
  45. data/lib/solargraph/pin/constant.rb +4 -4
  46. data/lib/solargraph/pin/conversions.rb +8 -8
  47. data/lib/solargraph/pin/duck_method.rb +3 -3
  48. data/lib/solargraph/pin/instance_variable.rb +30 -0
  49. data/lib/solargraph/pin/keyword.rb +1 -1
  50. data/lib/solargraph/pin/local_variable.rb +3 -3
  51. data/lib/solargraph/pin/localized.rb +9 -5
  52. data/lib/solargraph/pin/method.rb +26 -40
  53. data/lib/solargraph/pin/method_alias.rb +9 -6
  54. data/lib/solargraph/pin/namespace.rb +33 -10
  55. data/lib/solargraph/pin/parameter.rb +150 -0
  56. data/lib/solargraph/pin/proxy_type.rb +8 -8
  57. data/lib/solargraph/pin/reference.rb +1 -12
  58. data/lib/solargraph/pin/reference/override.rb +18 -0
  59. data/lib/solargraph/pin/reference/require.rb +2 -1
  60. data/lib/solargraph/pin/singleton.rb +9 -0
  61. data/lib/solargraph/pin/symbol.rb +9 -4
  62. data/lib/solargraph/pin/yard_pin/constant.rb +12 -3
  63. data/lib/solargraph/pin/yard_pin/method.rb +18 -6
  64. data/lib/solargraph/pin/yard_pin/namespace.rb +13 -1
  65. data/lib/solargraph/position.rb +1 -1
  66. data/lib/solargraph/range.rb +4 -0
  67. data/lib/solargraph/shell.rb +83 -4
  68. data/lib/solargraph/source.rb +32 -12
  69. data/lib/solargraph/source/chain.rb +48 -28
  70. data/lib/solargraph/source/chain/call.rb +37 -38
  71. data/lib/solargraph/source/chain/constant.rb +1 -1
  72. data/lib/solargraph/source/chain/head.rb +2 -8
  73. data/lib/solargraph/source/chain/instance_variable.rb +1 -1
  74. data/lib/solargraph/source/chain/link.rb +2 -0
  75. data/lib/solargraph/source/cursor.rb +59 -24
  76. data/lib/solargraph/source/node_chainer.rb +0 -2
  77. data/lib/solargraph/source/node_methods.rb +12 -6
  78. data/lib/solargraph/source/source_chainer.rb +38 -44
  79. data/lib/solargraph/source_map.rb +11 -18
  80. data/lib/solargraph/source_map/clip.rb +13 -15
  81. data/lib/solargraph/source_map/mapper.rb +37 -26
  82. data/lib/solargraph/source_map/node_processor.rb +13 -8
  83. data/lib/solargraph/source_map/node_processor/alias_node.rb +8 -8
  84. data/lib/solargraph/source_map/node_processor/args_node.rb +10 -16
  85. data/lib/solargraph/source_map/node_processor/base.rb +47 -4
  86. data/lib/solargraph/source_map/node_processor/block_node.rb +9 -4
  87. data/lib/solargraph/source_map/node_processor/casgn_node.rb +7 -2
  88. data/lib/solargraph/source_map/node_processor/cvasgn_node.rb +8 -3
  89. data/lib/solargraph/source_map/node_processor/def_node.rb +45 -38
  90. data/lib/solargraph/source_map/node_processor/defs_node.rb +16 -6
  91. data/lib/solargraph/source_map/node_processor/gvasgn_node.rb +8 -1
  92. data/lib/solargraph/source_map/node_processor/ivasgn_node.rb +20 -6
  93. data/lib/solargraph/source_map/node_processor/lvasgn_node.rb +10 -4
  94. data/lib/solargraph/source_map/node_processor/namespace_node.rb +18 -12
  95. data/lib/solargraph/source_map/node_processor/orasgn_node.rb +1 -1
  96. data/lib/solargraph/source_map/node_processor/resbody_node.rb +30 -0
  97. data/lib/solargraph/source_map/node_processor/sclass_node.rb +7 -1
  98. data/lib/solargraph/source_map/node_processor/send_node.rb +102 -52
  99. data/lib/solargraph/source_map/node_processor/sym_node.rb +4 -1
  100. data/lib/solargraph/source_map/region.rb +9 -8
  101. data/lib/solargraph/type_checker.rb +282 -0
  102. data/lib/solargraph/type_checker/param_def.rb +47 -0
  103. data/lib/solargraph/type_checker/problem.rb +25 -0
  104. data/lib/solargraph/version.rb +1 -1
  105. data/lib/solargraph/views/environment.erb +1 -1
  106. data/lib/solargraph/workspace.rb +2 -2
  107. data/lib/solargraph/workspace/config.rb +0 -8
  108. data/lib/solargraph/yard_map.rb +25 -69
  109. data/lib/solargraph/yard_map/core_docs.rb +8 -3
  110. data/lib/solargraph/yard_map/core_gen.rb +1 -3
  111. data/lib/solargraph/yard_map/mapper.rb +85 -0
  112. data/lib/yard-solargraph.rb +2 -0
  113. metadata +14 -14
  114. data/lib/solargraph/diagnostics/type_not_defined.rb +0 -108
  115. data/lib/solargraph/live_map.rb +0 -126
  116. data/lib/solargraph/live_map/cache.rb +0 -38
  117. data/lib/solargraph/pin/block_parameter.rb +0 -103
  118. data/lib/solargraph/pin/method_parameter.rb +0 -40
  119. data/lib/solargraph/pin/plugin/method.rb +0 -25
  120. data/lib/solargraph/plugin.rb +0 -8
  121. data/lib/solargraph/plugin/base.rb +0 -41
  122. data/lib/solargraph/plugin/canceler.rb +0 -11
  123. data/lib/solargraph/plugin/process.rb +0 -172
  124. data/lib/solargraph/plugin/runtime.rb +0 -134
  125. data/lib/yard-coregen.rb +0 -16
@@ -2,23 +2,40 @@ module Solargraph
2
2
  module Pin
3
3
  # The base class for method and attribute pins.
4
4
  #
5
- class BaseMethod < Base
6
- # @return [Symbol] :instance or :class
7
- attr_reader :scope
8
-
9
- # @return [Symbol] :public, :private, or :protected
5
+ class BaseMethod < Closure
6
+ # @return [::Symbol] :public, :private, or :protected
10
7
  attr_reader :visibility
11
8
 
12
- def return_complex_type
13
- @return_complex_type ||= generate_complex_type
9
+ # @param visibility [::Symbol] :public, :protected, or :private
10
+ def initialize visibility: :public, **splat
11
+ super(splat)
12
+ @visibility = visibility
13
+ end
14
+
15
+ def return_type
16
+ @return_type ||= generate_complex_type
17
+ end
18
+
19
+ def path
20
+ @path ||= namespace.to_s + (scope == :instance ? '#' : '.') + name.to_s
14
21
  end
15
22
 
16
23
  def typify api_map
17
24
  decl = super
18
25
  return decl unless decl.undefined?
19
- type = see_reference(api_map)
20
- return type unless type.nil?
21
- ComplexType::UNDEFINED
26
+ type = see_reference(api_map) || typify_from_super(api_map)
27
+ return type.qualify(api_map, namespace) unless type.nil?
28
+ name.end_with?('?') ? ComplexType::BOOLEAN : ComplexType::UNDEFINED
29
+ end
30
+
31
+ # @return [Array<String>]
32
+ def parameters
33
+ []
34
+ end
35
+
36
+ # @return [Array<String>]
37
+ def parameter_names
38
+ []
22
39
  end
23
40
 
24
41
  private
@@ -35,24 +52,35 @@ module Solargraph
35
52
  end
36
53
 
37
54
  # @param api_map [ApiMap]
38
- # @return [ComplexType]
55
+ # @return [ComplexType, nil]
39
56
  def see_reference api_map
40
57
  docstring.ref_tags.each do |ref|
41
58
  next unless ref.tag_name == 'return' && ref.owner
42
59
  result = resolve_reference(ref.owner.to_s, api_map)
43
60
  return result unless result.nil?
44
61
  end
45
- match = comments.match(/\(see (.*)\)/)
62
+ match = comments.match(/^[ \t]*\(see (.*)\)/m)
46
63
  return nil if match.nil?
47
64
  resolve_reference match[1], api_map
48
65
  end
49
66
 
67
+ # @param api_map [ApiMap]
68
+ # @return [ComplexType, nil]
69
+ def typify_from_super api_map
70
+ stack = api_map.get_method_stack(namespace, name, scope: scope).reject { |pin| pin.path == path }
71
+ return nil if stack.empty?
72
+ stack.each do |pin|
73
+ return pin.return_type unless pin.return_type.undefined?
74
+ end
75
+ nil
76
+ end
77
+
50
78
  # @param ref [String]
51
79
  # @param api_map [ApiMap]
52
80
  # @return [ComplexType]
53
81
  def resolve_reference ref, api_map
54
82
  parts = ref.split(/[\.#]/)
55
- if parts.first.empty?
83
+ if parts.first.empty? || parts.one?
56
84
  path = "#{namespace}#{ref}"
57
85
  else
58
86
  fqns = api_map.qualify(parts.first, namespace)
@@ -64,11 +92,6 @@ module Solargraph
64
92
  type = pin.typify(api_map)
65
93
  return type unless type.undefined?
66
94
  end
67
- pins = api_map.get_path_pins(path)
68
- pins.each do |pin|
69
- type = pin.typify(api_map)
70
- return type unless type.undefined?
71
- end
72
95
  nil
73
96
  end
74
97
  end
@@ -3,15 +3,11 @@ module Solargraph
3
3
  class BaseVariable < Base
4
4
  include Solargraph::Source::NodeMethods
5
5
 
6
- attr_reader :context
7
-
8
6
  attr_reader :assignment
9
7
 
10
- def initialize location, namespace, name, comments, assignment, literal, context
11
- super(location, namespace, name, comments)
8
+ def initialize assignment: nil, **splat
9
+ super(splat)
12
10
  @assignment = assignment
13
- @literal = literal
14
- @context = context
15
11
  end
16
12
 
17
13
  def signature
@@ -27,12 +23,12 @@ module Solargraph
27
23
  Solargraph::LanguageServer::SymbolKinds::VARIABLE
28
24
  end
29
25
 
30
- def return_complex_type
31
- @return_complex_type ||= generate_complex_type
26
+ def return_type
27
+ @return_type ||= generate_complex_type
32
28
  end
33
29
 
34
30
  def nil_assignment?
35
- return_complex_type.nil?
31
+ return_type.nil?
36
32
  end
37
33
 
38
34
  def variable?
@@ -41,10 +37,17 @@ module Solargraph
41
37
 
42
38
  def probe api_map
43
39
  return ComplexType::UNDEFINED if @assignment.nil?
44
- chain = Source::NodeChainer.chain(@assignment, filename)
45
- clip = api_map.clip_at(location.filename, location.range.start)
46
- locals = clip.locals - [self]
47
- chain.infer(api_map, ProxyType.anonymous(context), locals)
40
+ types = []
41
+ returns_from(@assignment).each do |node|
42
+ chain = Source::NodeChainer.chain(node, filename)
43
+ next if chain.links.first.word == name
44
+ clip = api_map.clip_at(location.filename, location.range.start)
45
+ locals = clip.locals - [self]
46
+ result = chain.infer(api_map, closure, locals)
47
+ types.push result unless result.undefined?
48
+ end
49
+ return ComplexType::UNDEFINED if types.empty?
50
+ ComplexType.try_parse(*types.map(&:tag))
48
51
  end
49
52
 
50
53
  def == other
@@ -55,7 +58,7 @@ module Solargraph
55
58
  def try_merge! pin
56
59
  return false unless super
57
60
  @assignment = pin.assignment
58
- @return_complex_type = pin.return_complex_type
61
+ @return_type = pin.return_type
59
62
  true
60
63
  end
61
64
 
@@ -64,7 +67,6 @@ module Solargraph
64
67
  def generate_complex_type
65
68
  tag = docstring.tag(:type)
66
69
  return ComplexType.try_parse(*tag.types) unless tag.nil? || tag.types.nil? || tag.types.empty?
67
- return ComplexType.try_parse(@literal) unless @literal.nil?
68
70
  ComplexType.new
69
71
  end
70
72
  end
@@ -1,15 +1,28 @@
1
1
  module Solargraph
2
2
  module Pin
3
- class Block < Base
3
+ class Block < Closure
4
4
  # The signature of the method that receives this block.
5
5
  #
6
6
  # @return [Parser::AST::Node]
7
7
  attr_reader :receiver
8
8
 
9
- def initialize location, namespace, name, comments, receiver, context
10
- super(location, namespace, name, comments)
9
+ def initialize receiver: nil, args: [], **splat
10
+ super(splat)
11
11
  @receiver = receiver
12
- @context = context
12
+ @parameters = args
13
+ end
14
+
15
+ def rebind context
16
+ @rebound = true
17
+ @binder = context unless context.undefined?
18
+ end
19
+
20
+ def rebound?
21
+ @rebound ||= false
22
+ end
23
+
24
+ def binder
25
+ @binder || context
13
26
  end
14
27
 
15
28
  def kind
@@ -21,6 +34,11 @@ module Solargraph
21
34
  @parameters ||= []
22
35
  end
23
36
 
37
+ # @return [Array<String>]
38
+ def parameter_names
39
+ @parameter_names ||= parameters.map{|p| p.split(/[ =:]/).first.gsub(/^(\*{1,2}|&)/, '')}
40
+ end
41
+
24
42
  def nearly? other
25
43
  return false unless super
26
44
  # @todo Trying to not to block merges too much
@@ -0,0 +1,28 @@
1
+ module Solargraph
2
+ module Pin
3
+ class Closure < Base
4
+ # @return [::Symbol] :class or :instance
5
+ attr_reader :scope
6
+
7
+ def initialize scope: :class, **splat
8
+ super(splat)
9
+ @scope = scope
10
+ end
11
+
12
+ def context
13
+ @context ||= begin
14
+ result = super
15
+ if scope == :instance
16
+ Solargraph::ComplexType.parse(result.namespace)
17
+ else
18
+ result
19
+ end
20
+ end
21
+ end
22
+
23
+ def binder
24
+ @binder || context
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,59 @@
1
+ module Solargraph
2
+ module Pin
3
+ module Common
4
+ attr_reader :location
5
+
6
+ # @return [Pin::Base, nil]
7
+ attr_reader :closure
8
+
9
+ # @return [String]
10
+ def name
11
+ @name ||= ''
12
+ end
13
+
14
+ def kind
15
+ @kind ||= Pin::KEYWORD
16
+ end
17
+
18
+ def return_type
19
+ @return_type ||= ComplexType::UNDEFINED
20
+ end
21
+
22
+ # @return [ComplexType]
23
+ def context
24
+ # Get the static context from the nearest namespace
25
+ @context ||= find_context
26
+ end
27
+ alias full_context context
28
+
29
+ def namespace
30
+ context.namespace.to_s
31
+ end
32
+
33
+ # @return [ComplexType]
34
+ def binder
35
+ @binder || context
36
+ end
37
+
38
+ def comments
39
+ @comments ||= ''
40
+ end
41
+
42
+ def path
43
+ @path ||= name.empty? ? context.namespace : "#{context.namespace}::#{name}"
44
+ end
45
+
46
+ private
47
+
48
+ # @return [ComplexType]
49
+ def find_context
50
+ here = closure
51
+ until here.nil?
52
+ return here.return_type if here.kind == Pin::NAMESPACE
53
+ here = here.closure
54
+ end
55
+ ComplexType::ROOT
56
+ end
57
+ end
58
+ end
59
+ end
@@ -3,8 +3,8 @@ module Solargraph
3
3
  class Constant < BaseVariable
4
4
  attr_reader :visibility
5
5
 
6
- def initialize location, namespace, name, comments, assignment, literal, context, visibility
7
- super(location, namespace, name, comments, assignment, literal, context)
6
+ def initialize visibility: :public, **splat
7
+ super(splat)
8
8
  @visibility = visibility
9
9
  end
10
10
 
@@ -22,8 +22,8 @@ module Solargraph
22
22
  end
23
23
 
24
24
  def path
25
- return name if namespace.empty?
26
- "#{namespace}::#{name}"
25
+ return name if context.namespace.to_s.empty?
26
+ "#{context.namespace}::#{name}"
27
27
  end
28
28
  end
29
29
  end
@@ -41,14 +41,14 @@ module Solargraph
41
41
 
42
42
  # @return [String]
43
43
  def detail
44
- if @detail.nil?
45
- @detail = ''
46
- @detail += "(#{parameters.join(', ')}) " unless kind != Pin::METHOD or parameters.empty?
47
- @detail += "=> #{return_complex_type}" unless return_complex_type.undefined?
48
- @detail.strip!
49
- end
50
- return nil if @detail.empty?
51
- @detail
44
+ # This property is not cached in an instance variable because it can
45
+ # change when pins get proxied.
46
+ detail = ''
47
+ detail += "(#{parameters.join(', ')}) " unless kind != Pin::METHOD or parameters.empty?
48
+ detail += "=#{probed? ? '~' : (proxied? ? '^' : '>')} #{return_type}" unless return_type.undefined?
49
+ detail.strip!
50
+ return nil if detail.empty?
51
+ detail
52
52
  end
53
53
 
54
54
  # Get a markdown-flavored link to a documentation page.
@@ -6,9 +6,9 @@ module Solargraph
6
6
  class DuckMethod < Pin::Method
7
7
  # @param location [Solargraph::Location]
8
8
  # @param name [String]
9
- def initialize location, name
10
- super(location, '', name, nil, :instance, :public, [])
11
- end
9
+ # def initialize location, name
10
+ # # super(location, '', name, nil, :instance, :public, [])
11
+ # end
12
12
  end
13
13
  end
14
14
  end
@@ -4,6 +4,36 @@ module Solargraph
4
4
  def kind
5
5
  Pin::INSTANCE_VARIABLE
6
6
  end
7
+
8
+ def binder
9
+ closure.binder
10
+ end
11
+
12
+ def scope
13
+ closure.binder.scope
14
+ end
15
+
16
+ def context
17
+ @context ||= begin
18
+ result = super
19
+ if scope == :class
20
+ ComplexType.parse("Class<#{result.namespace}>")
21
+ else
22
+ ComplexType.parse("#{result.namespace}")
23
+ end
24
+ end
25
+ end
26
+
27
+ def nearly? other
28
+ super && binder == other.binder
29
+ end
30
+
31
+ def try_merge! pin
32
+ return false unless super
33
+ @assignment = pin.assignment
34
+ @return_type = pin.return_type
35
+ true
36
+ end
7
37
  end
8
38
  end
9
39
  end
@@ -2,7 +2,7 @@ module Solargraph
2
2
  module Pin
3
3
  class Keyword < Base
4
4
  def initialize name
5
- @name = name
5
+ super(name: name)
6
6
  end
7
7
 
8
8
  def name
@@ -3,9 +3,9 @@ module Solargraph
3
3
  class LocalVariable < BaseVariable
4
4
  include Localized
5
5
 
6
- def initialize location, namespace, name, comments, assignment, literal, context, block, presence
7
- super(location, namespace, name, comments, assignment, literal, context)
8
- @block = block
6
+ def initialize assignment: nil, presence: nil, **splat
7
+ super(splat)
8
+ @assignment = assignment
9
9
  @presence = presence
10
10
  end
11
11
 
@@ -1,8 +1,6 @@
1
1
  module Solargraph
2
2
  module Pin
3
3
  module Localized
4
- attr_reader :block
5
-
6
4
  # @return [Range]
7
5
  attr_reader :presence
8
6
 
@@ -12,11 +10,17 @@ module Solargraph
12
10
  def visible_from?(other, position)
13
11
  position = Position.normalize(position)
14
12
  other.filename == filename and
15
- ( other == block or
16
- (block.location.range.contain?(other.location.range.start) and block.location.range.contain?(other.location.range.ending))
17
- ) and
13
+ (other == closure ||
14
+ (closure.location.range.contain?(closure.location.range.start) && closure.location.range.contain?(other.location.range.ending))
15
+ ) &&
18
16
  presence.contain?(position)
19
17
  end
18
+
19
+ # @param other_loc [Location]
20
+ def visible_at?(other_loc)
21
+ return false if location.filename != other_loc.filename
22
+ presence.include?(other_loc.range.start)
23
+ end
20
24
  end
21
25
  end
22
26
  end