ruby_mod_kit 0.0.4 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby_mod_kit.yml +1 -0
- data/.yardopts +3 -0
- data/README.md +89 -0
- data/examples/user.rb +4 -16
- data/lib/ruby_mod_kit/cli.rb +5 -0
- data/lib/ruby_mod_kit/config.rb +6 -1
- data/lib/ruby_mod_kit/core_ext/eval.rb +13 -10
- data/lib/ruby_mod_kit/core_ext/load.rb +10 -0
- data/lib/ruby_mod_kit/corrector.rb +8 -0
- data/lib/ruby_mod_kit/corrector_manager.rb +16 -6
- data/lib/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_corrector.rb +4 -0
- data/lib/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_mission.rb +3 -1
- data/lib/ruby_mod_kit/feature/instance_variable_parameter.rb +2 -0
- data/lib/ruby_mod_kit/feature/overload/overload_mission.rb +44 -13
- data/lib/ruby_mod_kit/feature/overload.rb +1 -0
- data/lib/ruby_mod_kit/feature/type/check/arguments/add_arguments_checker_mission.rb +58 -0
- data/lib/ruby_mod_kit/feature/type/check/arguments.rb +25 -0
- data/lib/ruby_mod_kit/feature/type/instance_variable_colon_corrector.rb +13 -4
- data/lib/ruby_mod_kit/feature/type/parameter_arrow_corrector.rb +41 -5
- data/lib/ruby_mod_kit/feature/type/rbs_inline/add_magic_comment_mission.rb +3 -0
- data/lib/ruby_mod_kit/feature/type/rbs_inline/type_attr_mission.rb +2 -0
- data/lib/ruby_mod_kit/feature/type/rbs_inline/type_instance_variable_mission.rb +5 -2
- data/lib/ruby_mod_kit/feature/type/rbs_inline/type_overload_mission.rb +3 -2
- data/lib/ruby_mod_kit/feature/type/rbs_inline/type_parameter_mission.rb +7 -4
- data/lib/ruby_mod_kit/feature/type/rbs_inline/type_return_mission.rb +3 -1
- data/lib/ruby_mod_kit/feature/type/rbs_inline.rb +1 -0
- data/lib/ruby_mod_kit/feature/type/return_value_colon_corrector.rb +5 -0
- data/lib/ruby_mod_kit/feature/type/type_attr_mission.rb +6 -9
- data/lib/ruby_mod_kit/feature/type/yard/type_parameter_mission.rb +37 -0
- data/lib/ruby_mod_kit/feature/type/yard/type_return_mission.rb +32 -0
- data/lib/ruby_mod_kit/feature/type/yard.rb +34 -0
- data/lib/ruby_mod_kit/feature/type.rb +2 -0
- data/lib/ruby_mod_kit/feature.rb +2 -0
- data/lib/ruby_mod_kit/generation.rb +67 -49
- data/lib/ruby_mod_kit/memo/def_parent_memo.rb +6 -0
- data/lib/ruby_mod_kit/memo/ivar_memo.rb +18 -8
- data/lib/ruby_mod_kit/memo/method_memo.rb +8 -1
- data/lib/ruby_mod_kit/memo/offset_memo.rb +4 -0
- data/lib/ruby_mod_kit/memo/overload_memo.rb +9 -1
- data/lib/ruby_mod_kit/memo/parameter_memo.rb +10 -3
- data/lib/ruby_mod_kit/memo_pad.rb +34 -0
- data/lib/ruby_mod_kit/mission.rb +2 -4
- data/lib/ruby_mod_kit/node/base_node.rb +43 -3
- data/lib/ruby_mod_kit/node/begin_node.rb +35 -0
- data/lib/ruby_mod_kit/node/call_node.rb +4 -0
- data/lib/ruby_mod_kit/node/def_node.rb +36 -0
- data/lib/ruby_mod_kit/node/def_parent_node.rb +10 -2
- data/lib/ruby_mod_kit/node/parameter_node.rb +7 -2
- data/lib/ruby_mod_kit/node/program_node.rb +3 -0
- data/lib/ruby_mod_kit/node/statements_node.rb +4 -0
- data/lib/ruby_mod_kit/node/symbol_node.rb +7 -2
- data/lib/ruby_mod_kit/node/untyped_node.rb +4 -0
- data/lib/ruby_mod_kit/node/wrap.rb +7 -1
- data/lib/ruby_mod_kit/node.rb +1 -0
- data/lib/ruby_mod_kit/offset_diff.rb +6 -0
- data/lib/ruby_mod_kit/version.rb +1 -1
- data/lib/ruby_mod_kit.rb +29 -8
- data/sig/generated/ruby_mod_kit/cli.rbs +5 -0
- data/sig/generated/ruby_mod_kit/config.rbs +7 -2
- data/sig/generated/ruby_mod_kit/core_ext/eval.rbs +11 -2
- data/sig/generated/ruby_mod_kit/core_ext/load.rbs +10 -0
- data/sig/generated/ruby_mod_kit/corrector.rbs +8 -0
- data/sig/generated/ruby_mod_kit/corrector_manager.rbs +7 -1
- data/sig/generated/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_corrector.rbs +4 -0
- data/sig/generated/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_mission.rbs +2 -0
- data/sig/generated/ruby_mod_kit/feature/instance_variable_parameter.rbs +2 -0
- data/sig/generated/ruby_mod_kit/feature/overload/overload_mission.rbs +3 -0
- data/sig/generated/ruby_mod_kit/feature/overload.rbs +1 -0
- data/sig/generated/ruby_mod_kit/feature/type/check/arguments/add_arguments_checker_mission.rbs +18 -0
- data/sig/generated/ruby_mod_kit/feature/type/check/arguments.rbs +17 -0
- data/sig/generated/ruby_mod_kit/feature/type/instance_variable_colon_corrector.rbs +4 -0
- data/sig/generated/ruby_mod_kit/feature/type/parameter_arrow_corrector.rbs +19 -0
- data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/add_magic_comment_mission.rbs +3 -0
- data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_attr_mission.rbs +2 -0
- data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_instance_variable_mission.rbs +2 -0
- data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_overload_mission.rbs +2 -0
- data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_parameter_mission.rbs +2 -0
- data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_return_mission.rbs +2 -0
- data/sig/generated/ruby_mod_kit/feature/type/rbs_inline.rbs +1 -0
- data/sig/generated/ruby_mod_kit/feature/type/return_value_colon_corrector.rbs +4 -0
- data/sig/generated/ruby_mod_kit/feature/type/type_attr_mission.rbs +3 -0
- data/sig/generated/ruby_mod_kit/feature/type/yard/type_parameter_mission.rbs +18 -0
- data/sig/generated/ruby_mod_kit/feature/type/yard/type_return_mission.rbs +18 -0
- data/sig/generated/ruby_mod_kit/feature/type/yard.rbs +20 -0
- data/sig/generated/ruby_mod_kit/feature/type.rbs +2 -0
- data/sig/generated/ruby_mod_kit/feature.rbs +2 -0
- data/sig/generated/ruby_mod_kit/generation.rbs +46 -25
- data/sig/generated/ruby_mod_kit/memo/def_parent_memo.rbs +6 -0
- data/sig/generated/ruby_mod_kit/memo/ivar_memo.rbs +20 -8
- data/sig/generated/ruby_mod_kit/memo/method_memo.rbs +8 -1
- data/sig/generated/ruby_mod_kit/memo/offset_memo.rbs +4 -0
- data/sig/generated/ruby_mod_kit/memo/overload_memo.rbs +8 -0
- data/sig/generated/ruby_mod_kit/memo/parameter_memo.rbs +12 -3
- data/sig/generated/ruby_mod_kit/memo_pad.rbs +23 -0
- data/sig/generated/ruby_mod_kit/mission.rbs +2 -4
- data/sig/generated/ruby_mod_kit/node/base_node.rbs +36 -3
- data/sig/generated/ruby_mod_kit/node/begin_node.rbs +30 -0
- data/sig/generated/ruby_mod_kit/node/call_node.rbs +4 -0
- data/sig/generated/ruby_mod_kit/node/def_node.rbs +24 -0
- data/sig/generated/ruby_mod_kit/node/def_parent_node.rbs +11 -3
- data/sig/generated/ruby_mod_kit/node/parameter_node.rbs +6 -1
- data/sig/generated/ruby_mod_kit/node/program_node.rbs +3 -0
- data/sig/generated/ruby_mod_kit/node/statements_node.rbs +4 -0
- data/sig/generated/ruby_mod_kit/node/symbol_node.rbs +8 -3
- data/sig/generated/ruby_mod_kit/node/untyped_node.rbs +4 -0
- data/sig/generated/ruby_mod_kit/node/wrap.rbs +4 -0
- data/sig/generated/ruby_mod_kit/offset_diff.rbs +6 -0
- data/sig/generated/ruby_mod_kit.rbs +31 -6
- metadata +15 -2
@@ -7,14 +7,27 @@ module RubyModKit
|
|
7
7
|
class Type
|
8
8
|
# the class to correct `def foo(Bar => bar, *Buz => buz)` -> `def foo(bar, *buz)`
|
9
9
|
class ParameterArrowCorrector < Corrector
|
10
|
+
# @rbs @last_parameter_offsets: Set[Integer]
|
11
|
+
|
10
12
|
# @rbs return: Array[Symbol]
|
13
|
+
# @return [Array<Symbol>]
|
11
14
|
def correctable_error_types
|
12
15
|
%i[unexpected_token_ignore def_params_term_paren argument_formal_constant]
|
13
16
|
end
|
14
17
|
|
18
|
+
# @rbs return: void
|
19
|
+
# @return [void]
|
20
|
+
def setup
|
21
|
+
super
|
22
|
+
@last_parameter_offsets = Set.new
|
23
|
+
end
|
24
|
+
|
15
25
|
# @rbs parse_error: Prism::ParseError
|
16
26
|
# @rbs generation: Generation
|
17
27
|
# @rbs return: void
|
28
|
+
# @param parse_error [Prism::ParseError]
|
29
|
+
# @param generation [Generation]
|
30
|
+
# @return [void]
|
18
31
|
def correct(parse_error, generation)
|
19
32
|
case parse_error.type
|
20
33
|
when :unexpected_token_ignore
|
@@ -31,46 +44,69 @@ module RubyModKit
|
|
31
44
|
# @rbs parse_error: Prism::ParseError
|
32
45
|
# @rbs generation: Generation
|
33
46
|
# @rbs return: void
|
47
|
+
# @param parse_error [Prism::ParseError]
|
48
|
+
# @param generation [Generation]
|
49
|
+
# @return [void]
|
34
50
|
def remove_arrow_before_parameter(parse_error, generation)
|
35
51
|
def_node = generation.root_node.def_node_at(parse_error.location.start_offset) || return
|
36
52
|
def_parent_node = def_node.parent
|
37
53
|
parameters_node, body_node, = def_node.children
|
54
|
+
body_node = body_node.children[0] if body_node.is_a?(Node::BeginNode)
|
38
55
|
return if !def_parent_node || !parameters_node || !body_node
|
39
56
|
|
40
57
|
last_parameter_node = parameters_node.children.max_by(&:offset) || return
|
41
58
|
last_parameter_offset = last_parameter_node.offset
|
59
|
+
return if @last_parameter_offsets.include?(last_parameter_offset)
|
42
60
|
|
61
|
+
@last_parameter_offsets << last_parameter_offset
|
43
62
|
right_node = body_node.children.find { _1.offset >= parse_error.location.end_offset } || return
|
44
63
|
right_offset = right_node.offset
|
64
|
+
name = right_node.slice[/\A\w+/]
|
45
65
|
parameter_type = generation[last_parameter_offset...right_offset] || raise(RubyModKit::Error)
|
46
66
|
parameter_type = parameter_type.sub(/\s*=>\s*\z/, "")
|
47
|
-
|
48
|
-
|
67
|
+
qualifier = nil
|
68
|
+
parameter_type = parameter_type.sub(/\A&\(\((.*)\) *: +(.*)\)\z/) do
|
69
|
+
qualifier = "&"
|
70
|
+
"(#{::Regexp.last_match(1)}) -> #{::Regexp.last_match(2)}"
|
71
|
+
end
|
72
|
+
generation[last_parameter_offset, right_offset - last_parameter_offset] = qualifier.to_s
|
73
|
+
parameter_memo = generation.memo_pad.parameter_memo(last_parameter_node)
|
74
|
+
parameter_memo.name = name.to_sym if name
|
75
|
+
parameter_memo.type = parameter_type
|
76
|
+
parameter_memo.qualifier = qualifier if qualifier
|
49
77
|
end
|
50
78
|
|
51
79
|
# @rbs parse_error: Prism::ParseError
|
52
80
|
# @rbs generation: Generation
|
53
81
|
# @rbs return: void
|
82
|
+
# @param parse_error [Prism::ParseError]
|
83
|
+
# @param generation [Generation]
|
84
|
+
# @return [void]
|
54
85
|
def remove_arrow_after_quailifier(parse_error, generation)
|
55
86
|
column = parse_error.location.start_column - 1
|
56
87
|
return if column < 0
|
57
88
|
|
58
89
|
line = generation.line(parse_error)[column..] || return
|
59
|
-
line =~
|
60
|
-
length = ::Regexp.last_match(
|
61
|
-
type = ::Regexp.last_match(
|
90
|
+
line =~ /(\A\*(.*?)\s*=>\s*)(\w*)/
|
91
|
+
length = ::Regexp.last_match(1)&.length || return
|
92
|
+
type = ::Regexp.last_match(2) || return
|
93
|
+
name = ::Regexp.last_match(3)
|
62
94
|
offset = parse_error.location.start_offset - 1
|
63
95
|
parameter_position_node = generation.root_node.node_at(offset + length) || return
|
64
96
|
|
65
97
|
generation[parse_error.location.start_offset, length - 1] = ""
|
66
98
|
parameter_memo = generation.memo_pad.parameter_memo(parameter_position_node)
|
67
99
|
parameter_memo.type = type
|
100
|
+
parameter_memo.name = name.to_sym if name
|
68
101
|
parameter_memo.qualifier = "*"
|
69
102
|
end
|
70
103
|
|
71
104
|
# @rbs parse_error: Prism::ParseError
|
72
105
|
# @rbs generation: Generation
|
73
106
|
# @rbs return: void
|
107
|
+
# @param parse_error [Prism::ParseError]
|
108
|
+
# @param generation [Generation]
|
109
|
+
# @return [void]
|
74
110
|
def wrap_parameter_type_for_next_parse(parse_error, generation)
|
75
111
|
line = generation.line(parse_error)
|
76
112
|
line = line[parse_error.location.start_column..] || return
|
@@ -11,6 +11,7 @@ module RubyModKit
|
|
11
11
|
# @rbs @reloaded: bool
|
12
12
|
|
13
13
|
# @rbs return: void
|
14
|
+
# @return [void]
|
14
15
|
def initialize
|
15
16
|
super
|
16
17
|
@reloaded = false
|
@@ -18,6 +19,8 @@ module RubyModKit
|
|
18
19
|
|
19
20
|
# @rbs generation: Generation
|
20
21
|
# @rbs return: bool
|
22
|
+
# @param generation [Generation]
|
23
|
+
# @return [Boolean]
|
21
24
|
def perform(generation)
|
22
25
|
return true unless generation.memo_pad.flags[:rbs_annotated]
|
23
26
|
|
@@ -10,6 +10,8 @@ module RubyModKit
|
|
10
10
|
class TypeAttrMission < Mission
|
11
11
|
# @rbs generation: Generation
|
12
12
|
# @rbs return: bool
|
13
|
+
# @param generation [Generation]
|
14
|
+
# @return [Boolean]
|
13
15
|
def perform(generation)
|
14
16
|
generation.memo_pad.def_parents_memo.each_value do |def_parent_memo|
|
15
17
|
ivars_memo = def_parent_memo.ivars_memo.dup
|
@@ -10,14 +10,17 @@ module RubyModKit
|
|
10
10
|
class TypeInstanceVariableMission < Mission
|
11
11
|
# @rbs generation: Generation
|
12
12
|
# @rbs return: bool
|
13
|
+
# @param generation [Generation]
|
14
|
+
# @return [Boolean]
|
13
15
|
def perform(generation)
|
14
16
|
generation.memo_pad.def_parents_memo.each_value do |def_parent_memo|
|
15
17
|
def_parent_memo.ivars_memo.each do |name, ivar_memo|
|
16
18
|
offset = ivar_memo.offset || next
|
17
19
|
def_parent_node = generation.root_node.def_parent_node_at(offset) || next
|
18
|
-
body_line_offset = generation.
|
20
|
+
body_line_offset = generation.line_offset(def_parent_node, 1) || next
|
19
21
|
generation.memo_pad.flags[:rbs_annotated] = true
|
20
|
-
|
22
|
+
script = "#{ivar_memo.indent}# @rbs @#{name}: #{ivar_memo.type}\n#{ivar_memo.separator}"
|
23
|
+
generation[body_line_offset, 0] = script
|
21
24
|
end
|
22
25
|
end
|
23
26
|
true
|
@@ -10,13 +10,14 @@ module RubyModKit
|
|
10
10
|
class TypeOverloadMission < Mission
|
11
11
|
# @rbs generation: Generation
|
12
12
|
# @rbs return: bool
|
13
|
+
# @param generation [Generation]
|
14
|
+
# @return [Boolean]
|
13
15
|
def perform(generation)
|
14
16
|
generation.memo_pad.overloads_memo.each_value do |overload_memo|
|
15
17
|
overload_memo.correct_offset(generation.root_node)
|
16
18
|
offset = overload_memo.offset
|
17
19
|
def_node = generation.root_node.def_node_at(offset) || raise(RubyModKit::Error)
|
18
|
-
|
19
|
-
indent = generation.lines[start_line][/\A */] || ""
|
20
|
+
indent = generation.line_indent(def_node)
|
20
21
|
offset -= indent.length
|
21
22
|
|
22
23
|
annotation = +""
|
@@ -10,22 +10,25 @@ module RubyModKit
|
|
10
10
|
class TypeParameterMission < Mission
|
11
11
|
# @rbs generation: Generation
|
12
12
|
# @rbs return: bool
|
13
|
+
# @param generation [Generation]
|
14
|
+
# @return [Boolean]
|
13
15
|
def perform(generation)
|
14
|
-
generation.memo_pad.
|
16
|
+
generation.memo_pad.each_parameter_memo do |parameter_memo|
|
15
17
|
next if parameter_memo.untyped?
|
16
18
|
|
19
|
+
offset = parameter_memo.offset
|
17
20
|
def_node = generation.root_node.def_node_at(offset)
|
18
21
|
raise RubyModKit::Error, "DefNode not found" if !def_node || !def_node.is_a?(Node::DefNode)
|
19
22
|
|
20
23
|
parameter_node = generation.root_node.parameter_node_at(offset)
|
21
24
|
raise RubyModKit::Error, "ParameterNode not found" unless parameter_node
|
22
25
|
|
26
|
+
line_offset = generation.line_offset(def_node) || raise(RubyModKit::Error)
|
23
27
|
type = parameter_memo.type
|
24
|
-
|
25
|
-
indent = def_node.offset - src_offset
|
28
|
+
indent = generation.line_indent(def_node)
|
26
29
|
qualified_name = "#{parameter_memo.qualifier}#{parameter_node.name}"
|
27
30
|
generation.memo_pad.flags[:rbs_annotated] = true
|
28
|
-
generation[
|
31
|
+
generation[line_offset, 0] = "#{indent}# @rbs #{qualified_name}: #{type}\n"
|
29
32
|
end
|
30
33
|
true
|
31
34
|
end
|
@@ -10,13 +10,15 @@ module RubyModKit
|
|
10
10
|
class TypeReturnMission < Mission
|
11
11
|
# @rbs generation: Generation
|
12
12
|
# @rbs return: bool
|
13
|
+
# @param generation [Generation]
|
14
|
+
# @return [Boolean]
|
13
15
|
def perform(generation)
|
14
16
|
generation.memo_pad.methods_memo.each do |offset, method_memo|
|
15
17
|
def_node = generation.root_node.def_node_at(offset)
|
16
18
|
raise RubyModKit::Error, "DefNode not found" if !def_node || !def_node.is_a?(Node::DefNode)
|
17
19
|
next if method_memo.untyped?
|
18
20
|
|
19
|
-
src_offset = generation.
|
21
|
+
src_offset = generation.line_offset(def_node) || raise(RubyModKit::Error)
|
20
22
|
indent = offset - src_offset
|
21
23
|
generation.memo_pad.flags[:rbs_annotated] = true
|
22
24
|
generation[src_offset, 0] = "#{" " * indent}# @rbs return: #{method_memo.type}\n"
|
@@ -8,6 +8,7 @@ module RubyModKit
|
|
8
8
|
# the class to correct `def foo: Some ...` -> `def foo ...`
|
9
9
|
class ReturnValueColonCorrector < Corrector
|
10
10
|
# @rbs return: Array[Symbol]
|
11
|
+
# @return [Array<Symbol>]
|
11
12
|
def correctable_error_types
|
12
13
|
%i[unexpected_token_ignore]
|
13
14
|
end
|
@@ -15,10 +16,14 @@ module RubyModKit
|
|
15
16
|
# @rbs parse_error: Prism::ParseError
|
16
17
|
# @rbs generation: Generation
|
17
18
|
# @rbs return: void
|
19
|
+
# @param parse_error [Prism::ParseError]
|
20
|
+
# @param generation [Generation]
|
21
|
+
# @return [void]
|
18
22
|
def correct(parse_error, generation)
|
19
23
|
return if parse_error.location.slice != ":"
|
20
24
|
|
21
25
|
def_node = generation.root_node.statements_node_at(parse_error.location.start_offset)&.parent
|
26
|
+
def_node = def_node.parent if def_node.is_a?(Node::BeginNode)
|
22
27
|
return unless def_node.is_a?(Node::DefNode)
|
23
28
|
|
24
29
|
lparen_loc = def_node.lparen_loc
|
@@ -10,6 +10,7 @@ module RubyModKit
|
|
10
10
|
# @rbs @modified: bool
|
11
11
|
|
12
12
|
# @rbs return: void
|
13
|
+
# @return [void]
|
13
14
|
def initialize
|
14
15
|
super
|
15
16
|
@modified = false
|
@@ -17,6 +18,8 @@ module RubyModKit
|
|
17
18
|
|
18
19
|
# @rbs generation: Generation
|
19
20
|
# @rbs return: bool
|
21
|
+
# @param generation [Generation]
|
22
|
+
# @return [Boolean]
|
20
23
|
def perform(generation)
|
21
24
|
return true if @modified
|
22
25
|
|
@@ -29,19 +32,13 @@ module RubyModKit
|
|
29
32
|
ivars_memo.keep_if { |_, ivar_memo| ivar_memo.attr_kind }
|
30
33
|
next if ivars_memo.empty?
|
31
34
|
|
32
|
-
add_first_separator_line = false
|
33
35
|
if attr_adding_line == 0
|
34
36
|
attr_adding_line = def_parent_node.location.start_line
|
35
|
-
|
36
|
-
while generation.line(attr_adding_line) =~ /\A\s*#.*|\A$/
|
37
|
-
prev_line = ::Regexp.last_match(0)
|
38
|
-
attr_adding_line += 1
|
39
|
-
end
|
40
|
-
add_first_separator_line = prev_line != ""
|
37
|
+
attr_adding_line += 1 while generation.line(attr_adding_line) =~ /\A\s*#.*|\A$/
|
41
38
|
end
|
42
39
|
line = generation.line(attr_adding_line) || next
|
43
40
|
add_separator_line = line != "\n" && line !~ /\A\s*end$/
|
44
|
-
offset = generation.
|
41
|
+
offset = generation.line_offset(attr_adding_line) || next
|
45
42
|
|
46
43
|
body_node = def_parent_node.body_node
|
47
44
|
if body_node
|
@@ -50,9 +47,9 @@ module RubyModKit
|
|
50
47
|
else
|
51
48
|
def_parent_line = generation.line(def_parent_node)
|
52
49
|
indent = " #{def_parent_line[/\A\s*/]}"
|
50
|
+
generation[offset, 0] = "\n"
|
53
51
|
end
|
54
52
|
|
55
|
-
generation[offset, 0] = "\n" if add_first_separator_line
|
56
53
|
ivars_memo.each do |name, ivar_memo|
|
57
54
|
attr = ivar_memo.attr_kind
|
58
55
|
attr = "#{ivar_memo.visibility} #{attr}" if ivar_memo.visibility
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rbs_inline: enabled
|
4
|
+
|
5
|
+
module RubyModKit
|
6
|
+
class Feature
|
7
|
+
class Type
|
8
|
+
class Yard
|
9
|
+
# The mission for parameter types
|
10
|
+
class TypeParameterMission < Mission
|
11
|
+
# @rbs generation: Generation
|
12
|
+
# @rbs return: bool
|
13
|
+
# @param generation [Generation]
|
14
|
+
# @return [Boolean]
|
15
|
+
def perform(generation)
|
16
|
+
generation.memo_pad.each_parameter_memo do |parameter_memo|
|
17
|
+
next if parameter_memo.untyped?
|
18
|
+
|
19
|
+
offset = parameter_memo.offset
|
20
|
+
def_node = generation.root_node.def_node_at(offset)
|
21
|
+
raise RubyModKit::Error, "DefNode not found" if !def_node || !def_node.is_a?(Node::DefNode)
|
22
|
+
|
23
|
+
parameter_node = generation.root_node.parameter_node_at(offset)
|
24
|
+
raise RubyModKit::Error, "ParameterNode not found" unless parameter_node
|
25
|
+
|
26
|
+
line_offset = generation.line_offset(def_node) || raise(RubyModKit::Error)
|
27
|
+
indent = generation.line_indent(def_node)
|
28
|
+
script = "#{indent}# @param #{parameter_node.name} [#{Yard.rbs2yard(parameter_memo.type)}]\n"
|
29
|
+
generation[line_offset, 0] = script
|
30
|
+
end
|
31
|
+
true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rbs_inline: enabled
|
4
|
+
|
5
|
+
module RubyModKit
|
6
|
+
class Feature
|
7
|
+
class Type
|
8
|
+
class Yard
|
9
|
+
# The mission for return value type
|
10
|
+
class TypeReturnMission < Mission
|
11
|
+
# @rbs generation: Generation
|
12
|
+
# @rbs return: bool
|
13
|
+
# @param generation [Generation]
|
14
|
+
# @return [Boolean]
|
15
|
+
def perform(generation)
|
16
|
+
generation.memo_pad.methods_memo.each do |offset, method_memo|
|
17
|
+
def_node = generation.root_node.def_node_at(offset)
|
18
|
+
raise RubyModKit::Error, "DefNode not found" if !def_node || !def_node.is_a?(Node::DefNode)
|
19
|
+
next if method_memo.untyped?
|
20
|
+
|
21
|
+
src_offset = generation.line_offset(def_node) || raise(RubyModKit::Error)
|
22
|
+
indent = offset - src_offset
|
23
|
+
generation.memo_pad.flags[:rbs_annotated] = true
|
24
|
+
generation[src_offset, 0] = "#{" " * indent}# @return [#{Yard.rbs2yard(method_memo.type)}]\n"
|
25
|
+
end
|
26
|
+
true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rbs_inline: enabled
|
4
|
+
|
5
|
+
module RubyModKit
|
6
|
+
class Feature
|
7
|
+
class Type
|
8
|
+
# namespace for type with rbs-line feature
|
9
|
+
class Yard < Feature
|
10
|
+
# @rbs return: Array[Mission]
|
11
|
+
# @return [Array<Mission>]
|
12
|
+
def create_missions
|
13
|
+
[
|
14
|
+
TypeParameterMission.new,
|
15
|
+
TypeReturnMission.new,
|
16
|
+
]
|
17
|
+
end
|
18
|
+
|
19
|
+
class << self
|
20
|
+
# @rbs type: String
|
21
|
+
# @rbs return: String
|
22
|
+
# @param type [String]
|
23
|
+
# @return [String]
|
24
|
+
def rbs2yard(type)
|
25
|
+
type.gsub(/\s*\|\s*/, ", ").tr("[]", "<>").gsub(/(?<=^|\W)bool(?=$|\W)/, "Boolean")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
require_relative "yard/type_parameter_mission"
|
34
|
+
require_relative "yard/type_return_mission"
|
@@ -7,6 +7,7 @@ module RubyModKit
|
|
7
7
|
# namespace for type feature
|
8
8
|
class Type < Feature
|
9
9
|
# @rbs return: Array[Corrector]
|
10
|
+
# @return [Array<Corrector>]
|
10
11
|
def create_correctors
|
11
12
|
[
|
12
13
|
InstanceVariableColonCorrector.new,
|
@@ -16,6 +17,7 @@ module RubyModKit
|
|
16
17
|
end
|
17
18
|
|
18
19
|
# @rbs return: Array[Mission]
|
20
|
+
# @return [Array<Mission>]
|
19
21
|
def create_missions
|
20
22
|
[
|
21
23
|
TypeAttrMission.new,
|
data/lib/ruby_mod_kit/feature.rb
CHANGED
@@ -6,11 +6,13 @@ module RubyModKit
|
|
6
6
|
# the base class of feature
|
7
7
|
class Feature
|
8
8
|
# @rbs return: Array[Corrector]
|
9
|
+
# @return [Array<Corrector>]
|
9
10
|
def create_correctors
|
10
11
|
[]
|
11
12
|
end
|
12
13
|
|
13
14
|
# @rbs return: Array[Mission]
|
15
|
+
# @return [Array<Mission>]
|
14
16
|
def create_missions
|
15
17
|
[]
|
16
18
|
end
|
@@ -18,6 +18,7 @@ module RubyModKit
|
|
18
18
|
# @rbs @errors: Array[Prism::ParseError]
|
19
19
|
# @rbs @lines: Array[String]
|
20
20
|
# @rbs @offsets: Array[Integer]
|
21
|
+
# @rbs @source: String
|
21
22
|
|
22
23
|
attr_reader :script #: String
|
23
24
|
attr_reader :memo_pad #: MemoPad
|
@@ -35,6 +36,15 @@ module RubyModKit
|
|
35
36
|
# @rbs corrector_manager: CorrectorManager | nil
|
36
37
|
# @rbs features: Array[Feature] | nil
|
37
38
|
# @rbs return: void
|
39
|
+
# @param script [String]
|
40
|
+
# @param missions [Array<Mission>]
|
41
|
+
# @param memo_pad [MemoPad, nil]
|
42
|
+
# @param generation_num [Integer]
|
43
|
+
# @param config [Config, nil]
|
44
|
+
# @param filename [String, nil]
|
45
|
+
# @param corrector_manager [CorrectorManager, nil]
|
46
|
+
# @param features [Array<Feature>, nil]
|
47
|
+
# @return [void]
|
38
48
|
def initialize(script, missions: [], memo_pad: nil, generation_num: 0, config: nil,
|
39
49
|
filename: nil, corrector_manager: nil, features: nil)
|
40
50
|
@script = script
|
@@ -51,11 +61,13 @@ module RubyModKit
|
|
51
61
|
@errors = parse_result.errors
|
52
62
|
@lines = parse_result.source.lines
|
53
63
|
@offsets = parse_result.source.offsets
|
64
|
+
@source = @script.dup
|
54
65
|
@root_node = Node::ProgramNode.new(parse_result.value)
|
55
66
|
init_missions
|
56
67
|
end
|
57
68
|
|
58
69
|
# @rbs return: void
|
70
|
+
# @return [void]
|
59
71
|
def init_missions
|
60
72
|
return unless first_generation?
|
61
73
|
|
@@ -67,20 +79,19 @@ module RubyModKit
|
|
67
79
|
end
|
68
80
|
|
69
81
|
# @rbs return: bool
|
82
|
+
# @return [Boolean]
|
70
83
|
def first_generation?
|
71
84
|
@generation_num == 0
|
72
85
|
end
|
73
86
|
|
74
87
|
# @rbs return: Generation
|
88
|
+
# @return [Generation]
|
75
89
|
def succ
|
76
90
|
if @errors.empty?
|
77
91
|
perform_missions
|
78
92
|
else
|
79
93
|
perform_corrector
|
80
94
|
end
|
81
|
-
@missions.each do |mission|
|
82
|
-
mission.succ(@offset_diff)
|
83
|
-
end
|
84
95
|
@memo_pad.succ(@offset_diff)
|
85
96
|
|
86
97
|
Generation.new(
|
@@ -96,11 +107,13 @@ module RubyModKit
|
|
96
107
|
end
|
97
108
|
|
98
109
|
# @rbs return: String
|
110
|
+
# @return [String]
|
99
111
|
def name
|
100
112
|
"#{@filename || "(eval)"}[gen #{@generation_num}]"
|
101
113
|
end
|
102
114
|
|
103
115
|
# @rbs return: bool
|
116
|
+
# @return [Boolean]
|
104
117
|
def completed?
|
105
118
|
@errors.empty? && @missions.empty?
|
106
119
|
end
|
@@ -109,24 +122,22 @@ module RubyModKit
|
|
109
122
|
# @rbs length: Integer
|
110
123
|
# @rbs str: String
|
111
124
|
# @rbs return: String
|
125
|
+
# @param src_offset [Integer]
|
126
|
+
# @param length [Integer]
|
127
|
+
# @param str [String]
|
128
|
+
# @return [String]
|
112
129
|
def []=(src_offset, length, str)
|
113
130
|
diff = str.length - length
|
114
131
|
@script[@offset_diff[src_offset], length] = str
|
115
132
|
@offset_diff.insert(src_offset, diff)
|
116
133
|
end
|
117
134
|
|
118
|
-
# @rbs src_range: Range[Integer]
|
135
|
+
# @rbs src_range: Range[Integer | nil]
|
119
136
|
# @rbs return: String
|
137
|
+
# @param src_range [Range<Integer, nil>]
|
138
|
+
# @return [String]
|
120
139
|
def [](src_range)
|
121
|
-
|
122
|
-
@script[dst_range] || raise(RubyModKit::Error, "Invalid range")
|
123
|
-
end
|
124
|
-
|
125
|
-
# @rbs offset: Integer
|
126
|
-
# @rbs return: String
|
127
|
-
def line_by_offset(offset)
|
128
|
-
offset = @offset_diff[offset]
|
129
|
-
(@script.match(/.*\n?/, offset) && Regexp.last_match(0)) || raise(RubyModKit::Error)
|
140
|
+
@source[src_range] || raise(RubyModKit::Error, "Invalid range")
|
130
141
|
end
|
131
142
|
|
132
143
|
# @rbs (Integer) -> String
|
@@ -134,62 +145,63 @@ module RubyModKit
|
|
134
145
|
# | (Prism::ParseError) -> String
|
135
146
|
def line(*args)
|
136
147
|
case args
|
137
|
-
in [Integer]
|
138
|
-
|
139
|
-
in [Node::BaseNode]
|
140
|
-
|
141
|
-
in [Prism::ParseError]
|
142
|
-
|
148
|
+
in [Integer => line_num]
|
149
|
+
@lines[line_num] || raise(RubyModKit::Error)
|
150
|
+
in [Node::BaseNode => node]
|
151
|
+
line(node.location.start_line - 1)
|
152
|
+
in [Prism::ParseError => parse_error]
|
153
|
+
begin
|
154
|
+
line(parse_error.location.start_line - 1)
|
155
|
+
rescue RubyModKit::Error
|
156
|
+
""
|
157
|
+
end
|
143
158
|
end
|
144
159
|
end
|
145
160
|
|
146
|
-
# @rbs line_num: Integer
|
147
|
-
# @rbs return: String
|
148
|
-
def line__overload0(line_num)
|
149
|
-
line_by_offset(@offsets[line_num])
|
150
|
-
end
|
151
|
-
|
152
|
-
# @rbs node: Node::BaseNode
|
153
|
-
# @rbs return: String
|
154
|
-
def line__overload1(node)
|
155
|
-
line(node.location.start_line - 1)
|
156
|
-
end
|
157
|
-
|
158
|
-
# @rbs parse_error: Prism::ParseError
|
159
|
-
# @rbs return: String
|
160
|
-
def line__overload2(parse_error)
|
161
|
-
line(parse_error.location.start_line - 1)
|
162
|
-
end
|
163
|
-
|
164
161
|
# @rbs (Integer) -> (Integer | nil)
|
162
|
+
# | (Node::BaseNode) -> (Integer | nil)
|
163
|
+
# | (Node::BaseNode, Integer) -> (Integer | nil)
|
165
164
|
# | (Prism::ParseError) -> (Integer | nil)
|
166
|
-
def
|
165
|
+
def line_offset(*args)
|
167
166
|
case args
|
168
|
-
in [Integer]
|
169
|
-
|
170
|
-
in [
|
171
|
-
|
167
|
+
in [Integer => line_num]
|
168
|
+
@offsets[line_num]
|
169
|
+
in [Node::BaseNode => node]
|
170
|
+
line_offset(node, 0)
|
171
|
+
in [Node::BaseNode => node, Integer => line_offset]
|
172
|
+
line_offset(node.location.start_line - 1 + line_offset)
|
173
|
+
in [Prism::ParseError => parse_error]
|
174
|
+
line_offset(parse_error.location.start_line - 1)
|
172
175
|
end
|
173
176
|
end
|
174
177
|
|
175
|
-
# @rbs
|
178
|
+
# @rbs node: Node::BaseNode
|
176
179
|
# @rbs return: Integer | nil
|
177
|
-
|
178
|
-
|
180
|
+
# @param node [Node::BaseNode]
|
181
|
+
# @return [Integer, nil]
|
182
|
+
def end_line_offset(node)
|
183
|
+
line_offset(node.location.end_line - 1)
|
179
184
|
end
|
180
185
|
|
181
|
-
# @rbs
|
182
|
-
#
|
183
|
-
def
|
184
|
-
|
186
|
+
# @rbs (Integer) -> String
|
187
|
+
# | (Node::BaseNode) -> String
|
188
|
+
def line_indent(*args)
|
189
|
+
case args
|
190
|
+
in [Integer => line_num]
|
191
|
+
line(line_num)[/\A[ \t]*/] || ""
|
192
|
+
in [Node::BaseNode => node]
|
193
|
+
line_indent(node.location.start_line - 1)
|
194
|
+
end
|
185
195
|
end
|
186
196
|
|
187
197
|
# @rbs return: void
|
198
|
+
# @return [void]
|
188
199
|
def perform_corrector
|
189
200
|
@corrector_manager.perform(self)
|
190
201
|
end
|
191
202
|
|
192
203
|
# @rbs return: void
|
204
|
+
# @return [void]
|
193
205
|
def perform_missions
|
194
206
|
@missions.delete_if do |mission|
|
195
207
|
mission.perform(self) || break
|
@@ -198,6 +210,8 @@ module RubyModKit
|
|
198
210
|
|
199
211
|
# @rbs mission: Mission
|
200
212
|
# @rbs return: void
|
213
|
+
# @param mission [Mission]
|
214
|
+
# @return [void]
|
201
215
|
def add_mission(mission)
|
202
216
|
@missions << mission
|
203
217
|
end
|
@@ -207,6 +221,10 @@ module RubyModKit
|
|
207
221
|
# @rbs filename: String | nil
|
208
222
|
# @rbs config: Config | nil
|
209
223
|
# @rbs return: Generation
|
224
|
+
# @param src [String]
|
225
|
+
# @param filename [String, nil]
|
226
|
+
# @param config [Config, nil]
|
227
|
+
# @return [Generation]
|
210
228
|
def resolve(src, filename: nil, config: nil)
|
211
229
|
generation = Generation.new(src.dup, filename: filename, config: config)
|
212
230
|
generation = generation.succ until generation.completed?
|