solargraph 0.23.4 → 0.23.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3d2dc2283964f7972f289ef9aa43a939948049b02d351f244ec522afc1033265
4
- data.tar.gz: 8e60c7d6d9a3f7bd25fcbc66566c1ce795b3b8999572b454e6d07a027460ec4d
3
+ metadata.gz: 9c281911d4b36b81d86b88a11979ee08e9c974cd10cbe83e1d07a03cf3f52185
4
+ data.tar.gz: 65d1fe2602ac1ac9b9272aaf52a0a4772edd5897465b29d370ee6ebc15cedb44
5
5
  SHA512:
6
- metadata.gz: 9ffd40c951fb253bef3653525c9cbf10362582c292c529559b59698a1636939ed589fe76d9eacb01b26f6e7340c4f854d557fff0bd94a34e4b9d277196c3e637
7
- data.tar.gz: d589e62eb1024c07eb2bd15cde0f29552a07089fa812b2508c51ad701622b1ab59e783b69f2cb4bc40645044c514f6167e83f2b1c3064c7eea8c372aad95c380
6
+ metadata.gz: d1c5981b4b14c3651833ddc5589c8002ede7d7d690519ee70d8a8e82a59bbfaecdcd6576b0d6706b29d6d92bda3f1a5c990a23286114d81b84ec49b99ca9bb8e
7
+ data.tar.gz: 0c75eb3da1835a7cd35ee8a594554ec0e6638c4afbe471aa27f05c7233df0841b47d5e313fb53d319b56af6fc46fd1876756dc9b8ace48476ca4e9353c23dba1
data/lib/solargraph.rb CHANGED
@@ -3,17 +3,22 @@ require 'rubygems/package'
3
3
  require 'yard-solargraph'
4
4
 
5
5
  module Solargraph
6
- class InvalidOffsetError < RangeError; end
7
- class DiagnosticsError < RuntimeError; end
8
- class FileNotFoundError < RuntimeError; end
6
+ class InvalidOffsetError < RangeError; end
7
+ class DiagnosticsError < RuntimeError; end
8
+ class FileNotFoundError < RuntimeError; end
9
9
  class SourceNotAvailableError < StandardError; end
10
-
11
- class WorkspaceTooLargeError < RuntimeError
10
+ class WorkspaceTooLargeError < RuntimeError
11
+ # @return [Integer]
12
12
  attr_reader :size
13
13
 
14
+ # @return [Integer]
15
+ attr_reader :max
16
+
14
17
  # @param size [Integer] The number of files included in the workspace
15
- def initialize size
18
+ # @param max [Integer] The maximum number of files allowed
19
+ def initialize size, max
16
20
  @size = size
21
+ @max = max
17
22
  end
18
23
  end
19
24
 
@@ -336,7 +336,8 @@ module Solargraph
336
336
  # @param fragment [Solargraph::Source::Fragment]
337
337
  # @return [Array<Solargraph::Pin::Base>]
338
338
  def define fragment
339
- return [] if fragment.string? or fragment.comment? or fragment.literal?
339
+ return get_path_suggestions(fragment.namespace) if fragment.whole_signature == 'self'
340
+ return [] if fragment.string? or fragment.comment? or fragment.literal? or fragment.whole_signature == 'self'
340
341
  if fragment.base_literal?
341
342
  probe.infer_signature_pins fragment.whole_signature, Pin::ProxyMethod.new(fragment.base_literal), fragment.locals
342
343
  else
@@ -526,6 +527,7 @@ module Solargraph
526
527
  fqis = qualify(is, fqns)
527
528
  result.concat inner_get_constants(fqis, [:public], skip) unless fqis.nil?
528
529
  end
530
+ result.concat live_map.get_constants(fqns)
529
531
  result
530
532
  end
531
533
 
@@ -48,6 +48,7 @@ module Solargraph
48
48
  def infer_signature_type signature, context_pin, locals
49
49
  pins = infer_signature_pins(signature, context_pin, locals)
50
50
  pins.each do |pin|
