solargraph 0.32.5 → 0.33.0

Sign up to get free protection for your applications and to get access to all the features.
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