solargraph 0.26.1 → 0.27.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 (80) hide show
  1. checksums.yaml +4 -4
  2. data/lib/solargraph.rb +5 -2
  3. data/lib/solargraph/api_map.rb +236 -234
  4. data/lib/solargraph/api_map/store.rb +18 -53
  5. data/lib/solargraph/bundle.rb +22 -0
  6. data/lib/solargraph/complex_type.rb +9 -5
  7. data/lib/solargraph/complex_type/type_methods.rb +113 -0
  8. data/lib/solargraph/complex_type/unique_type.rb +35 -0
  9. data/lib/solargraph/core_fills.rb +1 -0
  10. data/lib/solargraph/diagnostics.rb +6 -4
  11. data/lib/solargraph/diagnostics/base.rb +3 -0
  12. data/lib/solargraph/diagnostics/require_not_found.rb +2 -1
  13. data/lib/solargraph/diagnostics/rubocop.rb +21 -6
  14. data/lib/solargraph/diagnostics/type_not_defined.rb +4 -3
  15. data/lib/solargraph/diagnostics/update_errors.rb +18 -0
  16. data/lib/solargraph/language_server/host.rb +90 -222
  17. data/lib/solargraph/language_server/host/cataloger.rb +68 -0
  18. data/lib/solargraph/language_server/host/diagnoser.rb +85 -0
  19. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +35 -24
  20. data/lib/solargraph/language_server/message/text_document/completion.rb +6 -8
  21. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +1 -1
  22. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +0 -1
  23. data/lib/solargraph/language_server/transport/socket.rb +4 -6
  24. data/lib/solargraph/language_server/transport/stdio.rb +4 -6
  25. data/lib/solargraph/library.rb +152 -99
  26. data/lib/solargraph/live_map.rb +1 -1
  27. data/lib/solargraph/location.rb +28 -0
  28. data/lib/solargraph/pin.rb +2 -0
  29. data/lib/solargraph/pin/attribute.rb +26 -12
  30. data/lib/solargraph/pin/base.rb +15 -35
  31. data/lib/solargraph/pin/base_variable.rb +7 -15
  32. data/lib/solargraph/pin/block.rb +5 -9
  33. data/lib/solargraph/pin/block_parameter.rb +9 -7
  34. data/lib/solargraph/pin/conversions.rb +5 -5
  35. data/lib/solargraph/pin/duck_method.rb +1 -1
  36. data/lib/solargraph/pin/instance_variable.rb +0 -4
  37. data/lib/solargraph/pin/keyword.rb +4 -0
  38. data/lib/solargraph/pin/localized.rb +5 -3
  39. data/lib/solargraph/pin/method.rb +11 -0
  40. data/lib/solargraph/pin/namespace.rb +7 -3
  41. data/lib/solargraph/pin/proxy_type.rb +3 -7
  42. data/lib/solargraph/pin/reference.rb +2 -2
  43. data/lib/solargraph/pin/symbol.rb +1 -1
  44. data/lib/solargraph/pin/yard_pin/method.rb +2 -2
  45. data/lib/solargraph/pin/yard_pin/namespace.rb +16 -7
  46. data/lib/solargraph/position.rb +103 -0
  47. data/lib/solargraph/range.rb +70 -0
  48. data/lib/solargraph/source.rb +159 -328
  49. data/lib/solargraph/source/chain.rb +38 -55
  50. data/lib/solargraph/source/chain/call.rb +47 -29
  51. data/lib/solargraph/source/chain/class_variable.rb +2 -2
  52. data/lib/solargraph/source/chain/constant.rb +3 -3
  53. data/lib/solargraph/source/chain/definition.rb +7 -3
  54. data/lib/solargraph/source/chain/global_variable.rb +1 -1
  55. data/lib/solargraph/source/chain/head.rb +22 -9
  56. data/lib/solargraph/source/chain/instance_variable.rb +2 -2
  57. data/lib/solargraph/source/chain/link.rb +4 -4
  58. data/lib/solargraph/source/chain/literal.rb +1 -1
  59. data/lib/solargraph/source/chain/variable.rb +2 -2
  60. data/lib/solargraph/source/change.rb +0 -6
  61. data/lib/solargraph/source/cursor.rb +161 -0
  62. data/lib/solargraph/source/encoding_fixes.rb +1 -1
  63. data/lib/solargraph/source/node_chainer.rb +28 -21
  64. data/lib/solargraph/source/node_methods.rb +1 -1
  65. data/lib/solargraph/source/source_chainer.rb +217 -0
  66. data/lib/solargraph/source_map.rb +138 -0
  67. data/lib/solargraph/source_map/clip.rb +123 -0
  68. data/lib/solargraph/{source → source_map}/completion.rb +3 -3
  69. data/lib/solargraph/{source → source_map}/mapper.rb +143 -41
  70. data/lib/solargraph/version.rb +1 -1
  71. data/lib/solargraph/workspace.rb +13 -20
  72. data/lib/solargraph/yard_map.rb +77 -48
  73. metadata +17 -11
  74. data/lib/solargraph/basic_type.rb +0 -33
  75. data/lib/solargraph/basic_type_methods.rb +0 -111
  76. data/lib/solargraph/source/call_chainer.rb +0 -273
  77. data/lib/solargraph/source/fragment.rb +0 -342
  78. data/lib/solargraph/source/location.rb +0 -23
  79. data/lib/solargraph/source/position.rb +0 -95
  80. data/lib/solargraph/source/range.rb +0 -64
