rucoa 0.9.0 → 0.10.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/.rubocop.yml +6 -0
- data/Gemfile.lock +8 -8
- data/data/definitions_ruby_3_1 +0 -0
- data/lib/rucoa/configuration.rb +4 -1
- data/lib/rucoa/definition_store.rb +216 -83
- data/lib/rucoa/definitions/base.rb +14 -3
- data/lib/rucoa/definitions/class_definition.rb +14 -64
- data/lib/rucoa/definitions/constant_definition.rb +31 -19
- data/lib/rucoa/definitions/method_definition.rb +44 -52
- data/lib/rucoa/definitions/method_parameter_definition.rb +4 -1
- data/lib/rucoa/definitions/module_definition.rb +39 -0
- data/lib/rucoa/handler_concerns/diagnostics_publishable.rb +14 -3
- data/lib/rucoa/handlers/base.rb +12 -3
- data/lib/rucoa/handlers/text_document_definition_handler.rb +3 -99
- data/lib/rucoa/handlers/text_document_hover_handler.rb +21 -13
- data/lib/rucoa/handlers/text_document_selection_range_handler.rb +8 -2
- data/lib/rucoa/location.rb +37 -0
- data/lib/rucoa/node_concerns/body.rb +24 -0
- data/lib/rucoa/node_concerns/{name_fully_qualifiable.rb → qualified_name.rb} +2 -2
- data/lib/rucoa/node_concerns.rb +2 -1
- data/lib/rucoa/node_inspector.rb +17 -22
- data/lib/rucoa/nodes/base.rb +22 -6
- data/lib/rucoa/nodes/begin_node.rb +8 -0
- data/lib/rucoa/nodes/casgn_node.rb +1 -1
- data/lib/rucoa/nodes/class_node.rb +2 -1
- data/lib/rucoa/nodes/const_node.rb +33 -15
- data/lib/rucoa/nodes/def_node.rb +2 -2
- data/lib/rucoa/nodes/defs_node.rb +1 -1
- data/lib/rucoa/nodes/module_node.rb +2 -1
- data/lib/rucoa/nodes.rb +2 -1
- data/lib/rucoa/parser.rb +14 -14
- data/lib/rucoa/parser_builder.rb +6 -1
- data/lib/rucoa/position.rb +10 -1
- data/lib/rucoa/range.rb +11 -1
- data/lib/rucoa/rbs/class_definition_mapper.rb +13 -28
- data/lib/rucoa/rbs/constant_definition_mapper.rb +12 -6
- data/lib/rucoa/rbs/method_definition_mapper.rb +12 -6
- data/lib/rucoa/rbs/module_definition_mapper.rb +34 -6
- data/lib/rucoa/rubocop/investigator.rb +4 -1
- data/lib/rucoa/server.rb +8 -2
- data/lib/rucoa/source.rb +19 -4
- data/lib/rucoa/unqualified_name.rb +9 -0
- data/lib/rucoa/version.rb +1 -1
- data/lib/rucoa/yard/definition_generators/attribute_reader_definition_generator.rb +60 -0
- data/lib/rucoa/yard/definition_generators/attribute_writer_definition_generator.rb +60 -0
- data/lib/rucoa/yard/definition_generators/base.rb +117 -0
- data/lib/rucoa/yard/definition_generators/class_definition_generator.rb +66 -0
- data/lib/rucoa/yard/definition_generators/constant_assignment_definition_generator.rb +29 -0
- data/lib/rucoa/yard/definition_generators/method_definition_generator.rb +47 -0
- data/lib/rucoa/yard/definition_generators/module_definition_generator.rb +62 -0
- data/lib/rucoa/yard/definition_generators.rb +15 -0
- data/lib/rucoa/yard/definitions_loader.rb +1 -271
- data/lib/rucoa/yard.rb +1 -0
- data/lib/rucoa.rb +4 -2
- metadata +15 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3344309136313473ea6d4fecd4c57745fb4bc8fc1404c40f7126c0a5d5eef440
|
4
|
+
data.tar.gz: 1bfb57eee21c860f54b8c82452717d987a31bc977a5a7853b6e08b0d486fd5ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4e9efaf6fd608590febfdc450ba487306d35832196f026a77e6ce8b314b78f477a1a79179637153a3977be407ab0f7079ff8bdb23611a0ea2e0f89681bb9637d
|
7
|
+
data.tar.gz: cef07b36f534e390a977f694bf5ce97010b14fce34b990b19742682112a741b17914750e1c8de2e881da03620e8d01bce5d0014bc284b1afc725a0de91a8b88b
|
data/.rubocop.yml
CHANGED
@@ -32,9 +32,15 @@ RSpec/NamedSubject:
|
|
32
32
|
Security/MarshalLoad:
|
33
33
|
Enabled: false
|
34
34
|
|
35
|
+
Sevencop/AutoloadOrdered:
|
36
|
+
Enabled: true
|
37
|
+
|
35
38
|
Sevencop/HashLiteralOrder:
|
36
39
|
Enabled: true
|
37
40
|
|
41
|
+
Sevencop/MethodDefinitionMultilineArguments:
|
42
|
+
Enabled: true
|
43
|
+
|
38
44
|
Style/Documentation:
|
39
45
|
Enabled: false
|
40
46
|
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rucoa (0.
|
4
|
+
rucoa (0.10.0)
|
5
5
|
parser
|
6
6
|
rbs
|
7
7
|
rubocop
|
@@ -27,13 +27,13 @@ GEM
|
|
27
27
|
rspec-mocks (~> 3.11.0)
|
28
28
|
rspec-core (3.11.0)
|
29
29
|
rspec-support (~> 3.11.0)
|
30
|
-
rspec-expectations (3.11.
|
30
|
+
rspec-expectations (3.11.1)
|
31
31
|
diff-lcs (>= 1.2.0, < 2.0)
|
32
32
|
rspec-support (~> 3.11.0)
|
33
33
|
rspec-mocks (3.11.1)
|
34
34
|
diff-lcs (>= 1.2.0, < 2.0)
|
35
35
|
rspec-support (~> 3.11.0)
|
36
|
-
rspec-support (3.11.
|
36
|
+
rspec-support (3.11.1)
|
37
37
|
rubocop (1.36.0)
|
38
38
|
json (~> 2.3)
|
39
39
|
parallel (~> 1.10)
|
@@ -46,17 +46,17 @@ GEM
|
|
46
46
|
unicode-display_width (>= 1.4.0, < 3.0)
|
47
47
|
rubocop-ast (1.21.0)
|
48
48
|
parser (>= 3.1.1.0)
|
49
|
-
rubocop-performance (1.
|
49
|
+
rubocop-performance (1.15.0)
|
50
50
|
rubocop (>= 1.7.0, < 2.0)
|
51
51
|
rubocop-ast (>= 0.4.0)
|
52
52
|
rubocop-rake (0.6.0)
|
53
53
|
rubocop (~> 1.0)
|
54
|
-
rubocop-rspec (2.
|
55
|
-
rubocop (~> 1.
|
54
|
+
rubocop-rspec (2.13.2)
|
55
|
+
rubocop (~> 1.33)
|
56
56
|
ruby-progressbar (1.11.0)
|
57
|
-
sevencop (0.
|
57
|
+
sevencop (0.12.1)
|
58
58
|
rubocop
|
59
|
-
unicode-display_width (2.
|
59
|
+
unicode-display_width (2.3.0)
|
60
60
|
webrick (1.7.0)
|
61
61
|
yard (0.9.28)
|
62
62
|
webrick (~> 1.7.0)
|
data/data/definitions_ruby_3_1
CHANGED
Binary file
|
data/lib/rucoa/configuration.rb
CHANGED
@@ -3,22 +3,29 @@
|
|
3
3
|
module Rucoa
|
4
4
|
class DefinitionStore
|
5
5
|
def initialize
|
6
|
-
@
|
7
|
-
@
|
6
|
+
@definition_by_qualified_name = {}
|
7
|
+
@qualified_names_by_uri = ::Hash.new { |hash, key| hash[key] = [] }
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [String]
|
11
|
+
def inspect
|
12
|
+
"#<#{self.class} definitions_count=#{@definition_by_qualified_name.count}>"
|
8
13
|
end
|
9
14
|
|
10
15
|
# @param definitions [Array<Rucoa::Definition::Base>]
|
11
16
|
# @return [void]
|
12
17
|
def bulk_add(definitions)
|
13
|
-
definitions.
|
14
|
-
|
15
|
-
|
18
|
+
definitions.group_by(&:qualified_name).each_value.map do |grouped_definitions|
|
19
|
+
grouped_definitions.reduce(:merge!)
|
20
|
+
end.each do |definition|
|
21
|
+
@qualified_names_by_uri[definition.location.uri] << definition.qualified_name if definition.location
|
22
|
+
@definition_by_qualified_name[definition.qualified_name] = definition
|
16
23
|
end
|
17
24
|
end
|
18
25
|
|
19
26
|
# @param source [Rucoa::Source]
|
20
27
|
# @return [void]
|
21
|
-
# @example resolves super class name
|
28
|
+
# @example resolves super class name from definitions
|
22
29
|
# definition_store = Rucoa::DefinitionStore.new
|
23
30
|
# foo = Rucoa::Source.new(
|
24
31
|
# content: <<~RUBY,
|
@@ -40,62 +47,134 @@ module Rucoa
|
|
40
47
|
# uri: 'file:///path/to/a/bar.rb',
|
41
48
|
# )
|
42
49
|
# definition_store.update_from(bar)
|
43
|
-
# definition = definition_store.
|
44
|
-
# expect(definition.
|
50
|
+
# definition = definition_store.find_definition_by_qualified_name('A::Bar')
|
51
|
+
# expect(definition.super_class_qualified_name).to eq('A::Foo')
|
52
|
+
# @example resolves included module names from definitions
|
53
|
+
# definition_store = Rucoa::DefinitionStore.new
|
54
|
+
# foo = Rucoa::Source.new(
|
55
|
+
# content: <<~RUBY,
|
56
|
+
# module A
|
57
|
+
# module Foo
|
58
|
+
# end
|
59
|
+
# end
|
60
|
+
# RUBY
|
61
|
+
# uri: 'file:///path/to/a/foo.rb',
|
62
|
+
# )
|
63
|
+
# definition_store.update_from(foo)
|
64
|
+
# bar = Rucoa::Source.new(
|
65
|
+
# content: <<~RUBY,
|
66
|
+
# module A
|
67
|
+
# class Bar
|
68
|
+
# include Foo
|
69
|
+
# end
|
70
|
+
# end
|
71
|
+
# RUBY
|
72
|
+
# uri: 'file:///path/to/a/bar.rb',
|
73
|
+
# )
|
74
|
+
# definition_store.update_from(bar)
|
75
|
+
# definition = definition_store.find_definition_by_qualified_name('A::Bar')
|
76
|
+
# expect(definition.included_module_qualified_names).to eq(%w[A::Foo])
|
45
77
|
def update_from(source)
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
source.definitions.group_by(&:source_path).each do |source_path, definitions|
|
50
|
-
@fully_qualified_names_by_uri["file://#{source_path}"] += definitions.map(&:fully_qualified_name)
|
51
|
-
definitions.each do |definition|
|
52
|
-
@definition_by_full_qualified_name[definition.fully_qualified_name] = definition
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
source.definitions.each do |definition|
|
57
|
-
next unless definition.is_a?(Definitions::ClassDefinition)
|
58
|
-
next if definition.super_class_resolved?
|
59
|
-
|
60
|
-
definition.super_class_fully_qualified_name = resolve_super_class_of(definition)
|
61
|
-
end
|
78
|
+
delete_definitions_in(source)
|
79
|
+
add_definitions_in(source)
|
80
|
+
resolve_constants_in(source)
|
62
81
|
end
|
63
82
|
|
64
|
-
# @param
|
83
|
+
# @param qualified_name [String]
|
65
84
|
# @return [Rucoa::Definitions::Base, nil]
|
66
|
-
def
|
67
|
-
@
|
85
|
+
def find_definition_by_qualified_name(qualified_name)
|
86
|
+
@definition_by_qualified_name[qualified_name]
|
68
87
|
end
|
69
88
|
|
70
89
|
# @param method_name [String]
|
71
90
|
# @param namespace [String]
|
72
91
|
# @param singleton [Boolean]
|
73
92
|
# @return [Rucoa::Definition::MethodDefinition, nil]
|
74
|
-
# @example
|
93
|
+
# @example Supports inheritance
|
94
|
+
# source = Rucoa::Source.new(
|
95
|
+
# content: <<~RUBY,
|
96
|
+
# class A
|
97
|
+
# def foo
|
98
|
+
# end
|
99
|
+
# end
|
100
|
+
#
|
101
|
+
# class B < A
|
102
|
+
# end
|
103
|
+
# RUBY
|
104
|
+
# uri: 'file:///path/to/example.rb'
|
105
|
+
# )
|
75
106
|
# definition_store = Rucoa::DefinitionStore.new
|
76
|
-
# definition_store.
|
107
|
+
# definition_store.update_from(source)
|
77
108
|
# subject = definition_store.find_method_definition_by(
|
78
|
-
# method_name: '
|
79
|
-
# namespace: '
|
80
|
-
# singleton:
|
109
|
+
# method_name: 'foo',
|
110
|
+
# namespace: 'B',
|
111
|
+
# singleton: false
|
81
112
|
# )
|
82
|
-
# expect(subject.
|
83
|
-
|
84
|
-
|
113
|
+
# expect(subject.qualified_name).to eq('A#foo')
|
114
|
+
# @example supports `include`
|
115
|
+
# source = Rucoa::Source.new(
|
116
|
+
# content: <<~RUBY,
|
117
|
+
# module A
|
118
|
+
# def foo
|
119
|
+
# end
|
120
|
+
# end
|
121
|
+
#
|
122
|
+
# class B
|
123
|
+
# include A
|
124
|
+
# end
|
125
|
+
# RUBY
|
126
|
+
# uri: 'file:///path/to/example.rb'
|
127
|
+
# )
|
128
|
+
# definition_store = Rucoa::DefinitionStore.new
|
129
|
+
# definition_store.update_from(source)
|
130
|
+
# subject = definition_store.find_method_definition_by(
|
131
|
+
# method_name: 'foo',
|
132
|
+
# namespace: 'B',
|
133
|
+
# singleton: false
|
134
|
+
# )
|
135
|
+
# expect(subject.qualified_name).to eq('A#foo')
|
136
|
+
# @example supports `prepend`
|
137
|
+
# source = Rucoa::Source.new(
|
138
|
+
# content: <<~RUBY,
|
139
|
+
# module A
|
140
|
+
# def foo
|
141
|
+
# end
|
142
|
+
# end
|
143
|
+
#
|
144
|
+
# class B
|
145
|
+
# prepend A
|
146
|
+
#
|
147
|
+
# def foo
|
148
|
+
# end
|
149
|
+
# end
|
150
|
+
# RUBY
|
151
|
+
# uri: 'file:///path/to/example.rb'
|
152
|
+
# )
|
153
|
+
# definition_store = Rucoa::DefinitionStore.new
|
154
|
+
# definition_store.update_from(source)
|
155
|
+
# subject = definition_store.find_method_definition_by(
|
156
|
+
# method_name: 'foo',
|
157
|
+
# namespace: 'B',
|
158
|
+
# singleton: false
|
159
|
+
# )
|
160
|
+
# expect(subject.qualified_name).to eq('A#foo')
|
161
|
+
def find_method_definition_by(
|
162
|
+
method_name:,
|
163
|
+
namespace:,
|
164
|
+
singleton: false
|
165
|
+
)
|
166
|
+
definition = find_definition_by_qualified_name(namespace)
|
85
167
|
return unless definition
|
86
168
|
|
87
|
-
|
88
|
-
namespace,
|
89
|
-
*ancestor_definitions_of(definition).map(&:fully_qualified_name)
|
90
|
-
].find do |fully_qualified_name|
|
169
|
+
ancestors_of(definition).find do |ancestor|
|
91
170
|
method_marker = singleton ? '.' : '#'
|
92
|
-
|
93
|
-
|
171
|
+
qualified_method_name = [
|
172
|
+
ancestor.qualified_name,
|
94
173
|
method_marker,
|
95
174
|
method_name
|
96
175
|
].join
|
97
|
-
|
98
|
-
break
|
176
|
+
method_definition = find_definition_by_qualified_name(qualified_method_name)
|
177
|
+
break method_definition if method_definition
|
99
178
|
end
|
100
179
|
end
|
101
180
|
|
@@ -105,26 +184,23 @@ module Rucoa
|
|
105
184
|
# definition_store = Rucoa::DefinitionStore.new
|
106
185
|
# definition_store.bulk_add(Rucoa::DefinitionArchiver.load)
|
107
186
|
# subject = definition_store.instance_method_definitions_of('File')
|
108
|
-
# expect(subject.map(&:
|
187
|
+
# expect(subject.map(&:qualified_name)).to include('IO#raw')
|
109
188
|
# @example responds to `singleton<File>`
|
110
189
|
# definition_store = Rucoa::DefinitionStore.new
|
111
190
|
# definition_store.bulk_add(Rucoa::DefinitionArchiver.load)
|
112
191
|
# subject = definition_store.instance_method_definitions_of('singleton<File>')
|
113
|
-
# expect(subject.map(&:
|
192
|
+
# expect(subject.map(&:qualified_name)).to include('IO.write')
|
114
193
|
def instance_method_definitions_of(type)
|
115
194
|
singleton_class_name = singleton_class_name_from(type)
|
116
195
|
return singleton_method_definitions_of(singleton_class_name) if singleton_class_name
|
117
196
|
|
118
|
-
class_or_module_definition =
|
197
|
+
class_or_module_definition = find_definition_by_qualified_name(type)
|
119
198
|
return [] unless class_or_module_definition
|
120
199
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
].map(&:fully_qualified_name).flat_map do |fully_qualified_type_name|
|
126
|
-
definitions.select do |definition|
|
127
|
-
definition.namespace == fully_qualified_type_name
|
200
|
+
method_definitions = instance_method_definitions
|
201
|
+
ancestors_of(class_or_module_definition).flat_map do |ancestor|
|
202
|
+
method_definitions.select do |method_definition|
|
203
|
+
method_definition.namespace == ancestor.qualified_name
|
128
204
|
end
|
129
205
|
end
|
130
206
|
end
|
@@ -135,18 +211,15 @@ module Rucoa
|
|
135
211
|
# definition_store = Rucoa::DefinitionStore.new
|
136
212
|
# definition_store.bulk_add(Rucoa::DefinitionArchiver.load)
|
137
213
|
# subject = definition_store.singleton_method_definitions_of('File')
|
138
|
-
# expect(subject.map(&:
|
214
|
+
# expect(subject.map(&:qualified_name)).to include('IO.write')
|
139
215
|
def singleton_method_definitions_of(type)
|
140
|
-
class_or_module_definition =
|
216
|
+
class_or_module_definition = find_definition_by_qualified_name(type)
|
141
217
|
return [] unless class_or_module_definition
|
142
218
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
].map(&:fully_qualified_name).flat_map do |fully_qualified_type_name|
|
148
|
-
definitions.select do |definition|
|
149
|
-
definition.namespace == fully_qualified_type_name
|
219
|
+
method_definitions = singleton_method_definitions
|
220
|
+
ancestors_of(class_or_module_definition).flat_map do |ancestor|
|
221
|
+
method_definitions.select do |method_definition|
|
222
|
+
method_definition.namespace == ancestor.qualified_name
|
150
223
|
end
|
151
224
|
end
|
152
225
|
end
|
@@ -159,15 +232,27 @@ module Rucoa
|
|
159
232
|
end
|
160
233
|
end
|
161
234
|
|
235
|
+
# @param unqualified_name [Rucoa::UnqualifiedName]
|
236
|
+
# @return [String]
|
237
|
+
def resolve_constant(unqualified_name)
|
238
|
+
(
|
239
|
+
unqualified_name.module_nesting.map do |prefix|
|
240
|
+
"#{prefix}::#{unqualified_name.chained_name}"
|
241
|
+
end + [unqualified_name.chained_name]
|
242
|
+
).find do |candidate|
|
243
|
+
find_definition_by_qualified_name(candidate)
|
244
|
+
end || unqualified_name.chained_name
|
245
|
+
end
|
246
|
+
|
162
247
|
private
|
163
248
|
|
164
249
|
# @param source [Rucoa::Source]
|
165
250
|
# @return [void]
|
166
|
-
def
|
167
|
-
@
|
168
|
-
@
|
251
|
+
def delete_definitions_in(source)
|
252
|
+
@qualified_names_by_uri[source.uri].each do |qualified_name|
|
253
|
+
@definition_by_qualified_name.delete(qualified_name)
|
169
254
|
end
|
170
|
-
@
|
255
|
+
@qualified_names_by_uri.delete(source.uri)
|
171
256
|
end
|
172
257
|
|
173
258
|
# @param type [String]
|
@@ -176,25 +261,49 @@ module Rucoa
|
|
176
261
|
type[/singleton<(\w+)>/, 1]
|
177
262
|
end
|
178
263
|
|
179
|
-
# @param
|
180
|
-
# @return [Array<Rucoa::Definitions::Class>]
|
181
|
-
def
|
182
|
-
|
264
|
+
# @param definition [Rucoa::Definitions::Class, Rucoa::Definitions::Module]
|
265
|
+
# @return [Array<Rucoa::Definitions::Class>] The classes and modules that are traced in method search (as `Module#ancestors` in Ruby)
|
266
|
+
def ancestors_of(definition)
|
267
|
+
if definition.is_a?(Rucoa::Definitions::ClassDefinition)
|
268
|
+
[definition, *super_class_definitions_of(definition)]
|
269
|
+
else
|
270
|
+
[definition]
|
271
|
+
end.flat_map do |base|
|
272
|
+
module_ancestors_of(base)
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
# @param definition [Rucoa::Definitions::Class, Rucoa::Definitions::Module]
|
277
|
+
# @return [Array<Rucoa::Definitions::Class, Rucoa::Definitions::Module>] An array of prepended, itself, and included definitions
|
278
|
+
def module_ancestors_of(definition)
|
279
|
+
[
|
280
|
+
*definition.prepended_module_qualified_names.filter_map do |qualified_name|
|
281
|
+
find_definition_by_qualified_name(qualified_name)
|
282
|
+
end.reverse,
|
283
|
+
definition,
|
284
|
+
*definition.included_module_qualified_names.filter_map do |qualified_name|
|
285
|
+
find_definition_by_qualified_name(qualified_name)
|
286
|
+
end.reverse
|
287
|
+
]
|
288
|
+
end
|
183
289
|
|
290
|
+
# @param definition [Rucoa::Definitions::Class]
|
291
|
+
# @return [Array<Rucoa::Definitions::Class>] super "class"es (not including modules) in closest-first order
|
292
|
+
def super_class_definitions_of(definition)
|
184
293
|
result = []
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
break unless class_definition
|
294
|
+
while (super_class_qualified_name = definition.super_class_qualified_name)
|
295
|
+
super_definition = find_definition_by_qualified_name(super_class_qualified_name)
|
296
|
+
break unless super_definition
|
189
297
|
|
190
|
-
result <<
|
298
|
+
result << super_definition
|
299
|
+
definition = super_definition
|
191
300
|
end
|
192
301
|
result
|
193
302
|
end
|
194
303
|
|
195
304
|
# @return [Array<Rucoa::Definitions::Base>]
|
196
305
|
def definitions
|
197
|
-
@
|
306
|
+
@definition_by_qualified_name.values
|
198
307
|
end
|
199
308
|
|
200
309
|
# @return [Array<Rucoa::Definition::MethodDefinition>]
|
@@ -217,14 +326,38 @@ module Rucoa
|
|
217
326
|
definitions.grep(Definitions::ConstantDefinition)
|
218
327
|
end
|
219
328
|
|
220
|
-
# @param
|
221
|
-
# @return [
|
222
|
-
def
|
223
|
-
|
329
|
+
# @param source [Rucoa::Source]
|
330
|
+
# @return [void]
|
331
|
+
def add_definitions_in(source)
|
332
|
+
source.definitions.group_by do |definition|
|
333
|
+
definition.location.uri
|
334
|
+
end.each do |uri, definitions|
|
335
|
+
@qualified_names_by_uri[uri] += definitions.map(&:qualified_name)
|
336
|
+
definitions.each do |definition|
|
337
|
+
@definition_by_qualified_name[definition.qualified_name] = definition
|
338
|
+
end
|
339
|
+
end
|
340
|
+
end
|
224
341
|
|
225
|
-
|
226
|
-
|
227
|
-
|
342
|
+
# @param source [Rucoa::Source]
|
343
|
+
# @return [void]
|
344
|
+
def resolve_constants_in(source)
|
345
|
+
source.definitions.each do |definition|
|
346
|
+
next unless definition.is_a?(Definitions::ClassDefinition)
|
347
|
+
|
348
|
+
definition.super_class_qualified_name = resolve_constant(definition.super_class_unqualified_name)
|
349
|
+
definition.super_class_unqualified_name = nil
|
350
|
+
|
351
|
+
definition.included_module_qualified_names = definition.included_module_unqualified_names.map do |unqualified_name|
|
352
|
+
resolve_constant(unqualified_name)
|
353
|
+
end
|
354
|
+
definition.included_module_unqualified_names = []
|
355
|
+
|
356
|
+
definition.prepended_module_qualified_names = definition.prepended_module_unqualified_names.map do |unqualified_name|
|
357
|
+
resolve_constant(unqualified_name)
|
358
|
+
end
|
359
|
+
definition.prepended_module_unqualified_names = []
|
360
|
+
end
|
228
361
|
end
|
229
362
|
end
|
230
363
|
end
|
@@ -3,9 +3,20 @@
|
|
3
3
|
module Rucoa
|
4
4
|
module Definitions
|
5
5
|
class Base
|
6
|
-
# @return [String]
|
7
|
-
|
8
|
-
|
6
|
+
# @return [String, nil]
|
7
|
+
attr_reader :description
|
8
|
+
|
9
|
+
# @return [Rucoa::Location, nil]
|
10
|
+
attr_accessor :location
|
11
|
+
|
12
|
+
# @param description [String, nil]
|
13
|
+
# @param location [Rucoa::Location, nil]
|
14
|
+
def initialize(
|
15
|
+
description:,
|
16
|
+
location:
|
17
|
+
)
|
18
|
+
@description = description
|
19
|
+
@location = location
|
9
20
|
end
|
10
21
|
end
|
11
22
|
end
|
@@ -3,79 +3,29 @@
|
|
3
3
|
module Rucoa
|
4
4
|
module Definitions
|
5
5
|
class ClassDefinition < ModuleDefinition
|
6
|
-
# @return [Arra<String>, nil]
|
7
|
-
attr_reader :module_nesting
|
8
|
-
|
9
6
|
# @return [String, nil]
|
10
|
-
|
7
|
+
attr_accessor :super_class_qualified_name
|
11
8
|
|
12
|
-
# @return [
|
13
|
-
attr_accessor :
|
9
|
+
# @return [Rucoa::UnqualifiedName, nil]
|
10
|
+
attr_accessor :super_class_unqualified_name
|
14
11
|
|
15
|
-
# @param
|
16
|
-
# @param
|
17
|
-
# @param super_class_fully_qualified_name [String, nil]
|
12
|
+
# @param super_class_qualified_name [String, nil]
|
13
|
+
# @param super_class_unqualified_name [Rucoa::UnqualifiedName, nil]
|
18
14
|
def initialize(
|
19
|
-
|
20
|
-
|
21
|
-
super_class_fully_qualified_name: nil,
|
15
|
+
super_class_qualified_name: nil,
|
16
|
+
super_class_unqualified_name: nil,
|
22
17
|
**keyword_arguments
|
23
18
|
)
|
24
19
|
super(**keyword_arguments)
|
25
|
-
@
|
26
|
-
@
|
27
|
-
@super_class_fully_qualified_name = super_class_fully_qualified_name
|
20
|
+
@super_class_qualified_name = super_class_qualified_name
|
21
|
+
@super_class_unqualified_name = super_class_unqualified_name
|
28
22
|
end
|
29
23
|
|
30
|
-
# @
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
# super_class_chained_name: 'Bar'
|
36
|
-
# )
|
37
|
-
# expect(definition).not_to be_super_class_resolved
|
38
|
-
# @example returns true on resolved case
|
39
|
-
# definition = Rucoa::Definitions::ClassDefinition.new(
|
40
|
-
# fully_qualified_name: 'Foo',
|
41
|
-
# source_path: '/path/to/foo.rb',
|
42
|
-
# super_class_chained_name: 'Bar',
|
43
|
-
# super_class_fully_qualified_name: 'Bar'
|
44
|
-
# )
|
45
|
-
# expect(definition).to be_super_class_resolved
|
46
|
-
def super_class_resolved?
|
47
|
-
!@super_class_fully_qualified_name.nil?
|
48
|
-
end
|
49
|
-
|
50
|
-
# @return [Array<String>]
|
51
|
-
# @example returns candidates of super class fully qualified name
|
52
|
-
# class_definition = Rucoa::Definitions::ClassDefinition.new(
|
53
|
-
# fully_qualified_name: nil,
|
54
|
-
# module_nesting: %w[B::A B],
|
55
|
-
# source_path: '/path/to/b/a/c.rb',
|
56
|
-
# super_class_chained_name: 'C'
|
57
|
-
# )
|
58
|
-
# expect(class_definition.super_class_candidates).to eq(
|
59
|
-
# %w[B::A::C B::C C]
|
60
|
-
# )
|
61
|
-
# @example returns only correct answer if it's already resolved
|
62
|
-
# class_definition = Rucoa::Definitions::ClassDefinition.new(
|
63
|
-
# fully_qualified_name: 'B::A::C',
|
64
|
-
# source_path: '/path/to/b/a/c.rb',
|
65
|
-
# super_class_fully_qualified_name: 'B::A::C'
|
66
|
-
# )
|
67
|
-
# expect(class_definition.super_class_candidates).to eq(
|
68
|
-
# %w[B::A::C]
|
69
|
-
# )
|
70
|
-
def super_class_candidates
|
71
|
-
return [super_class_fully_qualified_name] if super_class_resolved?
|
72
|
-
|
73
|
-
module_nesting.map do |chained_name|
|
74
|
-
[
|
75
|
-
chained_name,
|
76
|
-
super_class_chained_name
|
77
|
-
].join('::')
|
78
|
-
end + [super_class_chained_name]
|
24
|
+
# @param other [Rucoa::Definitions::ClassDefinition]
|
25
|
+
def merge!(other)
|
26
|
+
self.super_class_qualified_name ||= other.super_class_qualified_name
|
27
|
+
self.super_class_unqualified_name ||= other.super_class_unqualified_name
|
28
|
+
super
|
79
29
|
end
|
80
30
|
end
|
81
31
|
end
|