51
+ return pin.return_type unless pin.return_type.nil?
51
52
  type = resolve_pin_type(pin, locals - [pin])
52
53
  return qualify(type, pin.named_context) unless type.nil?
53
54
  end
@@ -59,8 +60,9 @@ module Solargraph
59
60
  # Word search is ALWAYS internal
60
61
  def infer_word_pins word, context_pin, locals
61
62
  return [] if word.empty?
63
+ return infer_self(context_pin) if word == 'self'
62
64
  lvars = locals.select{|pin| pin.name == word}
63
- return lvars unless lvars.empty?
65
+ return resolve_word_types(lvars, locals) unless lvars.empty?
64
66
  return api_map.get_global_variable_pins.select{|pin| pin.name == word} if word.start_with?('$')
65
67
  namespace, scope = extract_namespace_and_scope_from_pin(context_pin)
66
68
  return api_map.pins.select{|pin| word_matches_context?(word, namespace, scope, pin)} if variable_name?(word)
@@ -75,7 +77,28 @@ module Solargraph
75
77
  result.concat api_map.get_path_suggestions(word) if result.empty?
76
78
  result.concat api_map.get_methods(namespace, scope: scope, visibility: [:public, :private, :protected]).select{|pin| pin.name == word} unless word.include?('::')
77
79
  result.concat api_map.get_constants('', namespace).select{|pin| pin.name == word} if result.empty?
78
- result
80
+ resolve_word_types(result, locals)
81
+ end
82
+
83
+ def resolve_word_types(pins, locals)
84
+ pins.each do |p|
85
+ next unless p.return_type.nil?
86
+ type = resolve_pin_type(p, locals)
87
+ # @todo Smelly instance variable access
88
+ p.instance_variable_set(:@return_type, type)
89
+ end
90
+ end
91
+
92
+ def infer_self context_pin
93
+ if context_pin.kind == Pin::METHOD
94
+ if context_pin.scope == :instance
95
+ return [Pin::ProxyMethod.new(context_pin.namespace)]
96
+ else
97
+ return api_map.get_path_suggestions(context_pin.namespace)
98
+ end
99
+ else
100
+ return api_map.get_path_suggestions(context_pin.path)
101
+ end
79
102
  end
80
103
 
81
104
  # Method name search is external by default
@@ -154,24 +177,27 @@ module Solargraph
154
177
  def resolve_pin_type pin, locals
155
178
  pin.return_type
156
179
  return pin.return_type unless pin.return_type.nil?
157
- return resolve_block_parameter(pin) if pin.kind == Pin::BLOCK_PARAMETER
180
+ return resolve_block_parameter(pin, locals) if pin.kind == Pin::BLOCK_PARAMETER
158
181
  return resolve_variable(pin, locals) if pin.variable?
159
182
  nil
160
183
  end
161
184
 
162
- def resolve_block_parameter pin
185
+ def resolve_block_parameter pin, locals
163
186
  return pin.return_type unless pin.return_type.nil?
164
187
  signature = pin.block.receiver
165
188
  # @todo Not sure if assuming the first pin is good here
166
- meth = @api_map.probe.infer_signature_pins(signature, pin.block, []).first
189
+ meth = infer_signature_pins(signature, pin.block, locals).first
167
190
  return nil if meth.nil?
168
191
  if (Solargraph::CoreFills::METHODS_WITH_YIELDPARAM_SUBTYPES.include?(meth.path))
169
192
  base = signature.split('.')[0..-2].join('.')
170
193
  return nil if base.nil? or base.empty?
171
194
  # @todo Not sure if assuming the first pin is good here
172
- bmeth = @api_map.probe.infer_signature_pins(base, pin.block, []).first
195
+ bmeth = infer_signature_pins(base, pin.block, locals).first
173
196
  return nil if bmeth.nil?
174
- subtypes = get_subtypes(bmeth.return_type)
197
+ btype = bmeth.return_type
198
+ btype = infer_signature_type(bmeth.signature, pin.block, locals) if btype.nil? and bmeth.variable?
199
+ subtypes = get_subtypes(btype)
200
+ return nil if subtypes.nil?
175
201
  return subtypes[0]
