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.
- checksums.yaml +4 -4
- data/.rubocop.yml +6 -0
- data/Gemfile.lock +8 -8
- data/data/definitions_ruby_3_1 +0 -0
- data/lib/rucoa/configuration.rb +4 -1
- data/lib/rucoa/definition_store.rb +268 -75
- data/lib/rucoa/definitions/base.rb +14 -3
- data/lib/rucoa/definitions/class_definition.rb +20 -4
- data/lib/rucoa/definitions/constant_definition.rb +31 -19
- data/lib/rucoa/definitions/method_definition.rb +44 -52
- data/lib/rucoa/definitions/method_parameter_definition.rb +4 -1
- data/lib/rucoa/definitions/module_definition.rb +39 -0
- data/lib/rucoa/handler_concerns/diagnostics_publishable.rb +14 -3
- data/lib/rucoa/handlers/base.rb +12 -3
- data/lib/rucoa/handlers/initialized_handler.rb +33 -5
- data/lib/rucoa/handlers/text_document_completion_handler.rb +1 -1
- data/lib/rucoa/handlers/text_document_definition_handler.rb +3 -99
- data/lib/rucoa/handlers/text_document_did_open_handler.rb +1 -4
- data/lib/rucoa/handlers/text_document_hover_handler.rb +21 -13
- data/lib/rucoa/handlers/text_document_selection_range_handler.rb +8 -2
- data/lib/rucoa/location.rb +37 -0
- data/lib/rucoa/node_concerns/body.rb +24 -0
- data/lib/rucoa/node_concerns/{name_full_qualifiable.rb → qualified_name.rb} +2 -2
- data/lib/rucoa/node_concerns.rb +2 -1
- data/lib/rucoa/node_inspector.rb +22 -26
- data/lib/rucoa/nodes/base.rb +51 -10
- data/lib/rucoa/nodes/begin_node.rb +8 -0
- data/lib/rucoa/nodes/casgn_node.rb +1 -1
- data/lib/rucoa/nodes/cbase_node.rb +8 -0
- data/lib/rucoa/nodes/class_node.rb +63 -1
- data/lib/rucoa/nodes/const_node.rb +64 -5
- data/lib/rucoa/nodes/def_node.rb +11 -9
- data/lib/rucoa/nodes/defs_node.rb +21 -0
- data/lib/rucoa/nodes/lvar_node.rb +2 -1
- data/lib/rucoa/nodes/module_node.rb +2 -1
- data/lib/rucoa/nodes/send_node.rb +14 -10
- data/lib/rucoa/nodes.rb +3 -1
- data/lib/rucoa/parse_result.rb +29 -0
- data/lib/rucoa/parser.rb +40 -8
- data/lib/rucoa/parser_builder.rb +7 -1
- data/lib/rucoa/position.rb +10 -1
- data/lib/rucoa/range.rb +11 -1
- data/lib/rucoa/rbs/class_definition_mapper.rb +13 -28
- data/lib/rucoa/rbs/constant_definition_mapper.rb +12 -6
- data/lib/rucoa/rbs/method_definition_mapper.rb +12 -6
- data/lib/rucoa/rbs/module_definition_mapper.rb +34 -6
- data/lib/rucoa/rubocop/autocorrector.rb +2 -2
- data/lib/rucoa/rubocop/investigator.rb +6 -3
- data/lib/rucoa/server.rb +9 -3
- data/lib/rucoa/source.rb +57 -27
- data/lib/rucoa/source_store.rb +0 -13
- data/lib/rucoa/unqualified_name.rb +9 -0
- data/lib/rucoa/version.rb +1 -1
- data/lib/rucoa/yard/definition_generators/attribute_reader_definition_generator.rb +60 -0
- data/lib/rucoa/yard/definition_generators/attribute_writer_definition_generator.rb +60 -0
- data/lib/rucoa/yard/definition_generators/base.rb +117 -0
- data/lib/rucoa/yard/definition_generators/class_definition_generator.rb +66 -0
- data/lib/rucoa/yard/definition_generators/constant_assignment_definition_generator.rb +29 -0
- data/lib/rucoa/yard/definition_generators/method_definition_generator.rb +47 -0
- data/lib/rucoa/yard/definition_generators/module_definition_generator.rb +62 -0
- data/lib/rucoa/yard/definition_generators.rb +15 -0
- data/lib/rucoa/yard/definitions_loader.rb +44 -65
- data/lib/rucoa/yard/type.rb +46 -0
- data/lib/rucoa/yard.rb +2 -1
- data/lib/rucoa.rb +4 -1
- metadata +18 -4
- data/lib/rucoa/yard/method_definition_mapper.rb +0 -215
data/lib/rucoa/parser_builder.rb
CHANGED
@@ -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(
|
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,
|
data/lib/rucoa/position.rb
CHANGED
@@ -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(
|
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(
|
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
|
-
|
23
|
-
|
24
|
-
|
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
|
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
|
-
|
23
|
-
|
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
|
36
|
+
def qualified_name
|
31
37
|
@declaration.name.to_s.delete_prefix('::')
|
32
38
|
end
|
33
39
|
|
34
|
-
# @return [
|
35
|
-
def
|
36
|
-
@declaration.location
|
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(
|
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(
|
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 [
|
69
|
-
def
|
70
|
-
@
|
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
|
-
|
23
|
-
|
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
|
38
|
+
def qualified_name
|
31
39
|
@declaration.name.to_s.delete_prefix('::')
|
32
40
|
end
|
33
41
|
|
34
|
-
# @return [
|
35
|
-
def
|
36
|
-
@declaration.location
|
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
|
@@ -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(
|
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?
|
54
|
+
if @source.untitled?
|
52
55
|
'untitled'
|
53
56
|
else
|
54
|
-
@source.
|
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.
|
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(
|
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(
|
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
|
13
|
-
def initialize(
|
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 ||=
|
38
|
-
|
39
|
-
|
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
|
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.
|
50
|
-
# @example returns
|
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.
|
56
|
-
def
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
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
|
-
|
80
|
-
rescue ::Parser::SyntaxError
|
81
|
-
nil
|
96
|
+
parse_result.root_node
|
82
97
|
end
|
83
98
|
|
84
99
|
# @return [Boolean]
|
85
|
-
def
|
86
|
-
|
100
|
+
def failed_to_parse?
|
101
|
+
parse_result.failed?
|
87
102
|
end
|
88
103
|
|
89
104
|
# @return [Boolean]
|
90
105
|
def untitled?
|
91
|
-
|
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
|
data/lib/rucoa/source_store.rb
CHANGED
@@ -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
|
data/lib/rucoa/version.rb
CHANGED
@@ -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
|