solargraph 0.44.1 → 0.47.2
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 +4 -4
- data/.github/workflows/rspec.yml +41 -0
- data/CHANGELOG.md +46 -0
- data/README.md +10 -2
- data/SPONSORS.md +3 -1
- data/lib/solargraph/api_map.rb +27 -22
- data/lib/solargraph/complex_type.rb +6 -2
- data/lib/solargraph/convention/rspec.rb +13 -4
- data/lib/solargraph/diagnostics/require_not_found.rb +16 -0
- data/lib/solargraph/diagnostics/rubocop.rb +1 -1
- data/lib/solargraph/language_server/message/text_document/hover.rb +16 -4
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +1 -1
- data/lib/solargraph/language_server/uri_helpers.rb +1 -1
- data/lib/solargraph/parser/legacy/class_methods.rb +9 -8
- data/lib/solargraph/parser/legacy/node_processors/block_node.rb +13 -17
- data/lib/solargraph/parser/rubyvm/class_methods.rb +2 -13
- data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +13 -17
- data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +0 -1
- data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +2 -2
- data/lib/solargraph/parser/rubyvm/node_processors.rb +1 -0
- data/lib/solargraph/pin/block.rb +2 -1
- data/lib/solargraph/pin/local_variable.rb +1 -1
- data/lib/solargraph/pin/namespace.rb +2 -2
- data/lib/solargraph/pin/parameter.rb +3 -8
- data/lib/solargraph/pin/search.rb +56 -0
- data/lib/solargraph/pin.rb +1 -0
- data/lib/solargraph/range.rb +1 -1
- data/lib/solargraph/source.rb +1 -1
- data/lib/solargraph/source_map/mapper.rb +29 -2
- data/lib/solargraph/source_map.rb +1 -10
- data/lib/solargraph/type_checker/checks.rb +13 -0
- data/lib/solargraph/type_checker.rb +41 -8
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace.rb +1 -0
- data/lib/solargraph/yard_map/core_fills.rb +7 -2
- data/lib/solargraph/yard_map.rb +32 -15
- data/lib/solargraph.rb +2 -2
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9d35030ae56f6aaff108a24e4fb06713f911ba4366feb2223b24ad0ea4568522
|
4
|
+
data.tar.gz: a9eeaee16171bc762922ac55d10c61d53bcfe6ef1df0b20623c81e0978a80c7d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0b13ae6284def50f72c9aaed3cad6f89e879306dc8421b1c13f622e18181e6d9aaecf4f57ffa56601a00c92066557bb798d3e8ee6a397920ff0072f909e05463
|
7
|
+
data.tar.gz: 9a0366309ebe9a4a784c2933a8452e2084c376ff9aa3cd6c3bf555f4d6ce046f11245679c688bef43c6c1e67d94b70afb4250149c9b01b80fc525b80a80b6486
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# This workflow uses actions that are not certified by GitHub.
|
2
|
+
# They are provided by a third-party and are governed by
|
3
|
+
# separate terms of service, privacy policy, and support
|
4
|
+
# documentation.
|
5
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with rspec.
|
6
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
7
|
+
|
8
|
+
name: RSpec
|
9
|
+
|
10
|
+
on:
|
11
|
+
push:
|
12
|
+
branches: [ master ]
|
13
|
+
pull_request:
|
14
|
+
branches: [ master ]
|
15
|
+
|
16
|
+
permissions:
|
17
|
+
contents: read
|
18
|
+
|
19
|
+
jobs:
|
20
|
+
test:
|
21
|
+
|
22
|
+
runs-on: ubuntu-latest
|
23
|
+
strategy:
|
24
|
+
matrix:
|
25
|
+
ruby-version: ['2.4', '2.5', '2.6', '2.7', '3.0']
|
26
|
+
|
27
|
+
steps:
|
28
|
+
- uses: actions/checkout@v3
|
29
|
+
- name: Set up Ruby
|
30
|
+
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
31
|
+
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
32
|
+
# uses: ruby/setup-ruby@v1
|
33
|
+
uses: ruby/setup-ruby@2b019609e2b0f1ea1a2bc8ca11cb82ab46ada124
|
34
|
+
with:
|
35
|
+
ruby-version: ${{ matrix.ruby-version }}
|
36
|
+
bundler-cache: false
|
37
|
+
- run: bundle install
|
38
|
+
- name: Set up yardocs
|
39
|
+
run: bundle exec yard gems
|
40
|
+
- name: Run tests
|
41
|
+
run: bundle exec rspec
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,49 @@
|
|
1
|
+
## 0.47.2 - September 30, 2022
|
2
|
+
- Fix complex type inference (#578)
|
3
|
+
- Off-by-one diagnostic (#595)
|
4
|
+
|
5
|
+
## 0.47.1 - September 27, 2022
|
6
|
+
- Remove debug code from release (#600)
|
7
|
+
|
8
|
+
## 0.47.0 - September 25, 2022
|
9
|
+
- Completion candidates for union types (#507)
|
10
|
+
- Nullify Hover object instead of contents value (#583)
|
11
|
+
- Mapping workspace stuck in 0 (#587)
|
12
|
+
- Fix parsing of nested subtypes (#589)
|
13
|
+
- Update YARD tags on Pin::Block methods (#588)
|
14
|
+
- @!visibility directive support (#566)
|
15
|
+
|
16
|
+
## 0.46.0 - August 22, 2022
|
17
|
+
- Ignore typecheck errors with @sg-ignore tag (#419)
|
18
|
+
- Strict checks report undefined method calls on variables (#553)
|
19
|
+
- Infer type from method arguments (#554)
|
20
|
+
- Return nil value for empty hover contents (#543)
|
21
|
+
|
22
|
+
## 0.45.0 - May 23, 2022
|
23
|
+
- Basic support for RSpec #describe and #it
|
24
|
+
- fix: domain can complete private method (#490)
|
25
|
+
- Update README.md (#533)
|
26
|
+
- Doc: update readme.md for add solargraph support (#536)
|
27
|
+
- Process DASGN node in Ruby 3
|
28
|
+
- File.open core fill
|
29
|
+
- replace with_unbundled_env with with_original_env (#489)
|
30
|
+
- Require specific version of gem (#509)
|
31
|
+
- Support URIs prefixed with single slashed file scheme (#529)
|
32
|
+
- Fix typo in README.md (#549)
|
33
|
+
- details on config behavior (#556)
|
34
|
+
- Consider overloads in arity checks
|
35
|
+
- ENV core fill for Hash-like methods (#537)
|
36
|
+
- Fix string ranges with substitutions (#463)
|
37
|
+
|
38
|
+
## 0.44.3 - January 22, 2022
|
39
|
+
- TypeChecker validates aliased namespaces (#497)
|
40
|
+
- Always use reference YARD tags when resolving param types (#515) (#516)
|
41
|
+
- Skip method aliases in strict type checking
|
42
|
+
|
43
|
+
## 0.44.2 - November 23, 2021
|
44
|
+
- Scope local variables in class_eval blocks (#503)
|
45
|
+
- Fix invalid UTF-8 in node comments (#504)
|
46
|
+
|
1
47
|
## 0.44.1 - November 18, 2021
|
2
48
|
- Chain nil safety navigation operator (#420)
|
3
49
|
- Update closure and context for class_eval receiver (#487)
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Solargraph
|
2
2
|
|
3
|
+
[](https://github.com/castwide/solargraph/actions/workflows/rspec.yml)
|
4
|
+
|
3
5
|
## A Ruby Language Server
|
4
6
|
|
5
7
|
Solargraph provides a comprehensive suite of tools for Ruby programming: intellisense, diagnostics, inline documentation, and type checking.
|
@@ -31,7 +33,9 @@ Plug-ins and extensions are available for the following editors:
|
|
31
33
|
* GitHub: https://github.com/castwide/atom-solargraph
|
32
34
|
|
33
35
|
* **Vim**
|
34
|
-
* GitHub: https://github.com/autozimu/LanguageClient-neovim
|
36
|
+
* GitHub: `LanguageClient-neovim`, https://github.com/autozimu/LanguageClient-neovim
|
37
|
+
* GitHub: `coc`, https://github.com/neoclide/coc-solargraph
|
38
|
+
* GitHub: `Vim-EasyComplete`, https://github.com/jayli/vim-easycomplete
|
35
39
|
|
36
40
|
* **Emacs**
|
37
41
|
* GitHub: `eglot.el`, https://github.com/joaotavora/eglot
|
@@ -41,13 +45,17 @@ Plug-ins and extensions are available for the following editors:
|
|
41
45
|
* Plugin: https://marketplace.eclipse.org/content/ruby-solargraph
|
42
46
|
* GitHub: https://github.com/PyvesB/eclipse-solargraph
|
43
47
|
|
48
|
+
### Configuration
|
49
|
+
|
50
|
+
Solargraph's behavior can be controlled via optional [configuration](https://solargraph.org/guides/configuration) files. The highest priority file is a `.solargraph.yml` file at the root of the project. If not present, any global configuration at `~/.config/solargraph/config.yml` will apply. The path to the global configuration can be overridden with the `SOLARGRAPH_GLOBAL_CONFIG` environment variable.
|
51
|
+
|
44
52
|
### Gem Support
|
45
53
|
|
46
54
|
Solargraph is capable of providing code completion and documentation for gems that have YARD documentation. You can make sure your gems are documented by running `yard gems` from the command line. (YARD is included as one of Solargraph's gem dependencies. The first time you run it might take a while if you have a lot of gems installed).
|
47
55
|
|
48
56
|
When editing code, a `require` call that references a gem will pull the documentation into the code maps and include the gem's API in code completion and intellisense.
|
49
57
|
|
50
|
-
If your project automatically requires bundled gems (e.g., `require 'bundler/require'`), Solargraph will add all of the Gemfile's default
|
58
|
+
If your project automatically requires bundled gems (e.g., `require 'bundler/require'`), Solargraph will add all of the Gemfile's default dependencies to the map.
|
51
59
|
|
52
60
|
### Type Checking
|
53
61
|
|
data/SPONSORS.md
CHANGED
data/lib/solargraph/api_map.rb
CHANGED
@@ -21,6 +21,9 @@ module Solargraph
|
|
21
21
|
# @return [Array<String>]
|
22
22
|
attr_reader :unresolved_requires
|
23
23
|
|
24
|
+
# @return [Array<String>]
|
25
|
+
attr_reader :missing_docs
|
26
|
+
|
24
27
|
# @param pins [Array<Solargraph::Pin::Base>]
|
25
28
|
def initialize pins: []
|
26
29
|
@source_map_hash = {}
|
@@ -68,6 +71,7 @@ module Solargraph
|
|
68
71
|
yard_map.change(external_requires, bench.workspace.directory, bench.workspace.source_gems)
|
69
72
|
@store = Store.new(yard_map.pins + implicit.pins + pins)
|
70
73
|
@unresolved_requires = yard_map.unresolved_requires
|
74
|
+
@missing_docs = yard_map.missing_docs
|
71
75
|
@rebindable_method_names = nil
|
72
76
|
store.block_pins.each { |blk| blk.rebind(self) }
|
73
77
|
self
|
@@ -255,7 +259,7 @@ module Solargraph
|
|
255
259
|
implicit.domains.each do |domain|
|
256
260
|
type = ComplexType.try_parse(domain)
|
257
261
|
next if type.undefined?
|
258
|
-
result.concat inner_get_methods(type.name, type.scope,
|
262
|
+
result.concat inner_get_methods(type.name, type.scope, visibility, deep, skip)
|
259
263
|
end
|
260
264
|
result.concat inner_get_methods(fqns, :class, visibility, deep, skip)
|
261
265
|
result.concat inner_get_methods(fqns, :instance, visibility, deep, skip)
|
@@ -281,33 +285,33 @@ module Solargraph
|
|
281
285
|
# type = Solargraph::ComplexType.parse('String')
|
282
286
|
# api_map.get_complex_type_methods(type)
|
283
287
|
#
|
284
|
-
# @param
|
288
|
+
# @param complex_type [Solargraph::ComplexType] The complex type of the namespace
|
285
289
|
# @param context [String] The context from which the type is referenced
|
286
290
|
# @param internal [Boolean] True to include private methods
|
287
291
|
# @return [Array<Solargraph::Pin::Base>]
|
288
|
-
def get_complex_type_methods
|
292
|
+
def get_complex_type_methods complex_type, context = '', internal = false
|
289
293
|
# This method does not qualify the complex type's namespace because
|
290
294
|
# it can cause conflicts between similar names, e.g., `Foo` vs.
|
291
295
|
# `Other::Foo`. It still takes a context argument to determine whether
|
292
296
|
# protected and private methods are visible.
|
293
|
-
return [] if
|
294
|
-
result =
|
295
|
-
|
296
|
-
type.
|
297
|
-
result.
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
297
|
+
return [] if complex_type.undefined? || complex_type.void?
|
298
|
+
result = Set.new
|
299
|
+
complex_type.each do |type|
|
300
|
+
if type.duck_type?
|
301
|
+
result.add Pin::DuckMethod.new(name: type.to_s[1..-1])
|
302
|
+
result.merge get_methods('Object')
|
303
|
+
else
|
304
|
+
unless type.nil? || type.name == 'void'
|
305
|
+
visibility = [:public]
|
306
|
+
if type.namespace == context || super_and_sub?(type.namespace, context)
|
307
|
+
visibility.push :protected
|
308
|
+
visibility.push :private if internal
|
309
|
+
end
|
310
|
+
result.merge get_methods(type.namespace, scope: type.scope, visibility: visibility)
|
306
311
|
end
|
307
|
-
result.concat get_methods(type.namespace, scope: type.scope, visibility: visibility)
|
308
312
|
end
|
309
313
|
end
|
310
|
-
result
|
314
|
+
result.to_a
|
311
315
|
end
|
312
316
|
|
313
317
|
# Get a stack of method pins for a method name in a namespace. The order
|
@@ -383,9 +387,10 @@ module Solargraph
|
|
383
387
|
# @param query [String]
|
384
388
|
# @return [Array<Pin::Base>]
|
385
389
|
def query_symbols query
|
386
|
-
|
387
|
-
|
388
|
-
|
390
|
+
Pin::Search.new(
|
391
|
+
source_map_hash.values.flat_map(&:document_symbols),
|
392
|
+
query
|
393
|
+
).results
|
389
394
|
end
|
390
395
|
|
391
396
|
# @param location [Solargraph::Location]
|
@@ -525,7 +530,7 @@ module Solargraph
|
|
525
530
|
end
|
526
531
|
store.domains(fqns).each do |d|
|
527
532
|
dt = ComplexType.try_parse(d)
|
528
|
-
result.concat inner_get_methods(dt.namespace, dt.scope,
|
533
|
+
result.concat inner_get_methods(dt.namespace, dt.scope, visibility, deep, skip)
|
529
534
|
end
|
530
535
|
end
|
531
536
|
result
|
@@ -74,6 +74,10 @@ module Solargraph
|
|
74
74
|
@items.all? &block
|
75
75
|
end
|
76
76
|
|
77
|
+
def any? &block
|
78
|
+
@items.any? &block
|
79
|
+
end
|
80
|
+
|
77
81
|
def selfy?
|
78
82
|
@items.any?(&:selfy?)
|
79
83
|
end
|
@@ -154,9 +158,9 @@ module Solargraph
|
|
154
158
|
subtype_string.clear
|
155
159
|
next
|
156
160
|
else
|
161
|
+
raise ComplexTypeError, "Invalid close in type #{type_string}" if point_stack == 0
|
157
162
|
point_stack -= 1
|
158
|
-
subtype_string += char
|
159
|
-
raise ComplexTypeError, "Invalid close in type #{type_string}" if point_stack < 0
|
163
|
+
subtype_string += char
|
160
164
|
end
|
161
165
|
next
|
162
166
|
elsif char == '{'
|
@@ -8,14 +8,23 @@ module Solargraph
|
|
8
8
|
@environ ||= Environ.new(
|
9
9
|
requires: ['rspec'],
|
10
10
|
domains: ['RSpec::Matchers', 'RSpec::ExpectationGroups'],
|
11
|
-
# This override is necessary due to an erroneous @return tag in
|
12
|
-
# rspec's YARD documentation.
|
13
|
-
# @todo The return types have been fixed (https://github.com/rspec/rspec-expectations/pull/1121)
|
14
11
|
pins: [
|
12
|
+
# This override is necessary due to an erroneous @return tag in
|
13
|
+
# rspec's YARD documentation.
|
14
|
+
# @todo The return types have been fixed (https://github.com/rspec/rspec-expectations/pull/1121)
|
15
15
|
Solargraph::Pin::Reference::Override.method_return('RSpec::Matchers#expect', 'RSpec::Expectations::ExpectationTarget')
|
16
|
-
]
|
16
|
+
].concat(extras)
|
17
17
|
)
|
18
18
|
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def extras
|
23
|
+
@@extras ||= SourceMap.load_string(%(
|
24
|
+
def describe(*args); end
|
25
|
+
def it(*args); end
|
26
|
+
)).pins
|
27
|
+
end
|
19
28
|
end
|
20
29
|
end
|
21
30
|
end
|
@@ -12,6 +12,10 @@ module Solargraph
|
|
12
12
|
refs = {}
|
13
13
|
map = api_map.source_map(source.filename)
|
14
14
|
map.requires.each { |ref| refs[ref.name] = ref }
|
15
|
+
api_map.missing_docs.each do |r|
|
16
|
+
next unless refs.key?(r)
|
17
|
+
result.push docs_error(r, refs[r].location)
|
18
|
+
end
|
15
19
|
api_map.unresolved_requires.each do |r|
|
16
20
|
next unless refs.key?(r)
|
17
21
|
result.push require_error(r, refs[r].location)
|
@@ -21,6 +25,18 @@ module Solargraph
|
|
21
25
|
|
22
26
|
private
|
23
27
|
|
28
|
+
# @param path [String]
|
29
|
+
# @param location [Location]
|
30
|
+
# @return [Hash]
|
31
|
+
def docs_error path, location
|
32
|
+
{
|
33
|
+
range: location.range.to_hash,
|
34
|
+
severity: Diagnostics::Severities::WARNING,
|
35
|
+
source: 'RequireNotFound',
|
36
|
+
message: "YARD docs not found for #{path}"
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
24
40
|
# @param path [String]
|
25
41
|
# @param location [Location]
|
26
42
|
# @return [Hash]
|
@@ -27,16 +27,28 @@ module Solargraph
|
|
27
27
|
last_link = this_link unless this_link.nil?
|
28
28
|
end
|
29
29
|
set_result(
|
30
|
-
contents
|
31
|
-
kind: 'markdown',
|
32
|
-
value: contents.join("\n\n")
|
33
|
-
}
|
30
|
+
contents_or_nil(contents)
|
34
31
|
)
|
35
32
|
rescue FileNotFoundError => e
|
36
33
|
Logging.logger.warn "[#{e.class}] #{e.message}"
|
37
34
|
Logging.logger.warn e.backtrace.join("\n")
|
38
35
|
set_result nil
|
39
36
|
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def contents_or_nil contents
|
41
|
+
stripped = contents
|
42
|
+
.map(&:strip)
|
43
|
+
.reject { |c| c.empty? }
|
44
|
+
return nil if stripped.empty?
|
45
|
+
{
|
46
|
+
contents: {
|
47
|
+
kind: 'markdown',
|
48
|
+
value: stripped.join("\n\n")
|
49
|
+
}
|
50
|
+
}
|
51
|
+
end
|
40
52
|
end
|
41
53
|
end
|
42
54
|
end
|
@@ -8,7 +8,7 @@ class Solargraph::LanguageServer::Message::Workspace::WorkspaceSymbol < Solargra
|
|
8
8
|
info = pins.map do |pin|
|
9
9
|
uri = file_to_uri(pin.location.filename)
|
10
10
|
{
|
11
|
-
name: pin.
|
11
|
+
name: pin.path,
|
12
12
|
containerName: pin.namespace,
|
13
13
|
kind: pin.symbol_kind,
|
14
14
|
location: {
|
@@ -14,7 +14,7 @@ module Solargraph
|
|
14
14
|
# @param uri [String]
|
15
15
|
# @return [String]
|
16
16
|
def uri_to_file uri
|
17
|
-
decode(uri).sub(/^file
|
17
|
+
decode(uri).sub(/^file\:(?:\/\/)?/, '').sub(/^\/([a-z]\:)/i, '\1')
|
18
18
|
end
|
19
19
|
|
20
20
|
# Convert a file path to a URI.
|
@@ -48,10 +48,16 @@ module Solargraph
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def references source, name
|
51
|
+
if name.end_with?("=")
|
52
|
+
reg = /#{Regexp.escape name[0..-2]}\s*=/
|
53
|
+
extract_offset = ->(code, offset) { reg.match(code, offset).offset(0) }
|
54
|
+
else
|
55
|
+
extract_offset = ->(code, offset) { [soff = code.index(name, offset), soff + name.length] }
|
56
|
+
end
|
51
57
|
inner_node_references(name, source.node).map do |n|
|
52
|
-
|
53
|
-
|
54
|
-
eoff =
|
58
|
+
rng = Range.from_node(n)
|
59
|
+
offset = Position.to_offset(source.code, rng.start)
|
60
|
+
soff, eoff = extract_offset[source.code, offset]
|
55
61
|
Location.new(
|
56
62
|
source.filename,
|
57
63
|
Range.new(
|
@@ -109,16 +115,11 @@ module Solargraph
|
|
109
115
|
result = []
|
110
116
|
if node.type == :str
|
111
117
|
result.push Range.from_node(node)
|
112
|
-
elsif node.type == :dstr
|
113
|
-
here = Range.from_node(node)
|
114
|
-
there = Range.from_node(node.children[1])
|
115
|
-
result.push Range.new(here.start, there.start)
|
116
118
|
end
|
117
119
|
node.children.each do |child|
|
118
120
|
result.concat string_ranges(child)
|
119
121
|
end
|
120
122
|
if node.type == :dstr && node.children.last.nil?
|
121
|
-
# result.push Range.new(result.last.ending, result.last.ending)
|
122
123
|
last = node.children[-2]
|
123
124
|
unless last.nil?
|
124
125
|
rng = Range.from_node(last)
|
@@ -8,17 +8,24 @@ module Solargraph
|
|
8
8
|
include Legacy::NodeMethods
|
9
9
|
|
10
10
|
def process
|
11
|
-
|
12
|
-
|
11
|
+
location = get_node_location(node)
|
12
|
+
parent = if other_class_eval?
|
13
|
+
Solargraph::Pin::Namespace.new(
|
14
|
+
location: location,
|
13
15
|
type: :class,
|
14
16
|
name: unpack_name(node.children[0].children[0])
|
15
17
|
)
|
16
|
-
make_block_in other_class.context
|
17
|
-
process_children region.update(closure: other_class)
|
18
18
|
else
|
19
|
-
|
20
|
-
process_children region.update(closure: pins.last)
|
19
|
+
region.closure
|
21
20
|
end
|
21
|
+
pins.push Solargraph::Pin::Block.new(
|
22
|
+
location: location,
|
23
|
+
closure: parent,
|
24
|
+
receiver: node.children[0],
|
25
|
+
comments: comments_for(node),
|
26
|
+
scope: region.scope || region.closure.context.scope
|
27
|
+
)
|
28
|
+
process_children region.update(closure: pins.last)
|
22
29
|
end
|
23
30
|
|
24
31
|
private
|
@@ -28,17 +35,6 @@ module Solargraph
|
|
28
35
|
node.children[0].children[1] == :class_eval &&
|
29
36
|
[:cbase, :const].include?(node.children[0].children[0]&.type)
|
30
37
|
end
|
31
|
-
|
32
|
-
def make_block_in context
|
33
|
-
pins.push Solargraph::Pin::Block.new(
|
34
|
-
location: get_node_location(node),
|
35
|
-
context: context,
|
36
|
-
closure: region.closure,
|
37
|
-
receiver: node.children[0],
|
38
|
-
comments: comments_for(node),
|
39
|
-
scope: region.scope || region.closure.context.scope
|
40
|
-
)
|
41
|
-
end
|
42
38
|
end
|
43
39
|
end
|
44
40
|
end
|
@@ -29,16 +29,6 @@ module Solargraph
|
|
29
29
|
NodeProcessor.process(source.node, Region.new(source: source))
|
30
30
|
end
|
31
31
|
|
32
|
-
# def returns_from node
|
33
|
-
# return [] unless Parser.is_ast_node?(node)
|
34
|
-
# if node.type == :SCOPE
|
35
|
-
# # node.children.select { |n| n.is_a?(RubyVM::AbstractSyntaxTree::Node) }.map { |n| DeepInference.get_return_nodes(n) }.flatten
|
36
|
-
# DeepInference.get_return_nodes(node.children[2])
|
37
|
-
# else
|
38
|
-
# DeepInference.get_return_nodes(node)
|
39
|
-
# end
|
40
|
-
# end
|
41
|
-
|
42
32
|
def references source, name
|
43
33
|
if name.end_with?("=")
|
44
34
|
reg = /#{Regexp.escape name[0..-2]}\s*=/
|
@@ -97,7 +87,7 @@ module Solargraph
|
|
97
87
|
end
|
98
88
|
|
99
89
|
def infer_literal_node_type node
|
100
|
-
|
90
|
+
NodeMethods.infer_literal_node_type node
|
101
91
|
end
|
102
92
|
|
103
93
|
def version
|
@@ -133,13 +123,12 @@ module Solargraph
|
|
133
123
|
elsif node.type == :DSTR
|
134
124
|
here = Range.from_node(node)
|
135
125
|
there = Range.from_node(node.children[1])
|
136
|
-
result.push Range.new(here.start, there.
|
126
|
+
result.push Range.new(here.start, there&.start || here.ending)
|
137
127
|
end
|
138
128
|
node.children.each do |child|
|
139
129
|
result.concat string_ranges(child)
|
140
130
|
end
|
141
131
|
if node.type == :DSTR && node.children.last.nil?
|
142
|
-
# result.push Range.new(result.last.ending, result.last.ending)
|
143
132
|
last = node.children[-2]
|
144
133
|
unless last.nil?
|
145
134
|
rng = Range.from_node(last)
|
@@ -8,17 +8,24 @@ module Solargraph
|
|
8
8
|
include NodeMethods
|
9
9
|
|
10
10
|
def process
|
11
|
-
|
12
|
-
|
11
|
+
location = get_node_location(node)
|
12
|
+
parent = if other_class_eval?
|
13
|
+
Solargraph::Pin::Namespace.new(
|
14
|
+
location: location,
|
13
15
|
type: :class,
|
14
16
|
name: unpack_name(node.children[0].children[0])
|
15
17
|
)
|
16
|
-
make_block_in other_class.context
|
17
|
-
process_children region.update(closure: other_class)
|
18
18
|
else
|
19
|
-
|
20
|
-
process_children region.update(closure: pins.last)
|
19
|
+
region.closure
|
21
20
|
end
|
21
|
+
pins.push Solargraph::Pin::Block.new(
|
22
|
+
location: location,
|
23
|
+
closure: parent,
|
24
|
+
receiver: node.children[0],
|
25
|
+
comments: comments_for(node),
|
26
|
+
scope: region.scope || region.closure.context.scope
|
27
|
+
)
|
28
|
+
process_children region.update(closure: pins.last)
|
22
29
|
end
|
23
30
|
|
24
31
|
private
|
@@ -28,17 +35,6 @@ module Solargraph
|
|
28
35
|
node.children[0].children[1] == :class_eval &&
|
29
36
|
[:COLON2, :CONST].include?(node.children[0].children[0].type)
|
30
37
|
end
|
31
|
-
|
32
|
-
def make_block_in context
|
33
|
-
pins.push Solargraph::Pin::Block.new(
|
34
|
-
location: get_node_location(node),
|
35
|
-
context: context,
|
36
|
-
closure: region.closure,
|
37
|
-
receiver: node.children[0],
|
38
|
-
comments: comments_for(node),
|
39
|
-
scope: region.scope || region.closure.context.scope
|
40
|
-
)
|
41
|
-
end
|
42
38
|
end
|
43
39
|
end
|
44
40
|
end
|
@@ -11,8 +11,8 @@ module Solargraph
|
|
11
11
|
closure: region.closure,
|
12
12
|
comments: comments_for(node),
|
13
13
|
name: node.children[0].children[0].to_s,
|
14
|
-
|
15
|
-
asgn_code: require_keyword?(node) ? nil: region.code_for(node.children[0].children[1]),
|
14
|
+
assignment: require_keyword?(node) ? nil : node.children[0].children[1],
|
15
|
+
asgn_code: require_keyword?(node) ? nil : region.code_for(node.children[0].children[1]),
|
16
16
|
presence: region.closure.location.range,
|
17
17
|
decl: require_keyword?(node) ? :kwarg : :kwoptarg
|
18
18
|
)
|
@@ -45,6 +45,7 @@ module Solargraph
|
|
45
45
|
register :IASGN, Rubyvm::NodeProcessors::IvasgnNode
|
46
46
|
register :CVASGN, Rubyvm::NodeProcessors::CvasgnNode
|
47
47
|
register :LASGN, Rubyvm::NodeProcessors::LvasgnNode
|
48
|
+
register :DASGN, Rubyvm::NodeProcessors::LvasgnNode
|
48
49
|
register :DASGN_CURR, Rubyvm::NodeProcessors::LvasgnNode
|
49
50
|
register :GASGN, Rubyvm::NodeProcessors::GvasgnNode
|
50
51
|
register :CDECL, Rubyvm::NodeProcessors::CasgnNode
|
data/lib/solargraph/pin/block.rb
CHANGED
@@ -8,6 +8,7 @@ module Solargraph
|
|
8
8
|
# @return [Parser::AST::Node]
|
9
9
|
attr_reader :receiver
|
10
10
|
|
11
|
+
# @param args [Array<Parameter>]
|
11
12
|
def initialize receiver: nil, args: [], context: nil, **splat
|
12
13
|
super(**splat)
|
13
14
|
@receiver = receiver
|
@@ -25,7 +26,7 @@ module Solargraph
|
|
25
26
|
@binder || closure.binder
|
26
27
|
end
|
27
28
|
|
28
|
-
# @return [Array<
|
29
|
+
# @return [Array<Parameter>]
|
29
30
|
def parameters
|
30
31
|
@parameters ||= []
|
31
32
|
end
|
@@ -41,7 +41,7 @@ module Solargraph
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def match_named_closure needle, haystack
|
44
|
-
return true if needle == haystack
|
44
|
+
return true if needle == haystack || haystack.is_a?(Pin::Block)
|
45
45
|
cursor = haystack
|
46
46
|
until cursor.nil?
|
47
47
|
return true if needle.path == cursor.path
|
@@ -9,8 +9,8 @@ module Solargraph
|
|
9
9
|
# @return [::Symbol] :class or :module
|
10
10
|
attr_reader :type
|
11
11
|
|
12
|
-
# @param type [Symbol] :class or :module
|
13
|
-
# @param visibility [Symbol] :public or :private
|
12
|
+
# @param type [::Symbol] :class or :module
|
13
|
+
# @param visibility [::Symbol] :public or :private
|
14
14
|
# @param gates [Array<String>]
|
15
15
|
def initialize type: :class, visibility: :public, gates: [''], **splat
|
16
16
|
# super(location, namespace, name, comments)
|
@@ -3,8 +3,10 @@
|
|
3
3
|
module Solargraph
|
4
4
|
module Pin
|
5
5
|
class Parameter < LocalVariable
|
6
|
+
# @return [Symbol]
|
6
7
|
attr_reader :decl
|
7
8
|
|
9
|
+
# @return [String]
|
8
10
|
attr_reader :asgn_code
|
9
11
|
|
10
12
|
def initialize decl: :arg, asgn_code: nil, **splat
|
@@ -91,10 +93,6 @@ module Solargraph
|
|
91
93
|
true
|
92
94
|
end
|
93
95
|
|
94
|
-
def probe api_map
|
95
|
-
typify api_map
|
96
|
-
end
|
97
|
-
|
98
96
|
private
|
99
97
|
|
100
98
|
# @return [YARD::Tags::Tag]
|
@@ -145,10 +143,7 @@ module Solargraph
|
|
145
143
|
# meths.shift # Ignore the first one
|
146
144
|
meths.each do |meth|
|
147
145
|
found = nil
|
148
|
-
params = meth.docstring.tags(:param)
|
149
|
-
if params.empty?
|
150
|
-
params = see_reference(docstring, api_map)
|
151
|
-
end
|
146
|
+
params = meth.docstring.tags(:param) + see_reference(docstring, api_map)
|
152
147
|
params.each do |p|
|
153
148
|
next unless p.name == name
|
154
149
|
found = p
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'jaro_winkler'
|
4
|
+
|
5
|
+
module Solargraph
|
6
|
+
module Pin
|
7
|
+
class Search
|
8
|
+
class Result
|
9
|
+
# @return [Float]
|
10
|
+
attr_reader :match
|
11
|
+
|
12
|
+
# @return [Pin::Base]
|
13
|
+
attr_reader :pin
|
14
|
+
|
15
|
+
def initialize match, pin
|
16
|
+
@match = match
|
17
|
+
@pin = pin
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# @param pins [Array<Pin::Base>]
|
22
|
+
# @param query [String]
|
23
|
+
def initialize pins, query
|
24
|
+
@pins = pins
|
25
|
+
@query = query
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [Array<Pin::Base>]
|
29
|
+
def results
|
30
|
+
@results ||= do_query
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# @return [Array<Pin::Base>]
|
36
|
+
def do_query
|
37
|
+
return @pins if @query.nil? || @query.empty?
|
38
|
+
@pins.map do |pin|
|
39
|
+
match = [fuzzy_string_match(pin.path, @query), fuzzy_string_match(pin.name, @query)].max
|
40
|
+
Result.new(match, pin) if match > 0.7
|
41
|
+
end
|
42
|
+
.compact
|
43
|
+
.sort { |a, b| b.match <=> a.match }
|
44
|
+
.map(&:pin)
|
45
|
+
end
|
46
|
+
|
47
|
+
# @param str1 [String]
|
48
|
+
# @param str2 [String]
|
49
|
+
# @return [Float]
|
50
|
+
def fuzzy_string_match str1, str2
|
51
|
+
return (1.0 + (str2.length.to_f / str1.length.to_f)) if str1.downcase.include?(str2.downcase)
|
52
|
+
JaroWinkler.distance(str1, str2, ignore_case: true)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/solargraph/pin.rb
CHANGED
@@ -30,6 +30,7 @@ module Solargraph
|
|
30
30
|
autoload :DuckMethod, 'solargraph/pin/duck_method'
|
31
31
|
autoload :Singleton, 'solargraph/pin/singleton'
|
32
32
|
autoload :KeywordParam, 'solargraph/pin/keyword_param'
|
33
|
+
autoload :Search, 'solargraph/pin/search'
|
33
34
|
|
34
35
|
ROOT_PIN = Pin::Namespace.new(type: :class, name: '', closure: nil)
|
35
36
|
end
|
data/lib/solargraph/range.rb
CHANGED
@@ -69,7 +69,7 @@ module Solargraph
|
|
69
69
|
if node.is_a?(RubyVM::AbstractSyntaxTree::Node)
|
70
70
|
Solargraph::Range.from_to(node.first_lineno - 1, node.first_column, node.last_lineno - 1, node.last_column)
|
71
71
|
end
|
72
|
-
elsif node
|
72
|
+
elsif node&.loc && node.loc.expression
|
73
73
|
from_expr(node.loc.expression)
|
74
74
|
end
|
75
75
|
end
|
data/lib/solargraph/source.rb
CHANGED
@@ -360,7 +360,7 @@ module Solargraph
|
|
360
360
|
skip = nil
|
361
361
|
comments.lines.each { |l|
|
362
362
|
# Trim the comment and minimum leading whitespace
|
363
|
-
p = l.gsub(/^#+/, '')
|
363
|
+
p = l.force_encoding('UTF-8').encode('UTF-8', invalid: :replace, replace: '?').gsub(/^#+/, '')
|
364
364
|
if p.strip.empty?
|
365
365
|
next unless started
|
366
366
|
ctxt.concat p
|
@@ -12,7 +12,7 @@ module Solargraph
|
|
12
12
|
|
13
13
|
private_class_method :new
|
14
14
|
|
15
|
-
MACRO_REGEXP = /(@\!method|@\!attribute|@\!domain|@\!macro|@\!parse|@\!override)/.freeze
|
15
|
+
MACRO_REGEXP = /(@\!method|@\!attribute|@\!visibility|@\!domain|@\!macro|@\!parse|@\!override)/.freeze
|
16
16
|
|
17
17
|
# Generate the data.
|
18
18
|
#
|
@@ -56,8 +56,10 @@ module Solargraph
|
|
56
56
|
@pins ||= []
|
57
57
|
end
|
58
58
|
|
59
|
+
# @param position [Solargraph::Position]
|
60
|
+
# @return [Solargraph::Pin::Closure]
|
59
61
|
def closure_at(position)
|
60
|
-
|
62
|
+
pins.select{|pin| pin.is_a?(Pin::Closure) and pin.location.range.contain?(position)}.last
|
61
63
|
end
|
62
64
|
|
63
65
|
def process_comment source_position, comment_position, comment
|
@@ -147,6 +149,27 @@ module Solargraph
|
|
147
149
|
pins.last.docstring.add_tag YARD::Tags::Tag.new(:param, '', pins.last.return_type.to_s.split(', '), 'value')
|
148
150
|
end
|
149
151
|
end
|
152
|
+
when 'visibility'
|
153
|
+
begin
|
154
|
+
kind = directive.tag.text&.to_sym
|
155
|
+
return unless [:private, :protected, :public].include?(kind)
|
156
|
+
|
157
|
+
name = directive.tag.name
|
158
|
+
closure = closure_at(source_position) || @pins.first
|
159
|
+
if closure.location.range.start.line < comment_position.line
|
160
|
+
closure = closure_at(comment_position)
|
161
|
+
end
|
162
|
+
if closure.is_a?(Pin::Method) && no_empty_lines?(comment_position.line, source_position.line)
|
163
|
+
# @todo Smelly instance variable access
|
164
|
+
closure.instance_variable_set(:@visibility, kind)
|
165
|
+
else
|
166
|
+
matches = pins.select{ |pin| pin.is_a?(Pin::Method) && pin.name == name && pin.namespace == namespace && pin.context.scope == namespace.is_a?(Pin::Singleton) ? :class : :instance }
|
167
|
+
matches.each do |pin|
|
168
|
+
# @todo Smelly instance variable access
|
169
|
+
pin.instance_variable_set(:@visibility, kind)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
150
173
|
when 'parse'
|
151
174
|
begin
|
152
175
|
ns = closure_at(source_position)
|
@@ -176,6 +199,10 @@ module Solargraph
|
|
176
199
|
end
|
177
200
|
end
|
178
201
|
|
202
|
+
def no_empty_lines?(line1, line2)
|
203
|
+
@code.lines[line1..line2].none? { |line| line.strip.empty? }
|
204
|
+
end
|
205
|
+
|
179
206
|
def remove_inline_comment_hashes comment
|
180
207
|
ctxt = ''
|
181
208
|
num = nil
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'jaro_winkler'
|
4
3
|
require 'yard'
|
5
4
|
require 'yard-solargraph'
|
6
5
|
require 'set'
|
@@ -76,8 +75,7 @@ module Solargraph
|
|
76
75
|
# @param query [String]
|
77
76
|
# @return [Array<Pin::Base>]
|
78
77
|
def query_symbols query
|
79
|
-
|
80
|
-
document_symbols.select{ |pin| fuzzy_string_match(pin.path, query) || fuzzy_string_match(pin.name, query) }
|
78
|
+
Pin::Search.new(document_symbols, query).results
|
81
79
|
end
|
82
80
|
|
83
81
|
# @param position [Position]
|
@@ -178,12 +176,5 @@ module Solargraph
|
|
178
176
|
# Assuming the root pin is always valid
|
179
177
|
found || pins.first
|
180
178
|
end
|
181
|
-
|
182
|
-
# @param str1 [String]
|
183
|
-
# @param str2 [String]
|
184
|
-
# @return [Boolean]
|
185
|
-
def fuzzy_string_match str1, str2
|
186
|
-
JaroWinkler.distance(str1, str2) > 0.6
|
187
|
-
end
|
188
179
|
end
|
189
180
|
end
|
@@ -61,6 +61,19 @@ module Solargraph
|
|
61
61
|
false
|
62
62
|
end
|
63
63
|
|
64
|
+
# @param api_map [ApiMap]
|
65
|
+
# @param inferred [ComplexType]
|
66
|
+
# @param expected [ComplexType]
|
67
|
+
# @return [Boolean]
|
68
|
+
def all_types_match? api_map, inferred, expected
|
69
|
+
return duck_types_match?(api_map, expected, inferred) if expected.duck_type?
|
70
|
+
inferred.each do |inf|
|
71
|
+
next if inf.duck_type?
|
72
|
+
return false unless expected.any? { |exp| exp == inf || either_way?(api_map, inf, exp) }
|
73
|
+
end
|
74
|
+
true
|
75
|
+
end
|
76
|
+
|
64
77
|
# @param api_map [ApiMap]
|
65
78
|
# @param expected [ComplexType]
|
66
79
|
# @param inferred [ComplexType]
|
@@ -40,10 +40,12 @@ module Solargraph
|
|
40
40
|
# @return [Array<Problem>]
|
41
41
|
def problems
|
42
42
|
@problems ||= begin
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
43
|
+
without_ignored(
|
44
|
+
method_tag_problems
|
45
|
+
.concat variable_type_tag_problems
|
46
|
+
.concat const_problems
|
47
|
+
.concat call_problems
|
48
|
+
)
|
47
49
|
end
|
48
50
|
end
|
49
51
|
|
@@ -84,12 +86,13 @@ module Solargraph
|
|
84
86
|
# @param pin [Pin::Method]
|
85
87
|
# @return [Array<Problem>]
|
86
88
|
def method_return_type_problems_for pin
|
89
|
+
return [] if pin.is_a?(Pin::MethodAlias)
|
87
90
|
result = []
|
88
91
|
declared = pin.typify(api_map).self_to(pin.full_context.namespace)
|
89
92
|
if declared.undefined?
|
90
93
|
if pin.return_type.undefined? && rules.require_type_tags?
|
91
94
|
result.push Problem.new(pin.location, "Missing @return tag for #{pin.path}", pin: pin)
|
92
|
-
elsif pin.return_type.defined?
|
95
|
+
elsif pin.return_type.defined? && !resolved_constant?(pin)
|
93
96
|
result.push Problem.new(pin.location, "Unresolved return type #{pin.return_type} for #{pin.path}", pin: pin)
|
94
97
|
elsif rules.must_tag_or_infer? && pin.probe(api_map).undefined?
|
95
98
|
result.push Problem.new(pin.location, "Untyped method #{pin.path} could not be inferred")
|
@@ -102,7 +105,7 @@ module Solargraph
|
|
102
105
|
result.push Problem.new(pin.location, "#{pin.path} return type could not be inferred", pin: pin)
|
103
106
|
end
|
104
107
|
else
|
105
|
-
unless (rules.rank > 1 ?
|
108
|
+
unless (rules.rank > 1 ? all_types_match?(api_map, inferred, declared) : any_types_match?(api_map, declared, inferred))
|
106
109
|
result.push Problem.new(pin.location, "Declared return type #{declared} does not match inferred type #{inferred} for #{pin.path}", pin: pin)
|
107
110
|
end
|
108
111
|
end
|
@@ -111,6 +114,20 @@ module Solargraph
|
|
111
114
|
result
|
112
115
|
end
|
113
116
|
|
117
|
+
# @todo This is not optimal. A better solution would probably be to mix
|
118
|
+
# namespace alias into types at the ApiMap level.
|
119
|
+
#
|
120
|
+
# @param pin [Pin::Base]
|
121
|
+
# @return [Boolean]
|
122
|
+
def resolved_constant? pin
|
123
|
+
api_map.get_constants('', pin.binder.tag)
|
124
|
+
.select { |p| p.name == pin.return_type.namespace }
|
125
|
+
.any? do |p|
|
126
|
+
inferred = p.infer(api_map)
|
127
|
+
['Class', 'Module'].include?(inferred.name)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
114
131
|
def virtual_pin? pin
|
115
132
|
pin.location && source_map.source.comment_at?(pin.location.range.ending)
|
116
133
|
end
|
@@ -160,7 +177,7 @@ module Solargraph
|
|
160
177
|
result.push Problem.new(pin.location, "Variable type could not be inferred for #{pin.name}", pin: pin)
|
161
178
|
end
|
162
179
|
else
|
163
|
-
unless
|
180
|
+
unless any_types_match?(api_map, declared, inferred)
|
164
181
|
result.push Problem.new(pin.location, "Declared type #{declared} does not match inferred type #{inferred} for variable #{pin.name}", pin: pin)
|
165
182
|
end
|
166
183
|
end
|
@@ -225,7 +242,7 @@ module Solargraph
|
|
225
242
|
base = base.base
|
226
243
|
end
|
227
244
|
closest = found.typify(api_map) if found
|
228
|
-
if !found || (closest.defined? && internal_or_core?(found))
|
245
|
+
if !found || found.is_a?(Pin::BaseVariable) || (closest.defined? && internal_or_core?(found))
|
229
246
|
unless ignored_pins.include?(found)
|
230
247
|
result.push Problem.new(location, "Unresolved call to #{missing.links.last.word}")
|
231
248
|
@marked_ranges.push rng
|
@@ -402,6 +419,15 @@ module Solargraph
|
|
402
419
|
|
403
420
|
# @param pin [Pin::Method]
|
404
421
|
def arity_problems_for(pin, arguments, location)
|
422
|
+
([pin] + pin.overloads).map do |p|
|
423
|
+
result = pin_arity_problems_for(p, arguments, location)
|
424
|
+
return [] if result.empty?
|
425
|
+
result
|
426
|
+
end.flatten.uniq(&:message)
|
427
|
+
end
|
428
|
+
|
429
|
+
# @param pin [Pin::Method]
|
430
|
+
def pin_arity_problems_for(pin, arguments, location)
|
405
431
|
return [] unless pin.explicit?
|
406
432
|
return [] if pin.parameters.empty? && arguments.empty?
|
407
433
|
if pin.parameters.empty?
|
@@ -506,5 +532,12 @@ module Solargraph
|
|
506
532
|
args.push Solargraph::Parser.chain_string('&') if with_block
|
507
533
|
args
|
508
534
|
end
|
535
|
+
|
536
|
+
def without_ignored problems
|
537
|
+
problems.reject do |problem|
|
538
|
+
node = source_map.source.node_at(problem.location.range.start.line, problem.location.range.start.column)
|
539
|
+
source_map.source.comments_for(node)&.include?('@sg-ignore')
|
540
|
+
end
|
541
|
+
end
|
509
542
|
end
|
510
543
|
end
|
data/lib/solargraph/version.rb
CHANGED
data/lib/solargraph/workspace.rb
CHANGED
@@ -101,6 +101,7 @@ module Solargraph
|
|
101
101
|
Override.method_return('File.dirname', 'String'),
|
102
102
|
Override.method_return('File.extname', 'String'),
|
103
103
|
Override.method_return('File.join', 'String'),
|
104
|
+
Override.method_return('File.open', 'File'),
|
104
105
|
|
105
106
|
Override.from_comment('Float#+', %(
|
106
107
|
@param y [Numeric]
|
@@ -110,14 +111,15 @@ module Solargraph
|
|
110
111
|
Override.from_comment('Hash#[]', %(
|
111
112
|
@return_value_parameter
|
112
113
|
)),
|
113
|
-
|
114
114
|
# @todo This override isn't robust enough. It needs to allow for
|
115
115
|
# parameterized Hash types, e.g., [Hash{Symbol => String}].
|
116
116
|
Override.from_comment('Hash#[]=', %(
|
117
117
|
@param_tuple
|
118
118
|
)),
|
119
|
-
|
120
119
|
Override.method_return('Hash#merge', 'Hash'),
|
120
|
+
Override.from_comment('Hash#store', %{
|
121
|
+
@overload store(key, value)
|
122
|
+
}),
|
121
123
|
|
122
124
|
Override.from_comment('Integer#+', %(
|
123
125
|
@param y [Numeric]
|
@@ -181,6 +183,9 @@ module Solargraph
|
|
181
183
|
)
|
182
184
|
|
183
185
|
PINS = [
|
186
|
+
# HACK: Extending Hash is not accurate to the implementation, but
|
187
|
+
# accurate enough to the behavior
|
188
|
+
Pin::Reference::Extend.new(closure: Pin::Namespace.new(name: 'ENV'), name: 'Hash'),
|
184
189
|
Pin::Reference::Superclass.new(closure: Pin::Namespace.new(name: 'File'), name: 'IO'),
|
185
190
|
Pin::Reference::Superclass.new(closure: Pin::Namespace.new(name: 'Integer'), name: 'Numeric'),
|
186
191
|
Pin::Reference::Superclass.new(closure: Pin::Namespace.new(name: 'Float'), name: 'Numeric')
|
data/lib/solargraph/yard_map.rb
CHANGED
@@ -107,6 +107,11 @@ module Solargraph
|
|
107
107
|
@unresolved_requires ||= []
|
108
108
|
end
|
109
109
|
|
110
|
+
# @return [Array<String>]
|
111
|
+
def missing_docs
|
112
|
+
@missing_docs ||= []
|
113
|
+
end
|
114
|
+
|
110
115
|
# @param y [String]
|
111
116
|
# @return [YARD::Registry]
|
112
117
|
def load_yardoc y
|
@@ -196,10 +201,11 @@ module Solargraph
|
|
196
201
|
required.merge @gemset.keys if required.include?('bundler/require')
|
197
202
|
pins.replace core_pins
|
198
203
|
unresolved_requires.clear
|
204
|
+
missing_docs.clear
|
199
205
|
stdlib_pins.clear
|
200
206
|
environ = Convention.for_global(self)
|
201
207
|
done = []
|
202
|
-
|
208
|
+
already_errored = []
|
203
209
|
(required + environ.requires).each do |r|
|
204
210
|
next if r.nil? || r.empty? || done.include?(r)
|
205
211
|
done.push r
|
@@ -219,24 +225,18 @@ module Solargraph
|
|
219
225
|
# YARD detects gems for certain libraries that do not have a yardoc
|
220
226
|
# but exist in the stdlib. `fileutils` is an example. Treat those
|
221
227
|
# cases as errors and check the stdlib yardoc.
|
222
|
-
|
228
|
+
if yd.nil?
|
229
|
+
process_error(r, result, already_errored, nil)
|
230
|
+
next
|
231
|
+
end
|
223
232
|
@gem_paths[spec.name] = spec.full_gem_path
|
224
233
|
unless yardocs.include?(yd)
|
225
234
|
yardocs.unshift yd
|
226
235
|
result.concat process_yardoc yd, spec
|
227
236
|
result.concat add_gem_dependencies(spec) if with_dependencies?
|
228
237
|
end
|
229
|
-
rescue Gem::LoadError, NoYardocError
|
230
|
-
|
231
|
-
next if from_std.include?(base)
|
232
|
-
from_std.push base
|
233
|
-
stdtmp = load_stdlib_pins(base)
|
234
|
-
if stdtmp.empty?
|
235
|
-
unresolved_requires.push r
|
236
|
-
else
|
237
|
-
stdlib_pins.concat stdtmp
|
238
|
-
result.concat stdtmp
|
239
|
-
end
|
238
|
+
rescue Gem::LoadError, NoYardocError
|
239
|
+
process_error(r, result, already_errored)
|
240
240
|
end
|
241
241
|
result.delete_if(&:nil?)
|
242
242
|
unless result.empty?
|
@@ -253,6 +253,21 @@ module Solargraph
|
|
253
253
|
pins.concat environ.pins
|
254
254
|
end
|
255
255
|
|
256
|
+
def process_error(req, result, already_errored, yd = 1)
|
257
|
+
base = req.split('/').first
|
258
|
+
return if already_errored.include?(base)
|
259
|
+
already_errored.push base
|
260
|
+
stdtmp = load_stdlib_pins(base)
|
261
|
+
if yd.nil?
|
262
|
+
missing_docs.push req
|
263
|
+
elsif stdtmp.empty?
|
264
|
+
unresolved_requires.push req
|
265
|
+
else
|
266
|
+
stdlib_pins.concat stdtmp
|
267
|
+
result.concat stdtmp
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
256
271
|
def process_gemsets
|
257
272
|
return {} if directory.empty? || !File.file?(File.join(directory, 'Gemfile'))
|
258
273
|
require_from_bundle(directory)
|
@@ -270,7 +285,7 @@ module Solargraph
|
|
270
285
|
@gem_paths[depspec.name] = depspec.full_gem_path
|
271
286
|
gy = yardoc_file_for_spec(depspec)
|
272
287
|
if gy.nil?
|
273
|
-
|
288
|
+
missing_docs.push dep.name
|
274
289
|
else
|
275
290
|
next if yardocs.include?(gy)
|
276
291
|
yardocs.unshift gy
|
@@ -343,7 +358,9 @@ module Solargraph
|
|
343
358
|
# @param path [String]
|
344
359
|
# @return [Gem::Specification]
|
345
360
|
def spec_for_require path
|
346
|
-
|
361
|
+
name = path.split('/').first
|
362
|
+
spec = Gem::Specification.find_by_name(name, @gemset[name])
|
363
|
+
|
347
364
|
# Avoid loading the spec again if it's going to be skipped anyway
|
348
365
|
return spec if @source_gems.include?(spec.name)
|
349
366
|
# Avoid loading the spec again if it's already the correct version
|
data/lib/solargraph.rb
CHANGED
@@ -59,8 +59,8 @@ module Solargraph
|
|
59
59
|
#
|
60
60
|
# @return [void]
|
61
61
|
def self.with_clean_env &block
|
62
|
-
meth = if Bundler.respond_to?(:
|
63
|
-
:
|
62
|
+
meth = if Bundler.respond_to?(:with_original_env)
|
63
|
+
:with_original_env
|
64
64
|
else
|
65
65
|
:with_clean_env
|
66
66
|
end
|
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.
|
4
|
+
version: 0.47.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fred Snyder
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-09-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: backport
|
@@ -301,6 +301,7 @@ executables:
|
|
301
301
|
extensions: []
|
302
302
|
extra_rdoc_files: []
|
303
303
|
files:
|
304
|
+
- ".github/workflows/rspec.yml"
|
304
305
|
- ".gitignore"
|
305
306
|
- ".rspec"
|
306
307
|
- ".travis.yml"
|
@@ -491,6 +492,7 @@ files:
|
|
491
492
|
- lib/solargraph/pin/reference/prepend.rb
|
492
493
|
- lib/solargraph/pin/reference/require.rb
|
493
494
|
- lib/solargraph/pin/reference/superclass.rb
|
495
|
+
- lib/solargraph/pin/search.rb
|
494
496
|
- lib/solargraph/pin/singleton.rb
|
495
497
|
- lib/solargraph/pin/symbol.rb
|
496
498
|
- lib/solargraph/position.rb
|
@@ -572,7 +574,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
572
574
|
- !ruby/object:Gem::Version
|
573
575
|
version: '0'
|
574
576
|
requirements: []
|
575
|
-
rubygems_version: 3.
|
577
|
+
rubygems_version: 3.3.7
|
576
578
|
signing_key:
|
577
579
|
specification_version: 4
|
578
580
|
summary: A Ruby language server
|