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.
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