@@ -21,7 +21,7 @@ module Solargraph
21
21
 
22
22
  # @return [Array<Solargraph::Pin::Base>]
23
23
  def get_methods(namespace, root = '', scope = 'instance', with_private = false)
24
- fqns = api_map.find_fully_qualified_namespace(namespace, root)
24
+ fqns = api_map.qualify(namespace, root)
25
25
  params = {
26
26
  namespace: namespace, root: root, scope: scope, with_private: with_private
27
27
  }
@@ -0,0 +1,28 @@
1
+ module Solargraph
2
+ class Location
3
+ # @return [String]
4
+ attr_reader :filename
5
+
6
+ # @return [Solargraph::Range]
7
+ attr_reader :range
8
+
9
+ # @param filename [String]
10
+ # @param range [Solargraph::Range]
11
+ def initialize filename, range
12
+ @filename = filename
13
+ @range = range
14
+ end
15
+
16
+ def to_hash
17
+ {
18
+ filename: filename,
19
+ range: range.to_hash
20
+ }
21
+ end
22
+
23
+ def == other
24
+ return false unless other.is_a?(Location)
25
+ filename == other.filename and range == other.range
26
+ end
27
+ end
28
+ end
@@ -36,5 +36,7 @@ module Solargraph
36
36
  SYMBOL = 10
37
37
  BLOCK = 11
38
38
  BLOCK_PARAMETER = 12
39
+
40
+ ROOT_PIN = Pin::Namespace.new(nil, '', '', '', :class, :public, nil)
39
41
  end
40
42
  end
@@ -7,10 +7,14 @@ module Solargraph
7
7
  # @return [Symbol] :class or :instance
8
8
  attr_reader :scope
9
9
 
10
- def initialize location, namespace, name, comments, access, scope
10
+ # @return [Symbol] :public, :protected, or :private
11
+ attr_reader :visibility
12
+
13
+ def initialize location, namespace, name, comments, access, scope, visibility
11
14
  super(location, namespace, name, comments)
12
15
  @access = access
13
16
  @scope = scope
17
+ @visibility = visibility
14
18
  end
15
19
 
16
20
  def kind
@@ -30,17 +34,7 @@ module Solargraph
30
34
  end
31
35
 
32
36
  def return_complex_type
33
- if @return_complex_type.nil?
34
- @return_complex_type = ComplexType.new
35
- tag = docstring.tag(:return)
36
- @return_complex_type = ComplexType.parse(*tag.types) unless tag.nil?
37
- end
38
- @return_complex_type
39
- end
40
-
41
- def visibility
42
- # @todo Check attribute visibility
43
- :public
37
+ @return_complex_type ||= generate_complex_type
44
38
  end
45
39
 
46
40
  def parameters
@@ -52,6 +46,26 @@ module Solargraph
52
46
  def parameter_names
53
47
  []
54
48
  end
49
+
50
+ private
51
+
52
+ # @todo DRY this method. It also exists in Pin::Method.
53
+ #
54
+ # @return [ComplexType]
55
+ def generate_complex_type
56
+ tag = docstring.tag(:return)
57
+ if tag.nil?
58
+ ol = docstring.tag(:overload)
59
+ tag = ol.tag(:return) unless ol.nil?
60
+ end
61
+ return ComplexType::UNDEFINED if tag.nil? or tag.types.nil? or tag.types.empty?
62
+ begin
63
+ ComplexType.parse *tag.types
64
+ rescue Solargraph::ComplexTypeError => e
65
+ STDERR.puts e.message
66
+ ComplexType::UNDEFINED
67
+ end
68
+ end
55
69
  end
