rucoa 0.9.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|