solargraph 0.38.6 → 0.39.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/SPONSORS.md +9 -0
- data/lib/solargraph.rb +1 -0
- data/lib/solargraph/api_map.rb +24 -13
- data/lib/solargraph/api_map/bundler_methods.rb +3 -0
- data/lib/solargraph/api_map/source_to_yard.rb +1 -6
- data/lib/solargraph/api_map/store.rb +19 -3
- data/lib/solargraph/complex_type/type_methods.rb +4 -4
- data/lib/solargraph/convention/base.rb +0 -5
- data/lib/solargraph/core_fills.rb +28 -2
- data/lib/solargraph/diagnostics/base.rb +1 -0
- data/lib/solargraph/diagnostics/type_check.rb +13 -13
- data/lib/solargraph/language_server/host.rb +11 -2
- data/lib/solargraph/language_server/host/sources.rb +20 -11
- data/lib/solargraph/language_server/message/text_document/formatting.rb +16 -11
- data/lib/solargraph/language_server/transport/data_reader.rb +2 -0
- data/lib/solargraph/library.rb +3 -3
- data/lib/solargraph/parser.rb +26 -0
- data/lib/solargraph/parser/comment_ripper.rb +52 -0
- data/lib/solargraph/parser/legacy.rb +12 -0
- data/lib/solargraph/parser/legacy/class_methods.rb +105 -0
- data/lib/solargraph/parser/legacy/flawed_builder.rb +16 -0
- data/lib/solargraph/parser/legacy/node_chainer.rb +115 -0
- data/lib/solargraph/parser/legacy/node_methods.rb +289 -0
- data/lib/solargraph/parser/legacy/node_processors.rb +54 -0
- data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +23 -0
- data/lib/solargraph/parser/legacy/node_processors/args_node.rb +35 -0
- data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +15 -0
- data/lib/solargraph/parser/legacy/node_processors/block_node.rb +22 -0
- data/lib/solargraph/parser/legacy/node_processors/casgn_node.rb +25 -0
- data/lib/solargraph/parser/legacy/node_processors/cvasgn_node.rb +23 -0
- data/lib/solargraph/parser/legacy/node_processors/def_node.rb +63 -0
- data/lib/solargraph/parser/legacy/node_processors/defs_node.rb +36 -0
- data/lib/solargraph/parser/legacy/node_processors/gvasgn_node.rb +23 -0
- data/lib/solargraph/parser/legacy/node_processors/ivasgn_node.rb +38 -0
- data/lib/solargraph/parser/legacy/node_processors/lvasgn_node.rb +28 -0
- data/lib/solargraph/parser/legacy/node_processors/namespace_node.rb +39 -0
- data/lib/solargraph/parser/legacy/node_processors/orasgn_node.rb +16 -0
- data/lib/solargraph/parser/legacy/node_processors/resbody_node.rb +36 -0
- data/lib/solargraph/parser/legacy/node_processors/sclass_node.rb +21 -0
- data/lib/solargraph/parser/legacy/node_processors/send_node.rb +232 -0
- data/lib/solargraph/parser/legacy/node_processors/sym_node.rb +18 -0
- data/lib/solargraph/parser/node_methods.rb +43 -0
- data/lib/solargraph/parser/node_processor.rb +43 -0
- data/lib/solargraph/parser/node_processor/base.rb +77 -0
- data/lib/solargraph/{source_map → parser}/region.rb +11 -6
- data/lib/solargraph/parser/rubyvm.rb +40 -0
- data/lib/solargraph/parser/rubyvm/class_methods.rb +146 -0
- data/lib/solargraph/parser/rubyvm/node_chainer.rb +133 -0
- data/lib/solargraph/parser/rubyvm/node_methods.rb +279 -0
- data/lib/solargraph/parser/rubyvm/node_processors.rb +60 -0
- data/lib/solargraph/parser/rubyvm/node_processors/alias_node.rb +23 -0
- data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +62 -0
- data/lib/solargraph/parser/rubyvm/node_processors/begin_node.rb +15 -0
- data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +22 -0
- data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +22 -0
- data/lib/solargraph/parser/rubyvm/node_processors/cvasgn_node.rb +23 -0
- data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +64 -0
- data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +57 -0
- data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +23 -0
- data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +38 -0
- data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +34 -0
- data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +20 -0
- data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +27 -0
- data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +39 -0
- data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +26 -0
- data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +15 -0
- data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +45 -0
- data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +21 -0
- data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +15 -0
- data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +292 -0
- data/lib/solargraph/parser/rubyvm/node_processors/sym_node.rb +18 -0
- data/lib/solargraph/parser/snippet.rb +13 -0
- data/lib/solargraph/pin/attribute.rb +8 -0
- data/lib/solargraph/pin/base.rb +1 -1
- data/lib/solargraph/pin/base_method.rb +26 -4
- data/lib/solargraph/pin/base_variable.rb +7 -8
- data/lib/solargraph/pin/block.rb +1 -1
- data/lib/solargraph/pin/constant.rb +16 -0
- data/lib/solargraph/pin/conversions.rb +2 -2
- data/lib/solargraph/pin/method.rb +26 -14
- data/lib/solargraph/pin/parameter.rb +56 -2
- data/lib/solargraph/pin/reference.rb +1 -0
- data/lib/solargraph/pin/reference/override.rb +2 -0
- data/lib/solargraph/pin/reference/prepend.rb +10 -0
- data/lib/solargraph/pin/yard_pin/constant.rb +2 -4
- data/lib/solargraph/pin/yard_pin/method.rb +34 -18
- data/lib/solargraph/pin/yard_pin/namespace.rb +3 -11
- data/lib/solargraph/pin/yard_pin/yard_mixin.rb +3 -12
- data/lib/solargraph/range.rb +8 -2
- data/lib/solargraph/shell.rb +17 -11
- data/lib/solargraph/source.rb +114 -135
- data/lib/solargraph/source/chain.rb +11 -3
- data/lib/solargraph/source/chain/call.rb +1 -2
- data/lib/solargraph/source/chain/constant.rb +44 -8
- data/lib/solargraph/source/chain/link.rb +1 -0
- data/lib/solargraph/source/cursor.rb +2 -28
- data/lib/solargraph/source/source_chainer.rb +12 -6
- data/lib/solargraph/source/updater.rb +2 -0
- data/lib/solargraph/source_map.rb +0 -2
- data/lib/solargraph/source_map/clip.rb +24 -17
- data/lib/solargraph/source_map/mapper.rb +34 -29
- data/lib/solargraph/type_checker.rb +367 -275
- data/lib/solargraph/type_checker/checks.rb +95 -0
- data/lib/solargraph/type_checker/param_def.rb +2 -17
- data/lib/solargraph/type_checker/rules.rb +53 -0
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/environment.erb +5 -3
- data/lib/solargraph/workspace.rb +17 -2
- data/lib/solargraph/workspace/config.rb +15 -7
- data/lib/solargraph/yard_map.rb +89 -49
- data/lib/solargraph/yard_map/core_docs.rb +1 -1
- data/solargraph.gemspec +2 -1
- metadata +88 -32
- data/OVERVIEW.md +0 -37
- data/lib/solargraph/source/flawed_builder.rb +0 -15
- data/lib/solargraph/source/node_chainer.rb +0 -111
- data/lib/solargraph/source/node_methods.rb +0 -240
- data/lib/solargraph/source_map/node_processor.rb +0 -85
- data/lib/solargraph/source_map/node_processor/alias_node.rb +0 -21
- data/lib/solargraph/source_map/node_processor/args_node.rb +0 -24
- data/lib/solargraph/source_map/node_processor/base.rb +0 -103
- data/lib/solargraph/source_map/node_processor/begin_node.rb +0 -13
- data/lib/solargraph/source_map/node_processor/block_node.rb +0 -21
- data/lib/solargraph/source_map/node_processor/casgn_node.rb +0 -21
- data/lib/solargraph/source_map/node_processor/cvasgn_node.rb +0 -21
- data/lib/solargraph/source_map/node_processor/def_node.rb +0 -62
- data/lib/solargraph/source_map/node_processor/defs_node.rb +0 -33
- data/lib/solargraph/source_map/node_processor/gvasgn_node.rb +0 -21
- data/lib/solargraph/source_map/node_processor/ivasgn_node.rb +0 -34
- data/lib/solargraph/source_map/node_processor/lvasgn_node.rb +0 -24
- data/lib/solargraph/source_map/node_processor/namespace_node.rb +0 -35
- data/lib/solargraph/source_map/node_processor/orasgn_node.rb +0 -14
- data/lib/solargraph/source_map/node_processor/resbody_node.rb +0 -32
- data/lib/solargraph/source_map/node_processor/sclass_node.rb +0 -19
- data/lib/solargraph/source_map/node_processor/send_node.rb +0 -217
- data/lib/solargraph/source_map/node_processor/sym_node.rb +0 -16
@@ -7,28 +7,20 @@ module Solargraph
|
|
7
7
|
include YardMixin
|
8
8
|
|
9
9
|
def initialize code_object, spec, closure = nil
|
10
|
-
@code_object = code_object
|
11
|
-
@spec = spec
|
12
10
|
closure ||= Solargraph::Pin::Namespace.new(
|
13
11
|
name: code_object.namespace.to_s,
|
14
12
|
closure: Pin::ROOT_PIN,
|
15
13
|
gates: [code_object.namespace.to_s]
|
16
14
|
)
|
17
15
|
super(
|
18
|
-
location:
|
16
|
+
location: object_location(code_object, spec),
|
19
17
|
name: code_object.name.to_s,
|
20
|
-
comments:
|
21
|
-
type:
|
18
|
+
comments: code_object.docstring ? code_object.docstring.all.to_s : '',
|
19
|
+
type: code_object.is_a?(YARD::CodeObjects::ClassObject) ? :class : :module,
|
22
20
|
visibility: code_object.visibility,
|
23
21
|
closure: closure
|
24
22
|
)
|
25
23
|
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
def namespace_type
|
30
|
-
code_object.is_a?(YARD::CodeObjects::ClassObject) ? :class : :module
|
31
|
-
end
|
32
24
|
end
|
33
25
|
end
|
34
26
|
end
|
@@ -8,23 +8,14 @@ module Solargraph
|
|
8
8
|
|
9
9
|
attr_reader :spec
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
def comments
|
14
|
-
@comments ||= code_object.docstring ? code_object.docstring.all.to_s : ''
|
15
|
-
end
|
11
|
+
attr_reader :location
|
16
12
|
|
17
|
-
|
18
|
-
# Guarding with @located because nil locations are valid
|
19
|
-
return @location if @located
|
20
|
-
@located = true
|
21
|
-
@location = object_location
|
22
|
-
end
|
13
|
+
@@gate_cache ||= {}
|
23
14
|
|
24
15
|
private
|
25
16
|
|
26
17
|
# @return [Solargraph::Location, nil]
|
27
|
-
def object_location
|
18
|
+
def object_location code_object, spec
|
28
19
|
return nil if spec.nil? || code_object.nil? || code_object.file.nil? || code_object.line.nil?
|
29
20
|
file = File.join(spec.full_gem_path, code_object.file)
|
30
21
|
Solargraph::Location.new(file, Solargraph::Range.from_to(code_object.line - 1, 0, code_object.line - 1, 0))
|
data/lib/solargraph/range.rb
CHANGED
@@ -62,10 +62,16 @@ module Solargraph
|
|
62
62
|
|
63
63
|
# Get a range from a node.
|
64
64
|
#
|
65
|
-
# @param node [Parser::AST::Node]
|
65
|
+
# @param node [RubyVM::AbstractSyntaxTree::Node, Parser::AST::Node]
|
66
66
|
# @return [Range]
|
67
67
|
def self.from_node node
|
68
|
-
|
68
|
+
if defined?(RubyVM::AbstractSyntaxTree::Node)
|
69
|
+
if node.is_a?(RubyVM::AbstractSyntaxTree::Node)
|
70
|
+
Solargraph::Range.from_to(node.first_lineno - 1, node.first_column, node.last_lineno - 1, node.last_column)
|
71
|
+
end
|
72
|
+
elsif node.loc && node.loc.expression
|
73
|
+
from_expr(node.loc.expression)
|
74
|
+
end
|
69
75
|
end
|
70
76
|
|
71
77
|
# Get a range from a Parser range, usually found in
|
data/lib/solargraph/shell.rb
CHANGED
@@ -14,7 +14,6 @@ module Solargraph
|
|
14
14
|
end
|
15
15
|
|
16
16
|
desc 'socket', 'Run a Solargraph socket server'
|
17
|
-
|
18
17
|
option :host, type: :string, aliases: :h, desc: 'The server host', default: '127.0.0.1'
|
19
18
|
option :port, type: :numeric, aliases: :p, desc: 'The server port', default: 7658
|
20
19
|
def socket
|
@@ -77,6 +76,8 @@ module Solargraph
|
|
77
76
|
ver = version || Solargraph::YardMap::CoreDocs.best_download
|
78
77
|
puts "Downloading docs for #{ver}..."
|
79
78
|
Solargraph::YardMap::CoreDocs.download ver
|
79
|
+
# Clear cached documentation if it exists
|
80
|
+
FileUtils.rm_rf Dir.glob(File.join(Solargraph::YardMap::CoreDocs.cache_dir, ver, '*.ser'))
|
80
81
|
rescue ArgumentError => e
|
81
82
|
STDERR.puts "ERROR: #{e.message}"
|
82
83
|
STDERR.puts "Run `solargraph available-cores` for a list."
|
@@ -93,7 +94,13 @@ module Solargraph
|
|
93
94
|
puts Solargraph::YardMap::CoreDocs.available.join("\n")
|
94
95
|
end
|
95
96
|
|
96
|
-
desc 'clear', 'Delete
|
97
|
+
desc 'clear', 'Delete all cached documentation'
|
98
|
+
long_desc %(
|
99
|
+
This command will delete all core and gem documentation from the cache.
|
100
|
+
You can also delete specific gem caches with the `uncache` command or
|
101
|
+
update documentation for specific Ruby versions with the `download-core`
|
102
|
+
command.
|
103
|
+
)
|
97
104
|
def clear
|
98
105
|
puts "Deleting the cached documentation"
|
99
106
|
Solargraph::YardMap::CoreDocs.clear
|
@@ -117,14 +124,14 @@ module Solargraph
|
|
117
124
|
puts Solargraph::Diagnostics.reporters
|
118
125
|
end
|
119
126
|
|
120
|
-
desc 'typecheck [FILE]', 'Run the type checker'
|
127
|
+
desc 'typecheck [FILE(s)]', 'Run the type checker'
|
121
128
|
long_desc %(
|
122
|
-
Perform type checking on one or more files
|
123
|
-
|
124
|
-
|
125
|
-
|
129
|
+
Perform type checking on one or more files in a workspace. Check the
|
130
|
+
entire workspace if no files are specified.
|
131
|
+
|
132
|
+
Type checking levels are normal, typed, strict, and strong.
|
126
133
|
)
|
127
|
-
option :
|
134
|
+
option :level, type: :string, aliases: [:mode, :m, :l], desc: 'Type checking level', default: 'normal'
|
128
135
|
option :directory, type: :string, aliases: :d, desc: 'The workspace directory', default: '.'
|
129
136
|
def typecheck *files
|
130
137
|
directory = File.realpath(options[:directory])
|
@@ -137,9 +144,8 @@ module Solargraph
|
|
137
144
|
probcount = 0
|
138
145
|
filecount = 0
|
139
146
|
files.each do |file|
|
140
|
-
checker = TypeChecker.new(file, api_map: api_map)
|
141
|
-
problems = checker.
|
142
|
-
problems.concat checker.strict_type_problems if options[:strict]
|
147
|
+
checker = TypeChecker.new(file, api_map: api_map, level: options[:level].to_sym)
|
148
|
+
problems = checker.problems
|
143
149
|
next if problems.empty?
|
144
150
|
problems.sort! { |a, b| a.location.range.start.line <=> b.location.range.start.line }
|
145
151
|
puts problems.map { |prob| "#{prob.location.filename}:#{prob.location.range.start.line + 1} - #{prob.message}" }.join("\n")
|
data/lib/solargraph/source.rb
CHANGED
@@ -1,25 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'parser/current'
|
4
3
|
require 'yard'
|
5
4
|
|
6
5
|
module Solargraph
|
7
6
|
# A Ruby file that has been parsed into an AST.
|
8
7
|
#
|
9
8
|
class Source
|
10
|
-
autoload :FlawedBuilder, 'solargraph/source/flawed_builder'
|
9
|
+
# autoload :FlawedBuilder, 'solargraph/source/flawed_builder'
|
11
10
|
autoload :Updater, 'solargraph/source/updater'
|
12
11
|
autoload :Change, 'solargraph/source/change'
|
13
12
|
autoload :Mapper, 'solargraph/source/mapper'
|
14
|
-
autoload :NodeMethods, 'solargraph/source/node_methods'
|
13
|
+
# autoload :NodeMethods, 'solargraph/source/node_methods'
|
15
14
|
autoload :EncodingFixes, 'solargraph/source/encoding_fixes'
|
16
15
|
autoload :Cursor, 'solargraph/source/cursor'
|
17
16
|
autoload :Chain, 'solargraph/source/chain'
|
18
17
|
autoload :SourceChainer, 'solargraph/source/source_chainer'
|
19
|
-
autoload :NodeChainer, 'solargraph/source/node_chainer'
|
18
|
+
# autoload :NodeChainer, 'solargraph/source/node_chainer'
|
20
19
|
|
21
20
|
include EncodingFixes
|
22
|
-
include NodeMethods
|
21
|
+
# include NodeMethods
|
23
22
|
|
24
23
|
# @return [String]
|
25
24
|
attr_reader :filename
|
@@ -30,7 +29,7 @@ module Solargraph
|
|
30
29
|
# @return [Parser::AST::Node]
|
31
30
|
attr_reader :node
|
32
31
|
|
33
|
-
# @return [Array<
|
32
|
+
# @return [Hash{Integer => Array<String>}]
|
34
33
|
attr_reader :comments
|
35
34
|
|
36
35
|
# @todo Deprecate?
|
@@ -47,7 +46,8 @@ module Solargraph
|
|
47
46
|
@version = version
|
48
47
|
@domains = []
|
49
48
|
begin
|
50
|
-
@node, @comments = Source.parse_with_comments(@code, filename)
|
49
|
+
# @node, @comments = Source.parse_with_comments(@code, filename)
|
50
|
+
@node, @comments = Solargraph::Parser.parse_with_comments(@code, filename)
|
51
51
|
@parsed = true
|
52
52
|
rescue Parser::SyntaxError, EncodingError => e
|
53
53
|
# @todo 100% whitespace results in a nil node, so there's no reason to parse it.
|
@@ -55,12 +55,12 @@ module Solargraph
|
|
55
55
|
# node with a location that encompasses the range.
|
56
56
|
# @node, @comments = Source.parse_with_comments(@code.gsub(/[^\s]/, ' '), filename)
|
57
57
|
@node = nil
|
58
|
-
@comments =
|
58
|
+
@comments = {}
|
59
59
|
@parsed = false
|
60
|
-
rescue Exception => e
|
61
|
-
|
62
|
-
|
63
|
-
|
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
64
|
ensure
|
65
65
|
@code.freeze
|
66
66
|
end
|
@@ -193,25 +193,41 @@ module Solargraph
|
|
193
193
|
# @param position [Position]
|
194
194
|
# @return [Boolean]
|
195
195
|
def string_at? position
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
inner = node_at(position.line, position.column)
|
204
|
-
next if inner.nil?
|
205
|
-
inner_range = Range.from_node(inner)
|
206
|
-
next unless range.include?(inner_range.ending)
|
207
|
-
return true if inner.type == :str
|
208
|
-
inner_code = at(Solargraph::Range.new(inner_range.start, position))
|
209
|
-
return true if (inner.type == :dstr && inner_range.ending.character <= position.character) && !inner_code.end_with?('}') ||
|
210
|
-
(inner.type != :dstr && inner_range.ending.line == position.line && position.character <= inner_range.ending.character && inner_code.end_with?('}'))
|
196
|
+
if Parser.rubyvm?
|
197
|
+
string_ranges.each do |range|
|
198
|
+
if synchronized?
|
199
|
+
return true if range.include?(position) || range.ending == position
|
200
|
+
else
|
201
|
+
return true if last_updater && last_updater.changes.one? && range.contain?(last_updater.changes.first.range.start)
|
202
|
+
end
|
211
203
|
end
|
212
|
-
|
204
|
+
false
|
205
|
+
else
|
206
|
+
return false if Position.to_offset(code, position) >= code.length
|
207
|
+
string_nodes.each do |node|
|
208
|
+
range = Range.from_node(node)
|
209
|
+
next if range.ending.line < position.line
|
210
|
+
break if range.ending.line > position.line
|
211
|
+
return true if node.type == :str && range.include?(position) && range.start != position
|
212
|
+
return true if [:STR, :str].include?(node.type) && range.include?(position) && range.start != position
|
213
|
+
if node.type == :dstr
|
214
|
+
inner = node_at(position.line, position.column)
|
215
|
+
next if inner.nil?
|
216
|
+
inner_range = Range.from_node(inner)
|
217
|
+
next unless range.include?(inner_range.ending)
|
218
|
+
return true if inner.type == :str
|
219
|
+
inner_code = at(Solargraph::Range.new(inner_range.start, position))
|
220
|
+
return true if (inner.type == :dstr && inner_range.ending.character <= position.character) && !inner_code.end_with?('}') ||
|
221
|
+
(inner.type != :dstr && inner_range.ending.line == position.line && position.character <= inner_range.ending.character && inner_code.end_with?('}'))
|
222
|
+
end
|
223
|
+
break if range.ending.line > position.line
|
224
|
+
end
|
225
|
+
false
|
213
226
|
end
|
214
|
-
|
227
|
+
end
|
228
|
+
|
229
|
+
def string_ranges
|
230
|
+
@string_ranges ||= Parser.string_ranges(node)
|
215
231
|
end
|
216
232
|
|
217
233
|
# @param position [Position]
|
@@ -228,18 +244,7 @@ module Solargraph
|
|
228
244
|
# @param name [String]
|
229
245
|
# @return [Array<Location>]
|
230
246
|
def references name
|
231
|
-
|
232
|
-
offset = Position.to_offset(code, get_node_start_position(n))
|
233
|
-
soff = code.index(name, offset)
|
234
|
-
eoff = soff + name.length
|
235
|
-
Location.new(
|
236
|
-
filename,
|
237
|
-
Range.new(
|
238
|
-
Position.from_offset(code, soff),
|
239
|
-
Position.from_offset(code, eoff)
|
240
|
-
)
|
241
|
-
)
|
242
|
-
end
|
247
|
+
Parser.references self, name
|
243
248
|
end
|
244
249
|
|
245
250
|
# @return [Array<Range>]
|
@@ -250,8 +255,9 @@ module Solargraph
|
|
250
255
|
# @param node [Parser::AST::Node]
|
251
256
|
# @return [String]
|
252
257
|
def code_for(node)
|
253
|
-
|
254
|
-
|
258
|
+
rng = Range.from_node(node)
|
259
|
+
b = Position.line_char_to_offset(@code, rng.start.line, rng.start.column)
|
260
|
+
e = Position.line_char_to_offset(@code, rng.ending.line, rng.ending.column)
|
255
261
|
frag = code[b..e-1].to_s
|
256
262
|
frag.strip.gsub(/,$/, '')
|
257
263
|
end
|
@@ -259,9 +265,10 @@ module Solargraph
|
|
259
265
|
# @param node [Parser::AST::Node]
|
260
266
|
# @return [String]
|
261
267
|
def comments_for node
|
262
|
-
|
263
|
-
|
264
|
-
|
268
|
+
rng = Range.from_node(node)
|
269
|
+
stringified_comments[rng.start.line] ||= begin
|
270
|
+
buff = associated_comments[rng.start.line]
|
271
|
+
buff ? stringify_comment_array(buff) : nil
|
265
272
|
end
|
266
273
|
end
|
267
274
|
|
@@ -275,9 +282,15 @@ module Solargraph
|
|
275
282
|
Location.new(filename, range)
|
276
283
|
end
|
277
284
|
|
278
|
-
FOLDING_NODE_TYPES =
|
279
|
-
|
280
|
-
|
285
|
+
FOLDING_NODE_TYPES = if Parser.rubyvm?
|
286
|
+
%i[
|
287
|
+
CLASS SCLASS MODULE DEFN DEFS IF WHILE UNLESS ITER STR
|
288
|
+
].freeze
|
289
|
+
else
|
290
|
+
%i[
|
291
|
+
class sclass module def defs if str dstr array while unless kwbegin hash block
|
292
|
+
].freeze
|
293
|
+
end
|
281
294
|
|
282
295
|
# Get an array of ranges that can be folded, e.g., the range of a class
|
283
296
|
# definition or an if condition.
|
@@ -305,23 +318,37 @@ module Solargraph
|
|
305
318
|
def associated_comments
|
306
319
|
@associated_comments ||= begin
|
307
320
|
result = {}
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
321
|
+
buffer = String.new('')
|
322
|
+
last = nil
|
323
|
+
@comments.each_pair do |num, snip|
|
324
|
+
if !last || num == last + 1
|
325
|
+
buffer.concat "#{snip.text}\n"
|
326
|
+
else
|
327
|
+
result[first_not_empty_from(last + 1)] = buffer.clone
|
328
|
+
buffer.replace "#{snip.text}\n"
|
329
|
+
end
|
330
|
+
last = num
|
313
331
|
end
|
332
|
+
result[first_not_empty_from(last + 1)] = buffer unless buffer.empty? || last.nil?
|
314
333
|
result
|
315
334
|
end
|
316
335
|
end
|
317
336
|
|
318
337
|
private
|
319
338
|
|
339
|
+
def first_not_empty_from line
|
340
|
+
cursor = line
|
341
|
+
cursor += 1 while cursor < code.lines.length && code.lines[cursor].strip.empty?
|
342
|
+
cursor = line if cursor > code.lines.length
|
343
|
+
cursor
|
344
|
+
end
|
345
|
+
|
320
346
|
# @param top [Parser::AST::Node]
|
321
347
|
# @param result [Array<Range>]
|
322
348
|
# @return [void]
|
323
349
|
def inner_folding_ranges top, result = []
|
324
|
-
return unless top.is_a?(Parser::AST::Node)
|
350
|
+
# return unless top.is_a?(::Parser::AST::Node)
|
351
|
+
return unless Parser.is_ast_node?(top)
|
325
352
|
if FOLDING_NODE_TYPES.include?(top.type)
|
326
353
|
range = Range.from_node(top)
|
327
354
|
if result.empty? || range.start.line > result.last.start.line
|
@@ -335,27 +362,24 @@ module Solargraph
|
|
335
362
|
|
336
363
|
# Get a string representation of an array of comments.
|
337
364
|
#
|
338
|
-
# @param comments [
|
365
|
+
# @param comments [String]
|
339
366
|
# @return [String]
|
340
367
|
def stringify_comment_array comments
|
341
|
-
ctxt = ''
|
342
|
-
num = nil
|
368
|
+
ctxt = String.new('')
|
343
369
|
started = false
|
344
|
-
|
345
|
-
comments.each { |l|
|
370
|
+
skip = nil
|
371
|
+
comments.lines.each { |l|
|
346
372
|
# Trim the comment and minimum leading whitespace
|
347
|
-
p = l.
|
348
|
-
if
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
373
|
+
p = l.gsub(/^#+/, '')
|
374
|
+
if p.strip.empty?
|
375
|
+
next unless started
|
376
|
+
ctxt.concat p
|
377
|
+
else
|
378
|
+
here = p.index(/[^ \t]/)
|
379
|
+
skip = here if skip.nil? || here < skip
|
380
|
+
ctxt.concat p[skip..-1]
|
354
381
|
end
|
355
|
-
|
356
|
-
ctxt += ("\n" * (l.loc.first_line - last_line - 1)) unless last_line.nil? || l.loc.first_line - last_line <= 0
|
357
|
-
ctxt += "#{p[num..-1]}\n" if started
|
358
|
-
last_line = l.loc.last_line if last_line.nil? || l.loc.last_line > last_line
|
382
|
+
started = true
|
359
383
|
}
|
360
384
|
ctxt
|
361
385
|
end
|
@@ -374,9 +398,7 @@ module Solargraph
|
|
374
398
|
|
375
399
|
# @return [Array<Range>]
|
376
400
|
def comment_ranges
|
377
|
-
@comment_ranges ||= @comments.map
|
378
|
-
Range.from_expr(cmnt.loc.expression)
|
379
|
-
end
|
401
|
+
@comment_ranges ||= @comments.values.map(&:range)
|
380
402
|
end
|
381
403
|
|
382
404
|
# Get an array of foldable comment block ranges. Blocks are excluded if
|
@@ -387,25 +409,15 @@ module Solargraph
|
|
387
409
|
return [] unless synchronized?
|
388
410
|
result = []
|
389
411
|
grouped = []
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
result.push Range.from_expr(cmnt.loc.expression)
|
394
|
-
elsif code.lines[cmnt.loc.expression.line].strip.start_with?('#')
|
395
|
-
if grouped.empty? || cmnt.loc.expression.line == grouped.last.loc.expression.line + 1
|
396
|
-
grouped.push cmnt
|
397
|
-
else
|
398
|
-
result.push Range.from_to(grouped.first.loc.expression.line, 0, grouped.last.loc.expression.line, 0) unless grouped.length < 3
|
399
|
-
grouped = [cmnt]
|
400
|
-
end
|
412
|
+
comments.keys.each do |l|
|
413
|
+
if grouped.empty? || l == grouped.last + 1
|
414
|
+
grouped.push l
|
401
415
|
else
|
402
|
-
unless grouped.length < 3
|
403
|
-
|
404
|
-
end
|
405
|
-
grouped.clear
|
416
|
+
result.push Range.from_to(grouped.first, 0, grouped.last, 0) unless grouped.length < 3
|
417
|
+
grouped = [l]
|
406
418
|
end
|
407
419
|
end
|
408
|
-
result.push Range.from_to(grouped.first
|
420
|
+
result.push Range.from_to(grouped.first, 0, grouped.last, 0) unless grouped.length < 3
|
409
421
|
result
|
410
422
|
end
|
411
423
|
|
@@ -413,8 +425,8 @@ module Solargraph
|
|
413
425
|
# @return [Array<Parser::AST::Node>]
|
414
426
|
def string_nodes_in n
|
415
427
|
result = []
|
416
|
-
if
|
417
|
-
if n.type == :str || n.type == :dstr
|
428
|
+
if Parser.is_ast_node?(n)
|
429
|
+
if n.type == :str || n.type == :dstr || n.type == :STR || n.type == :DSTR
|
418
430
|
result.push n
|
419
431
|
else
|
420
432
|
n.children.each{ |c| result.concat string_nodes_in(c) }
|
@@ -429,27 +441,23 @@ module Solargraph
|
|
429
441
|
# @return [void]
|
430
442
|
def inner_tree_at node, position, stack
|
431
443
|
return if node.nil?
|
432
|
-
here = Range.from_to(node.loc.expression.line, node.loc.expression.column, node.loc.expression.last_line, node.loc.expression.last_column)
|
433
|
-
|
444
|
+
# here = Range.from_to(node.loc.expression.line, node.loc.expression.column, node.loc.expression.last_line, node.loc.expression.last_column)
|
445
|
+
here = Range.from_node(node)
|
446
|
+
if here.contain?(position) || colonized(here, position, node)
|
434
447
|
stack.unshift node
|
435
448
|
node.children.each do |c|
|
436
|
-
next unless
|
437
|
-
next if c.loc.expression.nil?
|
449
|
+
next unless Parser.is_ast_node?(c)
|
450
|
+
next if !Parser.rubyvm? && c.loc.expression.nil?
|
438
451
|
inner_tree_at(c, position, stack)
|
439
452
|
end
|
440
453
|
end
|
441
454
|
end
|
442
455
|
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
if top.is_a?(AST::Node) && top.to_s.include?(":#{name}")
|
449
|
-
result.push top if top.children.any? { |c| c.to_s == name }
|
450
|
-
top.children.each { |c| result.concat inner_node_references(name, c) }
|
451
|
-
end
|
452
|
-
result
|
456
|
+
def colonized range, position, node
|
457
|
+
node.type == :COLON2 &&
|
458
|
+
range.ending.line == position.line &&
|
459
|
+
range.ending.character == position.character - 2 &&
|
460
|
+
code[Position.to_offset(code, Position.new(position.line, position.character - 2)), 2] == '::'
|
453
461
|
end
|
454
462
|
|
455
463
|
protected
|
@@ -502,35 +510,6 @@ module Solargraph
|
|
502
510
|
Source.new code, filename, version
|
503
511
|
end
|
504
512
|
|
505
|
-
# @param code [String]
|
506
|
-
# @param filename [String]
|
507
|
-
# @return [Array(Parser::AST::Node, Array<Parser::Source::Comment>)]
|
508
|
-
def parse_with_comments code, filename = nil
|
509
|
-
buffer = Parser::Source::Buffer.new(filename, 0)
|
510
|
-
buffer.source = code
|
511
|
-
parser.parse_with_comments(buffer)
|
512
|
-
end
|
513
|
-
|
514
|
-
# @param code [String]
|
515
|
-
# @param filename [String, nil]
|
516
|
-
# @param line [Integer]
|
517
|
-
# @return [Parser::AST::Node]
|
518
|
-
def parse code, filename = nil, line = 0
|
519
|
-
buffer = Parser::Source::Buffer.new(filename, line)
|
520
|
-
buffer.source = code
|
521
|
-
parser.parse(buffer)
|
522
|
-
end
|
523
|
-
|
524
|
-
# @return [Parser::Base]
|
525
|
-
def parser
|
526
|
-
# @todo Consider setting an instance variable. We might not need to
|
527
|
-
# recreate the parser every time we use it.
|
528
|
-
parser = Parser::CurrentRuby.new(FlawedBuilder.new)
|
529
|
-
parser.diagnostics.all_errors_are_fatal = true
|
530
|
-
parser.diagnostics.ignore_warnings = true
|
531
|
-
parser
|
532
|
-
end
|
533
|
-
|
534
513
|
# @param comments [String]
|
535
514
|
# @return [YARD::DocstringParser]
|
536
515
|
def parse_docstring comments
|