rucoa 0.3.0 → 0.5.1

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 (75) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/Gemfile +1 -0
  4. data/Gemfile.lock +12 -2
  5. data/README.md +37 -6
  6. data/data/definitions_ruby_3_1 +0 -0
  7. data/images/diagnostics.gif +0 -0
  8. data/images/document-formatting.gif +0 -0
  9. data/images/document-symbol.gif +0 -0
  10. data/images/selection-ranges.gif +0 -0
  11. data/lib/rucoa/configuration.rb +62 -28
  12. data/lib/rucoa/definition_archiver.rb +29 -0
  13. data/lib/rucoa/definition_builders/rbs_constant_definition_builder.rb +44 -0
  14. data/lib/rucoa/definition_builders/rbs_method_definition_builder.rb +106 -0
  15. data/lib/rucoa/definition_builders/yard_method_definition_builder.rb +218 -0
  16. data/lib/rucoa/definition_builders.rb +9 -0
  17. data/lib/rucoa/definition_store.rb +63 -0
  18. data/lib/rucoa/definitions/base.rb +12 -0
  19. data/lib/rucoa/definitions/constant_definition.rb +51 -0
  20. data/lib/rucoa/definitions/method_definition.rb +126 -0
  21. data/lib/rucoa/definitions/method_parameter_definition.rb +30 -0
  22. data/lib/rucoa/definitions.rb +9 -0
  23. data/lib/rucoa/handler_concerns/diagnostics_publishable.rb +140 -0
  24. data/lib/rucoa/handlers/base.rb +8 -0
  25. data/lib/rucoa/handlers/exit_handler.rb +11 -0
  26. data/lib/rucoa/handlers/initialize_handler.rb +7 -0
  27. data/lib/rucoa/handlers/initialized_handler.rb +10 -0
  28. data/lib/rucoa/handlers/shutdown_handler.rb +12 -0
  29. data/lib/rucoa/handlers/text_document_code_action_handler.rb +78 -3
  30. data/lib/rucoa/handlers/text_document_did_change_handler.rb +1 -20
  31. data/lib/rucoa/handlers/text_document_did_open_handler.rb +11 -4
  32. data/lib/rucoa/handlers/text_document_document_symbol_handler.rb +242 -0
  33. data/lib/rucoa/handlers/text_document_formatting_handler.rb +36 -5
  34. data/lib/rucoa/handlers/text_document_range_formatting_handler.rb +65 -13
  35. data/lib/rucoa/handlers/text_document_selection_range_handler.rb +124 -8
  36. data/lib/rucoa/handlers/text_document_signature_help_handler.rb +68 -0
  37. data/lib/rucoa/handlers.rb +4 -0
  38. data/lib/rucoa/node_concerns/name_full_qualifiable.rb +20 -0
  39. data/lib/rucoa/node_concerns.rb +7 -0
  40. data/lib/rucoa/node_inspector.rb +111 -0
  41. data/lib/rucoa/nodes/base.rb +43 -0
  42. data/lib/rucoa/nodes/casgn_node.rb +14 -0
  43. data/lib/rucoa/nodes/class_node.rb +8 -0
  44. data/lib/rucoa/nodes/const_node.rb +12 -0
  45. data/lib/rucoa/nodes/def_node.rb +71 -0
  46. data/lib/rucoa/nodes/defs_node.rb +12 -0
  47. data/lib/rucoa/nodes/lvar_node.rb +25 -0
  48. data/lib/rucoa/nodes/module_node.rb +21 -0
  49. data/lib/rucoa/nodes/sclass_node.rb +8 -0
  50. data/lib/rucoa/nodes/send_node.rb +60 -0
  51. data/lib/rucoa/nodes/str_node.rb +4 -0
  52. data/lib/rucoa/nodes/sym_node.rb +12 -0
  53. data/lib/rucoa/nodes.rb +10 -0
  54. data/lib/rucoa/parser_builder.rb +20 -10
  55. data/lib/rucoa/position.rb +2 -2
  56. data/lib/rucoa/range.rb +64 -14
  57. data/lib/rucoa/rbs_document_loader.rb +43 -0
  58. data/lib/rucoa/rubocop_autocorrector.rb +1 -1
  59. data/lib/rucoa/rubocop_investigator.rb +1 -1
  60. data/lib/rucoa/server.rb +20 -1
  61. data/lib/rucoa/source.rb +56 -6
  62. data/lib/rucoa/source_store.rb +6 -10
  63. data/lib/rucoa/types/method_type.rb +23 -0
  64. data/lib/rucoa/types.rb +7 -0
  65. data/lib/rucoa/version.rb +1 -1
  66. data/lib/rucoa/yard_glob_document_loader.rb +47 -0
  67. data/lib/rucoa/yard_string_document_loader.rb +70 -0
  68. data/lib/rucoa.rb +10 -5
  69. data/rucoa.gemspec +2 -0
  70. metadata +68 -7
  71. data/lib/rucoa/code_action_provider.rb +0 -102
  72. data/lib/rucoa/diagnostic_provider.rb +0 -143
  73. data/lib/rucoa/formatting_provider.rb +0 -54
  74. data/lib/rucoa/range_formatting_provider.rb +0 -67
  75. data/lib/rucoa/selection_range_provider.rb +0 -99
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7206c3901e7ceea282b2de34f31ab90cc5ffa7fa48c06e58ae64bb718f48cd52
4
- data.tar.gz: 6188a2047317b98160565599de3dc08663e732d7b54a546a8bc3e610379cb39a
3
+ metadata.gz: 4ffd244eb4ed0935120e2d33a03798897a4880e06ff999c1779a920e4926215c
4
+ data.tar.gz: fe7296dba2ff6d185a729e6649cd9630a5644961837d28306f3a5a193643d38e
5
5
  SHA512:
