solargraph 0.42.1 → 0.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +22 -0
- data/SPONSORS.md +0 -1
- data/lib/solargraph/api_map.rb +1 -1
- data/lib/solargraph/api_map/bundler_methods.rb +1 -6
- data/lib/solargraph/api_map/store.rb +17 -17
- data/lib/solargraph/bench.rb +1 -1
- data/lib/solargraph/complex_type.rb +4 -0
- data/lib/solargraph/complex_type/type_methods.rb +6 -3
- data/lib/solargraph/language_server/host.rb +2 -1
- data/lib/solargraph/language_server/host/dispatch.rb +2 -3
- data/lib/solargraph/language_server/transport/adapter.rb +1 -3
- data/lib/solargraph/library.rb +12 -5
- data/lib/solargraph/parser/legacy/node_chainer.rb +14 -1
- data/lib/solargraph/parser/legacy/node_methods.rb +9 -2
- data/lib/solargraph/parser/node_processor/base.rb +0 -3
- data/lib/solargraph/parser/rubyvm/node_chainer.rb +22 -1
- data/lib/solargraph/parser/rubyvm/node_methods.rb +5 -0
- data/lib/solargraph/pin/base.rb +1 -1
- data/lib/solargraph/pin/local_variable.rb +47 -1
- data/lib/solargraph/shell.rb +2 -2
- data/lib/solargraph/source.rb +0 -12
- data/lib/solargraph/source/chain.rb +1 -4
- data/lib/solargraph/source/chain/call.rb +3 -2
- data/lib/solargraph/source/chain/hash.rb +28 -0
- data/lib/solargraph/source_map.rb +2 -1
- data/lib/solargraph/source_map/clip.rb +1 -1
- data/lib/solargraph/type_checker.rb +11 -4
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace.rb +1 -1
- data/lib/solargraph/yard_map.rb +16 -14
- data/lib/solargraph/yard_map/core_fills.rb +18 -1
- data/lib/yard-solargraph.rb +3 -0
- data/solargraph.gemspec +1 -1
- metadata +9 -9
- data/lib/solargraph/pin/localized.rb +0 -43
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 89a1a9d76094688ff7ebe1af3dec4452c379819408ffc458eddcd75f5b66d2eb
|
4
|
+
data.tar.gz: 9b03143ba896ccd2d3bd0a44c9a1e90f06e3ed757a47a08e6b8aaf2a9f56e62e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a6d4e99416af96a8a11ca569d096f4ba1491155f3fde1efc734e59c73d1794007d0b7b1e936c1dfb248472df1fa679c7701866176de99119e8f6a0b8eef721d4
|
7
|
+
data.tar.gz: edd612d341e6c9bb421e4bbb8db04badc855e924eca469c47943c374813025810151aca1abdd0da13100597803799a50c7355a362b8a0ae65187c0760464e840
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,25 @@
|
|
1
|
+
## 0.43.0 - July 25, 2021
|
2
|
+
- Correct arity checks when restarg precedes arg (#418)
|
3
|
+
- Improve the performance of catalog by 4 times (#457)
|
4
|
+
- Type checker validates duck type variables and params (#453)
|
5
|
+
- Kernel#raise exception type checker
|
6
|
+
- Pin::Base#inspect includes path
|
7
|
+
- Fix arity with combined restargs and kwrestargs (#396)
|
8
|
+
|
9
|
+
## 0.42.4 - July 11, 2021
|
10
|
+
- Yardoc cache handling
|
11
|
+
- Fix required_paths when gemspec is used (#451)
|
12
|
+
- fix: yard stdout may break language client (#454)
|
13
|
+
|
14
|
+
## 0.42.3 - June 14, 2021
|
15
|
+
- Require 'pathname' for Library
|
16
|
+
|
17
|
+
## 0.42.2 - June 14, 2021
|
18
|
+
- Improve download-core command output
|
19
|
+
- Ignore missing requests to client responses
|
20
|
+
- Add automatically required gems to YardMap
|
21
|
+
- Use closures to identify local variables
|
22
|
+
|
1
23
|
## 0.42.1 - June 11, 2021
|
2
24
|
- YardMap#change sets new directory (#445)
|
3
25
|
|
data/SPONSORS.md
CHANGED
data/lib/solargraph/api_map.rb
CHANGED
@@ -138,7 +138,7 @@ module Solargraph
|
|
138
138
|
|
139
139
|
# An array of pins based on Ruby keywords (`if`, `end`, etc.).
|
140
140
|
#
|
141
|
-
# @return [
|
141
|
+
# @return [Enumerable<Solargraph::Pin::Keyword>]
|
142
142
|
def keyword_pins
|
143
143
|
store.pins_by_class(Pin::Keyword)
|
144
144
|
end
|
@@ -9,7 +9,7 @@ module Solargraph
|
|
9
9
|
# @param directory [String]
|
10
10
|
# @return [Hash]
|
11
11
|
def require_from_bundle directory
|
12
|
-
|
12
|
+
begin
|
13
13
|
Solargraph.logger.info "Loading gems for bundler/require"
|
14
14
|
Documentor.specs_from_bundle(directory)
|
15
15
|
rescue BundleNotFoundError => e
|
@@ -17,11 +17,6 @@ module Solargraph
|
|
17
17
|
{}
|
18
18
|
end
|
19
19
|
end
|
20
|
-
|
21
|
-
# @return [void]
|
22
|
-
def reset_require_from_bundle
|
23
|
-
@require_from_bundle = nil
|
24
|
-
end
|
25
20
|
end
|
26
21
|
end
|
27
22
|
end
|
@@ -5,10 +5,10 @@ require 'set'
|
|
5
5
|
module Solargraph
|
6
6
|
class ApiMap
|
7
7
|
class Store
|
8
|
-
# @return [
|
8
|
+
# @return [Enumerable<Solargraph::Pin::Base>]
|
9
9
|
attr_reader :pins
|
10
10
|
|
11
|
-
# @param pins [
|
11
|
+
# @param pins [Enumerable<Solargraph::Pin::Base>]
|
12
12
|
def initialize pins = []
|
13
13
|
@pins = pins
|
14
14
|
index
|
@@ -16,7 +16,7 @@ module Solargraph
|
|
16
16
|
|
17
17
|
# @param fqns [String]
|
18
18
|
# @param visibility [Array<Symbol>]
|
19
|
-
# @return [
|
19
|
+
# @return [Enumerable<Solargraph::Pin::Base>]
|
20
20
|
def get_constants fqns, visibility = [:public]
|
21
21
|
namespace_children(fqns).select { |pin|
|
22
22
|
!pin.name.empty? && (pin.is_a?(Pin::Namespace) || pin.is_a?(Pin::Constant)) && visibility.include?(pin.visibility)
|
@@ -26,7 +26,7 @@ module Solargraph
|
|
26
26
|
# @param fqns [String]
|
27
27
|
# @param scope [Symbol]
|
28
28
|
# @param visibility [Array<Symbol>]
|
29
|
-
# @return [
|
29
|
+
# @return [Enumerable<Solargraph::Pin::Base>]
|
30
30
|
def get_methods fqns, scope: :instance, visibility: [:public]
|
31
31
|
namespace_children(fqns).select do |pin|
|
32
32
|
pin.is_a?(Pin::Method) && pin.scope == scope && visibility.include?(pin.visibility)
|
@@ -61,14 +61,14 @@ module Solargraph
|
|
61
61
|
end
|
62
62
|
|
63
63
|
# @param path [String]
|
64
|
-
# @return [
|
64
|
+
# @return [Enumerable<Solargraph::Pin::Base>]
|
65
65
|
def get_path_pins path
|
66
66
|
path_pin_hash[path] || []
|
67
67
|
end
|
68
68
|
|
69
69
|
# @param fqns [String]
|
70
70
|
# @param scope [Symbol] :class or :instance
|
71
|
-
# @return [
|
71
|
+
# @return [Enumerable<Solargraph::Pin::Base>]
|
72
72
|
def get_instance_variables(fqns, scope = :instance)
|
73
73
|
all_instance_variables.select { |pin|
|
74
74
|
pin.binder.namespace == fqns && pin.binder.scope == scope
|
@@ -76,12 +76,12 @@ module Solargraph
|
|
76
76
|
end
|
77
77
|
|
78
78
|
# @param fqns [String]
|
79
|
-
# @return [
|
79
|
+
# @return [Enumerable<Solargraph::Pin::Base>]
|
80
80
|
def get_class_variables(fqns)
|
81
81
|
namespace_children(fqns).select{|pin| pin.is_a?(Pin::ClassVariable)}
|
82
82
|
end
|
83
83
|
|
84
|
-
# @return [
|
84
|
+
# @return [Enumerable<Solargraph::Pin::Base>]
|
85
85
|
def get_symbols
|
86
86
|
symbols.uniq(&:name)
|
87
87
|
end
|
@@ -97,12 +97,12 @@ module Solargraph
|
|
97
97
|
@namespaces ||= Set.new
|
98
98
|
end
|
99
99
|
|
100
|
-
# @return [
|
100
|
+
# @return [Enumerable<Solargraph::Pin::Base>]
|
101
101
|
def namespace_pins
|
102
102
|
pins_by_class(Solargraph::Pin::Namespace)
|
103
103
|
end
|
104
104
|
|
105
|
-
# @return [
|
105
|
+
# @return [Enumerable<Solargraph::Pin::Method>]
|
106
106
|
def method_pins
|
107
107
|
pins_by_class(Solargraph::Pin::Method)
|
108
108
|
end
|
@@ -131,7 +131,7 @@ module Solargraph
|
|
131
131
|
end
|
132
132
|
end
|
133
133
|
|
134
|
-
# @return [
|
134
|
+
# @return [Enumerable<Pin::Block>]
|
135
135
|
def block_pins
|
136
136
|
pins_by_class(Pin::Block)
|
137
137
|
end
|
@@ -142,9 +142,9 @@ module Solargraph
|
|
142
142
|
end
|
143
143
|
|
144
144
|
# @param klass [Class]
|
145
|
-
# @return [
|
145
|
+
# @return [Enumerable<Solargraph::Pin::Base>]
|
146
146
|
def pins_by_class klass
|
147
|
-
@pin_select_cache[klass] ||= @pin_class_hash.
|
147
|
+
@pin_select_cache[klass] ||= @pin_class_hash.each_with_object(Set.new) { |(key, o), n| n.merge(o) if key <= klass }
|
148
148
|
end
|
149
149
|
|
150
150
|
private
|
@@ -171,7 +171,7 @@ module Solargraph
|
|
171
171
|
end
|
172
172
|
end
|
173
173
|
|
174
|
-
# @return [
|
174
|
+
# @return [Enumerable<Solargraph::Pin::Symbol>]
|
175
175
|
def symbols
|
176
176
|
pins_by_class(Pin::Symbol)
|
177
177
|
end
|
@@ -193,7 +193,7 @@ module Solargraph
|
|
193
193
|
end
|
194
194
|
|
195
195
|
# @param name [String]
|
196
|
-
# @return [
|
196
|
+
# @return [Enumerable<Solargraph::Pin::Base>]
|
197
197
|
def namespace_children name
|
198
198
|
namespace_map[name] || []
|
199
199
|
end
|
@@ -216,8 +216,8 @@ module Solargraph
|
|
216
216
|
set = pins.to_set
|
217
217
|
@pin_class_hash = set.classify(&:class).transform_values(&:to_a)
|
218
218
|
@pin_select_cache = {}
|
219
|
-
@namespace_map = set.classify(&:namespace)
|
220
|
-
@path_pin_hash = set.classify(&:path)
|
219
|
+
@namespace_map = set.classify(&:namespace)
|
220
|
+
@path_pin_hash = set.classify(&:path)
|
221
221
|
@namespaces = @path_pin_hash.keys.compact.to_set
|
222
222
|
pins_by_class(Pin::Reference::Include).each do |pin|
|
223
223
|
include_references[pin.namespace] ||= []
|
data/lib/solargraph/bench.rb
CHANGED
@@ -51,6 +51,10 @@ module Solargraph
|
|
51
51
|
def select &block
|
52
52
|
@items.select &block
|
53
53
|
end
|
54
|
+
def namespace
|
55
|
+
# cache this attr for high frequency call
|
56
|
+
@namespace ||= method_missing(:namespace).to_s
|
57
|
+
end
|
54
58
|
|
55
59
|
def method_missing name, *args, &block
|
56
60
|
return if @items.first.nil?
|
@@ -72,9 +72,12 @@ module Solargraph
|
|
72
72
|
|
73
73
|
# @return [String]
|
74
74
|
def namespace
|
75
|
-
|
76
|
-
@namespace ||=
|
77
|
-
|
75
|
+
# if priority higher than ||=, old implements cause unnecessary check
|
76
|
+
@namespace ||= lambda do
|
77
|
+
return 'Object' if duck_type?
|
78
|
+
return 'NilClass' if nil_type?
|
79
|
+
return (name == 'Class' || name == 'Module') && !subtypes.empty? ? subtypes.first.name : name
|
80
|
+
end.call
|
78
81
|
end
|
79
82
|
|
80
83
|
# @return [Symbol] :class or :instance
|
@@ -31,7 +31,7 @@ module Solargraph
|
|
31
31
|
@cancel = []
|
32
32
|
@buffer = String.new
|
33
33
|
@stopped = true
|
34
|
-
@next_request_id =
|
34
|
+
@next_request_id = 1
|
35
35
|
@dynamic_capabilities = Set.new
|
36
36
|
@registered_capabilities = Set.new
|
37
37
|
end
|
@@ -113,6 +113,7 @@ module Solargraph
|
|
113
113
|
requests.delete request['id']
|
114
114
|
else
|
115
115
|
logger.warn "Discarding client response to unrecognized message #{request['id']}"
|
116
|
+
nil
|
116
117
|
end
|
117
118
|
else
|
118
119
|
logger.warn "Invalid message received."
|
@@ -41,7 +41,8 @@ module Solargraph
|
|
41
41
|
result = explicit_library_for(uri) ||
|
42
42
|
implicit_library_for(uri) ||
|
43
43
|
generic_library_for(uri)
|
44
|
-
|
44
|
+
# previous library for already call attach. avoid call twice
|
45
|
+
# result.attach sources.find(uri) if sources.include?(uri)
|
45
46
|
result
|
46
47
|
end
|
47
48
|
|
@@ -82,7 +83,6 @@ module Solargraph
|
|
82
83
|
libraries.each do |lib|
|
83
84
|
if filename.start_with?(lib.workspace.directory)
|
84
85
|
lib.attach sources.find(uri)
|
85
|
-
lib.catalog
|
86
86
|
return lib
|
87
87
|
end
|
88
88
|
end
|
@@ -98,7 +98,6 @@ module Solargraph
|
|
98
98
|
# @return [Library]
|
99
99
|
def generic_library_for uri
|
100
100
|
generic_library.attach sources.find(uri)
|
101
|
-
generic_library.catalog
|
102
101
|
generic_library
|
103
102
|
end
|
104
103
|
|
data/lib/solargraph/library.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'pathname'
|
4
|
+
|
3
5
|
module Solargraph
|
4
6
|
# A Library handles coordination between a Workspace and an ApiMap.
|
5
7
|
#
|
@@ -46,7 +48,7 @@ module Solargraph
|
|
46
48
|
# @return [void]
|
47
49
|
def attach source
|
48
50
|
mutex.synchronize do
|
49
|
-
if @current && @current.filename != source.filename && source_map_hash.key?(@current.filename) && !workspace.has_file?(@current.filename)
|
51
|
+
if @current && (!source || @current.filename != source.filename) && source_map_hash.key?(@current.filename) && !workspace.has_file?(@current.filename)
|
50
52
|
source_map_hash.delete @current.filename
|
51
53
|
source_map_external_require_hash.delete @current.filename
|
52
54
|
@external_requires = nil
|
@@ -54,7 +56,7 @@ module Solargraph
|
|
54
56
|
end
|
55
57
|
@current = source
|
56
58
|
maybe_map @current
|
57
|
-
|
59
|
+
catalog_inlock
|
58
60
|
end
|
59
61
|
end
|
60
62
|
|
@@ -349,7 +351,7 @@ module Solargraph
|
|
349
351
|
else
|
350
352
|
args = line.split(':').map(&:strip)
|
351
353
|
name = args.shift
|
352
|
-
|
354
|
+
reporter = Diagnostics.reporter(name)
|
353
355
|
raise DiagnosticsError, "Diagnostics reporter #{name} does not exist" if reporter.nil?
|
354
356
|
repargs[reporter] ||= []
|
355
357
|
repargs[reporter].concat args
|
@@ -366,12 +368,16 @@ module Solargraph
|
|
366
368
|
# @return [void]
|
367
369
|
def catalog
|
368
370
|
mutex.synchronize do
|
369
|
-
|
371
|
+
catalog_inlock
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
private def catalog_inlock
|
376
|
+
return if synchronized?
|
370
377
|
logger.info "Cataloging #{workspace.directory.empty? ? 'generic workspace' : workspace.directory}"
|
371
378
|
api_map.catalog bench
|
372
379
|
@synchronized = true
|
373
380
|
logger.info "Catalog complete (#{api_map.source_maps.length} files, #{api_map.pins.length} pins)" if logger.info?
|
374
|
-
end
|
375
381
|
end
|
376
382
|
|
377
383
|
def bench
|
@@ -511,6 +517,7 @@ module Solargraph
|
|
511
517
|
end
|
512
518
|
|
513
519
|
def maybe_map source
|
520
|
+
return unless source
|
514
521
|
if source_map_hash.key?(source.filename)
|
515
522
|
return if source_map_hash[source.filename].code == source.code &&
|
516
523
|
source_map_hash[source.filename].source.synchronized? &&
|
@@ -102,13 +102,26 @@ module Solargraph
|
|
102
102
|
result.concat generate_links(n.children[0])
|
103
103
|
elsif n.type == :block_pass
|
104
104
|
result.push Chain::BlockVariable.new("&#{n.children[0].children[0].to_s}")
|
105
|
+
elsif n.type == :hash
|
106
|
+
result.push Chain::Hash.new('::Hash', hash_is_splatted?(n))
|
105
107
|
else
|
106
108
|
lit = infer_literal_node_type(n)
|
107
|
-
|
109
|
+
# if lit == '::Hash'
|
110
|
+
# result.push Chain::Hash.new(lit, hash_is_splatted?(n))
|
111
|
+
# else
|
112
|
+
result.push (lit ? Chain::Literal.new(lit) : Chain::Link.new)
|
113
|
+
# end
|
108
114
|
end
|
109
115
|
result
|
110
116
|
end
|
111
117
|
|
118
|
+
def hash_is_splatted? node
|
119
|
+
return false unless Parser.is_ast_node?(node) && node.type == :hash
|
120
|
+
return false unless Parser.is_ast_node?(node.children.last) && node.children.last.type == :kwsplat
|
121
|
+
return false if Parser.is_ast_node?(node.children.last.children[0]) && node.children.last.children[0].type == :hash
|
122
|
+
true
|
123
|
+
end
|
124
|
+
|
112
125
|
def block_passed? node
|
113
126
|
node.children.last.is_a?(::Parser::AST::Node) && node.children.last.type == :block_pass
|
114
127
|
end
|
@@ -97,8 +97,10 @@ module Solargraph
|
|
97
97
|
end
|
98
98
|
|
99
99
|
def convert_hash node
|
100
|
-
return {} unless Parser.is_ast_node?(node)
|
101
|
-
return convert_hash(node.children[0]
|
100
|
+
return {} unless Parser.is_ast_node?(node)
|
101
|
+
return convert_hash(node.children[0]) if node.type == :kwsplat
|
102
|
+
return convert_hash(node.children[0]) if Parser.is_ast_node?(node.children[0]) && node.children[0].type == :kwsplat
|
103
|
+
return {} unless node.type == :hash
|
102
104
|
result = {}
|
103
105
|
node.children.each do |pair|
|
104
106
|
result[pair.children[0].children[0]] = Solargraph::Parser.chain(pair.children[1])
|
@@ -124,9 +126,14 @@ module Solargraph
|
|
124
126
|
end
|
125
127
|
|
126
128
|
def splatted_call? node
|
129
|
+
return false unless Parser.is_ast_node?(node)
|
127
130
|
Parser.is_ast_node?(node.children[0]) && node.children[0].type == :kwsplat && node.children[0].children[0].type != :hash
|
128
131
|
end
|
129
132
|
|
133
|
+
def any_splatted_call?(nodes)
|
134
|
+
nodes.any? { |n| splatted_call?(n) }
|
135
|
+
end
|
136
|
+
|
130
137
|
# @todo Temporarily here for testing. Move to Solargraph::Parser.
|
131
138
|
def call_nodes_from node
|
132
139
|
return [] unless node.is_a?(::Parser::AST::Node)
|
@@ -97,13 +97,31 @@ module Solargraph
|
|
97
97
|
result.concat generate_links(n.children[0])
|
98
98
|
elsif n.type == :BLOCK_PASS
|
99
99
|
result.push Chain::BlockVariable.new("&#{n.children[1].children[0].to_s}")
|
100
|
+
elsif n.type == :HASH
|
101
|
+
result.push Chain::Hash.new('::Hash', hash_is_splatted?(n))
|
100
102
|
else
|
101
103
|
lit = infer_literal_node_type(n)
|
102
|
-
|
104
|
+
if lit
|
105
|
+
if lit == '::Hash'
|
106
|
+
result.push Chain::Hash.new(lit, hash_is_splatted?(n))
|
107
|
+
else
|
108
|
+
result.push Chain::Literal.new(lit)
|
109
|
+
end
|
110
|
+
else
|
111
|
+
result.push Chain::Link.new
|
112
|
+
end
|
113
|
+
# result.push (lit ? Chain::Literal.new(lit) : Chain::Link.new)
|
103
114
|
end
|
104
115
|
result
|
105
116
|
end
|
106
117
|
|
118
|
+
def hash_is_splatted? node
|
119
|
+
return false unless Parser.is_ast_node?(node.children[0]) && node.children[0].type == :LIST
|
120
|
+
list = node.children[0].children
|
121
|
+
eol = list.rindex(&:nil?)
|
122
|
+
eol && Parser.is_ast_node?(list[eol + 1])
|
123
|
+
end
|
124
|
+
|
107
125
|
def block_passed? node
|
108
126
|
node.children.last.is_a?(RubyVM::AbstractSyntaxTree::Node) && node.children.last.type == :BLOCK_PASS
|
109
127
|
end
|
@@ -114,6 +132,9 @@ module Solargraph
|
|
114
132
|
node.children[0..-2].map { |c| NodeChainer.chain(c) }
|
115
133
|
elsif node.type == :SPLAT
|
116
134
|
[NodeChainer.chain(node)]
|
135
|
+
elsif node.type == :ARGSPUSH
|
136
|
+
result = node_to_argchains(node.children[0])
|
137
|
+
result.push NodeChainer.chain(node.children[1]) if Parser.is_ast_node?(node.children[1])
|
117
138
|
elsif node.type == :ARGSCAT
|
118
139
|
result = node.children[0].children[0..-2].map { |c| NodeChainer.chain(c) }
|
119
140
|
result.push NodeChainer.chain(node.children[1])
|
@@ -117,9 +117,14 @@ module Solargraph
|
|
117
117
|
end
|
118
118
|
|
119
119
|
def splatted_call? node
|
120
|
+
return false unless Parser.is_ast_node?(node)
|
120
121
|
splatted_node?(node) && node.children[0].children[1].type != :HASH
|
121
122
|
end
|
122
123
|
|
124
|
+
def any_splatted_call?(nodes)
|
125
|
+
nodes.any? { |n| splatted_call?(n) }
|
126
|
+
end
|
127
|
+
|
123
128
|
def node? node
|
124
129
|
node.is_a?(RubyVM::AbstractSyntaxTree::Node)
|
125
130
|
end
|
data/lib/solargraph/pin/base.rb
CHANGED
@@ -3,7 +3,8 @@
|
|
3
3
|
module Solargraph
|
4
4
|
module Pin
|
5
5
|
class LocalVariable < BaseVariable
|
6
|
-
|
6
|
+
# @return [Range]
|
7
|
+
attr_reader :presence
|
7
8
|
|
8
9
|
def initialize assignment: nil, presence: nil, **splat
|
9
10
|
super(**splat)
|
@@ -16,6 +17,51 @@ module Solargraph
|
|
16
17
|
@presence = pin.presence
|
17
18
|
true
|
18
19
|
end
|
20
|
+
|
21
|
+
# @param other [Pin::Base] The caller's block
|
22
|
+
# @param position [Position, Array(Integer, Integer)] The caller's position
|
23
|
+
# @return [Boolean]
|
24
|
+
def visible_from?(other, position)
|
25
|
+
position = Position.normalize(position)
|
26
|
+
other.filename == filename &&
|
27
|
+
match_tags(other.full_context.tag, full_context.tag) &&
|
28
|
+
(other == closure ||
|
29
|
+
(closure.location.range.contain?(other.location.range.start) && closure.location.range.contain?(other.location.range.ending))
|
30
|
+
) &&
|
31
|
+
presence.contain?(position)
|
32
|
+
end
|
33
|
+
|
34
|
+
# @param other_loc [Location]
|
35
|
+
def visible_at?(other_closure, other_loc)
|
36
|
+
return true if location.filename == other_loc.filename &&
|
37
|
+
presence.include?(other_loc.range.start) &&
|
38
|
+
match_named_closure(other_closure, closure)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
# @param tag1 [String]
|
44
|
+
# @param tag2 [String]
|
45
|
+
# @return [Boolean]
|
46
|
+
def match_tags tag1, tag2
|
47
|
+
# @todo This is an unfortunate hack made necessary by a discrepancy in
|
48
|
+
# how tags indicate the root namespace. The long-term solution is to
|
49
|
+
# standardize it, whether it's `Class<>`, an empty string, or
|
50
|
+
# something else.
|
51
|
+
tag1 == tag2 ||
|
52
|
+
(['', 'Class<>'].include?(tag1) && ['', 'Class<>'].include?(tag2))
|
53
|
+
end
|
54
|
+
|
55
|
+
def match_named_closure needle, haystack
|
56
|
+
return true if needle == haystack
|
57
|
+
cursor = haystack
|
58
|
+
until cursor.nil?
|
59
|
+
return true if needle.path == cursor.path
|
60
|
+
return false if cursor.path && !cursor.path.empty?
|
61
|
+
cursor = cursor.closure
|
62
|
+
end
|
63
|
+
false
|
64
|
+
end
|
19
65
|
end
|
20
66
|
end
|
21
67
|
end
|
data/lib/solargraph/shell.rb
CHANGED
@@ -76,12 +76,12 @@ module Solargraph
|
|
76
76
|
ver = version || Solargraph::YardMap::CoreDocs.best_download
|
77
77
|
if RUBY_VERSION != ver
|
78
78
|
puts "Documentation for #{RUBY_VERSION} is not available. Reverting to closest match..."
|
79
|
-
else
|
80
|
-
puts "Downloading docs for #{ver}..."
|
81
79
|
end
|
80
|
+
puts "Downloading docs for #{ver}..."
|
82
81
|
Solargraph::YardMap::CoreDocs.download ver
|
83
82
|
# Clear cached documentation if it exists
|
84
83
|
FileUtils.rm_rf Dir.glob(File.join(Solargraph::YardMap::CoreDocs.cache_dir, ver, '*.ser'))
|
84
|
+
puts "Download complete."
|
85
85
|
rescue ArgumentError => e
|
86
86
|
STDERR.puts "ERROR: #{e.message}"
|
87
87
|
STDERR.puts "Run `solargraph available-cores` for a list."
|
data/lib/solargraph/source.rb
CHANGED
@@ -6,19 +6,15 @@ module Solargraph
|
|
6
6
|
# A Ruby file that has been parsed into an AST.
|
7
7
|
#
|
8
8
|
class Source
|
9
|
-
# autoload :FlawedBuilder, 'solargraph/source/flawed_builder'
|
10
9
|
autoload :Updater, 'solargraph/source/updater'
|
11
10
|
autoload :Change, 'solargraph/source/change'
|
12
11
|
autoload :Mapper, 'solargraph/source/mapper'
|
13
|
-
# autoload :NodeMethods, 'solargraph/source/node_methods'
|
14
12
|
autoload :EncodingFixes, 'solargraph/source/encoding_fixes'
|
15
13
|
autoload :Cursor, 'solargraph/source/cursor'
|
16
14
|
autoload :Chain, 'solargraph/source/chain'
|
17
15
|
autoload :SourceChainer, 'solargraph/source/source_chainer'
|
18
|
-
# autoload :NodeChainer, 'solargraph/source/node_chainer'
|
19
16
|
|
20
17
|
include EncodingFixes
|
21
|
-
# include NodeMethods
|
22
18
|
|
23
19
|
# @return [String]
|
24
20
|
attr_reader :filename
|
@@ -50,17 +46,9 @@ module Solargraph
|
|
50
46
|
@node, @comments = Solargraph::Parser.parse_with_comments(@code, filename)
|
51
47
|
@parsed = true
|
52
48
|
rescue Parser::SyntaxError, EncodingError => e
|
53
|
-
# @todo 100% whitespace results in a nil node, so there's no reason to parse it.
|
54
|
-
# We still need to determine whether the resulting node should be nil or a dummy
|
55
|
-
# node with a location that encompasses the range.
|
56
|
-
# @node, @comments = Source.parse_with_comments(@code.gsub(/[^\s]/, ' '), filename)
|
57
49
|
@node = nil
|
58
50
|
@comments = {}
|
59
51
|
@parsed = false
|
60
|
-
# rescue Exception => e
|
61
|
-
# Solargraph.logger.warn "[#{e.class}] #{e.message}"
|
62
|
-
# Solargraph.logger.warn e.backtrace.join("\n")
|
63
|
-
# raise "Error parsing #{filename || '(source)'}: [#{e.class}] #{e.message}"
|
64
52
|
ensure
|
65
53
|
@code.freeze
|
66
54
|
end
|
@@ -21,6 +21,7 @@ module Solargraph
|
|
21
21
|
autoload :Or, 'solargraph/source/chain/or'
|
22
22
|
autoload :BlockVariable, 'solargraph/source/chain/block_variable'
|
23
23
|
autoload :ZSuper, 'solargraph/source/chain/z_super'
|
24
|
+
autoload :Hash, 'solargraph/source/chain/hash'
|
24
25
|
|
25
26
|
@@inference_stack = []
|
26
27
|
@@inference_depth = 0
|
@@ -61,10 +62,6 @@ module Solargraph
|
|
61
62
|
working_pin = name_pin
|
62
63
|
links[0..-2].each do |link|
|
63
64
|
pins = link.resolve(api_map, working_pin, locals)
|
64
|
-
# Locals are only used when resolving the first link
|
65
|
-
# @todo There's a problem here. Call links need to resolve arguments
|
66
|
-
# that might refer to local variables.
|
67
|
-
# locals = []
|
68
65
|
type = infer_first_defined(pins, working_pin, api_map)
|
69
66
|
return [] if type.undefined?
|
70
67
|
working_pin = Pin::ProxyType.anonymous(type)
|
@@ -77,6 +77,7 @@ module Solargraph
|
|
77
77
|
end
|
78
78
|
if match
|
79
79
|
type = extra_return_type(ol, context)
|
80
|
+
break if type
|
80
81
|
type = ComplexType.try_parse(*ol.tag(:return).types).self_to(context.to_s).qualify(api_map, context.namespace) if ol.has_tag?(:return) && ol.tag(:return).types && !ol.tag(:return).types.empty? && (type.nil? || type.undefined?)
|
81
82
|
type ||= ComplexType::UNDEFINED
|
82
83
|
end
|
@@ -170,8 +171,8 @@ module Solargraph
|
|
170
171
|
# @param context [ComplexType]
|
171
172
|
# @return [ComplexType]
|
172
173
|
def extra_return_type docstring, context
|
173
|
-
if docstring.has_tag?(:return_single_parameter)
|
174
|
-
return context.subtypes.first
|
174
|
+
if docstring.has_tag?(:return_single_parameter) #&& context.subtypes.one?
|
175
|
+
return context.subtypes.first || ComplexType::UNDEFINED
|
175
176
|
elsif docstring.has_tag?(:return_value_parameter) && context.value_types.one?
|
176
177
|
return context.value_types.first
|
177
178
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
class Source
|
5
|
+
class Chain
|
6
|
+
class Hash < Literal
|
7
|
+
# @param type [String]
|
8
|
+
# @param splatted [Boolean]
|
9
|
+
def initialize type, splatted = false
|
10
|
+
super(type)
|
11
|
+
@splatted = splatted
|
12
|
+
end
|
13
|
+
|
14
|
+
def word
|
15
|
+
@word ||= "<#{@type}>"
|
16
|
+
end
|
17
|
+
|
18
|
+
def resolve api_map, name_pin, locals
|
19
|
+
[Pin::ProxyType.anonymous(@complex_type)]
|
20
|
+
end
|
21
|
+
|
22
|
+
def splatted?
|
23
|
+
@splatted
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -131,7 +131,8 @@ module Solargraph
|
|
131
131
|
# @return [Array<Pin::LocalVariable>]
|
132
132
|
def locals_at(location)
|
133
133
|
return [] if location.filename != filename
|
134
|
-
|
134
|
+
closure = locate_named_path_pin(location.range.start.line, location.range.start.character)
|
135
|
+
locals.select { |pin| pin.visible_at?(closure, location) }
|
135
136
|
end
|
136
137
|
|
137
138
|
class << self
|
@@ -213,7 +213,7 @@ module Solargraph
|
|
213
213
|
result.concat api_map.get_methods(block.binder.namespace, scope: block.binder.scope, visibility: [:public, :private, :protected])
|
214
214
|
result.concat api_map.get_methods('Kernel')
|
215
215
|
# result.concat ApiMap.keywords
|
216
|
-
result.concat api_map.keyword_pins
|
216
|
+
result.concat api_map.keyword_pins.to_a
|
217
217
|
result.concat yielded_self_pins
|
218
218
|
end
|
219
219
|
end
|
@@ -148,6 +148,7 @@ module Solargraph
|
|
148
148
|
all_variables.each do |pin|
|
149
149
|
if pin.return_type.defined?
|
150
150
|
declared = pin.typify(api_map)
|
151
|
+
next if declared.duck_type?
|
151
152
|
if declared.defined?
|
152
153
|
if rules.validate_tags?
|
153
154
|
inferred = pin.probe(api_map)
|
@@ -416,7 +417,7 @@ module Solargraph
|
|
416
417
|
end
|
417
418
|
settled_kwargs = 0
|
418
419
|
unless unchecked.empty?
|
419
|
-
if
|
420
|
+
if any_splatted_call?(unchecked.map(&:node))
|
420
421
|
settled_kwargs = pin.parameters.count(&:keyword?)
|
421
422
|
else
|
422
423
|
kwargs = convert_hash(unchecked.last.node)
|
@@ -431,6 +432,7 @@ module Solargraph
|
|
431
432
|
kwargs.delete param.name.to_sym
|
432
433
|
settled_kwargs += 1
|
433
434
|
elsif param.decl == :kwarg
|
435
|
+
return [] if arguments.last.links.last.is_a?(Solargraph::Source::Chain::Hash) && arguments.last.links.last.splatted?
|
434
436
|
return [Problem.new(location, "Missing keyword argument #{param.name} to #{pin.path}")]
|
435
437
|
end
|
436
438
|
end
|
@@ -450,12 +452,17 @@ module Solargraph
|
|
450
452
|
if unchecked.length == req + opt + 1 && unchecked.last.links.last.is_a?(Source::Chain::BlockVariable)
|
451
453
|
return []
|
452
454
|
end
|
453
|
-
if req + add_params + 1 == unchecked.length &&
|
455
|
+
if req + add_params + 1 == unchecked.length && any_splatted_call?(unchecked.map(&:node)) && (pin.parameters.map(&:decl) & [:kwarg, :kwoptarg, :kwrestarg]).any?
|
454
456
|
return []
|
455
457
|
end
|
458
|
+
return [] if arguments.length - req == pin.parameters.select { |p| [:optarg, :kwoptarg].include?(p.decl) }.length
|
456
459
|
return [Problem.new(location, "Too many arguments to #{pin.path}")]
|
457
|
-
elsif unchecked.length < req - settled_kwargs && (arguments.empty? || !arguments.last.splat?)
|
458
|
-
|
460
|
+
elsif unchecked.length < req - settled_kwargs && (arguments.empty? || (!arguments.last.splat? && !arguments.last.links.last.is_a?(Solargraph::Source::Chain::Hash)))
|
461
|
+
# HACK: Kernel#raise signature is incorrect in Ruby 2.7 core docs.
|
462
|
+
# See https://github.com/castwide/solargraph/issues/418
|
463
|
+
unless arguments.empty? && pin.path == 'Kernel#raise'
|
464
|
+
return [Problem.new(location, "Not enough arguments to #{pin.path}")]
|
465
|
+
end
|
459
466
|
end
|
460
467
|
[]
|
461
468
|
end
|
data/lib/solargraph/version.rb
CHANGED
data/lib/solargraph/workspace.rb
CHANGED
data/lib/solargraph/yard_map.rb
CHANGED
@@ -156,12 +156,12 @@ module Solargraph
|
|
156
156
|
@base_required ||= Set.new
|
157
157
|
end
|
158
158
|
|
159
|
-
private
|
160
|
-
|
161
159
|
def directory
|
162
160
|
@directory ||= ''
|
163
161
|
end
|
164
162
|
|
163
|
+
private
|
164
|
+
|
165
165
|
# @return [YardMap::Cache]
|
166
166
|
def cache
|
167
167
|
@cache ||= YardMap::Cache.new
|
@@ -190,11 +190,8 @@ module Solargraph
|
|
190
190
|
|
191
191
|
# @return [void]
|
192
192
|
def process_requires
|
193
|
-
@gemset =
|
194
|
-
|
195
|
-
else
|
196
|
-
{}
|
197
|
-
end
|
193
|
+
@gemset = process_gemsets
|
194
|
+
required.merge @gemset.keys if required.include?('bundler/require')
|
198
195
|
pins.replace core_pins
|
199
196
|
unresolved_requires.clear
|
200
197
|
stdlib_pins.clear
|
@@ -254,6 +251,11 @@ module Solargraph
|
|
254
251
|
pins.concat environ.pins
|
255
252
|
end
|
256
253
|
|
254
|
+
def process_gemsets
|
255
|
+
return {} if directory.empty? || !File.file?(File.join(directory, 'Gemfile'))
|
256
|
+
require_from_bundle(directory)
|
257
|
+
end
|
258
|
+
|
257
259
|
# @param spec [Gem::Specification]
|
258
260
|
# @return [void]
|
259
261
|
def add_gem_dependencies spec
|
@@ -286,9 +288,6 @@ module Solargraph
|
|
286
288
|
# @return [Array<Pin::Base>]
|
287
289
|
def process_yardoc y, spec = nil
|
288
290
|
return [] if y.nil?
|
289
|
-
size = Dir.glob(File.join(y, '**', '*'))
|
290
|
-
.map{ |f| File.size(f) }
|
291
|
-
.inject(:+)
|
292
291
|
if spec
|
293
292
|
ser = File.join(CoreDocs.cache_dir, 'gems', "#{spec.name}-#{spec.version}.ser")
|
294
293
|
if File.file?(ser)
|
@@ -297,19 +296,24 @@ module Solargraph
|
|
297
296
|
dump = file.read
|
298
297
|
file.close
|
299
298
|
begin
|
300
|
-
|
299
|
+
result = Marshal.load(dump)
|
300
|
+
return result unless result.nil? || result.empty?
|
301
|
+
Solargraph.logger.warn "Empty cache for #{spec.name} #{spec.version}. Reloading"
|
301
302
|
rescue StandardError => e
|
302
303
|
Solargraph.logger.warn "Error loading pin cache: [#{e.class}] #{e.message}"
|
303
304
|
File.unlink ser
|
304
305
|
end
|
305
306
|
end
|
306
307
|
end
|
308
|
+
size = Dir.glob(File.join(y, '**', '*'))
|
309
|
+
.map{ |f| File.size(f) }
|
310
|
+
.inject(:+)
|
307
311
|
if !size.nil? && size > 20_000_000
|
308
312
|
Solargraph::Logging.logger.warn "Yardoc at #{y} is too large to process (#{size} bytes)"
|
309
313
|
return []
|
310
314
|
end
|
315
|
+
Solargraph.logger.info "Loading #{spec.name} #{spec.version} from #{y}"
|
311
316
|
load_yardoc y
|
312
|
-
Solargraph.logger.info "Loading #{spec.name} #{spec.version} from yardoc"
|
313
317
|
result = Mapper.new(YARD::Registry.all, spec).map
|
314
318
|
if spec
|
315
319
|
ser = File.join(CoreDocs.cache_dir, 'gems', "#{spec.name}-#{spec.version}.ser")
|
@@ -433,5 +437,3 @@ module Solargraph
|
|
433
437
|
end
|
434
438
|
|
435
439
|
Solargraph::YardMap::CoreDocs.require_minimum
|
436
|
-
# Change YARD log IO to avoid sending unexpected messages to STDOUT
|
437
|
-
YARD::Logger.instance.io = File.new(File::NULL, 'w')
|
@@ -82,6 +82,18 @@ module Solargraph
|
|
82
82
|
Override.method_return('Class#allocate', 'self'),
|
83
83
|
Override.method_return('Class.allocate', 'Class<Object>'),
|
84
84
|
|
85
|
+
Override.from_comment('Enumerable#detect', %(
|
86
|
+
@overload detect(&block)
|
87
|
+
@return_single_parameter
|
88
|
+
@overload detect()
|
89
|
+
@return [Enumerator]
|
90
|
+
)),
|
91
|
+
Override.from_comment('Enumerable#find', %(
|
92
|
+
@overload find(&block)
|
93
|
+
@return_single_parameter
|
94
|
+
@overload find()
|
95
|
+
@return [Enumerator]
|
96
|
+
)),
|
85
97
|
Override.method_return('Enumerable#select', 'self'),
|
86
98
|
|
87
99
|
Override.method_return('File.absolute_path', 'String'),
|
@@ -111,7 +123,12 @@ module Solargraph
|
|
111
123
|
@param y [Numeric]
|
112
124
|
@return [Numeric]
|
113
125
|
)),
|
114
|
-
Override.
|
126
|
+
Override.from_comment('Integer#times', %(
|
127
|
+
@overload times(&block)
|
128
|
+
@return [Integer]
|
129
|
+
@overload times()
|
130
|
+
@return [Enumerator]
|
131
|
+
)),
|
115
132
|
|
116
133
|
Override.method_return('Kernel#puts', 'nil'),
|
117
134
|
|
data/lib/yard-solargraph.rb
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
|
3
3
|
require 'yard'
|
4
4
|
|
5
|
+
# Change YARD log IO to avoid sending unexpected messages to STDOUT
|
6
|
+
YARD::Logger.instance.io = File.new(File::NULL, 'w')
|
7
|
+
|
5
8
|
module Solargraph
|
6
9
|
# A placeholder for the @!domain directive. It doesn't need to do anything
|
7
10
|
# for yardocs. It's only used for Solargraph API maps.
|
data/solargraph.gemspec
CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
|
20
20
|
s.required_ruby_version = '>= 2.4'
|
21
21
|
|
22
|
-
s.add_runtime_dependency 'backport', '~> 1.
|
22
|
+
s.add_runtime_dependency 'backport', '~> 1.2'
|
23
23
|
s.add_runtime_dependency 'benchmark'
|
24
24
|
s.add_runtime_dependency 'bundler', '>= 1.17.2'
|
25
25
|
s.add_runtime_dependency 'diff-lcs', '~> 1.4'
|
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.43.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fred Snyder
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-07-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: backport
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
19
|
+
version: '1.2'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
26
|
+
version: '1.2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: benchmark
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -477,7 +477,6 @@ files:
|
|
477
477
|
- lib/solargraph/pin/keyword.rb
|
478
478
|
- lib/solargraph/pin/keyword_param.rb
|
479
479
|
- lib/solargraph/pin/local_variable.rb
|
480
|
-
- lib/solargraph/pin/localized.rb
|
481
480
|
- lib/solargraph/pin/method.rb
|
482
481
|
- lib/solargraph/pin/method_alias.rb
|
483
482
|
- lib/solargraph/pin/namespace.rb
|
@@ -503,6 +502,7 @@ files:
|
|
503
502
|
- lib/solargraph/source/chain/class_variable.rb
|
504
503
|
- lib/solargraph/source/chain/constant.rb
|
505
504
|
- lib/solargraph/source/chain/global_variable.rb
|
505
|
+
- lib/solargraph/source/chain/hash.rb
|
506
506
|
- lib/solargraph/source/chain/head.rb
|
507
507
|
- lib/solargraph/source/chain/instance_variable.rb
|
508
508
|
- lib/solargraph/source/chain/link.rb
|
@@ -554,7 +554,7 @@ homepage: http://solargraph.org
|
|
554
554
|
licenses:
|
555
555
|
- MIT
|
556
556
|
metadata: {}
|
557
|
-
post_install_message:
|
557
|
+
post_install_message:
|
558
558
|
rdoc_options: []
|
559
559
|
require_paths:
|
560
560
|
- lib
|
@@ -569,8 +569,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
569
569
|
- !ruby/object:Gem::Version
|
570
570
|
version: '0'
|
571
571
|
requirements: []
|
572
|
-
rubygems_version: 3.1.
|
573
|
-
signing_key:
|
572
|
+
rubygems_version: 3.1.6
|
573
|
+
signing_key:
|
574
574
|
specification_version: 4
|
575
575
|
summary: A Ruby language server
|
576
576
|
test_files: []
|
@@ -1,43 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Solargraph
|
4
|
-
module Pin
|
5
|
-
module Localized
|
6
|
-
# @return [Range]
|
7
|
-
attr_reader :presence
|
8
|
-
|
9
|
-
# @param other [Pin::Base] The caller's block
|
10
|
-
# @param position [Position, Array(Integer, Integer)] The caller's position
|
11
|
-
# @return [Boolean]
|
12
|
-
def visible_from?(other, position)
|
13
|
-
position = Position.normalize(position)
|
14
|
-
other.filename == filename &&
|
15
|
-
match_tags(other.full_context.tag, full_context.tag) &&
|
16
|
-
(other == closure ||
|
17
|
-
(closure.location.range.contain?(other.location.range.start) && closure.location.range.contain?(other.location.range.ending))
|
18
|
-
) &&
|
19
|
-
presence.contain?(position)
|
20
|
-
end
|
21
|
-
|
22
|
-
# @param other_loc [Location]
|
23
|
-
def visible_at?(other_loc)
|
24
|
-
return false if location.filename != other_loc.filename
|
25
|
-
presence.include?(other_loc.range.start)
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
# @param tag1 [String]
|
31
|
-
# @param tag2 [String]
|
32
|
-
# @return [Boolean]
|
33
|
-
def match_tags tag1, tag2
|
34
|
-
# @todo This is an unfortunate hack made necessary by a discrepancy in
|
35
|
-
# how tags indicate the root namespace. The long-term solution is to
|
36
|
-
# standardize it, whether it's `Class<>`, an empty string, or
|
37
|
-
# something else.
|
38
|
-
tag1 == tag2 ||
|
39
|
-
(['', 'Class<>'].include?(tag1) && ['', 'Class<>'].include?(tag2))
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|