rucoa 0.9.0 → 0.11.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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +9 -0
  3. data/Gemfile.lock +8 -8
  4. data/data/definitions_ruby_3_1 +0 -0
  5. data/lib/rucoa/configuration.rb +4 -1
  6. data/lib/rucoa/definition_store.rb +350 -105
  7. data/lib/rucoa/definitions/base.rb +14 -3
  8. data/lib/rucoa/definitions/class_definition.rb +14 -64
  9. data/lib/rucoa/definitions/constant_definition.rb +31 -19
  10. data/lib/rucoa/definitions/method_definition.rb +44 -52
  11. data/lib/rucoa/definitions/method_parameter_definition.rb +4 -1
  12. data/lib/rucoa/definitions/module_definition.rb +53 -0
  13. data/lib/rucoa/handler_concerns/diagnostics_publishable.rb +14 -3
  14. data/lib/rucoa/handlers/base.rb +12 -3
  15. data/lib/rucoa/handlers/text_document_definition_handler.rb +3 -99
  16. data/lib/rucoa/handlers/text_document_hover_handler.rb +21 -13
  17. data/lib/rucoa/handlers/text_document_selection_range_handler.rb +8 -2
  18. data/lib/rucoa/location.rb +37 -0
  19. data/lib/rucoa/node_concerns/body.rb +24 -0
  20. data/lib/rucoa/node_concerns/{name_fully_qualifiable.rb → qualified_name.rb} +2 -2
  21. data/lib/rucoa/node_concerns.rb +2 -1
  22. data/lib/rucoa/node_inspector.rb +29 -23
  23. data/lib/rucoa/nodes/base.rb +22 -6
  24. data/lib/rucoa/nodes/begin_node.rb +8 -0
  25. data/lib/rucoa/nodes/casgn_node.rb +1 -1
  26. data/lib/rucoa/nodes/class_node.rb +2 -1
  27. data/lib/rucoa/nodes/const_node.rb +33 -15
  28. data/lib/rucoa/nodes/def_node.rb +2 -2
  29. data/lib/rucoa/nodes/defs_node.rb +1 -1
  30. data/lib/rucoa/nodes/module_node.rb +2 -1
  31. data/lib/rucoa/nodes.rb +2 -1
  32. data/lib/rucoa/parser.rb +14 -14
  33. data/lib/rucoa/parser_builder.rb +6 -1
  34. data/lib/rucoa/position.rb +10 -1
  35. data/lib/rucoa/range.rb +11 -1
  36. data/lib/rucoa/rbs/class_definition_mapper.rb +14 -28
  37. data/lib/rucoa/rbs/constant_definition_mapper.rb +12 -6
  38. data/lib/rucoa/rbs/method_definition_mapper.rb +12 -6
  39. data/lib/rucoa/rbs/module_definition_mapper.rb +39 -6
  40. data/lib/rucoa/rubocop/investigator.rb +4 -1
  41. data/lib/rucoa/server.rb +9 -3
  42. data/lib/rucoa/source.rb +19 -4
  43. data/lib/rucoa/unqualified_name.rb +9 -0
  44. data/lib/rucoa/version.rb +1 -1
  45. data/lib/rucoa/yard/definition_generators/attribute_reader_definition_generator.rb +76 -0
  46. data/lib/rucoa/yard/definition_generators/attribute_writer_definition_generator.rb +76 -0
  47. data/lib/rucoa/yard/definition_generators/base.rb +117 -0
  48. data/lib/rucoa/yard/definition_generators/class_definition_generator.rb +67 -0
  49. data/lib/rucoa/yard/definition_generators/constant_assignment_definition_generator.rb +29 -0
  50. data/lib/rucoa/yard/definition_generators/method_definition_generator.rb +60 -0
  51. data/lib/rucoa/yard/definition_generators/module_definition_generator.rb +68 -0
  52. data/lib/rucoa/yard/definition_generators.rb +15 -0
  53. data/lib/rucoa/yard/definitions_loader.rb +1 -271
  54. data/lib/rucoa/yard.rb +1 -0
  55. data/lib/rucoa.rb +4 -2
  56. metadata +15 -3
@@ -19,21 +19,54 @@ module Rucoa
19
19
  # @return [Rucoa::Definitions::ModuleDefinition]
20
20
  def call
