rucoa 0.8.0 → 0.10.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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +6 -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 +268 -75
  7. data/lib/rucoa/definitions/base.rb +14 -3
  8. data/lib/rucoa/definitions/class_definition.rb +20 -4
  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 +39 -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/initialized_handler.rb +33 -5
  16. data/lib/rucoa/handlers/text_document_completion_handler.rb +1 -1
  17. data/lib/rucoa/handlers/text_document_definition_handler.rb +3 -99
  18. data/lib/rucoa/handlers/text_document_did_open_handler.rb +1 -4
  19. data/lib/rucoa/handlers/text_document_hover_handler.rb +21 -13
  20. data/lib/rucoa/handlers/text_document_selection_range_handler.rb +8 -2
  21. data/lib/rucoa/location.rb +37 -0
  22. data/lib/rucoa/node_concerns/body.rb +24 -0
  23. data/lib/rucoa/node_concerns/{name_full_qualifiable.rb → qualified_name.rb} +2 -2
  24. data/lib/rucoa/node_concerns.rb +2 -1
  25. data/lib/rucoa/node_inspector.rb +22 -26
  26. data/lib/rucoa/nodes/base.rb +51 -10
  27. data/lib/rucoa/nodes/begin_node.rb +8 -0
  28. data/lib/rucoa/nodes/casgn_node.rb +1 -1
  29. data/lib/rucoa/nodes/cbase_node.rb +8 -0
  30. data/lib/rucoa/nodes/class_node.rb +63 -1
  31. data/lib/rucoa/nodes/const_node.rb +64 -5
  32. data/lib/rucoa/nodes/def_node.rb +11 -9
  33. data/lib/rucoa/nodes/defs_node.rb +21 -0
  34. data/lib/rucoa/nodes/lvar_node.rb +2 -1
  35. data/lib/rucoa/nodes/module_node.rb +2 -1
  36. data/lib/rucoa/nodes/send_node.rb +14 -10
  37. data/lib/rucoa/nodes.rb +3 -1
  38. data/lib/rucoa/parse_result.rb +29 -0
  39. data/lib/rucoa/parser.rb +40 -8
  40. data/lib/rucoa/parser_builder.rb +7 -1
  41. data/lib/rucoa/position.rb +10 -1
  42. data/lib/rucoa/range.rb +11 -1
  43. data/lib/rucoa/rbs/class_definition_mapper.rb +13 -28
  44. data/lib/rucoa/rbs/constant_definition_mapper.rb +12 -6
  45. data/lib/rucoa/rbs/method_definition_mapper.rb +12 -6
  46. data/lib/rucoa/rbs/module_definition_mapper.rb +34 -6
  47. data/lib/rucoa/rubocop/autocorrector.rb +2 -2
  48. data/lib/rucoa/rubocop/investigator.rb +6 -3
  49. data/lib/rucoa/server.rb +9 -3
  50. data/lib/rucoa/source.rb +57 -27
  51. data/lib/rucoa/source_store.rb +0 -13
  52. data/lib/rucoa/unqualified_name.rb +9 -0
  53. data/lib/rucoa/version.rb +1 -1
  54. data/lib/rucoa/yard/definition_generators/attribute_reader_definition_generator.rb +60 -0
  55. data/lib/rucoa/yard/definition_generators/attribute_writer_definition_generator.rb +60 -0
  56. data/lib/rucoa/yard/definition_generators/base.rb +117 -0
  57. data/lib/rucoa/yard/definition_generators/class_definition_generator.rb +66 -0
  58. data/lib/rucoa/yard/definition_generators/constant_assignment_definition_generator.rb +29 -0
  59. data/lib/rucoa/yard/definition_generators/method_definition_generator.rb +47 -0
  60. data/lib/rucoa/yard/definition_generators/module_definition_generator.rb +62 -0
  61. data/lib/rucoa/yard/definition_generators.rb +15 -0
  62. data/lib/rucoa/yard/definitions_loader.rb +44 -65
  63. data/lib/rucoa/yard/type.rb +46 -0
  64. data/lib/rucoa/yard.rb +2 -1
  65. data/lib/rucoa.rb +4 -1
  66. metadata +18 -4
  67. data/lib/rucoa/yard/method_definition_mapper.rb +0 -215
