rucoa 0.7.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/README.md +4 -1
  4. data/data/definitions_ruby_3_1 +0 -0
  5. data/lib/rucoa/configuration.rb +10 -0
  6. data/lib/rucoa/definition_store.rb +194 -27
  7. data/lib/rucoa/definitions/class_definition.rb +82 -0
  8. data/lib/rucoa/definitions/constant_definition.rb +7 -7
  9. data/lib/rucoa/definitions/method_definition.rb +18 -6
  10. data/lib/rucoa/definitions/module_definition.rb +8 -0
  11. data/lib/rucoa/definitions.rb +2 -0
  12. data/lib/rucoa/handlers/initialize_handler.rb +1 -0
  13. data/lib/rucoa/handlers/initialized_handler.rb +33 -5
  14. data/lib/rucoa/handlers/text_document_completion_handler.rb +2 -2
  15. data/lib/rucoa/handlers/text_document_definition_handler.rb +155 -0
  16. data/lib/rucoa/handlers/text_document_did_open_handler.rb +1 -4
  17. data/lib/rucoa/handlers/text_document_hover_handler.rb +3 -4
  18. data/lib/rucoa/handlers.rb +1 -0
  19. data/lib/rucoa/node_concerns/{name_full_qualifiable.rb → name_fully_qualifiable.rb} +2 -2
  20. data/lib/rucoa/node_concerns.rb +1 -1
  21. data/lib/rucoa/node_inspector.rb +56 -34
  22. data/lib/rucoa/nodes/base.rb +32 -7
  23. data/lib/rucoa/nodes/casgn_node.rb +1 -1
  24. data/lib/rucoa/nodes/cbase_node.rb +8 -0
  25. data/lib/rucoa/nodes/class_node.rb +62 -1
  26. data/lib/rucoa/nodes/const_node.rb +72 -0
  27. data/lib/rucoa/nodes/def_node.rb +11 -9
  28. data/lib/rucoa/nodes/defs_node.rb +21 -0
  29. data/lib/rucoa/nodes/lvar_node.rb +2 -1
  30. data/lib/rucoa/nodes/module_node.rb +1 -1
  31. data/lib/rucoa/nodes/send_node.rb +14 -10
  32. data/lib/rucoa/nodes.rb +1 -0
  33. data/lib/rucoa/parse_result.rb +29 -0
  34. data/lib/rucoa/parser.rb +40 -8
  35. data/lib/rucoa/parser_builder.rb +1 -0
  36. data/lib/rucoa/position.rb +1 -1
  37. data/lib/rucoa/rbs/class_definition_mapper.rb +46 -0
  38. data/lib/rucoa/rbs/constant_definition_mapper.rb +2 -2
  39. data/lib/rucoa/rbs/module_definition_mapper.rb +40 -0
  40. data/lib/rucoa/rbs/ruby_definitions_loader.rb +11 -7
  41. data/lib/rucoa/rbs.rb +2 -0
  42. data/lib/rucoa/rubocop/autocorrector.rb +12 -1
  43. data/lib/rucoa/rubocop/investigator.rb +10 -1
  44. data/lib/rucoa/server.rb +2 -1
  45. data/lib/rucoa/source.rb +47 -24
  46. data/lib/rucoa/source_store.rb +0 -13
  47. data/lib/rucoa/version.rb +1 -1
  48. data/lib/rucoa/yard/definitions_loader.rb +320 -48
  49. data/lib/rucoa/yard/type.rb +46 -0
  50. data/lib/rucoa/yard.rb +1 -1
  51. data/lib/rucoa.rb +1 -0
  52. metadata +11 -4
  53. data/lib/rucoa/yard/definition_mapper.rb +0 -217
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 48f65475f89a895b8fa3429ddcb5a10738c78e2181a0a0f41a8fe14ec8a2fd17
4
- data.tar.gz: b94bffab0ae35cf83ee0ae5146f41b583abcea4b4192eabcdc8acbcedf3418b4
3
+ metadata.gz: 237fa68185426d66437c43fc2a3f34f7f85ee7309eb4ed6bb6ce4e31b5dfbb6e
4
+ data.tar.gz: e9f96daf65c7ccef564b2e06756497fd4d98bd946911487ca2fdd32740436e4b
5
5
  SHA512:
6
- metadata.gz: 1693536178207fc2740ede4806a8803f140477b312c143e7ad0284875c1685244a09fa33dcd6208e993f4d0acb87284391a605a27e09d8479c71f556cf951d7f
7
- data.tar.gz: d4458ea8223b032e5df2680bfa4f8ed2f939f2971a19db327306a3c6fb6a9a6b3810ffd8ed56346b6e7defb36b916e9054bcb71d031f2494c30b0d6f216995eb
6
+ metadata.gz: 3698e9db246d46ce64314df9b4a7418278a6e9f65cc2e80dfece624b547c5ab238af42b456370d1096e872f6e30aefdb132b5b2bd435ec03d1e6cccdac0a908a
7
+ data.tar.gz: 5088d4dcc1fa5ad6e053a155246da87602071fa8283b4f42e1b4e9040b222be5f82622343ad2467b5cdf8003b02293e70ea8d391dc99f478ee36a1389311a9d4
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rucoa (0.7.0)
4
+ rucoa (0.9.0)
5
5
  parser
6
6
  rbs
7
7
  rubocop
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
Binary file
@@ -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
- @definitions = []
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 source_path [String]
13
- # @return [Array<Rucoa::Definition::Base>]
14
- def update_definitions_defined_in(source_path, definitions:)
15
- delete_definitions_defined_in(source_path)
16
- @definitions += definitions
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 full_qualified_name [String]
20
- # @return [Array<Rucoa::Definitions::Base>]
21
- def select_by_full_qualified_name(full_qualified_name)
22
- @definitions.select do |definition|
23
- definition.full_qualified_name == full_qualified_name
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
- def method_definitions_of(namespace)
30
- method_definitions.select do |method_definition|
31
- method_definition.namespace == namespace
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
- # @return [Array<Rucoa::Definition::ConstantDefinition>]
46
- def constant_definitions
47
- @definitions.grep(Definitions::ConstantDefinition)
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
- @definitions.grep(Definitions::MethodDefinition)
202
+ definitions.grep(Definitions::MethodDefinition)
53
203
  end
54
204
 
55
- # @param source_path [String]
56
- # @return [Array<Rucoa::Definition::Base>]
57
- def delete_definitions_defined_in(source_path)
58
- @definitions.delete_if do |definition|
59
- definition.source_path == source_path
60
- end
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 :full_qualified_name
8
+ attr_reader :fully_qualified_name
9
9
 
10
10
  # @return [String]
11
11
  attr_reader :source_path
12
12
 
13
- # @param full_qualified_name [String]
13
+ # @param fully_qualified_name [String]
14
14
  # @param source_path [String]
15
- def initialize(full_qualified_name:, source_path:)
15
+ def initialize(fully_qualified_name:, source_path:)
16
16
  super()
17
- @full_qualified_name = full_qualified_name
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
- # full_qualified_name: 'Foo::Bar::Baz',
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
- # full_qualified_name: 'Foo::Bar::Baz',
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 ||= full_qualified_name.split('::')
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.full_qualified_name).to eq('Foo::Bar#foo')
52
- def full_qualified_name
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
- '%<full_qualified_name>s(%<parameters>s) -> %<return_types>s',
106
- full_qualified_name: full_qualified_name,
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
- case @kind
118
- when :instance
130
+ if instance_method?
119
131
  '#'
120
132
  else
121
133
  '.'
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module Definitions
5
+ class ModuleDefinition < ConstantDefinition
6
+ end
7
+ end
8
+ end
@@ -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
@@ -13,6 +13,7 @@ module Rucoa
13
13
  .
14
14
  ]
15
15
  },
16
+ definitionProvider: true,
16
17
  documentFormattingProvider: true,
17
18
  documentRangeFormattingProvider: true,
18
19
  documentSymbolProvider: true,
@@ -7,16 +7,44 @@ module Rucoa
7
7
 
8
8
  def call
9
9
  request_workspace_configuration
10
- load_definitions
10
+ update_source_store
11
+ update_definition_store
11
12
  end
12
13
 
13
14
  private
14
15
 
15
16
  # @return [void]
16
- def load_definitions
17
- Yard::DefinitionsLoader.load_globs(
18
- globs: ::YARD::Parser::SourceParser::DEFAULT_PATH_GLOB
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.method_definitions_of(type)
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.syntax_error?
166
+ if source.failed_to_parse?
167
167
  repair
168
168
  repaired_node
169
169
  else