solargraph 0.47.2 → 0.53.3

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.
Files changed (185) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +1 -0
  3. data/.github/workflows/plugins.yml +40 -0
  4. data/.github/workflows/rspec.yml +4 -8
  5. data/.github/workflows/typecheck.yml +34 -0
  6. data/.yardopts +2 -2
  7. data/CHANGELOG.md +137 -3
  8. data/LICENSE +1 -1
  9. data/README.md +19 -16
  10. data/SPONSORS.md +2 -9
  11. data/lib/solargraph/api_map/cache.rb +60 -20
  12. data/lib/solargraph/api_map/source_to_yard.rb +17 -10
  13. data/lib/solargraph/api_map/store.rb +60 -12
  14. data/lib/solargraph/api_map.rb +171 -99
  15. data/lib/solargraph/bench.rb +3 -2
  16. data/lib/solargraph/cache.rb +77 -0
  17. data/lib/solargraph/complex_type/type_methods.rb +61 -12
  18. data/lib/solargraph/complex_type/unique_type.rb +193 -16
  19. data/lib/solargraph/complex_type.rb +113 -10
  20. data/lib/solargraph/convention/rakefile.rb +17 -0
  21. data/lib/solargraph/convention.rb +2 -3
  22. data/lib/solargraph/converters/dd.rb +5 -0
  23. data/lib/solargraph/converters/dl.rb +3 -0
  24. data/lib/solargraph/converters/dt.rb +3 -0
  25. data/lib/solargraph/diagnostics/rubocop.rb +23 -8
  26. data/lib/solargraph/diagnostics/rubocop_helpers.rb +4 -1
  27. data/lib/solargraph/diagnostics/type_check.rb +1 -0
  28. data/lib/solargraph/diagnostics.rb +2 -2
  29. data/lib/solargraph/doc_map.rb +171 -0
  30. data/lib/solargraph/gem_pins.rb +64 -0
  31. data/lib/solargraph/language_server/host/cataloger.rb +2 -1
  32. data/lib/solargraph/language_server/host/diagnoser.rb +2 -2
  33. data/lib/solargraph/language_server/host/dispatch.rb +15 -5
  34. data/lib/solargraph/language_server/host/message_worker.rb +4 -0
  35. data/lib/solargraph/language_server/host/sources.rb +7 -4
  36. data/lib/solargraph/language_server/host.rb +50 -26
  37. data/lib/solargraph/language_server/message/completion_item/resolve.rb +3 -1
  38. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +13 -1
  39. data/lib/solargraph/language_server/message/extended/download_core.rb +1 -5
  40. data/lib/solargraph/language_server/message/initialize.rb +13 -0
  41. data/lib/solargraph/language_server/message/initialized.rb +1 -0
  42. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +4 -1
  43. data/lib/solargraph/language_server/message/text_document/formatting.rb +4 -4
  44. data/lib/solargraph/language_server/message/text_document/hover.rb +2 -0
  45. data/lib/solargraph/language_server/message/text_document/signature_help.rb +1 -6
  46. data/lib/solargraph/language_server/message/text_document/type_definition.rb +24 -0
  47. data/lib/solargraph/language_server/message/text_document.rb +1 -1
  48. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +5 -0
  49. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +10 -3
  50. data/lib/solargraph/language_server/message.rb +1 -0
  51. data/lib/solargraph/language_server/transport/adapter.rb +16 -1
  52. data/lib/solargraph/language_server/transport/data_reader.rb +2 -0
  53. data/lib/solargraph/library.rb +124 -37
  54. data/lib/solargraph/location.rb +1 -0
  55. data/lib/solargraph/page.rb +6 -0
  56. data/lib/solargraph/parser/comment_ripper.rb +4 -0
  57. data/lib/solargraph/parser/node_methods.rb +47 -7
  58. data/lib/solargraph/parser/node_processor/base.rb +9 -0
  59. data/lib/solargraph/parser/{legacy → parser_gem}/class_methods.rb +31 -5
  60. data/lib/solargraph/parser/{legacy → parser_gem}/flawed_builder.rb +3 -1
  61. data/lib/solargraph/parser/{legacy → parser_gem}/node_chainer.rb +57 -41
  62. data/lib/solargraph/parser/parser_gem/node_methods.rb +499 -0
  63. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/alias_node.rb +1 -1
  64. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +53 -0
  65. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/begin_node.rb +1 -1
  66. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/block_node.rb +3 -2
  67. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/casgn_node.rb +14 -4
  68. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/cvasgn_node.rb +1 -1
  69. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/def_node.rb +7 -20
  70. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/defs_node.rb +2 -2
  71. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/gvasgn_node.rb +1 -1
  72. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/ivasgn_node.rb +2 -2
  73. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/lvasgn_node.rb +2 -2
  74. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/namespace_node.rb +2 -2
  75. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/orasgn_node.rb +1 -1
  76. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/resbody_node.rb +3 -3
  77. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +42 -0
  78. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/send_node.rb +2 -2
  79. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/sym_node.rb +1 -1
  80. data/lib/solargraph/parser/parser_gem/node_processors.rb +54 -0
  81. data/lib/solargraph/parser/parser_gem.rb +12 -0
  82. data/lib/solargraph/parser/region.rb +1 -1
  83. data/lib/solargraph/parser/snippet.rb +2 -0
  84. data/lib/solargraph/parser.rb +9 -10
  85. data/lib/solargraph/pin/base.rb +69 -11
  86. data/lib/solargraph/pin/base_variable.rb +8 -4
  87. data/lib/solargraph/pin/block.rb +21 -28
  88. data/lib/solargraph/pin/closure.rb +17 -2
  89. data/lib/solargraph/pin/common.rb +7 -3
  90. data/lib/solargraph/pin/conversions.rb +34 -8
  91. data/lib/solargraph/pin/delegated_method.rb +97 -0
  92. data/lib/solargraph/pin/documenting.rb +25 -34
  93. data/lib/solargraph/pin/instance_variable.rb +4 -0
  94. data/lib/solargraph/pin/local_variable.rb +13 -1
  95. data/lib/solargraph/pin/method.rb +270 -16
  96. data/lib/solargraph/pin/namespace.rb +17 -1
  97. data/lib/solargraph/pin/parameter.rb +52 -17
  98. data/lib/solargraph/pin/reference/override.rb +2 -2
  99. data/lib/solargraph/pin/reference.rb +8 -0
  100. data/lib/solargraph/pin/search.rb +4 -4
  101. data/lib/solargraph/pin/signature.rb +143 -0
  102. data/lib/solargraph/pin.rb +2 -1
  103. data/lib/solargraph/range.rb +4 -6
  104. data/lib/solargraph/rbs_map/conversions.rb +601 -0
  105. data/lib/solargraph/rbs_map/core_fills.rb +47 -0
  106. data/lib/solargraph/rbs_map/core_map.rb +28 -0
  107. data/lib/solargraph/rbs_map/stdlib_map.rb +33 -0
  108. data/lib/solargraph/rbs_map.rb +84 -0
  109. data/lib/solargraph/shell.rb +69 -48
  110. data/lib/solargraph/source/chain/array.rb +32 -0
  111. data/lib/solargraph/source/chain/block_symbol.rb +13 -0
  112. data/lib/solargraph/source/chain/call.rb +125 -61
  113. data/lib/solargraph/source/chain/constant.rb +15 -1
  114. data/lib/solargraph/source/chain/if.rb +23 -0
  115. data/lib/solargraph/source/chain/link.rb +8 -2
  116. data/lib/solargraph/source/chain/or.rb +1 -1
  117. data/lib/solargraph/source/chain/z_super.rb +3 -3
  118. data/lib/solargraph/source/chain.rb +44 -14
  119. data/lib/solargraph/source/change.rb +3 -0
  120. data/lib/solargraph/source/cursor.rb +2 -0
  121. data/lib/solargraph/source/source_chainer.rb +8 -5
  122. data/lib/solargraph/source.rb +18 -19
  123. data/lib/solargraph/source_map/clip.rb +30 -23
  124. data/lib/solargraph/source_map/mapper.rb +20 -5
  125. data/lib/solargraph/source_map.rb +28 -13
  126. data/lib/solargraph/type_checker/checks.rb +10 -2
  127. data/lib/solargraph/type_checker.rb +201 -98
  128. data/lib/solargraph/version.rb +1 -1
  129. data/lib/solargraph/views/environment.erb +2 -2
  130. data/lib/solargraph/workspace/config.rb +14 -11
  131. data/lib/solargraph/workspace.rb +28 -17
  132. data/lib/solargraph/yard_map/cache.rb +6 -0
  133. data/lib/solargraph/yard_map/helpers.rb +1 -1
  134. data/lib/solargraph/yard_map/mapper/to_method.rb +18 -5
  135. data/lib/solargraph/yard_map/mapper.rb +1 -1
  136. data/lib/solargraph/yard_map/to_method.rb +11 -4
  137. data/lib/solargraph/yard_map.rb +1 -443
  138. data/lib/solargraph/yard_tags.rb +20 -0
  139. data/lib/solargraph/yardoc.rb +52 -0
  140. data/lib/solargraph.rb +8 -6
  141. data/solargraph.gemspec +19 -8
  142. metadata +162 -98
  143. data/.travis.yml +0 -19
  144. data/lib/solargraph/api_map/bundler_methods.rb +0 -22
  145. data/lib/solargraph/compat.rb +0 -37
  146. data/lib/solargraph/convention/rspec.rb +0 -30
  147. data/lib/solargraph/documentor.rb +0 -76
  148. data/lib/solargraph/parser/legacy/node_methods.rb +0 -325
  149. data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +0 -23
  150. data/lib/solargraph/parser/legacy/node_processors/args_node.rb +0 -35
  151. data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +0 -15
  152. data/lib/solargraph/parser/legacy/node_processors/def_node.rb +0 -63
  153. data/lib/solargraph/parser/legacy/node_processors/sclass_node.rb +0 -21
  154. data/lib/solargraph/parser/legacy/node_processors.rb +0 -54
  155. data/lib/solargraph/parser/legacy.rb +0 -12
  156. data/lib/solargraph/parser/rubyvm/class_methods.rb +0 -144
  157. data/lib/solargraph/parser/rubyvm/node_chainer.rb +0 -160
  158. data/lib/solargraph/parser/rubyvm/node_methods.rb +0 -315
  159. data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +0 -85
  160. data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +0 -42
  161. data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +0 -22
  162. data/lib/solargraph/parser/rubyvm/node_processors/cvasgn_node.rb +0 -23
  163. data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +0 -57
  164. data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +0 -23
  165. data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +0 -38
  166. data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +0 -39
  167. data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +0 -20
  168. data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +0 -27
  169. data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +0 -39
  170. data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +0 -26
  171. data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +0 -15
  172. data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +0 -45
  173. data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +0 -21
  174. data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +0 -15
  175. data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +0 -277
  176. data/lib/solargraph/parser/rubyvm/node_processors/sym_node.rb +0 -18
  177. data/lib/solargraph/parser/rubyvm/node_processors.rb +0 -63
  178. data/lib/solargraph/parser/rubyvm.rb +0 -40
  179. data/lib/solargraph/yard_map/core_docs.rb +0 -170
  180. data/lib/solargraph/yard_map/core_fills.rb +0 -208
  181. data/lib/solargraph/yard_map/core_gen.rb +0 -76
  182. data/lib/solargraph/yard_map/rdoc_to_yard.rb +0 -140
  183. data/lib/solargraph/yard_map/stdlib_fills.rb +0 -43
  184. data/lib/yard-solargraph.rb +0 -33
  185. data/yardoc/2.2.2.tar.gz +0 -0