176
202
  else
177
203
  unless meth.docstring.nil?
@@ -8,11 +8,39 @@ module Solargraph
8
8
  autoload :Rubocop, 'solargraph/diagnostics/rubocop'
9
9
  autoload :RequireNotFound, 'solargraph/diagnostics/require_not_found'
10
10
 
11
- # Reporters identified by name for activation in .solargraph.yml files.
12
- #
13
- REPORTERS = {
14
- 'rubocop' => Rubocop,
15
- 'require_not_found' => RequireNotFound
16
- }
11
+ class << self
12
+ # Add a reporter with a name to identify it in .solargraph.yml files.
13
+ #
14
+ # @param name [String] The name
15
+ # @param klass [Class<Solargraph::Diagnostics::Base>] The class implementation
16
+ def register name, klass
17
+ reporter_hash[name] = klass
18
+ end
19
+
20
+ # Get an array of reporter names.
21
+ #
22
+ # @return [Array<String>]
23
+ def reporters
24
+ reporter_hash.keys
25
+ end
26
+
27
+ # Find a reporter by name.
28
+ #
29
+ # @param name [String] The name with which the reporter was registered
30
+ # @return [Class<Solargraph::Diagnostics::Base>]
31
+ def reporter name
32
+ reporter_hash[name]
33
+ end
34
+
35
+ private
36
+
37
+ # @return [Hash]
38
+ def reporter_hash
39
+ @reporter_hash ||= {}
40
+ end
41
+ end
42
+
43
+ register 'rubocop', Rubocop
44
+ register 'require_not_found', RequireNotFound
17
45
  end
18
46
  end
@@ -40,16 +40,27 @@ module Solargraph
40
40
  @options ||= default_configuration
41
41
  end
42
42
 
43
+ # Cancel the method with the specified ID.
44
+ #
45
+ # @param id [Integer]
43
46
  def cancel id
44
47
  @cancel_semaphore.synchronize { @cancel.push id }
45
48
  end
46
49
 
50
+ # True if the host received a request to cancel the method with the
51
+ # specified ID.
52
+ #
53
+ # @param id [Integer]
54
+ # @return [Boolean]
47
55
  def cancel? id
48
56
  result = false
49
57
  @cancel_semaphore.synchronize { result = @cancel.include? id }
50
58
  result
51
59
  end
52
60
 
61
+ # Delete the specified ID from the list of cancelled IDs if it exists.
62
+ #
63
+ # @param id [Integer]
53
64
  def clear id
54
65
  @cancel_semaphore.synchronize { @cancel.delete id }
55
66
  end
@@ -120,6 +131,7 @@ module Solargraph
120
131
 
121
132
  # True if the specified file is currently open in the library.
122
133
  #
134
+ # @param uri [String]
123
135
  # @return [Boolean]
124
136
  def open? uri
125
137
  result = nil
@@ -129,6 +141,9 @@ module Solargraph
129
141
  result
130
142
  end
131
143
 
144
+ # Close the file specified by the URI.
145
+ #
146
+ # @param uri [String]
132
147
  def close uri
133
148
  @change_semaphore.synchronize do
134
149
  library.close uri_to_file(uri)
@@ -200,7 +215,7 @@ module Solargraph
200
215
  rescue WorkspaceTooLargeError => e
201
216
  send_notification 'window/showMessage', {
202
217
  'type' => Solargraph::LanguageServer::MessageTypes::WARNING,
203
- 'message' => "The workspace is too large to index (#{e.size} files, max #{Workspace::MAX_WORKSPACE_SIZE})"
218
+ 'message' => "The workspace is too large to index (#{e.size} files, max #{e.max})"
204
219
  }
205
220
  @library = Solargraph::Library.load(nil)
206
221
  end
@@ -397,6 +412,8 @@ module Solargraph
397
412
  result
398
413
  end
399
414
 
415
+ # @param uri [String]
416
+ # @return [Array<Solargraph::Pin::Base>]
400
417
  def file_symbols uri