56
70
  end
57
71
  end
@@ -6,7 +6,7 @@ module Solargraph
6
6
  include Conversions
7
7
  include Documenting
8
8
 
9
- # @return [Solargraph::Source::Location]
9
+ # @return [Solargraph::Location]
10
10
  attr_reader :location
11
11
 
12
12
  # The namespace in which this pin is defined.
@@ -24,7 +24,7 @@ module Solargraph
24
24
  # @return [String]
25
25
  attr_reader :path
26
26
 
27
- # @param location [Solargraph::Source::Location]
27
+ # @param location [Solargraph::Location]
28
28
  # @param namespace [String]
29
29
  # @param name [String]
30
30
  # @param comments [String]
@@ -75,9 +75,9 @@ module Solargraph
75
75
  false
76
76
  end
77
77
 
78
- # @return [String]
79
- def named_context
80
- namespace
78
+ # @return [ComplexType]
79
+ def context
80
+ @context ||= ComplexType.parse(namespace || '')
81
81
  end
82
82
 
83
83
  # Pin equality is determined using the #nearly? method and also
@@ -85,7 +85,7 @@ module Solargraph
85
85
  #
86
86
  def == other
87
87
  return false unless nearly? other
88
- location == other.location
88
+ comments == other.comments and location == other.location
89
89
  end
90
90
 
91
91
  # True if the specified pin is a near match to this one. A near match
@@ -106,43 +106,18 @@ module Solargraph
106
106
  )
107
107
  end
108
108
 
109
- # The first return type associated with the pin.
110
- # Use return_complex_types for an array of all return types.
109
+ # An alias for return_complex_type.
111
110
  #
112
- # @return [String]
111
+ # @return [ComplexType]
113
112
  def return_type
114
- return nil if return_complex_type.void?
115
- return_complex_type.first.tag
116
- end
117
-
118
- # The namespace of the first return type.
119
- # Use return_complex_types for an array of all return types.
120
- #
121
- # @deprecated Not in active internal use
122
- #
123
- # @return [String]
124
- def return_namespace
125
- return_type
126
- return nil if return_complex_type.void?
127
- @return_namespace ||= return_complex_type.first.namespace
128
- end
129
-
130
- # The scope of the first return type.
131
- # Use return_complex_types for an array of all return types.
132
- #
133
- # @deprecated Not in active internal use
134
- #
135
- # @return [String]
136
- def return_scope
137
- return nil if return_complex_type.void?
138
- @return_scope ||= return_complex_type.first.scope
113
+ return_complex_type
139
114
  end
140
115
 
141
116
  # All of the pin's return types as an array of ComplexTypes.
142
117
  #
143
118
  # @return [ComplexType]
144
119
  def return_complex_type
145
- @return_complex_type ||= ComplexType.new
120
+ @return_complex_type ||= ComplexType::UNDEFINED
146
121
  end
147
122
 
148
123
  # @return [YARD::Docstring]
@@ -157,6 +132,11 @@ module Solargraph
157
132
  @directives
158
133
  end
159
134
 
135
+ # @return [Array<YARD::Tags::MacroDirective>]
136
+ def macros
137
+ @macros ||= []
138
+ end
139
+
160
140
  # Perform a quick check to see if this pin possibly includes YARD
161
141
  # directives. This method does not require parsing the comments.
162
142
  #
@@ -5,6 +5,8 @@ module Solargraph
5
5
 
6
6
  attr_reader :context
7
7
 
8
+ attr_reader :assignment
9
+
8
10
  def initialize location, namespace, name, comments, assignment, literal, context
9
11
  super(location, namespace, name, comments)
10
12
  @assignment = assignment
@@ -16,10 +18,6 @@ module Solargraph
16
18
  @signature ||= resolve_node_signature(@assignment)
17
19
  end
18
20
 
19
- def scope
20
- @scope ||= (context.kind == Pin::METHOD and context.scope == :instance ? :instance : :class)
21
- end
22
-
23
21
  def completion_item_kind
