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.
- checksums.yaml +4 -4
- data/.rubocop.yml +9 -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 +350 -105
- data/lib/rucoa/definitions/base.rb +14 -3
- data/lib/rucoa/definitions/class_definition.rb +14 -64
- 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 +53 -0
- data/lib/rucoa/handler_concerns/diagnostics_publishable.rb +14 -3
- data/lib/rucoa/handlers/base.rb +12 -3
- data/lib/rucoa/handlers/text_document_definition_handler.rb +3 -99
- 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_fully_qualifiable.rb → qualified_name.rb} +2 -2
- data/lib/rucoa/node_concerns.rb +2 -1
- data/lib/rucoa/node_inspector.rb +29 -23
- data/lib/rucoa/nodes/base.rb +22 -6
- data/lib/rucoa/nodes/begin_node.rb +8 -0
- data/lib/rucoa/nodes/casgn_node.rb +1 -1
- data/lib/rucoa/nodes/class_node.rb +2 -1
- data/lib/rucoa/nodes/const_node.rb +33 -15
- data/lib/rucoa/nodes/def_node.rb +2 -2
- data/lib/rucoa/nodes/defs_node.rb +1 -1
- data/lib/rucoa/nodes/module_node.rb +2 -1
- data/lib/rucoa/nodes.rb +2 -1
- data/lib/rucoa/parser.rb +14 -14
- data/lib/rucoa/parser_builder.rb +6 -1
- data/lib/rucoa/position.rb +10 -1
- data/lib/rucoa/range.rb +11 -1
- data/lib/rucoa/rbs/class_definition_mapper.rb +14 -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 +39 -6
- data/lib/rucoa/rubocop/investigator.rb +4 -1
- data/lib/rucoa/server.rb +9 -3
- data/lib/rucoa/source.rb +19 -4
- 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 +76 -0
- data/lib/rucoa/yard/definition_generators/attribute_writer_definition_generator.rb +76 -0
- data/lib/rucoa/yard/definition_generators/base.rb +117 -0
- data/lib/rucoa/yard/definition_generators/class_definition_generator.rb +67 -0
- data/lib/rucoa/yard/definition_generators/constant_assignment_definition_generator.rb +29 -0
- data/lib/rucoa/yard/definition_generators/method_definition_generator.rb +60 -0
- data/lib/rucoa/yard/definition_generators/module_definition_generator.rb +68 -0
- data/lib/rucoa/yard/definition_generators.rb +15 -0
- data/lib/rucoa/yard/definitions_loader.rb +1 -271
- data/lib/rucoa/yard.rb +1 -0
- data/lib/rucoa.rb +4 -2
- 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
|
-
|
23
|
-
|
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
|
39
|
+
def qualified_name
|
31
40
|
@declaration.name.to_s.delete_prefix('::')
|
32
41
|
end
|
33
42
|
|
34
|
-
# @return [
|
35
|
-
def
|
36
|
-
@declaration.location
|
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
|
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(
|
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
@@ -12,7 +12,10 @@ module Rucoa
|
|
12
12
|
|
13
13
|
# @param content [String]
|
14
14
|
# @param uri [String]
|
15
|
-
def initialize(
|
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
|
-
|
102
|
-
|
116
|
+
text: @content,
|
117
|
+
uri: @uri
|
103
118
|
)
|
104
119
|
end
|
105
120
|
|
data/lib/rucoa/version.rb
CHANGED
@@ -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
|