6
- metadata.gz: afa9c37dae4a5c460eb1f5505ca511138c20f5b8c483a5ba68f798d1f9b18a5f5c4a481ee3ec743eb8585328538b5daec613b9f69a9599e5337106c57b1c0ea8
7
- data.tar.gz: 539517254cff781a99b6ec463aed13bd04cbbcf3da3a9ff15cf72dac809b12c53ef9ff53c51828a163975bbdbe60a174767a472d2b4476f03f1813b5f513c62d
6
+ metadata.gz: 9f9965f568980d2f069a5670dcf5e008986399b8826a331410bdd0f31cacf10a01068bc8e37109241ccd2c1e79bf9f0bc639600b7608260fffd02b07251e310b
7
+ data.tar.gz: 1143b279fbbf845f07f0654b37eadf20226d96b1dc930ceea5fd9fc3daf90b6bd786d3a55c08b9601019d85b0e79284de1268de5ed628136cb0097be3e6af846
data/.rubocop.yml CHANGED
@@ -29,6 +29,9 @@ RSpec/MultipleMemoizedHelpers:
29
29
  RSpec/NamedSubject:
30
30
  Enabled: false
31
31
 
32
+ Security/MarshalLoad:
33
+ Enabled: false
34
+
32
35
  Sevencop/HashLiteralOrder:
33
36
  Enabled: true
34
37
 
data/Gemfile CHANGED
@@ -11,3 +11,4 @@ gem 'rubocop-performance'
11
11
  gem 'rubocop-rake'
12
12
  gem 'rubocop-rspec'
13
13
  gem 'sevencop'
14
+ gem 'yardspec'
data/Gemfile.lock CHANGED
@@ -1,9 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rucoa (0.3.0)
4
+ rucoa (0.5.1)
5
5
  parser
6
+ rbs
6
7
  rubocop
8
+ yard
7
9
 
8
10
  GEM
9
11
  remote: https://rubygems.org/
@@ -16,6 +18,7 @@ GEM
16
18
  ast (~> 2.4.1)
17
19
  rainbow (3.1.1)
18
20
  rake (13.0.6)
21
+ rbs (2.6.0)
19
22
  regexp_parser (2.5.0)
