solargraph 0.23.4 → 0.23.5

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