21
21
  Definitions::ModuleDefinition.new(
22
- fully_qualified_name: fully_qualified_name,
23
- source_path: source_path
22
+ description: description,
23
+ extended_module_qualified_names: extended_module_qualified_names,
24
+ included_module_qualified_names: included_module_qualified_names,
25
+ location: location,
26
+ prepended_module_qualified_names: prepended_module_qualified_names,
27
+ qualified_name: qualified_name
24
28
  )
25
29
  end
26
30
 
27
31
  private
28
32
 
33
+ # @return [String, nil]
34
+ def description
35
+ @declaration.comment&.string&.sub(/\A\s*<!--.*-->\s*/m, '')
36
+ end
37
+
29
38
  # @return [String]
30
- def fully_qualified_name
39
+ def qualified_name
31
40
  @declaration.name.to_s.delete_prefix('::')
32
41
  end
33
42
 
34
- # @return [String]
35
- def source_path
36
- @declaration.location.name
43
+ # @return [Rucoa::Location]
44
+ def location
45
+ Location.from_rbs_location(@declaration.location)
46
+ end
47
+
48
+ # @return [Array<String>]
49
+ def extended_module_qualified_names
50
+ module_qualified_names_for(::RBS::AST::Members::Extend)
51
+ end
52
+
53
+ # @return [Array<String>]
54
+ def included_module_qualified_names
55
+ module_qualified_names_for(::RBS::AST::Members::Include)
56
+ end
57
+
58
+ # @return [Array<String>]
59
+ def prepended_module_qualified_names
60
+ module_qualified_names_for(::RBS::AST::Members::Prepend)
61
+ end
62
+
63
+ def module_qualified_names_for(member_class)
64
+ @declaration.members.filter_map do |member|
65
+ case member
66
+ when member_class
67
+ member.name.to_s.delete_prefix('::')
68
+ end
69
+ end
37
70
  end
38
71
  end
39
72
  end
@@ -41,7 +41,10 @@ module Rucoa
41
41
  # @param file [String]
42
42
  # @param offenses [Array<RuboCop::Cop::Offense>]
43
43
  # @return [void]
44
- def file_finished(file, offenses)
44
+ def file_finished(
45
+ file,
46
+ offenses
47
+ )
45
48
  @offenses = offenses
46
49
  super
47
50
  end
data/lib/rucoa/server.rb CHANGED
@@ -43,8 +43,8 @@ module Rucoa
43
43
  # @param io_in [IO]
44
44
  # @param io_out [IO]
45
45
  def initialize(
46
- io_log: ::StringIO.new,
47
46
  io_in: ::StringIO.new,
47
+ io_log: ::StringIO.new,
48
48
  io_out: ::StringIO.new
49
49
  )
50
50
  @logger = ::Logger.new(io_log)
@@ -83,7 +83,10 @@ module Rucoa
83
83
  # @yieldparam response [Hash]
84
84
  # @param message [Hash]
85
85
  # @return [void]
86
- def write(message, &block)
86
+ def write(
87
+ message,
88
+ &block
89
+ )
87
90
  if block
88
91
  write_server_request(message, &block)
89
92
  else
@@ -139,7 +142,10 @@ module Rucoa
139
142
 
140
143
  # @param message [Hash]
141
144
  # @return [void]
142
- def write_server_request(message, &block)
145
+ def write_server_request(
146
+ message,
147
+ &block
148
+ )
143
149
  message = message.merge('id' => @server_request_id)
144
150
  debug do