20
23
  rexml (3.2.5)
21
24
  rspec (3.11.0)
@@ -51,9 +54,15 @@ GEM
51
54
  rubocop-rspec (2.12.1)
52
55
  rubocop (~> 1.31)
53
56
  ruby-progressbar (1.11.0)
54
- sevencop (0.9.3)
57
+ sevencop (0.10.0)
55
58
  rubocop
56
59
  unicode-display_width (2.2.0)
60
+ webrick (1.7.0)
61
+ yard (0.9.28)
62
+ webrick (~> 1.7.0)
63
+ yardspec (0.2.0)
64
+ rspec
65
+ yard
57
66
 
58
67
  PLATFORMS
59
68
  x86_64-linux
@@ -67,6 +76,7 @@ DEPENDENCIES
67
76
  rubocop-rspec
68
77
  rucoa!
69
78
  sevencop
79
+ yardspec
70
80
 
71
81
  BUNDLED WITH
72
82
  2.3.21
data/README.md CHANGED
@@ -6,7 +6,7 @@ Language server for Ruby.
6
6
 
7
7
  ## Usage
8
8
 
9
- Install both rucoa gem and [vscode-rucoa](https://github.com/r7kamura/vscode-rucoa) extension, then open your Ruby project in VSCode.
9
+ Install both rucoa gem and [vscode-rucoa](https://marketplace.visualstudio.com/items?itemName=r7kamura.vscode-rucoa) extension, then open your Ruby project in VSCode.
10
10
 
11
11
  To install rucoa gem, if your project is managed by bundler, add to your Gemfile:
12
12
 
@@ -32,10 +32,42 @@ gem install rucoa
32
32
 
33
33
  ## Features
34
34
 
35
- - Diagnostics
36
- - Formatting
37
- - Quick Fix
38
- - Selection Range
35
+ ### Diagnostics
36
+
37
+ Displays RuboCop offenses and provides Quick Fix action for autocorrection.
38
+
39
+ ![demo](images/diagnostics.gif)
40
+
41
+ ### Formatting
42
+
43
+ Run "Format Document" command or enable "Format On Save" in the settings to autocorrect RuboCop offenses.
44
+
45
+ ![demo](images/document-formatting.gif)
46
+
47
+ ### Selection
48
+
49
+ Run "Expand Selection" command to select appropriate ranges.
50
+
51
+ ![demo](images/selection-ranges.gif)
52
+
53
+ ### Symbol
54
+
55
+ See Outline section in the explorer panel to see document symbols in the current file, or run "Go to Symbol" command to search for symbols.
56
+
57
+ This extension supports the folowiing types of symbols:
58
+
59
+ - class
60
+ - module
61
+ - constant
62
+ - instance method
63
+ - singleton method (a.k.a. class method)
64
+ - attribute (attr_accessor, attr_reader, and attr_writer)
65
+
66
+ ![demo](images/document-symbol.gif)
67
+
68
+ ### Signature help (experimental)
69
+
70
+ Shows method signature help when you start to type method arguments like `"100".to_i(`.
39
71
 
40
72
  ### Coming soon
41
73
 
@@ -44,4 +76,3 @@ gem install rucoa
44
76
  - Go to Definition
45
77
  - Highlight
46
78
  - Semantic Tokens
47
- - Symbol
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -2,49 +2,68 @@
2
2
 
3
3
  module Rucoa
4
4
  class Configuration
5
- DEFAULT_SETTINGS = {
6
- 'base' => {
7
- 'enable' => 'auto',
8
- 'useBundler' => 'auto'
9
- },
10
- 'feature' => {
11
- 'codeAction' => {
12
- 'enable' => true
13
- },
14
- 'diagnostics' => {
15
- 'enable' => true
16
- },
17
- 'formatting' => {
18
- 'enable' => true
19
- },
20
- 'selectionRange' => {
21
- 'enable' => true
22
- }
23
- }
24
- }.freeze
25
-
26
5
  def initialize
27
- reset
6
+ @settings = {}
7
+ end
8
+
9
+ # @return [void]
10
+ def disable_code_action
11
+ disable('codeAction')
12
+ end
13
+
14
+ # @return [void]
15
+ def disable_diagnostics
16
+ disable('diagnostics')
17
+ end
18
+
19
+ # @return [void]
20
+ def disable_document_symbol
21
+ disable('documentSymbol')
22
+ end
23
+
24
+ # @return [void]
25
+ def disable_formatting
26
+ disable('formatting')
27
+ end
28
+
29
+ # @return [void]
30
+ def disable_selection_range
31
+ disable('selectionRange')
32
+ end
33
+
34
+ # @return [void]
35
+ def disable_signature_help
36
+ disable('signatureHelp')
28
37
  end
29
38
 
30
39
  # @return [Boolean]
31
40
  def enables_code_action?
32
- @settings.dig('feature', 'codeAction', 'enable')
41
+ enables?('codeAction')
33
42
  end
34
43
 
35
44
  # @return [Boolean]
36
45
  def enables_diagnostics?
37
- @settings.dig('feature', 'diagnostics', 'enable')
46
+ enables?('diagnostics')
47
+ end
48
+
49
+ # @return [Boolean]
50
+ def enables_document_symbol?
51
+ enables?('documentSymbol')
38
52
  end
39
53
 
40
54
  # @return [Boolean]
41
55
  def enables_formatting?
42
- @settings.dig('feature', 'formatting', 'enable')
56
+ enables?('formatting')
43
57
  end
44
58
 
45
59
  # @return [Boolean]
46
60
  def enables_selection_range?
47
- @settings.dig('feature', 'selectionRange', 'enable')
61
+ enables?('selectionRange')
62
+ end
63
+
64
+ # @return [Boolean]
65
+ def enables_signature_help?
66
+ enables?('signatureHelp')
48
67
  end
49
68
 
50
69
  # @param settings [Hash]
@@ -55,9 +74,24 @@ module Rucoa
55
74
 
56
75
  private
57
76
 
77
+ # @param feature [String]
58
78
  # @return [void]
59
- def reset
60
- @settings = DEFAULT_SETTINGS.dup
79
+ def disable(feature)
80
+ @settings ||= {}
81
+ @settings['feature'] ||= {}
82
+ @settings['feature'][feature] ||= {}
83
+ @settings['feature'][feature]['enable'] = false
84
+ end
85
+
86
+ # @param feature [String]
87
+ # @return [Boolean]
88
+ def enables?(feature)
89
+ value = @settings.dig('feature', feature, 'enable')
90
+ if value.nil?
91
+ true
92
+ else
93
+ value
94
+ end
61
95
  end
62
96
  end
63
97
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pathname'
4
+
5
+ module Rucoa
6
+ class DefinitionArchiver
7
+ RUBY_DEFINITIONS_DUMP_PATH = ::File.expand_path('../../data/definitions_ruby_3_1', __dir__).freeze
8
+ private_constant :RUBY_DEFINITIONS_DUMP_PATH
9
+
10
+ class << self
11
+ # @param definitions [Array<Rucoa::Definition::Base>]
12
+ # @return [void]
13
+ def dump(definitions)
14
+ pathname = ::Pathname.new(RUBY_DEFINITIONS_DUMP_PATH)
15
+ pathname.parent.mkpath
16
+ pathname.write(
17
+ ::Marshal.dump(definitions)
18
+ )
19
+ end
20
+
21
+ # @return [Array<Rucoa::Definition::Base>]
22
+ def load
23
+ ::Marshal.load(
24
+ ::File.binread(RUBY_DEFINITIONS_DUMP_PATH)
25
+ )
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module DefinitionBuilders
5
+ # Build Rucoa contant definition from RBS constant declaration.
6
+ class RbsConstantDefinitionBuilder
7
+ class << self
8
+ # @param declaration [RBS::AST::Declarations::Constant]
9
+ # @return [Rucoa::Definitions::ConstantDefinition]
10
+ def call(declaration:)
11
+ new(
12
+ declaration: declaration
13
+ ).call
14
+ end
15
+ end
16
+
17
+ # @param declaration [RBS::AST::Declarations::Constant]
18
+ # @return [Rucoa::Definitions::ConstantDefinition]
19
+ def initialize(declaration:)
20
+ @declaration = declaration
21
+ end
22
+
23
+ # @return [Rucoa::Definitions::ConstantDefinition]
24
+ def call
25
+ ::Rucoa::Definitions::ConstantDefinition.new(
26
+ full_qualified_name: full_qualified_name,
27
+ source_path: source_path
28
+ )
29
+ end
30
+
31
+ private
32
+
33
+ # @return [String]
34
+ def full_qualified_name
35
+ @declaration.name.to_s.delete_prefix('::')
36
+ end
37
+
38
+ # @return [String]
39
+ def source_path
40
+ @declaration.location.name
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rbs'
4
+
5
+ module Rucoa
6
+ module DefinitionBuilders
7
+ # Build Rucoa method definition from RBS method definition.
8
+ class RbsMethodDefinitionBuilder
9
+ class << self
10
+ # @param declaration [RBS::AST::Declarations::Class, RBS::AST::Declarations::Module]
11
+ # @param method_definition [RBS::AST::Members::MethodDefinition]
12
+ # @return [Rucoa::Definitions::MethodDefinition]
13
+ def call(declaration:, method_definition:)
14
+ new(
15
+ declaration: declaration,
16
+ method_definition: method_definition
17
+ ).call
18
+ end
19
+ end
20
+
21
+ # @param declaration [RBS::AST::Declarations::Class, RBS::AST::Declarations::Module]
22
+ # @param method_definition [RBS::AST::Members::MethodDefinition]
23
+ def initialize(declaration:, method_definition:)
24
+ @declaration = declaration
25
+ @method_definition = method_definition
26
+ end
27
+
28
+ # @return [Rucoa::Definitions::MethodDefinition]
29
+ def call
30
+ Definitions::MethodDefinition.new(
31
+ description: description,
32
+ kind: kind,
33
+ method_name: method_name,
34
+ namespace: namespace,
35
+ source_path: source_path,
36
+ types: types
37
+ )
38
+ end
39
+
40
+ private
41
+
42
+ # @return [Array<Rucoa::Types::MethodType>]
43
+ def types
44
+ @method_definition.types.map do |method_type|
45
+ RbsMethodTypeToRucoaMethodTypeMapper.call(
46
+ method_type: method_type
47
+ )
48
+ end
49
+ end
50
+
51
+ # @return [String, nil]
52
+ def description
53
+ @method_definition.comment&.string&.sub(/\A\s*<!--.*-->\s*/m, '')
54
+ end
55
+
56
+ # @return [String]
57
+ def namespace
58
+ @declaration.name.to_s.delete_prefix('::')
59
+ end
60
+
61
+ # @return [String]
62
+ def method_name
63
+ @method_definition.name.to_s
64
+ end
65
+
66
+ # @return [Symbol]
67
+ def kind
68
+ @method_definition.kind
69
+ end
70
+
71
+ # @return [String]
72
+ def source_path
73
+ @declaration.location.name
74
+ end
75
+
76
+ class RbsMethodTypeToRucoaMethodTypeMapper
77
+ class << self
78
+ # @param method_type [RBS::Types::MethodType]
79
+ # @return [Rucoa::Types::MethodType]
80
+ def call(method_type:)
81
+ new(method_type: method_type).call
82
+ end
83
+
84
+ # @param type [RBS::Types::Base]
85
+ # @return [String]
86
+ def stringify(type)
87
+ type.to_s.delete_prefix('::')
88
+ end
89
+ end
90
+
91
+ # @param method_type [RBS::Types::MethodType]
92
+ def initialize(method_type:)
93
+ @method_type = method_type
94
+ end
95
+
96
+ # @return [Rucoa::Types::MethodType]
97
+ def call
98
+ Types::MethodType.new(
99
+ parameters_string: @method_type.type.param_to_s,
100
+ return_type: self.class.stringify(@method_type.type.return_type)
101
+ )
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,218 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yard'
4
+
5
+ module Rucoa
6
+ module DefinitionBuilders
7
+ class YardMethodDefinitionBuilder
8
+ class << self
9
+ # @param code_object [YARD::CodeObjects::MethodObject]
10
+ # @param path [String]
11
+ # @return [Rucoa::Definitions::Base]
12
+ def call(code_object:, path:)
13
+ new(
14
+ code_object: code_object,
15
+ path: path
16
+ ).call
17
+ end
18
+ end
19
+
20
+ # @param code_object [YARD::CodeObjects::Base]
21
+ # @param path [String]
22
+ def initialize(code_object:, path:)
23
+ @code_object = code_object
24
+ @path = path
25
+ end
26
+
27
+ # @return [Rucoa::Definitions::Base]
28
+ def call
29
+ ::Rucoa::Definitions::MethodDefinition.new(
30
+ description: description,
31
+ kind: kind,
32
+ method_name: method_name,
33
+ namespace: namespace,
34
+ source_path: @path,
35
+ types: types
36
+ )
37
+ end
38
+
39
+ private
40
+
41
+ # @return [String]
42
+ def description
43
+ @code_object.docstring.to_s
44
+ end
45
+
46
+ # @return [Symbol]
47
+ def kind
48
+ if @code_object.scope == :instance
49
+ :instance
50
+ else
51
+ :singleton
52
+ end
53
+ end
54
+
55
+ # @return [String
56
+ def method_name
57
+ @code_object.name
58
+ end
59
+
60
+ # @return [String]
61
+ def namespace
62
+ @code_object.namespace.to_s
63
+ end
64
+
65
+ # @return [Array<Rucoa::Types::MethodType>]
66
+ def types
67
+ return_types.map do |return_type|
68
+ ::Rucoa::Types::MethodType.new(
69
+ parameters_string: parameters_string,
70
+ return_type: return_type
71
+ )
72
+ end
73
+ end
74
+
75
+ # @return [String]
76
+ # @example
77
+ # definitions = Rucoa::YardStringDocumentLoader.call(
78
+ # content: <<~RUBY,
79
+ # class Foo
80
+ # def bar(
81
+ # argument1,
82
+ # argument2 = nil,
83
+ # *arguments,
84
+ # keyword1:,
85
+ # keyword2: nil,
86
+ # **keywords,
87
+ # &block
88
+ # )
89
+ # end
90
+ # end
91
+ # RUBY
92
+ # path: '/path/to/foo.rb'
93
+ # )
94
+ # expect(definitions.first.signatures).to eq(
95
+ # [
96
+ # 'Foo#bar(argument1, argument2 = nil, *arguments, keyword1:, keyword2: nil, **keywords, &block) -> Object'
97
+ # ]
98
+ # )
99
+ def parameters_string
100
+ @code_object.parameters.map do |parameter_name, default_value|
101
+ default_value_part =
102
+ if default_value.nil?
103
+ nil
104
+ elsif parameter_name.end_with?(':')
105
+ " #{default_value}"
106
+ else
107
+ " = #{default_value}"
108
+ end
109
+ [
110
+ parameter_name,
111
+ default_value_part
112
+ ].join
113
+ end.join(', ')
114
+ end
115
+
116
+ # @return [Array<Rucoa::Definitions::MethodParameterDefinition>]
117
+ def parameters
118
+ parameter_tags.map do |parameter_tag|
119
+ ::Rucoa::Definitions::MethodParameterDefinition.new(
120
+ name: parameter_tag.name,
121
+ types: parameter_tag.types
122
+ )
123
+ end
124
+ end
125
+
126
+ # @return [Array<YARD::Tags::Tag>]
127
+ def parameter_tags
128
+ @code_object.tags(:param) + @code_object.tags(:overload).flat_map do |overload_tag|
129
+ overload_tag.tags(:param)
130
+ end
131
+ end
132
+
133
+ # @return [Array<String>]
134
+ # @return [String]
135
+ # @example returns return type annotated by YARD @return tags
136
+ # definitions = Rucoa::YardStringDocumentLoader.call(
137
+ # content: <<~RUBY,
138
+ # # @return [String]
139
+ # def foo
140
+ # 'foo'
141
+ # end
142
+ # RUBY
143
+ # path: '/path/to/foo.rb'
144
+ # )
145
+ # expect(definitions.first.return_types).to eq(
146
+ # %w[
147
+ # String
148
+ # ]
149
+ # )
150
+ # @example ignores empty @return tags
151
+ # definitions = Rucoa::YardStringDocumentLoader.call(
152
+ # content: <<~RUBY,
153
+ # # @return []
154
+ # def foo
155
+ # 'foo'
156
+ # end
157
+ # RUBY
158
+ # path: '/path/to/foo.rb'
159
+ # )
160
+ # expect(definitions.first.return_types).to eq([])
161
+ def return_types
162
+ return %w[Object] if return_tags.empty?
163
+
164
+ return_tags.flat_map(&:types).compact.map do |type|
165
+ YardType.new(type).to_rucoa_type
166
+ end
167
+ end
168
+
169
+ # @return [YARD::Tags::Tag]
170
+ def return_tags
171
+ @code_object.tags(:return) + @code_object.tags(:overload).flat_map do |overload_tag|
172
+ overload_tag.tags(:return)
173
+ end
174
+ end
175
+
176
+ class YardType
177
+ # @param type [String]
178
+ def initialize(type)
179
+ @type = type
180
+ end
181
+
182
+ # @return [String]
183
+ # @example scrubs "Array<String>" to "Array"
184
+ # yard_type = Rucoa::DefinitionBuilders::YardMethodDefinitionBuilder::YardType.new(
185
+ # 'Array<String>'
186
+ # )
187
+ # expect(yard_type.to_rucoa_type).to eq('Array')
188
+ # @example scrubs "Array(String, Integer)" to "Array"
189
+ # yard_type = Rucoa::DefinitionBuilders::YardMethodDefinitionBuilder::YardType.new(
190
+ # 'Array(String, Integer)'
191
+ # )
192
+ # expect(yard_type.to_rucoa_type).to eq('Array')
193
+ # @example scrubs "::Array" to "Array"
194
+ # yard_type = Rucoa::DefinitionBuilders::YardMethodDefinitionBuilder::YardType.new(
195
+ # '::Array'
196
+ # )
197
+ # expect(yard_type.to_rucoa_type).to eq('Array')
198
+ # @example scrubs "Hash{Symbol => Object}" to "Hash"
199
+ # yard_type = Rucoa::DefinitionBuilders::YardMethodDefinitionBuilder::YardType.new(
200
+ # 'Hash{Symbol => Object}'
201
+ # )
202
+ # expect(yard_type.to_rucoa_type).to eq('Hash')
203
+ # @example scrubs "Array<Array<Integer>>" to "Array"
204
+ # yard_type = Rucoa::DefinitionBuilders::YardMethodDefinitionBuilder::YardType.new(
205
+ # 'Array<Array<Integer>>'
206
+ # )
207
+ # expect(yard_type.to_rucoa_type).to eq('Array')
208
+ def to_rucoa_type
209
+ @type
210
+ .delete_prefix('::')
211
+ .gsub(/<.+>/, '')
212
+ .gsub(/\{.+\}/, '')
213
+ .gsub(/\(.+\)/, '')
214
+ end
215
+ end
216
+ end
217
+ end
218
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rucoa
4
+ module DefinitionBuilders
5
+ autoload :RbsConstantDefinitionBuilder, 'rucoa/definition_builders/rbs_constant_definition_builder'
6
+ autoload :RbsMethodDefinitionBuilder, 'rucoa/definition_builders/rbs_method_definition_builder'
7
+ autoload :YardMethodDefinitionBuilder, 'rucoa/definition_builders/yard_method_definition_builder'
8
+ end
9
+ end