@@ -5,7 +5,9 @@ require 'parser/current'
5
5
  module Rucoa
6
6
  class ParserBuilder < ::Parser::Builders::Default
7
7
  NODE_CLASS_BY_TYPE = {
8
+ begin: Nodes::BeginNode,
8
9
  casgn: Nodes::CasgnNode,
10
+ cbase: Nodes::CbaseNode,
9
11
  class: Nodes::ClassNode,
10
12
  const: Nodes::ConstNode,
11
13
  def: Nodes::DefNode,
@@ -27,7 +29,11 @@ module Rucoa
27
29
  end
28
30
 
29
31
  # @note Override.
30
- def n(type, children, source_map)
32
+ def n(
33
+ type,
34
+ children,
35
+ source_map
36
+ )
31
37
  self.class.node_class_for(type).new(
32
38
  type,
33
39
  children,
@@ -39,11 +39,20 @@ module Rucoa
39
39
 
40
40
  # @param column [Integer] 0-origin column number
41
41
  # @param line [Integer] 1-origin line number
42
- def initialize(column: 0, line: 1)
42
+ def initialize(
43
+ column: 0,
44
+ line: 1
45
+ )
43
46
  @column = column
44
47
  @line = line
45
48
  end
46
49
 
50
+ # @param other [Rucoa::Position]
51
+ # @return [Boolean]
52
+ def ==(other)
53
+ column == other.column && line == other.line
54
+ end
55
+
47
56
  # @param text [String]
48
57
  # @return [Integer]
49
58
  def to_index_of(text)
data/lib/rucoa/range.rb CHANGED
@@ -31,12 +31,22 @@ module Rucoa
31
31
  # @param beginning [Rucoa::Position]
32
32
  # @param ending [Ruoca::Position]
33
33
  # @param including_ending [Boolean]
34
- def initialize(beginning, ending, including_ending: true)
34
+ def initialize(
35
+ beginning,
36
+ ending,
37
+ including_ending: true
38
+ )
35
39
  @beginning = beginning
36
40
  @ending = ending
37
41
  @including_ending = including_ending
38
42
  end
39
43
 
44
+ # @param other [Rucoa::Range]
45
+ # @return [Boolean]
46
+ def ==(other)
47
+ beginning == other.beginning && ending == other.ending
48
+ end
49
+
40
50
  # @param range [Rucoa::Range]
41
51
  # @return [Boolean]
42
52
  # @example returns true when the range is contained in self
@@ -2,43 +2,28 @@
2
2
 
3
3
  module Rucoa
4
4
  module Rbs
5
- class ClassDefinitionMapper
6
- class << self
7
- # @param declaration [RBS::AST::Declarations::Class]
8
- # @return [Rucoa::Definitions::ClassDefinition]
9
- def call(declaration:)
10
- new(declaration: declaration).call
11
- end
12
- end
13
-
14
- # @param declaration [RBS::AST::Declarations::Class]
15
- def initialize(declaration:)
16
- @declaration = declaration
17
- end
18
-
5
+ class ClassDefinitionMapper < ModuleDefinitionMapper
19
6
  # @return [Rucoa::Definitions::ClassDefinition]
7
+ # @example supports `include`
8
+ # definition_store = Rucoa::DefinitionStore.new
9
+ # definition_store.bulk_add(Rucoa::DefinitionArchiver.load)
10
+ # subject = definition_store.find_definition_by_qualified_name('Array')
11
+ # expect(subject.included_module_qualified_names).to include('Enumerable')
20
12
  def call
21
13
  Definitions::ClassDefinition.new(
22
- full_qualified_name: full_qualified_name,
23
- source_path: source_path,
24
- super_class_name: super_class_name
14
+ description: description,
15
+ included_module_qualified_names: included_module_qualified_names,
16
+ location: location,
17
+ prepended_module_qualified_names: prepended_module_qualified_names,
18
+ qualified_name: qualified_name,
19
+ super_class_qualified_name: super_class_qualified_name
25
20
  )
26
21
  end
27
22
 
28
23
  private
29
24
 
30
- # @return [String]
31
- def full_qualified_name
32
- @declaration.name.to_s.delete_prefix('::')
33
- end
34
-
35
- # @return [String]
36
- def source_path
37
- @declaration.location.name
38
- end
39
-
40
25
  # @return [String, nil]
41
- def super_class_name
26
+ def super_class_qualified_name
42
27
  @declaration.super_class&.name&.to_s&.delete_prefix('::')
43
28
  end
44
29
  end
@@ -19,21 +19,27 @@ module Rucoa
19
19
  # @return [Rucoa::Definitions::ConstantDefinition]
20
20
  def call
21
21
  Definitions::ConstantDefinition.new(
22
- full_qualified_name: full_qualified_name,
23
- source_path: source_path
22
+ description: description,
23
+ location: location,
24
+ qualified_name: qualified_name
24
25
  )
25
26
  end
26
27
 
27
28
  private
28
29
 
30
+ # @return [String, nil]
31
+ def description
32
+ @declaration.comment&.string&.sub(/\A\s*<!--.*-->\s*/m, '')
33
+ end
34
+
29
35
  # @return [String]
30
- def full_qualified_name
36
+ def qualified_name
31
37
  @declaration.name.to_s.delete_prefix('::')
32
38
  end
33
39
 
34
- # @return [String]
35
- def source_path
36
- @declaration.location.name
40
+ # @return [Rucoa::Location]
41
+ def location
42
+ Location.from_rbs_location(@declaration.location)
37
43
  end
38
44
  end
39
45
  end
@@ -7,7 +7,10 @@ module Rucoa
7
7
  # @param declaration [RBS::AST::Declarations::Class, RBS::AST::Declarations::Module]
8
8
  # @param method_definition [RBS::AST::Members::MethodDefinition]
9
9
  # @return [Rucoa::Definitions::MethodDefinition]
10
- def call(declaration:, method_definition:)
10
+ def call(
11
+ declaration:,
12
+ method_definition:
13
+ )
11
14
  new(
12
15
  declaration: declaration,
13
16
  method_definition: method_definition
@@ -17,7 +20,10 @@ module Rucoa
17
20
 
18
21
  # @param declaration [RBS::AST::Declarations::Class, RBS::AST::Declarations::Module]
19
22
  # @param method_definition [RBS::AST::Members::MethodDefinition]
20
- def initialize(declaration:, method_definition:)
23
+ def initialize(
24
+ declaration:,
25
+ method_definition:
26
+ )
21
27
  @declaration = declaration
22
28
  @method_definition = method_definition
23
29
  end
@@ -27,9 +33,9 @@ module Rucoa
27
33
  Definitions::MethodDefinition.new(
28
34
  description: description,
29
35
  kind: kind,
36
+ location: location,
30
37
  method_name: method_name,
31
38
  namespace: namespace,
32
- source_path: source_path,
33
39
  types: types
34
40
  )
35
41
  end
@@ -65,9 +71,9 @@ module Rucoa
65
71
  @method_definition.kind
66
72
  end
67
73
 
68
- # @return [String]
69
- def source_path
70
- @declaration.location.name
74
+ # @return [Rucoa::Location]
75
+ def location
76
+ Location.from_rbs_location(@method_definition.location)
71
77
  end
72
78
 
73
79
  class MethodTypeMapper
@@ -19,21 +19,49 @@ module Rucoa
19
19
  # @return [Rucoa::Definitions::ModuleDefinition]
20
20
  def call
21
21
  Definitions::ModuleDefinition.new(
22
- full_qualified_name: full_qualified_name,
23
- source_path: source_path
22
+ description: description,
23
+ included_module_qualified_names: included_module_qualified_names,
24
+ location: location,
25
+ prepended_module_qualified_names: prepended_module_qualified_names,
26
+ qualified_name: qualified_name
24
27
  )
25
28
  end
26
29
 
27
30
  private
28
31
 
32
+ # @return [String, nil]
33
+ def description
34
+ @declaration.comment&.string&.sub(/\A\s*<!--.*-->\s*/m, '')
35
+ end
36
+
29
37
  # @return [String]
30
- def full_qualified_name
38
+ def qualified_name
31
39
  @declaration.name.to_s.delete_prefix('::')
32
40
  end
33
41
 
34
- # @return [String]
35
- def source_path
36
- @declaration.location.name
42
+ # @return [Rucoa::Location]
43
+ def location
44
+ Location.from_rbs_location(@declaration.location)
45
+ end
46
+
47
+ # @return [Array<String>]
48
+ def included_module_qualified_names
49
+ @declaration.members.filter_map do |member|
50
+ case member
51
+ when ::RBS::AST::Members::Include
52
+ member.name.to_s.delete_prefix('::')
53
+ end
54
+ end
55
+ end
56
+
57
+ # @return [Array<String>]
58
+ def prepended_module_qualified_names
59
+ @declaration.members.filter_map do |member|
60
+ case member
61
+ when ::RBS::AST::Members::Prepend
62
+ member.name.to_s.delete_prefix('::')
63
+ end
64
+ end
37
65
  end
38
66
  end
39
67
  end
@@ -40,10 +40,10 @@ module Rucoa
40
40
 
41
41
  # @return [String]
42
42
  def path
43
- if @source.untitled? || @source.path.nil?
43
+ if @source.untitled?
44
44
  'untitled'
45
45
  else
46
- @source.path
46
+ @source.name
47
47
  end
48
48
  end
49
49
  end
@@ -41,17 +41,20 @@ 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
48
51
 
49
52
  # @return [String]
50
53
  def path
51
- if @source.untitled? || @source.path.nil?
54
+ if @source.untitled?
52
55
  'untitled'
53
56
  else
54
- @source.path
57
+ @source.name
55
58
  end
56
59
  end
57
60
  end
data/lib/rucoa/server.rb CHANGED
@@ -59,7 +59,7 @@ module Rucoa
59
59
  @source_store = SourceStore.new
60
60
 
61
61
  @definition_store = DefinitionStore.new
62
- @definition_store.definitions += DefinitionArchiver.load
62
+ @definition_store.bulk_add(DefinitionArchiver.load)
63
63
  end
64
64
 
65
65
  # @return [void]
@@ -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
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'uri'
4
+
3
5
  module Rucoa
4
6
  class Source
5
7
  # @return [String]
@@ -9,8 +11,11 @@ module Rucoa
9
11
  attr_reader :uri
10
12
 
11
13
  # @param content [String]
12
- # @param uri [String, nil]
13
- def initialize(content:, uri: nil)
14
+ # @param uri [String]
15
+ def initialize(
16
+ content:,
17
+ uri:
18
+ )
14
19
  @content = content
15
20
  @uri = uri
16
21
  end
@@ -33,35 +38,49 @@ module Rucoa
33
38
  # a_kind_of(Rucoa::Definitions::MethodDefinition)
34
39
  # ]
35
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([])
36
53
  def definitions
37
- @definitions ||= Yard::DefinitionsLoader.load_string(
38
- content: @content,
39
- path: path
40
- )
54
+ @definitions ||=
55
+ if parse_result.failed? || root_node.nil?
56
+ []
57
+ else
58
+ Yard::DefinitionsLoader.call(
59
+ associations: parse_result.associations,
60
+ root_node: parse_result.root_node
61
+ )
62
+ end
41
63
  end
42
64
 
43
65
  # @return [String, nil]
44
- # @example returns path from given VSCode URI
66
+ # @example returns path for file URI
45
67
  # source = Rucoa::Source.new(
46
68
  # content: '',
47
69
  # uri: 'file:///path/to/foo.rb'
48
70
  # )
49
- # expect(source.path).to eq('/path/to/foo.rb')
50
- # @example returns name for untitled URI
71
+ # expect(source.name).to eq('/path/to/foo.rb')
72
+ # @example returns opaque for untitled URI
51
73
  # source = Rucoa::Source.new(
52
74
  # content: '',
53
75
  # uri: 'untitled:Untitled-1'
54
76
  # )
55
- # expect(source.path).to eq('Untitled-1')
56
- def path
57
- return unless @uri
58
-
59
- return @uri.split(':', 2).last if untitled?
60
-
61
- path = ::URI.parse(@uri).path
62
- return unless path
63
-
64
- ::CGI.unescape(path)
77
+ # expect(source.name).to eq('Untitled-1')
78
+ def name
79
+ if untitled?
80
+ uri_object.opaque
81
+ else
82
+ uri_object.path
83
+ end
65
84
  end
66
85
 
67
86
  # @param position [Rucoa::Position]
@@ -70,34 +89,45 @@ module Rucoa
70
89
  root_and_descendant_nodes.reverse.find do |node|
71
90
  node.include_position?(position)
72
91
  end
73
- rescue ::Parser::SyntaxError
74
- nil
75
92
  end
76
93
 
77
94
  # @return [Rucoa::Nodes::Base, nil]
78
95
  def root_node
79
- @root_node ||= Parser.call(@content)
80
- rescue ::Parser::SyntaxError
81
- nil
96
+ parse_result.root_node
82
97
  end
83
98
 
84
99
  # @return [Boolean]
85
- def syntax_error?
86
- root_node.nil?
100
+ def failed_to_parse?
101
+ parse_result.failed?
87
102
  end
88
103
 
89
104
  # @return [Boolean]
90
105
  def untitled?
91
- @uri&.start_with?('untitled:')
106
+ uri_object.scheme == 'untitled'
92
107
  end
93
108
 
94
109
  private
95
110
 
111
+ # @return [Rucoa::ParseResult]
112
+ def parse_result
113
+ return @parse_result if instance_variable_defined?(:@parse_result)
114
+
115
+ @parse_result = Parser.call(
116
+ text: @content,
117
+ uri: @uri
118
+ )
119
+ end
120
+
96
121
  # @return [Array<Rucoa::Nodes::Base>]
97
122
  def root_and_descendant_nodes
98
123
  return [] unless root_node
99
124
 
100
125
  [root_node, *root_node.descendants]
101
126
  end
127
+
128
+ # @return [URI]
129
+ def uri_object
130
+ @uri_object ||= ::URI.parse(@uri)
131
+ end
102
132
  end
103
133
  end
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'cgi'
4
- require 'uri'
5
-
6
3
  module Rucoa
7
4
  class SourceStore
8
5
  def initialize
@@ -26,15 +23,5 @@ module Rucoa
26
23
  def each_uri(&block)
27
24
  @data.each_key(&block)
28
25
  end
29
-
30
- private
31
-
32
- # @param uri [String]
33
- # @return [String]
34
- def path_from_uri(uri)
35
- ::CGI.unescape(
36
- ::URI.parse(uri).path || 'untitled'
37
- )
38
- end
39
26
  end
40
27
  end
@@ -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.8.0'
4
+ VERSION = '0.10.0'
5
5
  end
@@ -0,0 +1,60 @@
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
+ def call
39
+ return [] unless @node.is_a?(Nodes::SendNode) && READER_METHOD_NAMES.include?(@node.name)
40
+
41
+ @node.arguments.map do |argument|
42
+ Definitions::MethodDefinition.new(
43
+ description: description,
44
+ kind: :instance,
45
+ location: location,
46
+ method_name: argument.value.to_s,
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
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,60 @@
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
+ def call
39
+ return [] unless @node.is_a?(Nodes::SendNode) && WRITER_METHOD_NAMES.include?(@node.name)
40
+
41
+ @node.arguments.map do |argument|
42
+ Definitions::MethodDefinition.new(
43
+ description: description,
44
+ kind: :instance,
45
+ location: location,
46
+ method_name: "#{argument.value}=",
47
+ namespace: @node.namespace,
48
+ types: return_types.map do |type|
49
+ Types::MethodType.new(
50
+ parameters_string: 'value', # TODO
51
+ return_type: type
52
+ )
53
+ end
54
+ )
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end