24
22
  Solargraph::LanguageServer::CompletionItemKinds::VARIABLE
25
23
  end
@@ -34,7 +32,7 @@ module Solargraph
34
32
  end
35
33
 
36
34
  def nil_assignment?
37
- return_type == 'NilClass'
35
+ return_complex_type.nil?
38
36
  end
39
37
 
40
38
  def variable?
@@ -45,12 +43,10 @@ module Solargraph
45
43
  def infer api_map
46
44
  result = super
47
45
  return result if result.defined? or @assignment.nil?
48
- # chain = Source::Chain.new(filename, @assignment)
49
- # @todo Use NodeChainer
50
- chain = Source::NodeChainer.chain(location.filename, @assignment)
51
- fragment = api_map.fragment_at(location)
52
- locals = fragment.locals - [self]
53
- chain.infer_type_with(api_map, context, locals)
46
+ chain = Source::NodeChainer.chain(@assignment, filename)
47
+ clip = api_map.clip_at(location.filename, location.range.start)
48
+ locals = clip.locals - [self]
49
+ chain.infer(api_map, ProxyType.anonymous(context), locals)
54
50
  end
55
51
 
56
52
  def == other
@@ -65,10 +61,6 @@ module Solargraph
65
61
  true
66
62
  end
67
63
 
68
- protected
69
-
70
- attr_reader :assignment
71
-
72
64
  private
73
65
 
74
66
  def generate_complex_type
@@ -9,29 +9,25 @@ module Solargraph
9
9
  # @return [Array<String>]
10
10
  attr_reader :parameters
11
11
 
12
- attr_reader :scope
13
-
14
- def initialize location, namespace, name, comments, receiver, scope
12
+ def initialize location, namespace, name, comments, receiver, context
15
13
  super(location, namespace, name, comments)
16
14
  @receiver = receiver
17
- @scope = scope
15
+ @context = context
18
16
  end
19
17
 
20
18
  def kind
21
19
  Pin::BLOCK
22
20
  end
23
21
 
24
- def return_complex_type
25
- @return_complex_type ||= Solargraph::ComplexType.parse(namespace)
26
- end
27
-
28
22
  def parameters
29
23
  @parameters ||= []
30
24
  end
31
25
 
32
26
  def nearly? other
33
27
  return false unless super
34
- receiver == other.receiver and parameters == other.parameters
28
+ # @todo Trying to not to block merges too much
29
+ # receiver == other.receiver and parameters == other.parameters
30
+ true
35
31
  end
36
32
  end
37
33
  end
@@ -42,8 +42,9 @@ module Solargraph
42
42
  def try_merge! other
43
43
  return false unless super
44
44
  @block = other.block
45
- @presence = block.location.range
45
+ @presence = other.block.location.range
46
46
  @return_complex_type = nil
47
+ true
47
48
  end
48
49
 
49
50
  # @return [Array<Solargraph::ComplexType>]
@@ -65,17 +66,18 @@ module Solargraph
65
66
  block
66
67
  end
67
68
 
69
+ # @param api_map [ApiMap]
68
70
  def infer api_map
69
71
  return return_complex_type unless return_complex_type.undefined?
70
- chain = Source::NodeChainer.chain(location.filename, block.receiver)
71
- fragment = api_map.fragment_at(location)
72
- locals = fragment.locals - [self]
73
- meths = chain.define_with(api_map, block, fragment.locals)
72
+ chain = Source::NodeChainer.chain(block.receiver, filename)
73
+ clip = api_map.clip_at(location.filename, location.range.start)
74
+ locals = clip.locals - [self]
75
+ meths = chain.define(api_map, block, locals)
74
76
  meths.each do |meth|
75
77
  if (Solargraph::CoreFills::METHODS_WITH_YIELDPARAM_SUBTYPES.include?(meth.path))
76
- bmeth = chain.define_base_with(api_map, context, locals).first
78
+ bmeth = chain.base.define(api_map, context, locals).first
77
79
  return ComplexType::UNDEFINED if bmeth.nil? or bmeth.return_complex_type.undefined? or bmeth.return_complex_type.subtypes.empty?
78
- return bmeth.return_complex_type.subtypes.first.qualify(api_map)
80
+ return bmeth.return_complex_type.subtypes.first.qualify(api_map, bmeth.context.namespace)
79
81
  else
80
82
  yps = meth.docstring.tags(:yieldparam)
