solargraph 0.44.0 → 0.44.1
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 +7 -0
- data/lib/solargraph/complex_type.rb +4 -0
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +1 -1
- data/lib/solargraph/parser/legacy/node_chainer.rb +17 -0
- data/lib/solargraph/parser/legacy/node_processors/block_node.rb +25 -1
- data/lib/solargraph/parser/rubyvm/class_methods.rb +7 -2
- data/lib/solargraph/parser/rubyvm/node_chainer.rb +5 -0
- data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +25 -1
- data/lib/solargraph/pin/block.rb +19 -9
- data/lib/solargraph/pin/documenting.rb +1 -1
- data/lib/solargraph/pin/local_variable.rb +1 -13
- data/lib/solargraph/source/chain/link.rb +4 -0
- data/lib/solargraph/source/chain/q_call.rb +11 -0
- data/lib/solargraph/source/chain.rb +14 -1
- data/lib/solargraph/source.rb +0 -3
- data/lib/solargraph/source_map/clip.rb +5 -5
- data/lib/solargraph/source_map/mapper.rb +4 -4
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/yard_map.rb +1 -1
- data/solargraph.gemspec +1 -1
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 346926f891270e103d6c7170fe5897587c1d5da45ea33b2a7f4238914b38b236
|
4
|
+
data.tar.gz: 451b09bf70dc9d760ebfdeb726821e6e653f196bd867da8c7638888803e33a72
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 624d1de49ef2762477d7a413adf282a058143a71689ea8cdfcc91177db94c765b997fca00fefd8d0d4915e44e6cd4ae1867297671611ba6d119d610116c5b80a
|
7
|
+
data.tar.gz: 9f146a371e075407cb8be7b96de08ff24583cf18eb1a29310c1a711c1bd347715d07b0ff6603e9a98b71be7406148e17c907abdcf3bd1a2aba58bd5aeff14685
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
## 0.44.1 - November 18, 2021
|
2
|
+
- Chain nil safety navigation operator (#420)
|
3
|
+
- Update closure and context for class_eval receiver (#487)
|
4
|
+
- SourceMap::Mapper handles invalid byte sequences (#474)
|
5
|
+
- Special handle var= references, which may use as var = (have space) (#498)
|
6
|
+
- Rebind define_method to self (#494)
|
7
|
+
|
1
8
|
## 0.44.0 - September 27, 2021
|
2
9
|
- Allow opening parenthesis, space, and comma when using Diff::LCS (#465)
|
3
10
|
- Support textDocument/documentHighlight
|
@@ -31,7 +31,7 @@ module Solargraph
|
|
31
31
|
# @param code [String]
|
32
32
|
# @return [Array(Array<String>, Array<String>)]
|
33
33
|
def generate_options filename, code
|
34
|
-
args = ['-f', 'j', filename]
|
34
|
+
args = ['-f', 'j', '--force-exclusion', filename]
|
35
35
|
base_options = RuboCop::Options.new
|
36
36
|
options, paths = base_options.parse(args)
|
37
37
|
options[:stdin] = code
|
@@ -71,6 +71,23 @@ module Solargraph
|
|
71
71
|
else
|
72
72
|
raise "No idea what to do with #{n}"
|
73
73
|
end
|
74
|
+
elsif n.type == :csend
|
75
|
+
if n.children[0].is_a?(::Parser::AST::Node)
|
76
|
+
result.concat generate_links(n.children[0])
|
77
|
+
args = []
|
78
|
+
n.children[2..-1].each do |c|
|
79
|
+
args.push NodeChainer.chain(c)
|
80
|
+
end
|
81
|
+
result.push Chain::QCall.new(n.children[1].to_s, args, @in_block > 0 || block_passed?(n))
|
82
|
+
elsif n.children[0].nil?
|
83
|
+
args = []
|
84
|
+
n.children[2..-1].each do |c|
|
85
|
+
args.push NodeChainer.chain(c)
|
86
|
+
end
|
87
|
+
result.push Chain::QCall.new(n.children[1].to_s, args, @in_block > 0 || block_passed?(n))
|
88
|
+
else
|
89
|
+
raise "No idea what to do with #{n}"
|
90
|
+
end
|
74
91
|
elsif n.type == :self
|
75
92
|
result.push Chain::Head.new('self')
|
76
93
|
elsif n.type == :zsuper
|
@@ -5,15 +5,39 @@ module Solargraph
|
|
5
5
|
module Legacy
|
6
6
|
module NodeProcessors
|
7
7
|
class BlockNode < Parser::NodeProcessor::Base
|
8
|
+
include Legacy::NodeMethods
|
9
|
+
|
8
10
|
def process
|
11
|
+
if other_class_eval?
|
12
|
+
other_class = Solargraph::Pin::Namespace.new(
|
13
|
+
type: :class,
|
14
|
+
name: unpack_name(node.children[0].children[0])
|
15
|
+
)
|
16
|
+
make_block_in other_class.context
|
17
|
+
process_children region.update(closure: other_class)
|
18
|
+
else
|
19
|
+
make_block_in nil
|
20
|
+
process_children region.update(closure: pins.last)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def other_class_eval?
|
27
|
+
node.children[0].type == :send &&
|
28
|
+
node.children[0].children[1] == :class_eval &&
|
29
|
+
[:cbase, :const].include?(node.children[0].children[0]&.type)
|
30
|
+
end
|
31
|
+
|
32
|
+
def make_block_in context
|
9
33
|
pins.push Solargraph::Pin::Block.new(
|
10
34
|
location: get_node_location(node),
|
35
|
+
context: context,
|
11
36
|
closure: region.closure,
|
12
37
|
receiver: node.children[0],
|
13
38
|
comments: comments_for(node),
|
14
39
|
scope: region.scope || region.closure.context.scope
|
15
40
|
)
|
16
|
-
process_children region.update(closure: pins.last)
|
17
41
|
end
|
18
42
|
end
|
19
43
|
end
|
@@ -40,11 +40,16 @@ module Solargraph
|
|
40
40
|
# end
|
41
41
|
|
42
42
|
def references source, name
|
43
|
+
if name.end_with?("=")
|
44
|
+
reg = /#{Regexp.escape name[0..-2]}\s*=/
|
45
|
+
extract_offset = ->(code, offset) { reg.match(code, offset).offset(0) }
|
46
|
+
else
|
47
|
+
extract_offset = ->(code, offset) { [soff = code.index(name, offset), soff + name.length] }
|
48
|
+
end
|
43
49
|
inner_node_references(name, source.node).map do |n|
|
44
50
|
rng = Range.from_node(n)
|
45
51
|
offset = Position.to_offset(source.code, rng.start)
|
46
|
-
soff = source.code
|
47
|
-
eoff = soff + name.length
|
52
|
+
soff, eoff = extract_offset[source.code, offset]
|
48
53
|
Location.new(
|
49
54
|
source.filename,
|
50
55
|
Range.new(
|
@@ -60,6 +60,11 @@ module Solargraph
|
|
60
60
|
result.concat generate_links(c)
|
61
61
|
end
|
62
62
|
result.push Chain::Call.new(n.children[-2].to_s, node_to_argchains(n.children.last), @in_block > 0 || block_passed?(n))
|
63
|
+
elsif n.type == :QCALL
|
64
|
+
n.children[0..-3].each do |c|
|
65
|
+
result.concat generate_links(c)
|
66
|
+
end
|
67
|
+
result.push Chain::QCall.new(n.children[-2].to_s, node_to_argchains(n.children.last), @in_block > 0 || block_passed?(n))
|
63
68
|
elsif n.type == :ATTRASGN
|
64
69
|
result.concat generate_links(n.children[0])
|
65
70
|
result.push Chain::Call.new(n.children[1].to_s, node_to_argchains(n.children[2]), @in_block > 0 || block_passed?(n))
|
@@ -5,15 +5,39 @@ module Solargraph
|
|
5
5
|
module Rubyvm
|
6
6
|
module NodeProcessors
|
7
7
|
class BlockNode < Parser::NodeProcessor::Base
|
8
|
+
include NodeMethods
|
9
|
+
|
8
10
|
def process
|
11
|
+
if other_class_eval?
|
12
|
+
other_class = Solargraph::Pin::Namespace.new(
|
13
|
+
type: :class,
|
14
|
+
name: unpack_name(node.children[0].children[0])
|
15
|
+
)
|
16
|
+
make_block_in other_class.context
|
17
|
+
process_children region.update(closure: other_class)
|
18
|
+
else
|
19
|
+
make_block_in nil
|
20
|
+
process_children region.update(closure: pins.last)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def other_class_eval?
|
27
|
+
node.children[0].type == :CALL &&
|
28
|
+
node.children[0].children[1] == :class_eval &&
|
29
|
+
[:COLON2, :CONST].include?(node.children[0].children[0].type)
|
30
|
+
end
|
31
|
+
|
32
|
+
def make_block_in context
|
9
33
|
pins.push Solargraph::Pin::Block.new(
|
10
34
|
location: get_node_location(node),
|
35
|
+
context: context,
|
11
36
|
closure: region.closure,
|
12
37
|
receiver: node.children[0],
|
13
38
|
comments: comments_for(node),
|
14
39
|
scope: region.scope || region.closure.context.scope
|
15
40
|
)
|
16
|
-
process_children region.update(closure: pins.last)
|
17
41
|
end
|
18
42
|
end
|
19
43
|
end
|
data/lib/solargraph/pin/block.rb
CHANGED
@@ -8,9 +8,10 @@ module Solargraph
|
|
8
8
|
# @return [Parser::AST::Node]
|
9
9
|
attr_reader :receiver
|
10
10
|
|
11
|
-
def initialize receiver: nil, args: [], **splat
|
11
|
+
def initialize receiver: nil, args: [], context: nil, **splat
|
12
12
|
super(**splat)
|
13
13
|
@receiver = receiver
|
14
|
+
@context = context
|
14
15
|
@parameters = args
|
15
16
|
end
|
16
17
|
|
@@ -44,15 +45,24 @@ module Solargraph
|
|
44
45
|
return nil unless api_map.rebindable_method_names.include?(word)
|
45
46
|
chain = Parser.chain(receiver, location.filename)
|
46
47
|
locals = api_map.source_map(location.filename).locals_at(location)
|
47
|
-
|
48
|
+
links_last_word = chain.links.last.word
|
49
|
+
if %w[instance_eval instance_exec class_eval class_exec module_eval module_exec].include?(links_last_word)
|
48
50
|
return chain.base.infer(api_map, self, locals)
|
49
|
-
|
50
|
-
|
51
|
-
if
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
51
|
+
end
|
52
|
+
if 'define_method' == links_last_word and chain.define(api_map, self, locals).first&.path == 'Module#define_method' # change class type to instance type
|
53
|
+
if chain.links.size > 1 # Class.define_method
|
54
|
+
ty = chain.base.infer(api_map, self, locals)
|
55
|
+
return Solargraph::ComplexType.parse(ty.namespace)
|
56
|
+
else # define_method without self
|
57
|
+
return Solargraph::ComplexType.parse(closure.binder.namespace)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
# other case without early return, read block yieldself tags
|
61
|
+
receiver_pin = chain.define(api_map, self, locals).first
|
62
|
+
if receiver_pin && receiver_pin.docstring
|
63
|
+
ys = receiver_pin.docstring.tag(:yieldself)
|
64
|
+
if ys && ys.types && !ys.types.empty?
|
65
|
+
return ComplexType.try_parse(*ys.types).qualify(api_map, receiver_pin.context.namespace)
|
56
66
|
end
|
57
67
|
end
|
58
68
|
nil
|
@@ -18,19 +18,7 @@ module Solargraph
|
|
18
18
|
true
|
19
19
|
end
|
20
20
|
|
21
|
-
# @param
|
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
|
-
|
21
|
+
# @param other_closure [Pin::Closure]
|
34
22
|
# @param other_loc [Location]
|
35
23
|
def visible_at?(other_closure, other_loc)
|
36
24
|
return true if location.filename == other_loc.filename &&
|
@@ -11,6 +11,7 @@ module Solargraph
|
|
11
11
|
class Chain
|
12
12
|
autoload :Link, 'solargraph/source/chain/link'
|
13
13
|
autoload :Call, 'solargraph/source/chain/call'
|
14
|
+
autoload :QCall, 'solargraph/source/chain/q_call'
|
14
15
|
autoload :Variable, 'solargraph/source/chain/variable'
|
15
16
|
autoload :ClassVariable, 'solargraph/source/chain/class_variable'
|
16
17
|
autoload :Constant, 'solargraph/source/chain/constant'
|
@@ -76,7 +77,8 @@ module Solargraph
|
|
76
77
|
# @return [ComplexType]
|
77
78
|
def infer api_map, name_pin, locals
|
78
79
|
pins = define(api_map, name_pin, locals)
|
79
|
-
infer_first_defined(pins, links.last.last_context, api_map)
|
80
|
+
type = infer_first_defined(pins, links.last.last_context, api_map)
|
81
|
+
maybe_nil(type)
|
80
82
|
end
|
81
83
|
|
82
84
|
# @return [Boolean]
|
@@ -101,6 +103,10 @@ module Solargraph
|
|
101
103
|
@splat
|
102
104
|
end
|
103
105
|
|
106
|
+
def nullable?
|
107
|
+
links.any?(&:nullable?)
|
108
|
+
end
|
109
|
+
|
104
110
|
private
|
105
111
|
|
106
112
|
# @param pins [Array<Pin::Base>]
|
@@ -146,6 +152,13 @@ module Solargraph
|
|
146
152
|
return type if context.nil? || context.return_type.undefined?
|
147
153
|
type.self_to(context.return_type.namespace)
|
148
154
|
end
|
155
|
+
|
156
|
+
# @param type [ComplexType]
|
157
|
+
def maybe_nil type
|
158
|
+
return type if type.undefined? || type.void? || type.nullable?
|
159
|
+
return type unless nullable?
|
160
|
+
ComplexType.try_parse("#{type}, nil")
|
161
|
+
end
|
149
162
|
end
|
150
163
|
end
|
151
164
|
end
|
data/lib/solargraph/source.rb
CHANGED
@@ -42,7 +42,6 @@ module Solargraph
|
|
42
42
|
@version = version
|
43
43
|
@domains = []
|
44
44
|
begin
|
45
|
-
# @node, @comments = Source.parse_with_comments(@code, filename)
|
46
45
|
@node, @comments = Solargraph::Parser.parse_with_comments(@code, filename)
|
47
46
|
@parsed = true
|
48
47
|
rescue Parser::SyntaxError, EncodingError => e
|
@@ -336,7 +335,6 @@ module Solargraph
|
|
336
335
|
# @param parent [Symbol]
|
337
336
|
# @return [void]
|
338
337
|
def inner_folding_ranges top, result = [], parent = nil
|
339
|
-
# return unless top.is_a?(::Parser::AST::Node)
|
340
338
|
return unless Parser.is_ast_node?(top)
|
341
339
|
if FOLDING_NODE_TYPES.include?(top.type)
|
342
340
|
# @todo Smelly exception for hash's first-level array in RubyVM
|
@@ -433,7 +431,6 @@ module Solargraph
|
|
433
431
|
# @return [void]
|
434
432
|
def inner_tree_at node, position, stack
|
435
433
|
return if node.nil?
|
436
|
-
# here = Range.from_to(node.loc.expression.line, node.loc.expression.column, node.loc.expression.last_line, node.loc.expression.last_column)
|
437
434
|
here = Range.from_node(node)
|
438
435
|
if here.contain?(position) || colonized(here, position, node)
|
439
436
|
stack.unshift node
|
@@ -53,11 +53,7 @@ module Solargraph
|
|
53
53
|
#
|
54
54
|
# @return [Array<Solargraph::Pin::Base>]
|
55
55
|
def locals
|
56
|
-
|
57
|
-
adj_pos = Position.new(loc_pos.line, (loc_pos.column.zero? ? 0 : loc_pos.column - 1))
|
58
|
-
@locals ||= source_map.locals.select { |pin|
|
59
|
-
pin.visible_from?(block, adj_pos)
|
60
|
-
}.reverse
|
56
|
+
@locals ||= source_map.locals_at(location)
|
61
57
|
end
|
62
58
|
|
63
59
|
def gates
|
@@ -92,6 +88,10 @@ module Solargraph
|
|
92
88
|
@source_map ||= api_map.source_map(cursor.filename)
|
93
89
|
end
|
94
90
|
|
91
|
+
def location
|
92
|
+
Location.new(source_map.filename, Solargraph::Range.new(cursor.position, cursor.position))
|
93
|
+
end
|
94
|
+
|
95
95
|
# @return [Solargraph::Pin::Base]
|
96
96
|
def block
|
97
97
|
@block ||= source_map.locate_block_pin(cursor.node_position.line, cursor.node_position.character)
|
@@ -61,7 +61,7 @@ module Solargraph
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def process_comment source_position, comment_position, comment
|
64
|
-
return unless comment =~ MACRO_REGEXP
|
64
|
+
return unless comment.encode('UTF-8', invalid: :replace, replace: '?') =~ MACRO_REGEXP
|
65
65
|
cmnt = remove_inline_comment_hashes(comment)
|
66
66
|
parse = Solargraph::Source.parse_docstring(cmnt)
|
67
67
|
last_line = 0
|
@@ -169,7 +169,7 @@ module Solargraph
|
|
169
169
|
# @todo Handle parser errors in !parse directives
|
170
170
|
end
|
171
171
|
when 'domain'
|
172
|
-
namespace = closure_at(source_position)
|
172
|
+
namespace = closure_at(source_position) || Pin::ROOT_PIN
|
173
173
|
namespace.domains.concat directive.tag.types unless directive.tag.types.nil?
|
174
174
|
when 'override'
|
175
175
|
pins.push Pin::Reference::Override.new(location, directive.tag.name, docstring.tags)
|
@@ -182,7 +182,7 @@ module Solargraph
|
|
182
182
|
started = false
|
183
183
|
comment.lines.each { |l|
|
184
184
|
# Trim the comment and minimum leading whitespace
|
185
|
-
p = l.gsub(/^#/, '')
|
185
|
+
p = l.encode('UTF-8', invalid: :replace, replace: '?').gsub(/^#/, '')
|
186
186
|
if num.nil? && !p.strip.empty?
|
187
187
|
num = p.index(/[^ ]/)
|
188
188
|
started = true
|
@@ -197,7 +197,7 @@ module Solargraph
|
|
197
197
|
|
198
198
|
# @return [void]
|
199
199
|
def process_comment_directives
|
200
|
-
return unless @code =~ MACRO_REGEXP
|
200
|
+
return unless @code.encode('UTF-8', invalid: :replace, replace: '?') =~ MACRO_REGEXP
|
201
201
|
code_lines = @code.lines
|
202
202
|
@source.associated_comments.each do |line, comments|
|
203
203
|
src_pos = line ? Position.new(line, code_lines[line].to_s.chomp.index(/[^\s]/) || 0) : Position.new(code_lines.length, 0)
|
data/lib/solargraph/version.rb
CHANGED
data/lib/solargraph/yard_map.rb
CHANGED
@@ -88,7 +88,7 @@ module Solargraph
|
|
88
88
|
@rebindable_method_names ||= pins_by_class(Pin::Method)
|
89
89
|
.select { |pin| pin.comments && pin.comments.include?('@yieldself') }
|
90
90
|
.map(&:name)
|
91
|
-
.concat(['instance_eval', 'instance_exec', 'class_eval', 'class_exec', 'module_eval', 'module_exec'])
|
91
|
+
.concat(['instance_eval', 'instance_exec', 'class_eval', 'class_exec', 'module_eval', 'module_exec', 'define_method'])
|
92
92
|
.to_set
|
93
93
|
end
|
94
94
|
|
data/solargraph.gemspec
CHANGED
@@ -34,7 +34,7 @@ Gem::Specification.new do |s|
|
|
34
34
|
s.add_runtime_dependency 'tilt', '~> 2.0'
|
35
35
|
s.add_runtime_dependency 'yard', '~> 0.9', '>= 0.9.24'
|
36
36
|
|
37
|
-
s.add_development_dependency 'pry'
|
37
|
+
s.add_development_dependency 'pry'
|
38
38
|
s.add_development_dependency 'public_suffix', '~> 3.1'
|
39
39
|
s.add_development_dependency 'rspec', '~> 3.5', '>= 3.5.0'
|
40
40
|
s.add_development_dependency 'simplecov', '~> 0.14'
|
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.44.
|
4
|
+
version: 0.44.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fred Snyder
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-11-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: backport
|
@@ -222,16 +222,16 @@ dependencies:
|
|
222
222
|
name: pry
|
223
223
|
requirement: !ruby/object:Gem::Requirement
|
224
224
|
requirements:
|
225
|
-
- - "
|
225
|
+
- - ">="
|
226
226
|
- !ruby/object:Gem::Version
|
227
|
-
version: 0
|
227
|
+
version: '0'
|
228
228
|
type: :development
|
229
229
|
prerelease: false
|
230
230
|
version_requirements: !ruby/object:Gem::Requirement
|
231
231
|
requirements:
|
232
|
-
- - "
|
232
|
+
- - ">="
|
233
233
|
- !ruby/object:Gem::Version
|
234
|
-
version: 0
|
234
|
+
version: '0'
|
235
235
|
- !ruby/object:Gem::Dependency
|
236
236
|
name: public_suffix
|
237
237
|
requirement: !ruby/object:Gem::Requirement
|
@@ -510,6 +510,7 @@ files:
|
|
510
510
|
- lib/solargraph/source/chain/link.rb
|
511
511
|
- lib/solargraph/source/chain/literal.rb
|
512
512
|
- lib/solargraph/source/chain/or.rb
|
513
|
+
- lib/solargraph/source/chain/q_call.rb
|
513
514
|
- lib/solargraph/source/chain/variable.rb
|
514
515
|
- lib/solargraph/source/chain/z_super.rb
|
515
516
|
- lib/solargraph/source/change.rb
|