rucoa 0.7.0 → 0.9.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/Gemfile.lock +1 -1
- data/README.md +4 -1
- data/data/definitions_ruby_3_1 +0 -0
- data/lib/rucoa/configuration.rb +10 -0
- data/lib/rucoa/definition_store.rb +194 -27
- data/lib/rucoa/definitions/class_definition.rb +82 -0
- data/lib/rucoa/definitions/constant_definition.rb +7 -7
- data/lib/rucoa/definitions/method_definition.rb +18 -6
- data/lib/rucoa/definitions/module_definition.rb +8 -0
- data/lib/rucoa/definitions.rb +2 -0
- data/lib/rucoa/handlers/initialize_handler.rb +1 -0
- data/lib/rucoa/handlers/initialized_handler.rb +33 -5
- data/lib/rucoa/handlers/text_document_completion_handler.rb +2 -2
- data/lib/rucoa/handlers/text_document_definition_handler.rb +155 -0
- data/lib/rucoa/handlers/text_document_did_open_handler.rb +1 -4
- data/lib/rucoa/handlers/text_document_hover_handler.rb +3 -4
- data/lib/rucoa/handlers.rb +1 -0
- data/lib/rucoa/node_concerns/{name_full_qualifiable.rb → name_fully_qualifiable.rb} +2 -2
- data/lib/rucoa/node_concerns.rb +1 -1
- data/lib/rucoa/node_inspector.rb +56 -34
- data/lib/rucoa/nodes/base.rb +32 -7
- data/lib/rucoa/nodes/casgn_node.rb +1 -1
- data/lib/rucoa/nodes/cbase_node.rb +8 -0
- data/lib/rucoa/nodes/class_node.rb +62 -1
- data/lib/rucoa/nodes/const_node.rb +72 -0
- data/lib/rucoa/nodes/def_node.rb +11 -9
- data/lib/rucoa/nodes/defs_node.rb +21 -0
- data/lib/rucoa/nodes/lvar_node.rb +2 -1
- data/lib/rucoa/nodes/module_node.rb +1 -1
- data/lib/rucoa/nodes/send_node.rb +14 -10
- data/lib/rucoa/nodes.rb +1 -0
- data/lib/rucoa/parse_result.rb +29 -0
- data/lib/rucoa/parser.rb +40 -8
- data/lib/rucoa/parser_builder.rb +1 -0
- data/lib/rucoa/position.rb +1 -1
- data/lib/rucoa/rbs/class_definition_mapper.rb +46 -0
- data/lib/rucoa/rbs/constant_definition_mapper.rb +2 -2
- data/lib/rucoa/rbs/module_definition_mapper.rb +40 -0
- data/lib/rucoa/rbs/ruby_definitions_loader.rb +11 -7
- data/lib/rucoa/rbs.rb +2 -0
- data/lib/rucoa/rubocop/autocorrector.rb +12 -1
- data/lib/rucoa/rubocop/investigator.rb +10 -1
- data/lib/rucoa/server.rb +2 -1
- data/lib/rucoa/source.rb +47 -24
- data/lib/rucoa/source_store.rb +0 -13
- data/lib/rucoa/version.rb +1 -1
- data/lib/rucoa/yard/definitions_loader.rb +320 -48
- data/lib/rucoa/yard/type.rb +46 -0
- data/lib/rucoa/yard.rb +1 -1
- data/lib/rucoa.rb +1 -0
- metadata +11 -4
- data/lib/rucoa/yard/definition_mapper.rb +0 -217
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 237fa68185426d66437c43fc2a3f34f7f85ee7309eb4ed6bb6ce4e31b5dfbb6e
|
4
|
+
data.tar.gz: e9f96daf65c7ccef564b2e06756497fd4d98bd946911487ca2fdd32740436e4b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3698e9db246d46ce64314df9b4a7418278a6e9f65cc2e80dfece624b547c5ab238af42b456370d1096e872f6e30aefdb132b5b2bd435ec03d1e6cccdac0a908a
|
7
|
+
data.tar.gz: 5088d4dcc1fa5ad6e053a155246da87602071fa8283b4f42e1b4e9040b222be5f82622343ad2467b5cdf8003b02293e70ea8d391dc99f478ee36a1389311a9d4
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -62,6 +62,10 @@ This extension supports the folowiing types of symbols:
|
|
62
62
|
|
63
63
|
Provides completion items for constant names and method names.
|
64
64
|
|
65
|
+
### Definition
|
66
|
+
|
67
|
+
Provides "Go to Definition" command to jump to the definition.
|
68
|
+
|
65
69
|
### Hover
|
66
70
|
|
67
71
|
Shows documentation for the symbol under the cursor.
|
@@ -72,6 +76,5 @@ Shows method signature help when you start to type method arguments like `"100".
|
|
72
76
|
|
73
77
|
## Coming soon
|
74
78
|
|
75
|
-
- Go to Definition
|
76
79
|
- Highlight
|
77
80
|
- Semantic Tokens
|
data/data/definitions_ruby_3_1
CHANGED
Binary file
|
data/lib/rucoa/configuration.rb
CHANGED
@@ -16,6 +16,11 @@ module Rucoa
|
|
16
16
|
disable_feature('completion')
|
17
17
|
end
|
18
18
|
|
19
|
+
# @return [void]
|
20
|
+
def disable_definition
|
21
|
+
disable_feature('definition')
|
22
|
+
end
|
23
|
+
|
19
24
|
# @return [void]
|
20
25
|
def disable_diagnostics
|
21
26
|
disable_feature('diagnostics')
|
@@ -82,6 +87,11 @@ module Rucoa
|
|
82
87
|
enables_feature?('completion')
|
83
88
|
end
|
84
89
|
|
90
|
+
# @return [Boolean]
|
91
|
+
def enables_definition?
|
92
|
+
enables_feature?('definition')
|
93
|
+
end
|
94
|
+
|
85
95
|
# @return [Boolean]
|
86
96
|
def enables_diagnostics?
|
87
97
|
enables_feature?('diagnostics')
|
@@ -2,33 +2,152 @@
|
|
2
2
|
|
3
3
|
module Rucoa
|
4
4
|
class DefinitionStore
|
5
|
-
# @return [Array<Rucoa::Definition::Base>]
|
6
|
-
attr_accessor :definitions
|
7
|
-
|
8
5
|
def initialize
|
9
|
-
@
|
6
|
+
@definition_by_full_qualified_name = {}
|
7
|
+
@fully_qualified_names_by_uri = ::Hash.new { |hash, key| hash[key] = [] }
|
10
8
|
end
|
11
9
|
|
12
|
-
# @param
|
13
|
-
# @return [
|
14
|
-
def
|
15
|
-
|
16
|
-
|
10
|
+
# @param definitions [Array<Rucoa::Definition::Base>]
|
11
|
+
# @return [void]
|
12
|
+
def bulk_add(definitions)
|
13
|
+
definitions.each do |definition|
|
14
|
+
@fully_qualified_names_by_uri["file://#{definition.source_path}"] << definition.fully_qualified_name
|
15
|
+
@definition_by_full_qualified_name[definition.fully_qualified_name] = definition
|
16
|
+
end
|
17
17
|
end
|
18
18
|
|
19
|
-
# @param
|
20
|
-
# @return [
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
# @param source [Rucoa::Source]
|
20
|
+
# @return [void]
|
21
|
+
# @example resolves super class name correctly by using existent definitions
|
22
|
+
# definition_store = Rucoa::DefinitionStore.new
|
23
|
+
# foo = Rucoa::Source.new(
|
24
|
+
# content: <<~RUBY,
|
25
|
+
# module A
|
26
|
+
# class Foo
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
# RUBY
|
30
|
+
# uri: 'file:///path/to/a/foo.rb',
|
31
|
+
# )
|
32
|
+
# definition_store.update_from(foo)
|
33
|
+
# bar = Rucoa::Source.new(
|
34
|
+
# content: <<~RUBY,
|
35
|
+
# module A
|
36
|
+
# class Bar < Foo
|
37
|
+
# end
|
38
|
+
# end
|
39
|
+
# RUBY
|
40
|
+
# uri: 'file:///path/to/a/bar.rb',
|
41
|
+
# )
|
42
|
+
# definition_store.update_from(bar)
|
43
|
+
# definition = definition_store.find_definition_by_fully_qualified_name('A::Bar')
|
44
|
+
# expect(definition.super_class_fully_qualified_name).to eq('A::Foo')
|
45
|
+
def update_from(source)
|
46
|
+
delete_definitions_about(source)
|
47
|
+
|
48
|
+
# Need to store definitions before super class resolution.
|
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)
|
24
61
|
end
|
25
62
|
end
|
26
63
|
|
64
|
+
# @param fully_qualified_name [String]
|
65
|
+
# @return [Rucoa::Definitions::Base, nil]
|
66
|
+
def find_definition_by_fully_qualified_name(fully_qualified_name)
|
67
|
+
@definition_by_full_qualified_name[fully_qualified_name]
|
68
|
+
end
|
69
|
+
|
70
|
+
# @param method_name [String]
|
27
71
|
# @param namespace [String]
|
72
|
+
# @param singleton [Boolean]
|
73
|
+
# @return [Rucoa::Definition::MethodDefinition, nil]
|
74
|
+
# @example has the ability to find `IO.write` from `File.write`
|
75
|
+
# definition_store = Rucoa::DefinitionStore.new
|
76
|
+
# definition_store.bulk_add(Rucoa::DefinitionArchiver.load)
|
77
|
+
# subject = definition_store.find_method_definition_by(
|
78
|
+
# method_name: 'write',
|
79
|
+
# namespace: 'File',
|
80
|
+
# singleton: true
|
81
|
+
# )
|
82
|
+
# expect(subject.fully_qualified_name).to eq('IO.write')
|
83
|
+
def find_method_definition_by(method_name:, namespace:, singleton: false)
|
84
|
+
definition = find_definition_by_fully_qualified_name(namespace)
|
85
|
+
return unless definition
|
86
|
+
|
87
|
+
[
|
88
|
+
namespace,
|
89
|
+
*ancestor_definitions_of(definition).map(&:fully_qualified_name)
|
90
|
+
].find do |fully_qualified_name|
|
91
|
+
method_marker = singleton ? '.' : '#'
|
92
|
+
fully_qualified_method_name = [
|
93
|
+
fully_qualified_name,
|
94
|
+
method_marker,
|
95
|
+
method_name
|
96
|
+
].join
|
97
|
+
definition = find_definition_by_fully_qualified_name(fully_qualified_method_name)
|
98
|
+
break definition if definition
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# @param type [String]
|
28
103
|
# @return [Array<Rucoa::Definitions::MethodDefinition>]
|
29
|
-
|
30
|
-
|
31
|
-
|
104
|
+
# @example includes ancestors' methods
|
105
|
+
# definition_store = Rucoa::DefinitionStore.new
|
106
|
+
# definition_store.bulk_add(Rucoa::DefinitionArchiver.load)
|
107
|
+
# subject = definition_store.instance_method_definitions_of('File')
|
108
|
+
# expect(subject.map(&:fully_qualified_name)).to include('IO#raw')
|
109
|
+
# @example responds to `singleton<File>`
|
110
|
+
# definition_store = Rucoa::DefinitionStore.new
|
111
|
+
# definition_store.bulk_add(Rucoa::DefinitionArchiver.load)
|
112
|
+
# subject = definition_store.instance_method_definitions_of('singleton<File>')
|
113
|
+
# expect(subject.map(&:fully_qualified_name)).to include('IO.write')
|
114
|
+
def instance_method_definitions_of(type)
|
115
|
+
singleton_class_name = singleton_class_name_from(type)
|
116
|
+
return singleton_method_definitions_of(singleton_class_name) if singleton_class_name
|
117
|
+
|
118
|
+
class_or_module_definition = find_definition_by_fully_qualified_name(type)
|
119
|
+
return [] unless class_or_module_definition
|
120
|
+
|
121
|
+
definitions = instance_method_definitions
|
122
|
+
[
|
123
|
+
class_or_module_definition,
|
124
|
+
*ancestor_definitions_of(class_or_module_definition)
|
125
|
+
].map(&:fully_qualified_name).flat_map do |fully_qualified_type_name|
|
126
|
+
definitions.select do |definition|
|
127
|
+
definition.namespace == fully_qualified_type_name
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# @param type [String]
|
133
|
+
# @return [Array<Rucoa::Definitions::MethodDefinition>]
|
134
|
+
# @example returns singleton method definitions of File
|
135
|
+
# definition_store = Rucoa::DefinitionStore.new
|
136
|
+
# definition_store.bulk_add(Rucoa::DefinitionArchiver.load)
|
137
|
+
# subject = definition_store.singleton_method_definitions_of('File')
|
138
|
+
# expect(subject.map(&:fully_qualified_name)).to include('IO.write')
|
139
|
+
def singleton_method_definitions_of(type)
|
140
|
+
class_or_module_definition = find_definition_by_fully_qualified_name(type)
|
141
|
+
return [] unless class_or_module_definition
|
142
|
+
|
143
|
+
definitions = singleton_method_definitions
|
144
|
+
[
|
145
|
+
class_or_module_definition,
|
146
|
+
*ancestor_definitions_of(class_or_module_definition)
|
147
|
+
].map(&:fully_qualified_name).flat_map do |fully_qualified_type_name|
|
148
|
+
definitions.select do |definition|
|
149
|
+
definition.namespace == fully_qualified_type_name
|
150
|
+
end
|
32
151
|
end
|
33
152
|
end
|
34
153
|
|
@@ -42,22 +161,70 @@ module Rucoa
|
|
42
161
|
|
43
162
|
private
|
44
163
|
|
45
|
-
# @
|
46
|
-
|
47
|
-
|
164
|
+
# @param source [Rucoa::Source]
|
165
|
+
# @return [void]
|
166
|
+
def delete_definitions_about(source)
|
167
|
+
@fully_qualified_names_by_uri[source.uri].each do |fully_qualified_name|
|
168
|
+
@definition_by_full_qualified_name.delete(fully_qualified_name)
|
169
|
+
end
|
170
|
+
@fully_qualified_names_by_uri.delete(source.uri)
|
171
|
+
end
|
172
|
+
|
173
|
+
# @param type [String]
|
174
|
+
# @return [String, nil]
|
175
|
+
def singleton_class_name_from(type)
|
176
|
+
type[/singleton<(\w+)>/, 1]
|
177
|
+
end
|
178
|
+
|
179
|
+
# @param class_or_module_definition [Rucoa::Definitions::Class, Rucoa::Definitions::Module]
|
180
|
+
# @return [Array<Rucoa::Definitions::Class>]
|
181
|
+
def ancestor_definitions_of(class_or_module_definition)
|
182
|
+
return [] unless class_or_module_definition.is_a?(Definitions::ClassDefinition)
|
183
|
+
|
184
|
+
result = []
|
185
|
+
class_definition = class_or_module_definition
|
186
|
+
while (super_class_fully_qualified_name = class_definition.super_class_fully_qualified_name)
|
187
|
+
class_definition = find_definition_by_fully_qualified_name(super_class_fully_qualified_name)
|
188
|
+
break unless class_definition
|
189
|
+
|
190
|
+
result << class_definition
|
191
|
+
end
|
192
|
+
result
|
193
|
+
end
|
194
|
+
|
195
|
+
# @return [Array<Rucoa::Definitions::Base>]
|
196
|
+
def definitions
|
197
|
+
@definition_by_full_qualified_name.values
|
48
198
|
end
|
49
199
|
|
50
200
|
# @return [Array<Rucoa::Definition::MethodDefinition>]
|
51
201
|
def method_definitions
|
52
|
-
|
202
|
+
definitions.grep(Definitions::MethodDefinition)
|
53
203
|
end
|
54
204
|
|
55
|
-
# @
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
205
|
+
# @return [Array<Rucoa::Definition::MethodDefinition>]
|
206
|
+
def instance_method_definitions
|
207
|
+
method_definitions.select(&:instance_method?)
|
208
|
+
end
|
209
|
+
|
210
|
+
# @return [Array<Rucoa::Definition::MethodDefinition>]
|
211
|
+
def singleton_method_definitions
|
212
|
+
method_definitions.select(&:singleton_method?)
|
213
|
+
end
|
214
|
+
|
215
|
+
# @return [Array<Rucoa::Definition::ConstantDefinition>]
|
216
|
+
def constant_definitions
|
217
|
+
definitions.grep(Definitions::ConstantDefinition)
|
218
|
+
end
|
219
|
+
|
220
|
+
# @param class_definition [Rucoa::Definitions::ClassDefinition]
|
221
|
+
# @return [String]
|
222
|
+
def resolve_super_class_of(class_definition)
|
223
|
+
return 'Object' unless class_definition.super_class_chained_name
|
224
|
+
|
225
|
+
class_definition.super_class_candidates.find do |candidate|
|
226
|
+
find_definition_by_fully_qualified_name(candidate)
|
227
|
+
end || class_definition.super_class_chained_name
|
61
228
|
end
|
62
229
|
end
|
63
230
|
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rucoa
|
4
|
+
module Definitions
|
5
|
+
class ClassDefinition < ModuleDefinition
|
6
|
+
# @return [Arra<String>, nil]
|
7
|
+
attr_reader :module_nesting
|
8
|
+
|
9
|
+
# @return [String, nil]
|
10
|
+
attr_reader :super_class_chained_name
|
11
|
+
|
12
|
+
# @return [String, nil]
|
13
|
+
attr_accessor :super_class_fully_qualified_name
|
14
|
+
|
15
|
+
# @param module_nesting [Array<String>, nil]
|
16
|
+
# @param super_class_chained_name [String, nil]
|
17
|
+
# @param super_class_fully_qualified_name [String, nil]
|
18
|
+
def initialize(
|
19
|
+
module_nesting: nil,
|
20
|
+
super_class_chained_name: nil,
|
21
|
+
super_class_fully_qualified_name: nil,
|
22
|
+
**keyword_arguments
|
23
|
+
)
|
24
|
+
super(**keyword_arguments)
|
25
|
+
@module_nesting = module_nesting
|
26
|
+
@super_class_chained_name = super_class_chained_name
|
27
|
+
@super_class_fully_qualified_name = super_class_fully_qualified_name
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [Boolean]
|
31
|
+
# @example returns false on not-resolved case
|
32
|
+
# definition = Rucoa::Definitions::ClassDefinition.new(
|
33
|
+
# fully_qualified_name: 'Foo',
|
34
|
+
# source_path: '/path/to/foo.rb',
|
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]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -5,23 +5,23 @@ module Rucoa
|
|
5
5
|
# Represents class definition, module definition, or constant assignment.
|
6
6
|
class ConstantDefinition < Base
|
7
7
|
# @return [String]
|
8
|
-
attr_reader :
|
8
|
+
attr_reader :fully_qualified_name
|
9
9
|
|
10
10
|
# @return [String]
|
11
11
|
attr_reader :source_path
|
12
12
|
|
13
|
-
# @param
|
13
|
+
# @param fully_qualified_name [String]
|
14
14
|
# @param source_path [String]
|
15
|
-
def initialize(
|
15
|
+
def initialize(fully_qualified_name:, source_path:)
|
16
16
|
super()
|
17
|
-
@
|
17
|
+
@fully_qualified_name = fully_qualified_name
|
18
18
|
@source_path = source_path
|
19
19
|
end
|
20
20
|
|
21
21
|
# @return [String]
|
22
22
|
# @example returns non-full-qualified name
|
23
23
|
# definition = Rucoa::Definitions::ConstantDefinition.new(
|
24
|
-
#
|
24
|
+
# fully_qualified_name: 'Foo::Bar::Baz',
|
25
25
|
# source_path: '/path/to/foo/bar/baz.rb'
|
26
26
|
# )
|
27
27
|
# expect(definition.name).to eq('Baz')
|
@@ -32,7 +32,7 @@ module Rucoa
|
|
32
32
|
# @return [String]
|
33
33
|
# @example returns namespace
|
34
34
|
# definition = Rucoa::Definitions::ConstantDefinition.new(
|
35
|
-
#
|
35
|
+
# fully_qualified_name: 'Foo::Bar::Baz',
|
36
36
|
# source_path: '/path/to/foo/bar/baz.rb'
|
37
37
|
# )
|
38
38
|
# expect(definition.namespace).to eq('Foo::Bar')
|
@@ -44,7 +44,7 @@ module Rucoa
|
|
44
44
|
|
45
45
|
# @return [Array<String>]
|
46
46
|
def names
|
47
|
-
@names ||=
|
47
|
+
@names ||= fully_qualified_name.split('::')
|
48
48
|
end
|
49
49
|
end
|
50
50
|
end
|
@@ -6,6 +6,9 @@ module Rucoa
|
|
6
6
|
# @return [String, nil]
|
7
7
|
attr_reader :description
|
8
8
|
|
9
|
+
# @return [Symbol]
|
10
|
+
attr_reader :kind
|
11
|
+
|
9
12
|
# @return [String]
|
10
13
|
attr_reader :method_name
|
11
14
|
|
@@ -48,8 +51,8 @@ module Rucoa
|
|
48
51
|
# source_path: '/path/to/foo/bar.rb',
|
49
52
|
# types: []
|
50
53
|
# )
|
51
|
-
# expect(method_definition.
|
52
|
-
def
|
54
|
+
# expect(method_definition.fully_qualified_name).to eq('Foo::Bar#foo')
|
55
|
+
def fully_qualified_name
|
53
56
|
[
|
54
57
|
@namespace,
|
55
58
|
method_kind_symbol,
|
@@ -102,20 +105,29 @@ module Rucoa
|
|
102
105
|
def signatures
|
103
106
|
@types.map do |type|
|
104
107
|
format(
|
105
|
-
'%<
|
106
|
-
|
108
|
+
'%<fully_qualified_name>s(%<parameters>s) -> %<return_types>s',
|
109
|
+
fully_qualified_name: fully_qualified_name,
|
107
110
|
parameters: type.parameters_string,
|
108
111
|
return_types: type.return_type
|
109
112
|
)
|
110
113
|
end
|
111
114
|
end
|
112
115
|
|
116
|
+
# @return [Boolean]
|
117
|
+
def instance_method?
|
118
|
+
@kind == :instance
|
119
|
+
end
|
120
|
+
|
121
|
+
# @return [Boolean]
|
122
|
+
def singleton_method?
|
123
|
+
!instance_method?
|
124
|
+
end
|
125
|
+
|
113
126
|
private
|
114
127
|
|
115
128
|
# @return [String]
|
116
129
|
def method_kind_symbol
|
117
|
-
|
118
|
-
when :instance
|
130
|
+
if instance_method?
|
119
131
|
'#'
|
120
132
|
else
|
121
133
|
'.'
|
data/lib/rucoa/definitions.rb
CHANGED
@@ -3,7 +3,9 @@
|
|
3
3
|
module Rucoa
|
4
4
|
module Definitions
|
5
5
|
autoload :Base, 'rucoa/definitions/base'
|
6
|
+
autoload :ClassDefinition, 'rucoa/definitions/class_definition'
|
6
7
|
autoload :ConstantDefinition, 'rucoa/definitions/constant_definition'
|
7
8
|
autoload :MethodDefinition, 'rucoa/definitions/method_definition'
|
9
|
+
autoload :ModuleDefinition, 'rucoa/definitions/module_definition'
|
8
10
|
end
|
9
11
|
end
|
@@ -7,16 +7,44 @@ module Rucoa
|
|
7
7
|
|
8
8
|
def call
|
9
9
|
request_workspace_configuration
|
10
|
-
|
10
|
+
update_source_store
|
11
|
+
update_definition_store
|
11
12
|
end
|
12
13
|
|
13
14
|
private
|
14
15
|
|
15
16
|
# @return [void]
|
16
|
-
def
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
def update_definition_store
|
18
|
+
sources.each do |source|
|
19
|
+
definition_store.update_from(source)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# @return [void]
|
24
|
+
def update_source_store
|
25
|
+
sources.each do |source|
|
26
|
+
source_store.update(source)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [Array<Rucoa::Source>]
|
31
|
+
def sources
|
32
|
+
@sources ||= pathnames.map do |pathname|
|
33
|
+
Source.new(
|
34
|
+
content: pathname.read,
|
35
|
+
uri: "file://#{pathname}"
|
36
|
+
)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# @return [Array<Pathname>]
|
41
|
+
def pathnames
|
42
|
+
::Pathname.glob(glob)
|
43
|
+
end
|
44
|
+
|
45
|
+
# @return [String]
|
46
|
+
def glob
|
47
|
+
::File.expand_path('{app,lib}/**/*.rb')
|
20
48
|
end
|
21
49
|
end
|
22
50
|
end
|
@@ -148,7 +148,7 @@ module Rucoa
|
|
148
148
|
# @return [Array<String>]
|
149
149
|
def callable_method_definitions
|
150
150
|
receiver_types.flat_map do |type|
|
151
|
-
definition_store.
|
151
|
+
definition_store.instance_method_definitions_of(type)
|
152
152
|
end
|
153
153
|
end
|
154
154
|
|
@@ -163,7 +163,7 @@ module Rucoa
|
|
163
163
|
# @return [Rucoa::Node, nil]
|
164
164
|
def node
|
165
165
|
@node ||=
|
166
|
-
if source.
|
166
|
+
if source.failed_to_parse?
|
167
167
|
repair
|
168
168
|
repaired_node
|
169
169
|
else
|