solargraph 0.26.1 → 0.27.0

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