rucoa 0.3.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
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