81
83
  unless yps[index].nil? or yps[index].types.nil? or yps[index].types.empty?
@@ -10,8 +10,8 @@ module Solargraph
10
10
  detail: detail,
11
11
  data: {
12
12
  path: path,
13
- return_type: return_type,
14
- location: location,
13
+ return_type: return_type.tag,
14
+ location: (location ? location.to_hash : nil),
15
15
  deprecated: deprecated?
16
16
  }
17
17
  }
@@ -69,9 +69,9 @@ module Solargraph
69
69
  private
70
70
 
71
71
  def generate_link
72
- return nil if return_complex_type.undefined?
73
- this_path = path || return_type
74
- return nil if this_path.nil?
72
+ this_path = path || return_type.tag
73
+ return this_path if comments.empty?
74
+ return nil if this_path.nil? or this_path == 'undefined'
75
75
  "[#{this_path.gsub('_', '\\\\_')}](solargraph:/document?query=#{URI.encode(this_path)})"
76
76
  end
77
77
  end
@@ -4,7 +4,7 @@ module Solargraph
4
4
  # use duck typing, e.g., `@param file [#read]`.
5
5
  #
6
6
  class DuckMethod < Pin::Method
7
- # @param location [Solargraph::Source::Location]
7
+ # @param location [Solargraph::Location]
8
8
  # @param name [String]
9
9
  def initialize location, name
10
10
  super(location, 'Object', name, nil, :instance, :public, [])
@@ -4,10 +4,6 @@ module Solargraph
4
4
  def kind
5
5
  Pin::INSTANCE_VARIABLE
6
6
  end
7
-
8
- def scope
9
- @scope ||= (context.kind == Pin::NAMESPACE ? :class : context.scope)
10
- end
11
7
  end
12
8
  end
13
9
  end
@@ -9,6 +9,10 @@ module Solargraph
9
9
  @name
10
10
  end
11
11
 
12
+ def kind
13
+ Solargraph::Pin::KEYWORD
14
+ end
15
+
12
16
  def completion_item_kind
13
17
  Solargraph::LanguageServer::CompletionItemKinds::KEYWORD
14
18
  end
@@ -3,15 +3,17 @@ module Solargraph
3
3
  module Localized
4
4
  attr_reader :block
5
5
 
6
- # @return [Source::Range]
6
+ # @return [Range]
7
7
  attr_reader :presence
8
8
 
9
9
  # @param other [Pin::Base] The caller's block
10
- # @param position [Source::Position] The caller's position
10
+ # @param position [Position] The caller's position
11
11
  # @return [Boolean]
12
12
  def visible_from?(other, position)
13
13
  other.filename == filename and
14
- (other == block or other.named_context == named_context) and
14
+ ( other == block or
15
+ (block.location.range.contain?(other.location.range.start) and block.location.range.contain?(other.location.range.ending))
16
+ ) and
15
17
  presence.contain?(position)
16
18
  end
17
19
  end
@@ -30,6 +30,17 @@ module Solargraph
30
30
  @path ||= namespace + (scope == :instance ? '#' : '.') + name
31
31
  end
32
32
 
33
+ def context
34
+ @context ||= begin
35
+ if scope == :class
36
+ # @todo Determine whether the namespace is a class or a module
37
+ ComplexType.parse("Class<#{namespace}>")
38
+ else
39
+ ComplexType.parse(namespace)
40
+ end
41
+ end
42
+ end
43
+
33
44
  def completion_item_kind
34
45
  Solargraph::LanguageServer::CompletionItemKinds::METHOD
35
46
  end
@@ -30,12 +30,12 @@ module Solargraph
30
30
  Pin::NAMESPACE
31
31
  end
32
32
 
33
- def named_context
34
- path
33
+ def context
34
+ @context ||= ComplexType.parse("#{type.to_s.capitalize}<#{path}>")
35
35
  end
36
36
 
37
37
  def scope
38
- :class
38
+ context.scope
39
39
  end
40
40
 
41
41
  def completion_item_kind
@@ -55,6 +55,10 @@ module Solargraph
55
55
  @return_complex_type ||= ComplexType.parse( (type == :class ? 'Class' : 'Module') + "<#{path}>" )
56
56
  end
57
57
 
58
+ def domains
59
+ @domains ||= []
60
+ end
61
+
58
62
  def infer api_map
59
63
  # Assuming that namespace pins are always fully qualified
60
64
  return_complex_type