401
418
  library.file_symbols(uri_to_file(uri))
402
419
  end
@@ -9,22 +9,17 @@ module Solargraph::LanguageServer::Message::TextDocument
9
9
  col = params['position']['character']
10
10
  contents = []
11
11
  suggestions = host.definitions_at(filename, line, col)
12
- last_path = nil
12
+ last_link = nil
13
13
  suggestions.each do |pin|
14
14
  parts = []
15
- this_path = nil
16
- if pin.kind_of?(Solargraph::Pin::BaseVariable)
17
- this_path = pin.return_type
18
- else
19
- this_path = pin.path
20
- end
21
- if !this_path.nil? and this_path != last_path
22
- parts.push link_documentation(this_path)
15
+ this_link = pin.link_documentation
16
+ if !this_link.nil? and this_link != last_link
17
+ parts.push this_link
23
18
  end
24
19
  parts.push HTMLEntities.new.encode(pin.detail) unless pin.kind == Solargraph::Pin::NAMESPACE or pin.detail.nil?
25
20
  parts.push pin.documentation unless pin.documentation.nil? or pin.documentation.empty?
26
21
  contents.push parts.join("\n\n") unless parts.empty?
27
- last_path = this_path unless this_path.nil?
22
+ last_link = this_link unless this_link.nil?
28
23
  end
29
24
  set_result(
30
25
  contents: {
@@ -33,13 +28,5 @@ module Solargraph::LanguageServer::Message::TextDocument
33
28
  }
34
29
  )
35
30
  end
36
-
37
- private
38
-
39
- # @todo: DRY this method. It exists in Conversions
40
- def link_documentation path
41
- uri = "solargraph:/document?query=" + URI.encode(path)
42
- "[#{path}](#{uri})"
43
- end
44
31
  end
45
32
  end
@@ -218,14 +218,19 @@ module Solargraph
218
218
  api_map.query_symbols query
219
219
  end
220
220
 
221
+ # @param filename [String]
222
+ # @return [Array<Solargraph::Pin::Base>]
221
223
  def file_symbols filename
222
224
  read(filename).all_symbols
223
225
  end
224
226
 
227
+ # @param path [String]
228
+ # @return [Array<Solargraph::Pin::Base>]
225
229
  def path_pins path
226
230
  api_map.get_path_suggestions(path)
227
231
  end
228
232
 
233
+ # @param updater [Solargraph::Source::Updater]
229
234
  def synchronize updater
230
235
  source = read(updater.filename)
231
236
  source.synchronize updater
@@ -242,6 +247,7 @@ module Solargraph
242
247
 
243
248
  # Get diagnostics about a file.
244
249
  #
250
+ # @param filename [String]
245
251
  # @return [Array<Hash>]
246
252
  def diagnose filename
247
253
  # @todo Only open files get diagnosed. Determine whether anything or
@@ -251,7 +257,7 @@ module Solargraph
251
257
  result = []
252
258
  source = read(filename)
253
259
  workspace.config.reporters.each do |name|
254
- reporter = Diagnostics::REPORTERS[name]
260
+ reporter = Diagnostics.reporter(name)
255
261
  raise DiagnosticsError, "Diagnostics reporter #{name} does not exist" if reporter.nil?
256
262
  result.concat reporter.new.diagnose(source, api_map)
257
263
  end
@@ -54,13 +54,14 @@ module Solargraph
54
54
  suggestions = []
55
55
  result.uniq.each do |r|
56
56
  path = (r['namespace'].empty? ? '' : "#{r['namespace']}::") + r['name']
57
- kind = Suggestion::CONSTANT
57
+ kind = Pin::CONSTANT
58
58
  if r['class'] == 'Class'
59
- kind = Suggestion::CLASS
59
+ suggestions.push Pin::Namespace.new(nil, r['namespace'], r['name'], YARD::Docstring.new("(defined at runtime)"), :class, :public, nil)
60
60
  elsif r['class'] == 'Module'