145
151
  {
data/lib/rucoa/source.rb CHANGED
@@ -12,7 +12,10 @@ module Rucoa
12
12
 
13
13
  # @param content [String]
14
14
  # @param uri [String]
15
- def initialize(content:, uri:)
15
+ def initialize(
16
+ content:,
17
+ uri:
18
+ )
16
19
  @content = content
17
20
  @uri = uri
18
21
  end
@@ -35,9 +38,21 @@ module Rucoa
35
38
  # a_kind_of(Rucoa::Definitions::MethodDefinition)
36
39
  # ]
37
40
  # )
41
+ # @example returns empty array when failed to parse
42
+ # source = Rucoa::Source.new(
43
+ # content: 'class Foo',
44
+ # uri: 'file:///path/to/foo.rb'
45
+ # )
46
+ # expect(source.definitions).to eq([])
47
+ # @example returns empty array when no node is found from content
48
+ # source = Rucoa::Source.new(
49
+ # content: '',
50
+ # uri: 'file:///path/to/foo.rb'
51
+ # )
52
+ # expect(source.definitions).to eq([])
38
53
  def definitions
39
54
  @definitions ||=
40
- if parse_result.failed?
55
+ if parse_result.failed? || root_node.nil?
41
56
  []
42
57
  else
43
58
  Yard::DefinitionsLoader.call(
@@ -98,8 +113,8 @@ module Rucoa
98
113
  return @parse_result if instance_variable_defined?(:@parse_result)
99
114
 
100
115
  @parse_result = Parser.call(
101
- path: name,
102
- text: @content
116
+ text: @content,
117
+ uri: @uri
103
118
  )
104
119
  end
105
120
 
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ UnqualifiedName = ::Struct.new(
5
+ :chained_name,
6
+ :module_nesting,
7
+ keyword_init: true
8
+ )
9
+ end
data/lib/rucoa/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rucoa
4
- VERSION = '0.9.0'
4
+ VERSION = '0.11.0'
5
5
  end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module Yard
5
+ module DefinitionGenerators
6
+ class AttributeReaderDefinitionGenerator < Base
7
+ READER_METHOD_NAMES = ::Set[
8
+ 'attr_accessor',
9
+ 'attr_reader'
10
+ ].freeze
11
+
12
+ # @example returns method definition for attr_reader node
13
+ # definitions = Rucoa::Source.new(
14
+ # content: <<~RUBY,
15
+ # class Foo
16
+ # attr_reader :bar
17
+ # end
18
+ # RUBY
19
+ # uri: '/path/to/foo.rb'
20
+ # ).definitions
21
+ # expect(definitions[1]).to be_a(Rucoa::Definitions::MethodDefinition)
22
+ # @example returns method definition for attr_accessor node
23
+ # definitions = Rucoa::Source.new(
24
+ # content: <<~RUBY,
25
+ # class Foo
26
+ # attr_accessor :bar
27
+ # end
28
+ # RUBY
29
+ # uri: '/path/to/foo.rb'
30
+ # ).definitions
31
+ # expect(definitions.map(&:qualified_name)).to eq(
32
+ # %w[
33
+ # Foo
34
+ # Foo#bar
35
+ # Foo#bar=
36
+ # ]
37
+ # )
38
+ # @example ignores unrecognizable attributes
39
+ # definitions = Rucoa::Source.new(
40
+ # content: <<~RUBY,
41
+ # class Foo
42
+ # attr_reader foo
43
+ # end
44
+ # RUBY
45
+ # uri: '/path/to/foo.rb'
46
+ # ).definitions
47
+ # expect(definitions.map(&:qualified_name)).to eq(
48
+ # %w[
49
+ # Foo
50
+ # ]
51
+ # )
52
+ def call
53
+ return [] unless @node.is_a?(Nodes::SendNode) && READER_METHOD_NAMES.include?(@node.name)
54
+
55
+ @node.arguments.filter_map do |argument|
56
+ next unless argument.respond_to?(:value)
57
+
58
+ Definitions::MethodDefinition.new(
59
+ description: description,
60
+ kind: :instance,
61
+ location: location,
62
+ method_name: argument.value.to_s,
63
+ namespace: @node.namespace,
64
+ types: return_types.map do |type|
65
+ Types::MethodType.new(
66
+ parameters_string: '', # TODO
67
+ return_type: type
68
+ )
69
+ end
70
+ )
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module Yard
5
+ module DefinitionGenerators
6
+ class AttributeWriterDefinitionGenerator < Base
7
+ WRITER_METHOD_NAMES = ::Set[
8
+ 'attr_accessor',
9
+ 'attr_writer'
10
+ ].freeze
11
+
12
+ # @example returns method definition for attr_writer node
13
+ # definitions = Rucoa::Source.new(
14
+ # content: <<~RUBY,
15
+ # class Foo
16
+ # attr_writer :bar
17
+ # end
18
+ # RUBY
19
+ # uri: '/path/to/foo.rb'
20
+ # ).definitions
21
+ # expect(definitions[1]).to be_a(Rucoa::Definitions::MethodDefinition)
22
+ # @example returns method definition for attr_accessor node
23
+ # definitions = Rucoa::Source.new(
24
+ # content: <<~RUBY,
25
+ # class Foo
26
+ # attr_accessor :bar
27
+ # end
28
+ # RUBY
29
+ # uri: '/path/to/foo.rb'
30
+ # ).definitions
31
+ # expect(definitions.map(&:qualified_name)).to eq(
32
+ # %w[
33
+ # Foo
34
+ # Foo#bar
35
+ # Foo#bar=
36
+ # ]
37
+ # )
38
+ # @example ignores unrecognizable attributes
39
+ # definitions = Rucoa::Source.new(
40
+ # content: <<~RUBY,
41
+ # class Foo
42
+ # attr_writer foo
43
+ # end
44
+ # RUBY
45
+ # uri: '/path/to/foo.rb'
46
+ # ).definitions
47
+ # expect(definitions.map(&:qualified_name)).to eq(
48
+ # %w[
49
+ # Foo
50
+ # ]
51
+ # )
52
+ def call
53
+ return [] unless @node.is_a?(Nodes::SendNode) && WRITER_METHOD_NAMES.include?(@node.name)
54
+
55
+ @node.arguments.filter_map do |argument|
56
+ next unless argument.respond_to?(:value)
57
+
58
+ Definitions::MethodDefinition.new(
59
+ description: description,
60
+ kind: :instance,
61
+ location: location,
62
+ method_name: "#{argument.value}=",
63
+ namespace: @node.namespace,
64
+ types: return_types.map do |type|
65
+ Types::MethodType.new(
66
+ parameters_string: 'value', # TODO
67
+ return_type: type
68
+ )
69
+ end
70
+ )
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module Yard
5
+ module DefinitionGenerators
6
+ class Base
7
+ class << self
8
+ # @param comment [String]
9
+ # @param node [Rucoa::Nodes::Base]
10
+ # @return [Array<Rucoa::Definitions::Base>]
11
+ def call(
12
+ comment:,
13
+ node:
14
+ )
15
+ new(
16
+ comment: comment,
17
+ node: node
18
+ ).call
19
+ end
20
+ end
21
+
22
+ # @param comment [String]
23
+ # @param node [Rucoa::Nodes::Base]
24
+ def initialize(
25
+ comment:,
26
+ node:
27
+ )
28
+ @comment = comment
29
+ @node = node
30
+ end
31
+
32
+ # @return [Array<Rucoa::Definitions::Base>]
33
+ def call
34
+ raise ::NotImplementedError
35
+ end
36
+
37
+ private
38
+
39
+ # @return [String]
40
+ def description
41
+ docstring_parser.to_docstring.to_s
42
+ end
43
+
44
+ # @return [YARD::DocstringParser]
45
+ def docstring_parser
46
+ @docstring_parser ||= ::YARD::Logger.instance.enter_level(::Logger::FATAL) do
47
+ ::YARD::Docstring.parser.parse(
48
+ @comment,
49
+ ::YARD::CodeObjects::Base.new(:root, 'stub')
50
+ )
51
+ end
52
+ end
53
+
54
+ # @return [Rucoa::Location]
55
+ # @example returns source uri and entire range of target node
56
+ # definitions = Rucoa::Source.new(
57
+ # content: <<~RUBY,
58
+ # class Foo
59
+ # end
60
+ # RUBY
61
+ # uri: '/path/to/foo.rb'
62
+ # ).definitions
63
+ # expect(definitions[0].location).to eq(
64
+ # Rucoa::Location.new(
65
+ # range: Rucoa::Range.new(
66
+ # Rucoa::Position.new(
67
+ # column: 0,
68
+ # line: 1
69
+ # ),
70
+ # Rucoa::Position.new(
71
+ # column: 3,
72
+ # line: 2
73
+ # )
74
+ # ),
75
+ # uri: '/path/to/foo.rb'
76
+ # )
77
+ # )
78
+ def location
79
+ Location.from_rucoa_node(@node)
80
+ end
81
+
82
+ # @return [Array<String>]
83
+ # @example returns annotated return types if return tag is provided
84
+ # definitions = Rucoa::Source.new(
85
+ # content: <<~RUBY,
86
+ # # @return [String]
87
+ # def foo
88
+ # end
89
+ # RUBY
90
+ # uri: '/path/to/foo.rb'
91
+ # ).definitions
92
+ # expect(definitions[0].return_types).to eq(%w[String])
93
+ # @example returns Object if no return tag is provided
94
+ # definitions = Rucoa::Source.new(
95
+ # content: <<~RUBY,
96
+ # def foo
97
+ # end
98
+ # RUBY
99
+ # uri: '/path/to/foo.rb'
100
+ # ).definitions
101
+ # expect(definitions[0].return_types).to eq(%w[Object])
102
+ def return_types
103
+ types = docstring_parser.tags.select do |tag|
104
+ tag.tag_name == 'return'
105
+ end.flat_map(&:types).compact.map do |yard_type|
106
+ Type.new(yard_type).to_rucoa_type
107
+ end
108
+ if types.empty?
109
+ %w[Object]
110
+ else
111
+ types
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module Yard
5
+ module DefinitionGenerators
6
+ class ClassDefinitionGenerator < ModuleDefinitionGenerator
7
+ # @example returns class definition for class node
8
+ # definitions = Rucoa::Source.new(
9
+ # content: <<~RUBY,
10
+ # class Foo
11
+ # end
12
+ # RUBY
13
+ # uri: '/path/to/foo.rb'
14
+ # ).definitions
15
+ # expect(definitions[0]).to be_a(Rucoa::Definitions::ClassDefinition)
16
+ # @example detects single-argument include
17
+ # definitions = Rucoa::Source.new(
18
+ # content: <<~RUBY,
19
+ # class Foo
20
+ # include Bar
21
+ # end
22
+ # RUBY
23
+ # uri: '/path/to/foo.rb'
24
+ # ).definitions
25
+ # expect(definitions[0].included_module_unqualified_names.map(&:chained_name)).to eq(%w[Bar])
26
+ # @example detects multi-arguments include
27
+ # definitions = Rucoa::Source.new(
28
+ # content: <<~RUBY,
29
+ # class Foo
30
+ # include Bar, Baz
31
+ # end
32
+ # RUBY
33
+ # uri: '/path/to/foo.rb'
34
+ # ).definitions
35
+ # expect(definitions[0].included_module_unqualified_names.map(&:chained_name)).to eq(%w[Bar Baz])
36
+ # @example ignores non-simple include
37
+ # definitions = Rucoa::Source.new(
38
+ # content: <<~RUBY,
39
+ # class Foo
40
+ # include foo
41
+ # end
42
+ # RUBY
43
+ # uri: '/path/to/foo.rb'
44
+ # ).definitions
45
+ # expect(definitions[0].included_module_unqualified_names.map(&:chained_name)).to eq([])
46
+ def call
47
+ return [] unless @node.is_a?(Nodes::ClassNode)
48
+
49
+ [
50
+ Definitions::ClassDefinition.new(
51
+ description: description,
52
+ extended_module_unqualified_names: extended_module_unqualified_names,
53
+ included_module_unqualified_names: included_module_unqualified_names,
54
+ location: location,
55
+ prepended_module_unqualified_names: prepended_module_unqualified_names,
56
+ qualified_name: @node.qualified_name,
57
+ super_class_unqualified_name: UnqualifiedName.new(
58
+ chained_name: @node.super_class_chained_name,
59
+ module_nesting: @node.module_nesting
60
+ )
61
+ )
62
+ ]
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module Yard
5
+ module DefinitionGenerators
6
+ class ConstantAssignmentDefinitionGenerator < Base
7
+ # @example returns constant definition for constant assignment node
8
+ # definitions = Rucoa::Source.new(
9
+ # content: <<~RUBY,
10
+ # Foo = 'foo'
11
+ # RUBY
12
+ # uri: '/path/to/foo.rb'
13
+ # ).definitions
14
+ # expect(definitions[0]).to be_a(Rucoa::Definitions::ConstantDefinition)
15
+ def call
16
+ return [] unless @node.is_a?(Nodes::CasgnNode)
17
+
18
+ [
19
+ Definitions::ConstantDefinition.new(
20
+ description: description,
21
+ location: location,
22
+ qualified_name: @node.qualified_name
23
+ )
24
+ ]
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module Yard
5
+ module DefinitionGenerators
6
+ class MethodDefinitionGenerator < Base
7
+ # @example returns method definition for def node
8
+ # definitions = Rucoa::Source.new(
9
+ # content: <<~RUBY,
10
+ # def foo
11
+ # end
12
+ # RUBY
13
+ # uri: '/path/to/foo.rb'
14
+ # ).definitions
15
+ # expect(definitions[0]).to be_a(Rucoa::Definitions::MethodDefinition)
16
+ # @example returns method definition for defs node
17
+ # definitions = Rucoa::Source.new(
18
+ # content: <<~RUBY,
19
+ # def self.foo
20
+ # end
21
+ # RUBY
22
+ # uri: '/path/to/foo.rb'
23
+ # ).definitions
24
+ # expect(definitions[0]).to be_a(Rucoa::Definitions::MethodDefinition)
25
+ # @example returns method definition for another style of singleton def node
26
+ # definitions = Rucoa::Source.new(
27
+ # content: <<~RUBY,
28
+ # class Foo
29
+ # class << self
30
+ # def bar
31
+ # end
32
+ # end
33
+ # end
34
+ # RUBY
35
+ # uri: '/path/to/foo.rb'
36
+ # ).definitions
37
+ # expect(definitions[1].qualified_name).to eq('Foo.bar')
38
+ def call
39
+ return [] unless @node.is_a?(Nodes::DefNode) || @node.is_a?(Nodes::DefsNode)
40
+
41
+ [
42
+ Definitions::MethodDefinition.new(
43
+ description: description,
44
+ kind: @node.singleton? ? :singleton : :instance,
45
+ location: location,
46
+ method_name: @node.name,
47
+ namespace: @node.namespace,
48
+ types: return_types.map do |type|
49
+ Types::MethodType.new(
50
+ parameters_string: '', # TODO
51
+ return_type: type
52
+ )
53
+ end
54
+ )
55
+ ]
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module Yard
5
+ module DefinitionGenerators
6
+ class ModuleDefinitionGenerator < Base
7
+ # @example returns module definition for module node
8
+ # definitions = Rucoa::Source.new(
9
+ # content: <<~RUBY,
10
+ # module Foo
11
+ # end
12
+ # RUBY
13
+ # uri: '/path/to/foo.rb'
14
+ # ).definitions
15
+ # expect(definitions[0]).to be_a(Rucoa::Definitions::ModuleDefinition)
16
+ def call
17
+ return [] unless @node.is_a?(Nodes::ModuleNode)
18
+
19
+ [
20
+ Definitions::ModuleDefinition.new(
21
+ description: description,
22
+ extended_module_unqualified_names: extended_module_unqualified_names,
23
+ included_module_unqualified_names: included_module_unqualified_names,
24
+ location: location,
25
+ prepended_module_unqualified_names: prepended_module_unqualified_names,
26
+ qualified_name: @node.qualified_name
27
+ )
28
+ ]
29
+ end
30
+
31
+ private
32
+
33
+ # @return [Array<Rucoa::UnqualifiedName>]
34
+ def extended_module_unqualified_names
35
+ unqualified_names_for('extend')
36
+ end
37
+
38
+ # @return [Array<Rucoa::UnqualifiedName>]
39
+ def included_module_unqualified_names
40
+ unqualified_names_for('include')
41
+ end
42
+
43
+ # @return [Array<Rucoa::UnqualifiedName>]
44
+ def prepended_module_unqualified_names
45
+ unqualified_names_for('prepend')
46
+ end
47
+
48
+ # @param method_name [String]
49
+ # @return [Array<Rucoa::UnqualifiedName>]
50
+ def unqualified_names_for(method_name)
51
+ @node.body_children.flat_map do |child|
52
+ next [] unless child.is_a?(Nodes::SendNode)
53
+ next [] unless child.name == method_name
54
+
55
+ child.arguments.filter_map do |argument|
56
+ next unless argument.is_a?(Nodes::ConstNode)
57
+
58
+ UnqualifiedName.new(
59
+ chained_name: argument.chained_name,
60
+ module_nesting: @node.module_nesting
61
+ )
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module Yard
5
+ module DefinitionGenerators
6
+ autoload :AttributeReaderDefinitionGenerator, 'rucoa/yard/definition_generators/attribute_reader_definition_generator'
7
+ autoload :AttributeWriterDefinitionGenerator, 'rucoa/yard/definition_generators/attribute_writer_definition_generator'
8
+ autoload :Base, 'rucoa/yard/definition_generators/base'
9
+ autoload :ClassDefinitionGenerator, 'rucoa/yard/definition_generators/class_definition_generator'
10
+ autoload :ConstantAssignmentDefinitionGenerator, 'rucoa/yard/definition_generators/constant_assignment_definition_generator'
11
+ autoload :MethodDefinitionGenerator, 'rucoa/yard/definition_generators/method_definition_generator'
12
+ autoload :ModuleDefinitionGenerator, 'rucoa/yard/definition_generators/module_definition_generator'
13
+ end
14
+ end
15
+ end