@@ -1,54 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'solargraph/parser/node_processor'
4
-
5
- module Solargraph
6
- module Parser
7
- module Legacy
8
- module NodeProcessors
9
- autoload :BeginNode, 'solargraph/parser/legacy/node_processors/begin_node'
10
- autoload :DefNode, 'solargraph/parser/legacy/node_processors/def_node'
11
- autoload :DefsNode, 'solargraph/parser/legacy/node_processors/defs_node'
12
- autoload :SendNode, 'solargraph/parser/legacy/node_processors/send_node'
13
- autoload :NamespaceNode, 'solargraph/parser/legacy/node_processors/namespace_node'
14
- autoload :SclassNode, 'solargraph/parser/legacy/node_processors/sclass_node'
15
- autoload :ModuleNode, 'solargraph/parser/legacy/node_processors/module_node'
16
- autoload :IvasgnNode, 'solargraph/parser/legacy/node_processors/ivasgn_node'
17
- autoload :CvasgnNode, 'solargraph/parser/legacy/node_processors/cvasgn_node'
18
- autoload :LvasgnNode, 'solargraph/parser/legacy/node_processors/lvasgn_node'
19
- autoload :GvasgnNode, 'solargraph/parser/legacy/node_processors/gvasgn_node'
20
- autoload :CasgnNode, 'solargraph/parser/legacy/node_processors/casgn_node'
21
- autoload :AliasNode, 'solargraph/parser/legacy/node_processors/alias_node'
22
- autoload :ArgsNode, 'solargraph/parser/legacy/node_processors/args_node'
23
- autoload :BlockNode, 'solargraph/parser/legacy/node_processors/block_node'
24
- autoload :OrasgnNode, 'solargraph/parser/legacy/node_processors/orasgn_node'
25
- autoload :SymNode, 'solargraph/parser/legacy/node_processors/sym_node'
26
- autoload :ResbodyNode, 'solargraph/parser/legacy/node_processors/resbody_node'
27
- end
28
- end
29
-
30
- module NodeProcessor
31
- register :source, Legacy::NodeProcessors::BeginNode
32
- register :begin, Legacy::NodeProcessors::BeginNode
33
- register :kwbegin, Legacy::NodeProcessors::BeginNode
34
- register :rescue, Legacy::NodeProcessors::BeginNode
35
- register :resbody, Legacy::NodeProcessors::ResbodyNode
36
- register :def, Legacy::NodeProcessors::DefNode
37
- register :defs, Legacy::NodeProcessors::DefsNode
38
- register :send, Legacy::NodeProcessors::SendNode
39
- register :class, Legacy::NodeProcessors::NamespaceNode
40
- register :module, Legacy::NodeProcessors::NamespaceNode
41
- register :sclass, Legacy::NodeProcessors::SclassNode
42
- register :ivasgn, Legacy::NodeProcessors::IvasgnNode
43
- register :cvasgn, Legacy::NodeProcessors::CvasgnNode
44
- register :lvasgn, Legacy::NodeProcessors::LvasgnNode
45
- register :gvasgn, Legacy::NodeProcessors::GvasgnNode
46
- register :casgn, Legacy::NodeProcessors::CasgnNode
47
- register :alias, Legacy::NodeProcessors::AliasNode
48
- register :args, Legacy::NodeProcessors::ArgsNode
49
- register :block, Legacy::NodeProcessors::BlockNode
50
- register :or_asgn, Legacy::NodeProcessors::OrasgnNode
51
- register :sym, Legacy::NodeProcessors::SymNode
52
- end
53
- end
54
- end
@@ -1,12 +0,0 @@
1
- module Solargraph
2
- module Parser
3
- module Legacy
4
- autoload :FlawedBuilder, 'solargraph/parser/legacy/flawed_builder'
5
- autoload :ClassMethods, 'solargraph/parser/legacy/class_methods'
6
- autoload :NodeMethods, 'solargraph/parser/legacy/node_methods'
7
- autoload :NodeChainer, 'solargraph/parser/legacy/node_chainer'
8
- end
9
- end
10
- end
11
-
12
- require 'solargraph/parser/legacy/node_processors'
@@ -1,144 +0,0 @@
1
- require 'solargraph/parser/rubyvm/node_processors'
2
-
3
- module Solargraph
4
- module Parser
5
- module Rubyvm
6
- module ClassMethods
7
- # @param code [String]
8
- # @param filename [String]
9
- # @return [Array(Parser::AST::Node, Array<Parser::Source::Comment>)]
10
- def parse_with_comments code, filename = nil
11
- node = RubyVM::AbstractSyntaxTree.parse(code).children[2]
12
- comments = CommentRipper.new(code).parse
13
- [node, comments]
14
- rescue ::SyntaxError => e
15
- raise Parser::SyntaxError, e.message
16
- end
17
-
18
- # @param code [String]
19
- # @param filename [String, nil]
20
- # @param line [Integer]
21
- # @return [Parser::AST::Node]
22
- def parse code, filename = nil, line = 0
23
- RubyVM::AbstractSyntaxTree.parse(code).children[2]
24
- rescue ::SyntaxError => e
25
- raise Parser::SyntaxError, e.message
26
- end
27
-
28
- def map source
29
- NodeProcessor.process(source.node, Region.new(source: source))
30
- end
31
-
32
- def references source, name
33
- if name.end_with?("=")
34
- reg = /#{Regexp.escape name[0..-2]}\s*=/
35
- extract_offset = ->(code, offset) { reg.match(code, offset).offset(0) }
36
- else
37
- extract_offset = ->(code, offset) { [soff = code.index(name, offset), soff + name.length] }
38
- end
39
- inner_node_references(name, source.node).map do |n|
40
- rng = Range.from_node(n)
41
- offset = Position.to_offset(source.code, rng.start)
42
- soff, eoff = extract_offset[source.code, offset]
43
- Location.new(
44
- source.filename,
45
- Range.new(
46
- Position.from_offset(source.code, soff),
47
- Position.from_offset(source.code, eoff)
48
- )
49
- )
50
- end
51
- end
52
-
53
- # @param name [String]
54
- # @param top [AST::Node]
55
- # @return [Array<AST::Node>]
56
- def inner_node_references name, top
57
- result = []
58
- if Parser.rubyvm?
59
- if Parser.is_ast_node?(top)
60
- result.push top if match_rubyvm_node_to_ref(top, name)
61
- top.children.each { |c| result.concat inner_node_references(name, c) }
62
- end
63
- else
64
- if Parser.is_ast_node?(top) && top.to_s.include?(":#{name}")
65
- result.push top if top.children.any? { |c| c.to_s == name }
66
- top.children.each { |c| result.concat inner_node_references(name, c) }
67
- end
68
- end
69
- result
70
- end
71
-
72
- def match_rubyvm_node_to_ref(top, name)
73
- top.children.select { |c| c.is_a?(Symbol) }.any? { |c| c.to_s == name } ||
74
- top.children.select { |c| c.is_a?(Array) }.any? { |c| c.include?(name.to_sym) }
75
- end
76
-
77
- def chain *args
78
- NodeChainer.chain *args
79
- end
80
-
81
- def chain_string *args
82
- NodeChainer.load_string *args
83
- end
84
-
85
- def process_node *args
86
- Solargraph::Parser::NodeProcessor.process *args
87
- end
88
-
89
- def infer_literal_node_type node
90
- NodeMethods.infer_literal_node_type node
91
- end
92
-
93
- def version
94
- Ruby::VERSION
95
- end
96
-
97
- def is_ast_node? node
98
- if Parser.rubyvm?
99
- node.is_a?(RubyVM::AbstractSyntaxTree::Node)
100
- else
101
- node.is_a?(::Parser::AST::Node)
102
- end
103
- end
104
-
105
- def node_range node
106
- st = Position.new(node.first_lineno - 1, node.first_column)
107
- en = Position.new(node.last_lineno - 1, node.last_column)
108
- Range.new(st, en)
109
- end
110
-
111
- def recipient_node tree
112
- tree.each_with_index do |node, idx|
113
- return tree[idx + 1] if [:ARRAY, :ZARRAY, :LIST].include?(node.type) && tree[idx + 1] && [:FCALL, :VCALL, :CALL].include?(tree[idx + 1].type)
114
- end
115
- nil
116
- end
117
-
118
- def string_ranges node
119
- return [] unless is_ast_node?(node)
120
- result = []
121
- if node.type == :STR
122
- result.push Range.from_node(node)
123
- elsif node.type == :DSTR
124
- here = Range.from_node(node)
125
- there = Range.from_node(node.children[1])
126
- result.push Range.new(here.start, there&.start || here.ending)
127
- end
128
- node.children.each do |child|
129
- result.concat string_ranges(child)
130
- end
131
- if node.type == :DSTR && node.children.last.nil?
132
- last = node.children[-2]
133
- unless last.nil?
134
- rng = Range.from_node(last)
135
- pos = Position.new(rng.ending.line, rng.ending.column - 1)
136
- result.push Range.new(pos, pos)
137
- end
138
- end
139
- result
140
- end
141
- end
142
- end
143
- end
144
- end
@@ -1,160 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- module Parser
5
- module Rubyvm
6
- # A factory for generating chains from nodes.
7
- #
8
- class NodeChainer
9
- include Rubyvm::NodeMethods
10
-
11
- Chain = Source::Chain
12
-
13
- # @param node [Parser::AST::Node]
14
- # @param filename [String]
15
- def initialize node, filename = nil, in_block = false
16
- @node = node
17
- @filename = filename
18
- @in_block = in_block ? 1 : 0
19
- end
20
-
21
- # @return [Source::Chain]
22
- def chain
23
- links = generate_links(@node)
24
- Chain.new(links, @node, (Parser.is_ast_node?(@node) && @node.type == :SPLAT))
25
- end
26
-
27
- class << self
28
- # @param node [Parser::AST::Node]
29
- # @param filename [String]
30
- # @return [Source::Chain]
31
- def chain node, filename = nil, in_block = false
32
- NodeChainer.new(node, filename, in_block).chain
33
- end
34
-
35
- # @param code [String]
36
- # @return [Source::Chain]
37
- def load_string(code)
38
- node = Parser.parse(code.sub(/\.$/, ''))
39
- chain = NodeChainer.new(node).chain
40
- chain.links.push(Chain::Link.new) if code.end_with?('.')
41
- chain
42
- end
43
- end
44
-
45
- private
46
-
47
- # @param n [Parser::AST::Node]
48
- # @return [Array<Chain::Link>]
49
- def generate_links n
50
- return [] unless Parser.is_ast_node?(n)
51
- return generate_links(n.children[2]) if n.type == :SCOPE
52
- return generate_links(n.children[0]) if n.type == :SPLAT
53
- result = []
54
- if n.type == :ITER
55
- @in_block += 1
56
- result.concat generate_links(n.children[0])
57
- @in_block -= 1
58
- elsif n.type == :CALL || n.type == :OPCALL
59
- n.children[0..-3].each do |c|
60
- result.concat generate_links(c)
61
- end
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))
68
- elsif n.type == :ATTRASGN
69
- result.concat generate_links(n.children[0])
70
- result.push Chain::Call.new(n.children[1].to_s, node_to_argchains(n.children[2]), @in_block > 0 || block_passed?(n))
71
- elsif n.type == :VCALL
72
- result.push Chain::Call.new(n.children[0].to_s, [], @in_block > 0 || block_passed?(n))
73
- elsif n.type == :FCALL
74
- result.push Chain::Call.new(n.children[0].to_s, node_to_argchains(n.children[1]), @in_block > 0 || block_passed?(n))
75
- elsif n.type == :SELF
76
- result.push Chain::Head.new('self')
77
- elsif n.type == :ZSUPER
78
- result.push Chain::ZSuper.new('super', @in_block > 0 || block_passed?(n))
79
- elsif n.type == :SUPER
80
- result.push Chain::Call.new('super', node_to_argchains(n.children.last), @in_block > 0 || block_passed?(n))
81
- elsif [:COLON2, :COLON3, :CONST].include?(n.type)
82
- const = unpack_name(n)
83
- result.push Chain::Constant.new(const)
84
- elsif [:LVAR, :LASGN, :DVAR].include?(n.type)
85
- result.push Chain::Call.new(n.children[0].to_s)
86
- elsif [:IVAR, :IASGN].include?(n.type)
87
- result.push Chain::InstanceVariable.new(n.children[0].to_s)
88
- elsif [:CVAR, :CVASGN].include?(n.type)
89
- result.push Chain::ClassVariable.new(n.children[0].to_s)
90
- elsif [:GVAR, :GASGN].include?(n.type)
91
- result.push Chain::GlobalVariable.new(n.children[0].to_s)
92
- elsif n.type == :OP_ASGN_OR
93
- result.concat generate_links n.children[2]
94
- elsif [:class, :module, :def, :defs].include?(n.type)
95
- # @todo Undefined or what?
96
- result.push Chain::UNDEFINED_CALL
97
- elsif n.type == :AND
98
- result.concat generate_links(n.children.last)
99
- elsif n.type == :OR
100
- result.push Chain::Or.new([NodeChainer.chain(n.children[0], @filename), NodeChainer.chain(n.children[1], @filename)])
101
- elsif n.type == :begin
102
- result.concat generate_links(n.children[0])
103
- elsif n.type == :BLOCK_PASS
104
- result.push Chain::BlockVariable.new("&#{n.children[1].children[0].to_s}")
105
- elsif n.type == :HASH
106
- result.push Chain::Hash.new('::Hash', hash_is_splatted?(n))
107
- else
108
- lit = infer_literal_node_type(n)
109
- if lit
110
- if lit == '::Hash'
111
- result.push Chain::Hash.new(lit, hash_is_splatted?(n))
112
- else
113
- result.push Chain::Literal.new(lit)
114
- end
115
- else
116
- result.push Chain::Link.new
117
- end
118
- # result.push (lit ? Chain::Literal.new(lit) : Chain::Link.new)
119
- end
120
- result
121
- end
122
-
123
- def hash_is_splatted? node
124
- return false unless Parser.is_ast_node?(node.children[0]) && node.children[0].type == :LIST
125
- list = node.children[0].children
126
- eol = list.rindex(&:nil?)
127
- eol && Parser.is_ast_node?(list[eol + 1])
128
- end
129
-
130
- def block_passed? node
131
- node.children.last.is_a?(RubyVM::AbstractSyntaxTree::Node) && node.children.last.type == :BLOCK_PASS
132
- end
133
-
134
- def node_to_argchains node
135
- return [] unless Parser.is_ast_node?(node)
136
- if [:ZARRAY, :ARRAY, :LIST].include?(node.type)
137
- node.children[0..-2].map { |c| NodeChainer.chain(c) }
138
- elsif node.type == :SPLAT
139
- [NodeChainer.chain(node)]
140
- elsif node.type == :ARGSPUSH
141
- result = node_to_argchains(node.children[0])
142
- result.push NodeChainer.chain(node.children[1]) if Parser.is_ast_node?(node.children[1])
143
- elsif node.type == :ARGSCAT
144
- result = node.children[0].children[0..-2].map { |c| NodeChainer.chain(c) }
145
- result.push NodeChainer.chain(node.children[1])
146
- # @todo Smelly instance variable access
147
- result.last.instance_variable_set(:@splat, true)
148
- result
149
- elsif node.type == :BLOCK_PASS
150
- result = node_to_argchains(node.children[0])
151
- result.push Chain.new([Chain::BlockVariable.new("&#{node.children[1].children[0].to_s}")])
152
- result
153
- else
154
- []
155
- end
156
- end
157
- end
158
- end
159
- end
160
- end
@@ -1,315 +0,0 @@
1
- module Solargraph
2
- module Parser
3
- module Rubyvm
4
- module NodeMethods
5
- module_function
6
-
7
- # @param node [RubyVM::AbstractSyntaxTree::Node]
8
- # @return [String]
9
- def unpack_name node
10
- pack_name(node).join('::')
11
- end
12
-
13
- # @param node [RubyVM::AbstractSyntaxTree::Node]
14
- # @return [Array<String>]
15
- def pack_name(node)
16
- parts = []
17
- if node.is_a?(RubyVM::AbstractSyntaxTree::Node)
18
- parts.push '' if node.type == :COLON3
19
- node.children.each { |n|
20
- if n.is_a?(RubyVM::AbstractSyntaxTree::Node)
21
- parts += pack_name(n)
22
- else
23
- parts.push n unless n.nil?
24
- end
25
- }
26
- end
27
- parts
28
- end
29
-
30
- # @param node [RubyVM::AbstractSyntaxTree::Node]
31
- # @return [String, nil]
32
- def infer_literal_node_type node
33
- return nil unless Parser.is_ast_node?(node)
34
- case node.type
35
- when :LIT, :STR
36
- "::#{node.children.first.class.to_s}"
37
- when :DSTR
38
- "::String"
39
- when :ARRAY, :ZARRAY, :LIST, :ZLIST
40
- '::Array'
41
- when :HASH
42
- '::Hash'
43
- when :DOT2, :DOT3
44
- '::Range'
45
- when :TRUE, :FALSE
46
- '::Boolean'
47
- when :SCOPE
48
- infer_literal_node_type(node.children[2])
49
- end
50
- end
51
-
52
- def returns_from node
53
- return [] unless Parser.is_ast_node?(node)
54
- if node.type == :SCOPE
55
- # node.children.select { |n| n.is_a?(RubyVM::AbstractSyntaxTree::Node) }.map { |n| DeepInference.get_return_nodes(n) }.flatten
56
- DeepInference.get_return_nodes(node.children[2])
57
- else
58
- DeepInference.get_return_nodes(node)
59
- end
60
- end
61
-
62
- def const_nodes_from node
63
- return [] unless Parser.is_ast_node?(node)
64
- result = []
65
- if [:CONST, :COLON2, :COLON3].include?(node.type)
66
- result.push node
67
- else
68
- node.children.each { |child| result.concat const_nodes_from(child) }
69
- end
70
- result
71
- end
72
-
73
- def call_nodes_from node
74
- return [] unless Parser.is_ast_node?(node)
75
- result = []
76
- if node.type == :ITER
77
- result.push node.children[0]
78
- node.children[1..-1].each { |child| result.concat call_nodes_from(child) }
79
- elsif node.type == :MASGN
80
- # @todo We're treating a mass assignment as a call node, but the
81
- # type checker still needs the logic to handle it.
82
- result.push node
83
- elsif [:CALL, :VCALL, :FCALL, :ATTRASGN, :OPCALL].include?(node.type)
84
- result.push node
85
- node.children.each { |child| result.concat call_nodes_from(child) }
86
- else
87
- node.children.each { |child| result.concat call_nodes_from(child) }
88
- end
89
- result
90
- end
91
-
92
- def convert_hash node
93
- return {} unless node?(node) && node.type == :HASH
94
- return convert_hash(node.children[0].children[1]) if splatted_hash?(node)
95
- return {} unless node?(node.children[0])
96
- result = {}
97
- index = 0
98
- until index > node.children[0].children.length - 2
99
- k = node.children[0].children[index]
100
- return {} unless node?(k)
101
- v = node.children[0].children[index + 1]
102
- result[k.children[0]] = Solargraph::Parser.chain(v)
103
- index += 2
104
- end
105
- result
106
- end
107
-
108
- def splatted_hash? node
109
- splatted_node?(node) && node.children[0].children[1].type == :HASH
110
- end
111
-
112
- def splatted_node? node
113
- node?(node.children[0]) &&
114
- [:ARRAY, :LIST].include?(node.children[0].type) &&
115
- node.children[0].children[0].nil? &&
116
- node?(node.children[0].children[1])
117
- end
118
-
119
- def splatted_call? node
120
- return false unless Parser.is_ast_node?(node)
121
- splatted_node?(node) && node.children[0].children[1].type != :HASH
122
- end
123
-
124
- def any_splatted_call?(nodes)
125
- nodes.any? { |n| splatted_call?(n) }
126
- end
127
-
128
- def node? node
129
- node.is_a?(RubyVM::AbstractSyntaxTree::Node)
130
- end
131
-
132
- # @param cursor [Solargraph::Source::Cursor]
133
- def find_recipient_node cursor
134
- if cursor.source.synchronized?
135
- NodeMethods.synchronized_find_recipient_node cursor
136
- else
137
- NodeMethods.unsynchronized_find_recipient_node cursor
138
- end
139
- end
140
-
141
- class << self
142
- protected
143
-
144
- # @param cursor [Source::Cursor]
145
- # @return [RubyVM::AbstractSyntaxTree::Node, nil]
146
- def synchronized_find_recipient_node cursor
147
- cursor = maybe_adjust_cursor(cursor)
148
- source = cursor.source
149
- position = cursor.position
150
- offset = cursor.offset
151
- tree = source.tree_at(position.line, position.column)
152
- .select { |n| [:FCALL, :VCALL, :CALL].include?(n.type) }
153
- unless source.repaired?
154
- tree.shift while tree.first && !source.code_for(tree.first).strip.end_with?(')')
155
- end
156
- return tree.first if source.repaired? || source.code[0..offset-1] =~ /\(\s*$/
157
- tree.each do |node|
158
- args = node.children.find { |c| Parser.is_ast_node?(c) && [:ARRAY, :ZARRAY, :LIST].include?(c.type) }
159
- if args
160
- match = source.code[0..offset-1].match(/,[^\)]*\z/)
161
- rng = Solargraph::Range.from_node(args)
162
- if match
163
- rng = Solargraph::Range.new(rng.start, position)
164
- end
165
- return node if rng.contain?(position)
166
- end
167
- end
168
- nil
169
- end
170
-
171
- # @param cursor [Source::Cursor]
172
- # @return [Source::Cursor]
173
- def maybe_adjust_cursor cursor
174
- return cursor unless (cursor.source.repaired? && cursor.source.code[cursor.offset - 1] == '(') || [',', ' '].include?(cursor.source.code[cursor.offset - 1])
175
- cursor.source.cursor_at([cursor.position.line, cursor.position.column - 1])
176
- end
177
-
178
- def unsynchronized_find_recipient_node cursor
179
- source = cursor.source
180
- position = cursor.position
181
- offset = cursor.offset
182
- if source.code[0..offset-1] =~ /\([A-Zaz0-9_\s]*\z$/
183
- tree = source.tree_at(position.line, position.column - 1)
184
- if tree.first && [:FCALL, :VCALL, :CALL].include?(tree.first.type)
185
- return tree.first
186
- else
187
- return nil
188
- end
189
- else
190
- match = source.code[0..offset-1].match(/[\(,][A-Zaz0-9_\s]*\z/)
191
- if match
192
- moved = Position.from_offset(source.code, offset - match[0].length)
193
- tree = source.tree_at(moved.line, moved.column)
194
- tree.shift if match[0].start_with?(',')
195
- tree.shift while tree.first && ![:FCALL, :VCALL, :CALL].include?(tree.first.type)
196
- if tree.first && [:FCALL, :VCALL, :CALL].include?(tree.first.type)
197
- return tree.first
198
- end
199
- end
200
- return nil
201
- end
202
- end
203
- end
204
-
205
- module DeepInference
206
- class << self
207
- CONDITIONAL = [:IF, :UNLESS]
208
- REDUCEABLE = [:BLOCK]
209
- SKIPPABLE = [:DEFN, :DEFS, :CLASS, :SCLASS, :MODULE]
210
-
211
- # @param node [Parser::AST::Node]
212
- # @return [Array<Parser::AST::Node>]
213
- def get_return_nodes node
214
- return [] unless node.is_a?(RubyVM::AbstractSyntaxTree::Node)
215
- result = []
216
- if REDUCEABLE.include?(node.type)
217
- result.concat get_return_nodes_from_children(node)
218
- elsif CONDITIONAL.include?(node.type)
219
- result.concat reduce_to_value_nodes(node.children[1..-1])
220
- elsif node.type == :RESCUE
221
- result.concat reduce_to_value_nodes([node.children[0]])
222
- result.concat reduce_to_value_nodes(node.children[1..-2])
223
- elsif node.type == :OR
224
- result.concat reduce_to_value_nodes(node.children)
225
- elsif node.type == :RETURN
226
- result.concat reduce_to_value_nodes([node.children[0]])
227
- elsif node.type == :ITER
228
- result.push node
229
- result.concat get_return_nodes_only(node.children[1])
230
- elsif node.type == :CASE
231
- node.children[1..-1].each do |cc|
232
- result.concat reduce_to_value_nodes(cc.children[1..-1])
233
- end
234
- else
235
- result.push node
236
- end
237
- result
238
- end
239
-
240
- private
241
-
242
- def get_return_nodes_from_children parent
243
- result = []
244
- nodes = parent.children.select{|n| n.is_a?(RubyVM::AbstractSyntaxTree::Node)}
245
- nodes.each_with_index do |node, idx|
246
- if node.type == :BLOCK
247
- result.concat get_return_nodes_only(node.children[2])
248
- elsif SKIPPABLE.include?(node.type)
249
- next
250
- elsif CONDITIONAL.include?(node.type)
251
- result.concat get_return_nodes_only(node)
252
- elsif node.type == :RETURN
253
- result.concat reduce_to_value_nodes([node.children[0]])
254
- # Return the result here because the rest of the code is
255
- # unreachable
256
- return result
257
- else
258
- result.concat get_return_nodes_only(node)
259
- end
260
- result.concat reduce_to_value_nodes([nodes.last]) if idx == nodes.length - 1
261
- end
262
- result
263
- end
264
-
265
- def get_return_nodes_only parent
266
- return [] unless parent.is_a?(RubyVM::AbstractSyntaxTree::Node)
267
- result = []
268
- nodes = parent.children.select{|n| n.is_a?(RubyVM::AbstractSyntaxTree::Node)}
269
- nodes.each do |node|
270
- next if SKIPPABLE.include?(node.type)
271
- if node.type == :RETURN
272
- result.concat reduce_to_value_nodes([node.children[0]])
273
- # Return the result here because the rest of the code is
274
- # unreachable
275
- return result
276
- else
277
- result.concat get_return_nodes_only(node)
278
- end
279
- end
280
- result
281
- end
282
-
283
- def reduce_to_value_nodes nodes
284
- result = []
285
- nodes.each do |node|
286
- if !node.is_a?(RubyVM::AbstractSyntaxTree::Node)
287
- result.push nil
288
- elsif REDUCEABLE.include?(node.type)
289
- result.concat get_return_nodes_from_children(node)
290
- elsif CONDITIONAL.include?(node.type)
291
- result.concat reduce_to_value_nodes(node.children[1..-1])
292
- elsif node.type == :RETURN
293
- if node.children[0].nil?
294
- result.push nil
295
- else
296
- result.concat get_return_nodes(node.children[0])
297
- end
298
- elsif node.type == :OR
299
- result.concat reduce_to_value_nodes(node.children)
300
- elsif node.type == :BLOCK
301
- result.concat get_return_nodes_only(node.children[2])
302
- elsif node.type == :RESBODY
303
- result.concat reduce_to_value_nodes([node.children[1]])
304
- else
305
- result.push node
306
- end
307
- end
308
- result
309
- end
310
- end
311
- end
312
- end
313
- end
314
- end
315
- end