61
- kind = Suggestion::MODULE
61
+ suggestions.push Pin::Namespace.new(nil, r['namespace'], r['name'], YARD::Docstring.new("(defined at runtime)"), :module, :public, nil)
62
+ else
63
+ suggestions.push Pin::Constant.new(nil, r['namespace'], r['name'], YARD::Docstring.new("(defined at runtime"), nil, nil, nil, :public)
62
64
  end
63
- suggestions.push(Suggestion.new(r['name'], kind: kind, path: path))
64
65
  end
65
66
  cache.set_constants(namespace, root, suggestions)
66
67
  suggestions
@@ -22,6 +22,10 @@ module Solargraph
22
22
  Solargraph::LanguageServer::CompletionItemKinds::PROPERTY
23
23
  end
24
24
 
25
+ def symbol_kind
26
+ Solargraph::LanguageServer::SymbolKinds::PROPERTY
27
+ end
28
+
25
29
  def path
26
30
  @path ||= namespace + (scope == :instance ? '#' : '.') + name
27
31
  end
@@ -21,6 +21,10 @@ module Solargraph
21
21
  Solargraph::LanguageServer::CompletionItemKinds::VARIABLE
22
22
  end
23
23
 
24
+ def symbol_kind
25
+ Solargraph::LanguageServer::SymbolKinds::VARIABLE
26
+ end
27
+
24
28
  def index
25
29
  block.parameters.index(self)
26
30
  end
@@ -21,7 +21,7 @@ module Solargraph
21
21
  if @resolve_completion_item.nil?
22
22
  extra = {}
23
23
  alldoc = ''
24
- alldoc += link_documentation(path) unless path.nil?
24
+ alldoc += link_documentation unless link_documentation.nil?
25
25
  alldoc += "\n\n" unless alldoc.empty?
26
26
  alldoc += documentation unless documentation.nil?
27
27
  extra[:documentation] = alldoc unless alldoc.empty?
@@ -50,10 +50,19 @@ module Solargraph
50
50
  @detail
51
51
  end
52
52
 
53
+ # Get a markdown-flavored link to a documentation page.
54
+ #
55
+ # @return [String]
56
+ def link_documentation
57
+ @link_documentation ||= generate_link
58
+ end
59
+
53
60
  private
54
61
 
55
- def link_documentation path
56
- @link_documentation ||= "[#{path}](solargraph:/document?query=#{URI.encode(path)})"
62
+ def generate_link
63
+ this_path = path || return_type
64
+ return nil if this_path.nil?
65
+ "[#{this_path.gsub('_', '\\\\_')}](solargraph:/document?query=#{URI.encode(this_path)})"
57
66
  end
58
67
  end
59
68
  end
@@ -17,7 +17,6 @@ module Solargraph
17
17
  end
18
18
 
19
19
  def completion_item_kind
20
- # Solargraph::Suggestion::METHOD
21
20
  Solargraph::LanguageServer::CompletionItemKinds::METHOD
22
21
  end
23
22
  end
@@ -4,7 +4,7 @@ module Solargraph
4
4
  # to type inference methods. ApiMap::Probe can treat it as an anonymous
5
5
  # method while analyzing signatures.
6
6
  #
7
- class ProxyMethod
7
+ class ProxyMethod < Base
8
8
  # @return [String]
9
9
  attr_reader :return_type
10
10
 
@@ -10,16 +10,16 @@ module Solargraph
10
10
  # @return [String]
11
11
  attr_reader :name
12
12
 
13
+ # @param location [Source::Location]
14
+ # @param namespace [String]
15
+ # @param name [String]
13
16
  def initialize location, namespace, name
14
17
  @location = location
15
18
  @namespace = namespace
16
19
  @name = name
17
20
  end
18
21
 
19
- # @todo Deprecaate
20
- def resolve api_map
21
- end
22
-
22
+ # @return [String]
23
23
  def filename
24
24
  location.filename
25
25
  end
@@ -61,20 +61,21 @@ module Solargraph
61
61
 
62
62
  def get_methods args
63
63
  result = []
64
+ # @type [Class]
64
65
  con = find_constant(args['namespace'], args['root'])
65
66
  unless con.nil?
66
67
  if (args['scope'] == 'class')
67
- result.concat con.methods(false) if args['with_private']
68
- result.concat con.public_methods(false)
68
+ result.concat con.methods if args['with_private']
69
+ result.concat con.public_methods
69
70
  elsif (args['scope'] == 'instance')
70
- result.concat con.instance_methods(false) if args['with_private']
71
- result.concat con.public_instance_methods(false)
71
+ result.concat con.instance_methods if args['with_private']
72
+ result.concat con.public_instance_methods
72
73
  end
73
74
  end
74
75
  result.keep_if{|m| m.to_s.match(/^[a-z_]/i)}
75
76
  respond_ok (result.uniq.sort.map do |name|
76
77
  # @type [Method]
77
- meth = con.method(name)
78
+ meth = args['scope'] == 'class' ? con.method(name) : con.instance_method(name)
78
79
  {
79
80
  name: name,
80
81
  parameters: build_parameter_array(meth.parameters)
@@ -125,7 +125,7 @@ module Solargraph
125
125
 
126
126
  desc 'reporters', 'Get a list of diagnostics reporters'
127
127
  def reporters
128
- puts Solargraph::Diagnostics::REPORTERS.keys.sort
128
+ puts Solargraph::Diagnostics.reporters
129
129
  end
130
130
  end
131
131
  end
@@ -44,6 +44,7 @@ module Solargraph
44
44
  # @return [Array<Solargraph::Pin::Base>]
45
45
  attr_reader :pins
46
46
 
47
+ # @return [Array<Solargraph::Pin::Reference>]
47
48
  attr_reader :requires
48
49
 
49
50
  attr_reader :domains
@@ -53,15 +54,18 @@ module Solargraph
53
54
  include NodeMethods
54
55
 
55
56
  def initialize code, filename = nil
56
- @code = code
57
- @fixed = code
58
- @filename = filename
59
- # @stubbed_lines = stubbed_lines
60
- @version = 0
61
57
  begin
62
- parse
63
- rescue Parser::SyntaxError, EncodingError
64
- hard_fix_node
58
+ @code = code
59
+ @fixed = code
60
+ @filename = filename
61
+ @version = 0
62
+ begin
63
+ parse
64
+ rescue Parser::SyntaxError, EncodingError
65
+ hard_fix_node
66
+ end
67
+ rescue Exception => e
68
+ raise RuntimeError, "Error parsing #{filename || '(source)'}: [#{e.class}] #{e.message}"
65
69
  end
66
70
  end
67
71
 
@@ -75,6 +79,7 @@ module Solargraph
75
79
  end
76
80
 
77
81
  # @todo Name problem
82
+ # @return [Array<Solargraph::Pin::Reference>]
78
83
  def required
79
84
  requires
80
85
  end
@@ -111,6 +116,7 @@ module Solargraph
111
116
  pins.select{|pin| pin.kind == Pin::CLASS_VARIABLE}
112
117
  end
113
118
 
119
+ # @return [Array<Solargraph::Pin::Base>]
114
120
  def locals
115
121
  @locals
116
122
  end
@@ -130,6 +136,7 @@ module Solargraph
130
136
  @symbols
131
137
  end
132
138
 
139
+ # @return [Array<Solargraph::Pin::Symbol>]
133
140
  def symbols
134
141
  symbol_pins
135
142
  end
@@ -171,6 +178,11 @@ module Solargraph
171
178
  tree_at(line, column).first
172
179
  end
173
180
 
181
+ # True if the specified location is inside a string.
182
+ #
183
+ # @param line [Integer]
184
+ # @param column [Integer]
185
+ # @return [Boolean]
174
186
  def string_at?(line, column)
175
187
  node = node_at(line, column)
176
188
  # @todo raise InvalidOffset or InvalidRange or something?
@@ -232,7 +244,7 @@ module Solargraph
232
244
 
233
245
  def all_symbols
234
246
  @all_symbols ||= pins.select{ |pin|
235
- [Pin::ATTRIBUTE, Pin::CONSTANT, Pin::METHOD, Pin::NAMESPACE].include?(pin.kind)
247
+ [Pin::ATTRIBUTE, Pin::CONSTANT, Pin::METHOD, Pin::NAMESPACE].include?(pin.kind) and !pin.name.empty?
236
248
  }
237
249
  end
238
250
 
@@ -25,13 +25,15 @@ module Solargraph
25
25
  # @return [String] The updated text.
26
26
  def write text, nullable = false
27
27
  if nullable and !range.nil? and new_text.match(/[\.\[\{\(@\$:]$/)
28
- if new_text == ':'
28
+ [':', '@'].each do |dupable|
29
+ next unless new_text == dupable
29
30
  offset = Position.to_offset(text, range.start)
30
- if text[offset - 1] == ':'
31
+ if text[offset - 1] == dupable
31
32
  p = Position.from_offset(text, offset - 1)
32
33
  r = Change.new(Range.new(p, range.start), ' ')
33
34
  text = r.write(text)
34
35
  end
36
+ break
35
37
  end
36
38
  commit text, "#{new_text[0..-2]} "
37
39
  elsif range.nil?
@@ -3,8 +3,14 @@ module Solargraph
3
3
  class Fragment
4
4
  include NodeMethods
5
5
 
6
+ # The zero-based line number of the fragment's location.
7
+ #
8
+ # @return [Integer]
6
9
  attr_reader :line
7
10
 
11
+ # The zero-based column number of the fragment's location.
12
+ #
13
+ # @return [Integer]
8
14
  attr_reader :column
9
15
 
10
16
  # @return [Solargraph::Source]
@@ -21,10 +27,14 @@ module Solargraph
21
27
  @calculated_literal = false
22
28
  end
23
29
 
30
+ # An alias for #column.
31
+ #
32
+ # @return [Integer]
24
33
  def character
25
34
  @column
26
35
  end
27
36
 
37
+ # @return [Source::Position]
28
38
  def position
29
39
  @position ||= Position.new(line, column)
30
40
  end
@@ -40,6 +50,8 @@ module Solargraph
40
50
  @namespace
41
51
  end
42
52
 
53
+ # True if the fragment is inside a method argument.
54
+ #
43
55
  # @return [Boolean]
44
56
  def argument?
45
57
  @argument ||= !signature_position.nil?
@@ -159,6 +171,8 @@ module Solargraph
159
171
 
160
172
  # Get the word before the current offset. Given the text `foo.bar`, the
161
173
  # word at offset 6 is `ba`.
174
+ #
175
+ # @return [String]
162
176
  def word
163
177
  @word ||= word_at(offset)
164
178
  end
@@ -194,14 +208,17 @@ module Solargraph
194
208
  @whole_word_range ||= word_range_at(offset, true)
195
209
  end
196
210
 
211
+ # @return [Solargraph::Pin::Base]
197
212
  def block
198
213
  @block ||= @source.locate_block_pin(line, character)
199
214
  end
200
215
 
216
+ # @return [Solargraph::Pin::Base]
201
217
  def named_path
202
218
  @named_path ||= @source.locate_named_path_pin(line, character)
203
219
  end
204
220
 
221
+ # @return [Array<Solargraph::Pin::Base>]
205
222
  def locals
206
223
  @locals ||= @source.locals.select{|pin| pin.visible_from?(block, position)}
207
224
  end
@@ -227,10 +244,17 @@ module Solargraph
227
244
  @base_literal
228
245
  end
229
246
 
247
+ # True if the fragment is inside a literal value.
248
+ #
249
+ # @return [Boolean]
230
250
  def literal?
231
251
  !literal.nil?
232
252
  end
233
253
 
254
+ # The fragment's literal type, or nil if the fragment is not inside a
255
+ # literal value.
256
+ #
257
+ # @return [String]
234
258
  def literal
235
259
  if @literal.nil? and !@calculated_actual_literal
236
260
  @calculated_actual_literal = true
@@ -299,7 +323,7 @@ module Solargraph
299
323
  end
300
324
  if brackets.zero? and parens.zero? and squares.zero?
301
325
  break if ['"', "'", ',', ';', '%'].include?(char)
302
- signature = char + signature if char.match(/[a-z0-9:\._@\$]/i) and @code[index - 1] != '%'
326
+ signature = char + signature if char.match(/[a-z0-9:\._@\$\?\!]/i) and @code[index - 1] != '%'
303
327
  break if char == '$'
304
328
  if char == '@'
305
329
  signature = "@#{signature}" if @code[index-1, 1] == '@'
@@ -18,10 +18,7 @@ module Solargraph
18
18
  @filename = filename
19
19
  @code = code
20
20
  @node = node
21
- @comments = comments
22
21
  @node_stack = []
23
- # @node_tree = []
24
- @comment_hash = {}
25
22
  @directives = {}
26
23
  @docstring_hash = associate_comments(node, comments)
27
24
  # @todo Stuff that needs to be resolved
@@ -60,18 +57,10 @@ module Solargraph
60
57
  frag.strip.gsub(/,$/, '')
61
58
  end
62
59
 
63
- def comment_hash
64
- @comment_hash
65
- end
66
-
67
60
  def filename
68
61
  @filename
69
62
  end
70
63
 
71
- def comments
72
- @comments
73
- end
74
-
75
64
  def pins
76
65
  @pins ||= []
77
66
  end
@@ -334,10 +323,6 @@ module Solargraph
334
323
  @pins.select{|pin| [Pin::NAMESPACE, Pin::METHOD].include?(pin.kind) and pin.location.range.contain?(position)}.last
335
324
  end
336
325
 
337
- def get_namespace_pin position
338
- @pins.select{|pin| pin.kind == Pin::NAMESPACE and pin.location.range.contain?(position)}.last
339
- end
340
-
341
326
  # @return [YARD::Docstring]
342
327
  def docstring_for node
343
328
  return @docstring_hash[node.loc] if node.respond_to?(:loc)
@@ -25,6 +25,7 @@ module Solargraph
25
25
  @output = nil
26
26
  end
27
27
 
28
+ # @return [String]
28
29
  def write text, nullable = false
29
30
  can_nullify = (nullable and changes.length == 1)
30
31
  return @output if @input == text and can_nullify == @did_nullify
@@ -37,6 +38,7 @@ module Solargraph
37
38
  @output
38
39
  end
39
40
 
41
+ # @return [String]
40
42
  def repair text
41
43
  changes.each do |ch|
42
44
  text = ch.repair(text)
@@ -1,3 +1,3 @@
1
1
  module Solargraph
2
- VERSION = '0.23.4'
2
+ VERSION = '0.23.5'
3
3
  end
@@ -101,10 +101,16 @@ module Solargraph
101
101
  false
102
102
  end
103
103
 
104
+ # True if the workspace contains at least one gemspec file.
105
+ #
106
+ # @return [Boolean]
104
107
  def gemspec?
105
- return true unless gemspecs.empty?
108
+ !gemspecs.empty?
106
109
  end
107
110
 
111
+ # Get an array of all gemspec files in the workspace.
112
+ #
113
+ # @return [Array<String>]
108
114
  def gemspecs
109
115
  return [] if directory.nil?
110
116
  @gemspecs ||= Dir[File.join(directory, '**/*.gemspec')]
@@ -121,7 +127,7 @@ module Solargraph
121
127
  source_hash.clear
122
128
  unless directory.nil?
123
129
  size = config.calculated.length
124
- raise WorkspaceTooLargeError.new(size) if config.max_files > 0 and size > config.max_files
130
+ raise WorkspaceTooLargeError.new(size, config.max_files) if config.max_files > 0 and size > config.max_files
125
131
 
126
132
  config.calculated.each do |filename|
127
133
  source_hash[filename] = Solargraph::Source.load(filename)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solargraph
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.23.4
4
+ version: 0.23.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fred Snyder
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-09 00:00:00.000000000 Z
11
+ date: 2018-07-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser